Skip to content

Commit 209c13d

Browse files
Fix(vm): Use checked_pow to prevent silent i128 wrap in Pow.
1 parent 419f0f0 commit 209c13d

File tree

3 files changed

+25
-6
lines changed

3 files changed

+25
-6
lines changed

compiler/src/modules/vm/mod.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -281,11 +281,11 @@ impl<'a> VM<'a> {
281281
(true, true) => {
282282
let exp = b.as_int();
283283
if exp >= 0 {
284-
let result = (a.as_int() as i128).pow(exp as u32);
285-
if result >= Val::INT_MIN as i128 && result <= Val::INT_MAX as i128 {
286-
Val::int(result as i64)
287-
} else {
288-
Val::float(result as f64)
284+
match (a.as_int() as i128).checked_pow(exp as u32) {
285+
Some(result) if result >= Val::INT_MIN as i128
286+
&& result <= Val::INT_MAX as i128 => Val::int(result as i64),
287+
Some(result) => Val::float(result as f64),
288+
None => Val::float(fpowi(a.as_int() as f64, exp as i32)),
289289
}
290290
} else {
291291
Val::float(fpowi(a.as_int() as f64, exp as i32))

compiler/tests/cases/parser_cases.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1618,5 +1618,12 @@
16181618
"names": ["x_1"],
16191619
"instructions": [["LoadConst",0], ["StoreName",0], ["ReturnValue",0]],
16201620
"annotations": {}
1621+
},
1622+
{
1623+
"src": "a[0] += 1",
1624+
"constants": ["0", "1"],
1625+
"names": ["a_0"],
1626+
"instructions": [["LoadName",0], ["LoadConst",0], ["Dup2",0], ["GetItem",0], ["LoadConst",1], ["Add",0], ["StoreItem",0], ["ReturnValue",0]],
1627+
"annotations": {}
16211628
}
16221629
]

compiler/tests/cases/vm_cases.json

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,5 +181,17 @@
181181
{"src": "a = 140737488355328\nprint(-a - 1)", "output": ["-140737488355329"], "result": "None"},
182182
{"src": "print(-(-(2**47)))", "output": ["140737488355328"], "result": "None"},
183183
{"src": "a = 140737488355327\nb = 1\nr = 0\nfor i in range(10):\n r = a + b\nprint(r)", "output": ["140737488355328"], "result": "None"},
184-
{"src": "x = -140737488355328\nprint(-x)", "output": ["140737488355328"], "result": "None"}
184+
{"src": "x = -140737488355328\nprint(-x)", "output": ["140737488355328"], "result": "None"},
185+
{"src": "print(2**62)", "output": ["4611686018427387904"], "result": "None"},
186+
{"src": "print(2**63 > 0)", "output": ["True"], "result": "None"},
187+
{"src": "print(2**127 > 0)", "output": ["True"], "result": "None"},
188+
{"src": "print(2**128 > 0)", "output": ["True"], "result": "None"},
189+
{"src": "print(2**129 > 0)", "output": ["True"], "result": "None"},
190+
{"src": "print(3**40 > 0)", "output": ["True"], "result": "None"},
191+
{"src": "print(2**0)", "output": ["1"], "result": "None"},
192+
{"src": "x = [10, 20, 30]\nx[0] += 5\nprint(x)", "output": ["[15, 20, 30]"], "result": "None"},
193+
{"src": "x = [10, 20, 30]\nx[1] -= 3\nprint(x)", "output": ["[10, 17, 30]"], "result": "None"},
194+
{"src": "x = [2, 3, 4]\nx[2] *= 10\nprint(x)", "output": ["[2, 3, 40]"], "result": "None"},
195+
{"src": "d = {'a': 1}\nd['a'] += 99\nprint(d['a'])", "output": ["100"], "result": "None"},
196+
{"src": "x = [0]\nx[0] += 1\nx[0] += 1\nx[0] += 1\nprint(x[0])", "output": ["3"], "result": "None"}
185197
]

0 commit comments

Comments
 (0)