mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-07-29 20:29:18 +00:00
LibWasm: Adjust signed integer operations to avoid UB
Perform signed integer shifts, addition, subtraction, and rotations using their corresponding unsigned type. Additionally, mod the right hand side of shifts and rotations by the bit width of the integer per the spec. This seems strange, but the spec is clear on the desired wrapping behavior of arithmetic operations.
This commit is contained in:
parent
d74eca78aa
commit
2af591267c
Notes:
sideshowbarker
2024-07-18 09:10:57 +09:00
Author: https://github.com/ADKaster
Commit: 2af591267c
Pull-request: https://github.com/SerenityOS/serenity/pull/8633
Issue: https://github.com/SerenityOS/serenity/issues/7158
Issue: https://github.com/SerenityOS/serenity/issues/8629
1 changed files with 17 additions and 16 deletions
|
@ -216,6 +216,7 @@ void BytecodeInterpreter::call_address(Configuration& configuration, FunctionAdd
|
|||
auto lhs = lhs_entry.get<Value>().to<type>(); \
|
||||
TRAP_IF_NOT(lhs.has_value()); \
|
||||
TRAP_IF_NOT(rhs.has_value()); \
|
||||
__VA_ARGS__; \
|
||||
auto result = operation(lhs.value(), rhs.value()); \
|
||||
dbgln_if(WASM_TRACE_DEBUG, "{}({} {}) = {}", #operation, lhs.value(), rhs.value(), result); \
|
||||
configuration.stack().peek() = Value(cast(result)); \
|
||||
|
@ -881,11 +882,11 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
|||
case Instructions::i32_popcnt.value():
|
||||
UNARY_NUMERIC_OPERATION(i32, __builtin_popcount);
|
||||
case Instructions::i32_add.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, +, i32);
|
||||
BINARY_NUMERIC_OPERATION(u32, +, i32);
|
||||
case Instructions::i32_sub.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, -, i32);
|
||||
BINARY_NUMERIC_OPERATION(u32, -, i32);
|
||||
case Instructions::i32_mul.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, *, i32);
|
||||
BINARY_NUMERIC_OPERATION(u32, *, i32);
|
||||
case Instructions::i32_divs.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, /, i32, TRAP_IF_NOT(!(Checked<i32>(lhs.value()) /= rhs.value()).has_overflow()));
|
||||
case Instructions::i32_divu.value():
|
||||
|
@ -901,15 +902,15 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
|||
case Instructions::i32_xor.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, ^, i32);
|
||||
case Instructions::i32_shl.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, <<, i32);
|
||||
BINARY_NUMERIC_OPERATION(u32, <<, i32, (rhs = rhs.value() % 32));
|
||||
case Instructions::i32_shrs.value():
|
||||
BINARY_NUMERIC_OPERATION(i32, >>, i32);
|
||||
BINARY_NUMERIC_OPERATION(u32, >>, i32, (rhs = rhs.value() % 32)); // FIXME: eh, shouldn't we keep lhs as signed?
|
||||
case Instructions::i32_shru.value():
|
||||
BINARY_NUMERIC_OPERATION(u32, >>, i32);
|
||||
BINARY_NUMERIC_OPERATION(u32, >>, i32, (rhs = rhs.value() % 32));
|
||||
case Instructions::i32_rotl.value():
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u32, rotl, i32);
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u32, rotl, i32, (rhs = rhs.value() % 32));
|
||||
case Instructions::i32_rotr.value():
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u32, rotr, i32);
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u32, rotr, i32, (rhs = rhs.value() % 32));
|
||||
case Instructions::i64_clz.value():
|
||||
UNARY_NUMERIC_OPERATION(i64, clz);
|
||||
case Instructions::i64_ctz.value():
|
||||
|
@ -917,11 +918,11 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
|||
case Instructions::i64_popcnt.value():
|
||||
UNARY_NUMERIC_OPERATION(i64, __builtin_popcountll);
|
||||
case Instructions::i64_add.value():
|
||||
BINARY_NUMERIC_OPERATION(i64, +, i64);
|
||||
BINARY_NUMERIC_OPERATION(u64, +, i64);
|
||||
case Instructions::i64_sub.value():
|
||||
BINARY_NUMERIC_OPERATION(i64, -, i64);
|
||||
BINARY_NUMERIC_OPERATION(u64, -, i64);
|
||||
case Instructions::i64_mul.value():
|
||||
BINARY_NUMERIC_OPERATION(i64, *, i64);
|
||||
BINARY_NUMERIC_OPERATION(u64, *, i64);
|
||||
case Instructions::i64_divs.value():
|
||||
OVF_CHECKED_BINARY_NUMERIC_OPERATION(i64, /, i64, TRAP_IF_NOT(rhs.value() != 0));
|
||||
case Instructions::i64_divu.value():
|
||||
|
@ -937,15 +938,15 @@ void BytecodeInterpreter::interpret(Configuration& configuration, InstructionPoi
|
|||
case Instructions::i64_xor.value():
|
||||
BINARY_NUMERIC_OPERATION(i64, ^, i64);
|
||||
case Instructions::i64_shl.value():
|
||||
BINARY_NUMERIC_OPERATION(i64, <<, i64);
|
||||
BINARY_NUMERIC_OPERATION(u64, <<, i64, (rhs = rhs.value() % 64));
|
||||
case Instructions::i64_shrs.value():
|
||||
BINARY_NUMERIC_OPERATION(i64, >>, i64);
|
||||
BINARY_NUMERIC_OPERATION(u64, >>, i64, (rhs = rhs.value() % 64)); // FIXME: eh, shouldn't we keep lhs as signed?
|
||||
case Instructions::i64_shru.value():
|
||||
BINARY_NUMERIC_OPERATION(u64, >>, i64);
|
||||
BINARY_NUMERIC_OPERATION(u64, >>, i64, (rhs = rhs.value() % 64));
|
||||
case Instructions::i64_rotl.value():
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u64, rotl, i64);
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u64, rotl, i64, (rhs = rhs.value() % 64));
|
||||
case Instructions::i64_rotr.value():
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u64, rotr, i64);
|
||||
BINARY_PREFIX_NUMERIC_OPERATION(u64, rotr, i64, (rhs = rhs.value() % 64));
|
||||
case Instructions::f32_abs.value():
|
||||
UNARY_NUMERIC_OPERATION(float, fabsf);
|
||||
case Instructions::f32_neg.value():
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue