Add illegal arithmetic runtime error

This commit is contained in:
Lachlan Sneff
2019-03-04 19:56:02 -08:00
parent 3be7144892
commit fe8f8a0132
5 changed files with 35 additions and 77 deletions

View File

@ -70,6 +70,7 @@ public:
IncorrectCallIndirectSignature = 1,
MemoryOutOfBounds = 2,
CallIndirectOOB = 3,
IllegalArithmetic = 4,
Unknown,
};
@ -98,6 +99,12 @@ private:
case Type::MemoryOutOfBounds:
out << "memory access out-of-bounds";
break;
case Type::CallIndirectOOB:
out << "call_indirect out-of-bounds";
break;
case Type::IllegalArithmetic:
out << "illegal arithmetic operation";
break;
case Type::Unknown:
default:
out << "unknown";
@ -142,7 +149,6 @@ extern "C" {
}
[[noreturn]] void throw_trap(WasmTrap::Type ty) {
std::cout << "throwing trap: " << ty << std::endl;
throw WasmTrap(ty);
}

View File

@ -61,6 +61,8 @@ enum WasmTrapType {
Unreachable = 0,
IncorrectCallIndirectSignature = 1,
MemoryOutOfBounds = 2,
CallIndirectOOB = 3,
IllegalArithmetic = 4,
Unknown,
}
@ -407,6 +409,12 @@ impl ProtectedCaller for LLVMProtectedCaller {
WasmTrapType::MemoryOutOfBounds => RuntimeError::Trap {
msg: "memory out-of-bounds access".into(),
},
WasmTrapType::CallIndirectOOB => RuntimeError::Trap {
msg: "call_indirect out-of-bounds".into(),
},
WasmTrapType::IllegalArithmetic => RuntimeError::Trap {
msg: "illegal arithmetic operation".into(),
},
WasmTrapType::Unknown => RuntimeError::Trap {
msg: "unknown trap".into(),
},

View File

@ -122,6 +122,8 @@ pub fn parse_function_bodies(
generate_trampolines(info, &signatures, &module, &context, &builder, &intrinsics);
println!("done generating ir");
let pass_manager = PassManager::create_for_module();
// pass_manager.add_verifier_pass();
pass_manager.add_function_inlining_pass();
@ -131,11 +133,13 @@ pub fn parse_function_bodies(
pass_manager.add_aggressive_inst_combiner_pass();
pass_manager.add_merged_load_store_motion_pass();
// pass_manager.add_sccp_pass();
pass_manager.add_gvn_pass();
// pass_manager.add_new_gvn_pass();
// pass_manager.add_gvn_pass();
pass_manager.add_new_gvn_pass();
pass_manager.add_aggressive_dce_pass();
pass_manager.run_on_module(&module);
println!("done optimizing ir");
// module.print_to_stderr();
Ok((module, intrinsics))
@ -2116,7 +2120,7 @@ fn trap_if_zero_or_overflow(
builder.position_at_end(&should_trap_block);
builder.build_call(
intrinsics.throw_trap,
&[intrinsics.trap_memory_oob],
&[intrinsics.trap_illegal_arithmetic],
"throw",
);
builder.build_unreachable();
@ -2158,7 +2162,7 @@ fn trap_if_zero(
builder.position_at_end(&should_trap_block);
builder.build_call(
intrinsics.throw_trap,
&[intrinsics.trap_memory_oob],
&[intrinsics.trap_illegal_arithmetic],
"throw",
);
builder.build_unreachable();

View File

@ -97,6 +97,7 @@ pub struct Intrinsics {
pub trap_call_indirect_sig: BasicValueEnum,
pub trap_call_indirect_oob: BasicValueEnum,
pub trap_memory_oob: BasicValueEnum,
pub trap_illegal_arithmetic: BasicValueEnum,
// VM intrinsics.
pub memory_grow_dynamic_local: FunctionValue,
@ -295,6 +296,7 @@ impl Intrinsics {
trap_call_indirect_sig: i32_ty.const_int(1, false).as_basic_value_enum(),
trap_call_indirect_oob: i32_ty.const_int(3, false).as_basic_value_enum(),
trap_memory_oob: i32_ty.const_int(2, false).as_basic_value_enum(),
trap_illegal_arithmetic: i32_ty.const_int(4, false).as_basic_value_enum(),
// VM intrinsics.
memory_grow_dynamic_local: module.add_function(

View File

@ -4,76 +4,14 @@ use wabt::wat2wasm;
static WAT: &'static str = r#"
(module
(type (;0;) (func (param i32 i32)))
(type (;1;) (func (param i32 i64)))
(type (;2;) (func (param i32) (result i32)))
(type (;3;) (func (param i32) (result i64)))
(type (;4;) (func (param i64) (result i64)))
(type (;5;) (func (param f32) (result f32)))
(type (;6;) (func (param f64) (result f64)))
(func (;0;) (type 0) (param i32 i32)
local.get 0
local.get 1
i32.store8
local.get 0
i32.const 1
i32.add
local.get 1
i32.const 8
i32.shr_u
i32.store8)
(func (;1;) (type 0) (param i32 i32)
local.get 0
local.get 1
call 0
local.get 0
i32.const 2
i32.add
local.get 1
i32.const 16
i32.shr_u
call 0)
(func (;2;) (type 1) (param i32 i64)
local.get 0
local.get 1
i32.wrap_i64
call 1
local.get 0
i32.const 4
i32.add
local.get 1
i64.const 32
i64.shr_u
i32.wrap_i64
call 1)
(func (;3;) (type 2) (param i32) (result i32)
local.get 0
i32.load8_u
local.get 0
i32.const 1
i32.add
i32.load8_u
i32.const 8
i32.shl
i32.or)
(func (;4;) (type 2) (param i32) (result i32)
local.get 0
call 3
local.get 0
i32.const 2
i32.add
call 3
i32.const 16
i32.shl
i32.or)
(func (;5;) (type 3) (param i32) (result i64)
local.get 0
i64.extend_i32_u
local.get 0
call 4
i64.extend_i32_u
i64.or)
(memory (;0;) 1))
(type (;0;) (func (result i32)))
(func $dbz (result i32)
i32.const 42
i32.const 0
i32.div_u
)
(export "dbz" (func $dbz))
)
"#;
// static WAT2: &'static str = r#"
@ -110,9 +48,9 @@ fn main() -> Result<(), error::Error> {
println!("instantiating");
let instance = module.instantiate(&imports! {})?;
let foo = instance.dyn_func("four")?;
let foo = instance.dyn_func("dbz")?;
let result = foo.call(&[Value::I32(10)]);
let result = foo.call(&[]);
println!("result: {:?}", result);