Skip to content

Commit 5f8d770

Browse files
authored
fix(compiler): Properly parse large hex numbers (#1546)
1 parent e7f6d21 commit 5f8d770

File tree

4 files changed

+152
-1
lines changed

4 files changed

+152
-1
lines changed

compiler/src/utils/literals.re

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,18 @@ let simple_number_max = 1073741823L;
33
let simple_number_min = (-1073741824L);
44

55
let conv_number_int = s => {
6-
Int64.of_string_opt(s);
6+
switch (Int64.of_string_opt(s)) {
7+
| Some(n) =>
8+
// We may accidentally parse the number using its two's
9+
// compliment representation when it should be a bigint
10+
// We just return None in this case
11+
if (n < 0L && s.[0] != '-' || n > 0L && s.[0] == '-') {
12+
None;
13+
} else {
14+
Some(n);
15+
}
16+
| None => None
17+
};
718
};
819

920
let conv_number_float = s => {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
basic functionality › bigint_start_pos
2+
(module
3+
(type $none_=>_i32 (func (result i32)))
4+
(type $none_=>_none (func))
5+
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
6+
(import \"_grainEnv\" \"mem\" (memory $0 0))
7+
(import \"_grainEnv\" \"tbl\" (table $tbl 0 funcref))
8+
(import \"_grainEnv\" \"relocBase\" (global $relocBase_0 i32))
9+
(import \"_grainEnv\" \"moduleRuntimeId\" (global $moduleRuntimeId_0 i32))
10+
(import \"GRAIN$MODULE$runtime/gc\" \"GRAIN$EXPORT$malloc\" (global $GRAIN$EXPORT$malloc_0 (mut i32)))
11+
(import \"GRAIN$MODULE$runtime/gc\" \"malloc\" (func $malloc_0 (param i32 i32) (result i32)))
12+
(global $GRAIN$TABLE_SIZE i32 (i32.const 0))
13+
(elem $elem (global.get $relocBase_0))
14+
(export \"memory\" (memory $0))
15+
(export \"_gmain\" (func $_gmain))
16+
(export \"_start\" (func $_start))
17+
(export \"GRAIN$TABLE_SIZE\" (global $GRAIN$TABLE_SIZE))
18+
(func $_gmain (result i32)
19+
(local $0 i32)
20+
(local $1 i32)
21+
(local $2 i32)
22+
(local $3 i64)
23+
(local $4 f32)
24+
(local $5 f64)
25+
(return
26+
(block $cleanup_locals.3 (result i32)
27+
(local.set $0
28+
(block $compile_block.2 (result i32)
29+
(block $allocate_number.1 (result i32)
30+
(i32.store
31+
(local.tee $0
32+
(call $malloc_0
33+
(global.get $GRAIN$EXPORT$malloc_0)
34+
(i32.const 24)
35+
)
36+
)
37+
(i32.const 5)
38+
)
39+
(i32.store offset=4
40+
(local.get $0)
41+
(i32.const 6)
42+
)
43+
(i32.store offset=8
44+
(local.get $0)
45+
(i32.const 1)
46+
)
47+
(i32.store offset=12
48+
(local.get $0)
49+
(i32.const 0)
50+
)
51+
(i64.store offset=16
52+
(local.get $0)
53+
(i64.const -1)
54+
)
55+
(local.get $0)
56+
)
57+
)
58+
)
59+
(local.get $0)
60+
)
61+
)
62+
)
63+
(func $_start
64+
(drop
65+
(call $_gmain)
66+
)
67+
)
68+
;; custom section \"cmi\", size 248
69+
)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
basic functionality › bigint_start_neg
2+
(module
3+
(type $none_=>_i32 (func (result i32)))
4+
(type $none_=>_none (func))
5+
(type $i32_i32_=>_i32 (func (param i32 i32) (result i32)))
6+
(import \"_grainEnv\" \"mem\" (memory $0 0))
7+
(import \"_grainEnv\" \"tbl\" (table $tbl 0 funcref))
8+
(import \"_grainEnv\" \"relocBase\" (global $relocBase_0 i32))
9+
(import \"_grainEnv\" \"moduleRuntimeId\" (global $moduleRuntimeId_0 i32))
10+
(import \"GRAIN$MODULE$runtime/gc\" \"GRAIN$EXPORT$malloc\" (global $GRAIN$EXPORT$malloc_0 (mut i32)))
11+
(import \"GRAIN$MODULE$runtime/gc\" \"malloc\" (func $malloc_0 (param i32 i32) (result i32)))
12+
(global $GRAIN$TABLE_SIZE i32 (i32.const 0))
13+
(elem $elem (global.get $relocBase_0))
14+
(export \"memory\" (memory $0))
15+
(export \"_gmain\" (func $_gmain))
16+
(export \"_start\" (func $_start))
17+
(export \"GRAIN$TABLE_SIZE\" (global $GRAIN$TABLE_SIZE))
18+
(func $_gmain (result i32)
19+
(local $0 i32)
20+
(local $1 i32)
21+
(local $2 i32)
22+
(local $3 i64)
23+
(local $4 f32)
24+
(local $5 f64)
25+
(return
26+
(block $cleanup_locals.3 (result i32)
27+
(local.set $0
28+
(block $compile_block.2 (result i32)
29+
(block $allocate_number.1 (result i32)
30+
(i32.store
31+
(local.tee $0
32+
(call $malloc_0
33+
(global.get $GRAIN$EXPORT$malloc_0)
34+
(i32.const 24)
35+
)
36+
)
37+
(i32.const 5)
38+
)
39+
(i32.store offset=4
40+
(local.get $0)
41+
(i32.const 6)
42+
)
43+
(i32.store offset=8
44+
(local.get $0)
45+
(i32.const 1)
46+
)
47+
(i32.store offset=12
48+
(local.get $0)
49+
(i32.const 1)
50+
)
51+
(i64.store offset=16
52+
(local.get $0)
53+
(i64.const -1)
54+
)
55+
(local.get $0)
56+
)
57+
)
58+
)
59+
(local.get $0)
60+
)
61+
)
62+
)
63+
(func $_start
64+
(drop
65+
(call $_gmain)
66+
)
67+
)
68+
;; custom section \"cmi\", size 248
69+
)

compiler/test/suites/basic_functionality.re

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ describe("basic functionality", ({test, testSkip}) => {
1616
assertSnapshot("neg", "-40");
1717
assertSnapshot("simple_min", "-1073741824");
1818
assertSnapshot("simple_max", "1073741823");
19+
assertSnapshot("bigint_start_neg", "-0xffff_ffff_ffff_ffff");
20+
assertSnapshot("bigint_start_pos", "0xffff_ffff_ffff_ffff");
1921
assertSnapshot("heap_number_i32_wrapper", "1073741824");
2022
assertSnapshot("heap_number_i32_wrapper_max", "2147483647");
2123
assertSnapshot("heap_number_i64_wrapper", "2147483648");

0 commit comments

Comments
 (0)