Skip to content

Commit d413dec

Browse files
authored
jsgen: fix javascript backend treating u32 as i32 (fix #20499) (#20618)
1 parent 7b6349f commit d413dec

File tree

3 files changed

+25
-1
lines changed

3 files changed

+25
-1
lines changed

vlib/v/gen/js/builtin_types.v

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -335,7 +335,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
335335
for typ_name in v_types {
336336
// TODO: JsDoc
337337
match typ_name {
338-
'i8', 'i16', 'int', 'u16', 'u32', 'int_literal' {
338+
'i8', 'i16', 'int', 'u16', 'int_literal' {
339339
// TODO: Bounds checking
340340
g.gen_builtin_prototype(
341341
typ_name: typ_name
@@ -348,6 +348,19 @@ fn (mut g JsGen) gen_builtin_type_defs() {
348348
to_jsval: '+this'
349349
)
350350
}
351+
// u32 requires special handling in JavaScript to correctly represent it as an unsigned 32-bit integer.
352+
// The '>>> 0' bit operation ensures it is treated as unsigned, covering the full 0 to 2^32-1 range.
353+
'u32' {
354+
g.gen_builtin_prototype(
355+
typ_name: typ_name
356+
default_value: 'new Number(0)'
357+
constructor: 'this.val = Math.floor(Number(val) & 0xffffffff) >>> 0'
358+
value_of: 'Number(this.val)'
359+
to_string: 'this.valueOf().toString()'
360+
eq: 'new bool(self.valueOf() === other.valueOf())'
361+
to_jsval: '+this'
362+
)
363+
}
351364
// u64 and i64 are so big that their values do not fit into JS number so we use BigInt.
352365
'u64' {
353366
if g.pref.output_es5 {

vlib/v/gen/js/tests/testdata/u32.out

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
4294967295
2+
0
3+
true
4+
25600000

vlib/v/gen/js/tests/testdata/u32.v

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
fn main() {
2+
println(u32(0xFFFFFFFF))
3+
println(u32(4294967295) + 1)
4+
5+
println(u32(42) == u32(42))
6+
println(u32(100000) * 256)
7+
}

0 commit comments

Comments
 (0)