Skip to content

Commit

Permalink
jsgen: fix javascript backend treating u32 as i32 (fix #20499) (#20618)
Browse files Browse the repository at this point in the history
  • Loading branch information
GGRei committed Jan 21, 2024
1 parent 7b6349f commit d413dec
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
15 changes: 14 additions & 1 deletion vlib/v/gen/js/builtin_types.v
Expand Up @@ -335,7 +335,7 @@ fn (mut g JsGen) gen_builtin_type_defs() {
for typ_name in v_types {
// TODO: JsDoc
match typ_name {
'i8', 'i16', 'int', 'u16', 'u32', 'int_literal' {
'i8', 'i16', 'int', 'u16', 'int_literal' {
// TODO: Bounds checking
g.gen_builtin_prototype(
typ_name: typ_name
Expand All @@ -348,6 +348,19 @@ fn (mut g JsGen) gen_builtin_type_defs() {
to_jsval: '+this'
)
}
// u32 requires special handling in JavaScript to correctly represent it as an unsigned 32-bit integer.
// The '>>> 0' bit operation ensures it is treated as unsigned, covering the full 0 to 2^32-1 range.
'u32' {
g.gen_builtin_prototype(
typ_name: typ_name
default_value: 'new Number(0)'
constructor: 'this.val = Math.floor(Number(val) & 0xffffffff) >>> 0'
value_of: 'Number(this.val)'
to_string: 'this.valueOf().toString()'
eq: 'new bool(self.valueOf() === other.valueOf())'
to_jsval: '+this'
)
}
// u64 and i64 are so big that their values do not fit into JS number so we use BigInt.
'u64' {
if g.pref.output_es5 {
Expand Down
4 changes: 4 additions & 0 deletions vlib/v/gen/js/tests/testdata/u32.out
@@ -0,0 +1,4 @@
4294967295
0
true
25600000
7 changes: 7 additions & 0 deletions vlib/v/gen/js/tests/testdata/u32.v
@@ -0,0 +1,7 @@
fn main() {
println(u32(0xFFFFFFFF))
println(u32(4294967295) + 1)

println(u32(42) == u32(42))
println(u32(100000) * 256)
}

0 comments on commit d413dec

Please sign in to comment.