Skip to content

Commit

Permalink
jsgen: fix inconsistent output (u32) in JS backend (#20691)
Browse files Browse the repository at this point in the history
  • Loading branch information
GGRei committed Jan 30, 2024
1 parent 804a7bd commit afa1a9a
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 7 deletions.
22 changes: 16 additions & 6 deletions vlib/v/gen/js/builtin_types.v
Expand Up @@ -348,15 +348,25 @@ fn (mut g JsGen) gen_builtin_type_defs() {
to_jsval: '+this'
)
}
// u16 / 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.
// For u16, '>>> 0' combined with a mask of 0xffff limits it to the 0 to 2^16-1 range, correctly handling values as unsigned 16-bit integers.
'u16', 'u32' {
// u16 and u32 requires special handling in JavaScript to correctly represent it.
// u16, '>>> 0' combined with a mask of 0xffff limits it to the 0 to 2^16-1 range, correctly handling values as unsigned 16-bit integers.
'u16' {
g.gen_builtin_prototype(
typ_name: typ_name
default_value: 'new Number(0)'
constructor: "this.val = Math.floor(Number(val) & ('" + typ_name +
'\' === "u16" ? 0xffff : 0xffffffff)) >>> 0'
constructor: 'this.val = Math.floor(Number(val) & 0xffff) >>> 0'
value_of: 'Number(this.val)'
to_string: 'this.valueOf().toString()'
eq: 'new bool(self.valueOf() === other.valueOf())'
to_jsval: '+this'
)
}
// u32 '>>> 0' combined with a mask of 0xffffffff limits it to the 0 to 2^32-1 range, correctly handling values as unsigned 32-bit integers.
'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())'
Expand Down
8 changes: 8 additions & 0 deletions vlib/v/gen/js/str.v
Expand Up @@ -120,11 +120,19 @@ fn (mut g JsGen) gen_expr_to_string(expr ast.Expr, etype ast.Type) {
is_var_mut := expr.is_auto_deref_var()
str_fn_name := g.get_str_fn(typ)
g.write('${str_fn_name}(')

if str_method_expects_ptr && !is_ptr {
g.write('new \$ref(')
}
if typ == ast.u32_type && expr is ast.CastExpr {
g.write('new u32(')
}

g.expr(expr)

if typ == ast.u32_type && expr is ast.CastExpr {
g.write(')')
}
if (!str_method_expects_ptr && is_ptr && !is_shared) || is_var_mut {
g.write('.val')
}
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/gen/js/tests/testdata/u32.out
@@ -1,4 +1,4 @@
-1
4294967295
0
true
25600000

0 comments on commit afa1a9a

Please sign in to comment.