Remove multiple throwing functions, just use one.

This commit is contained in:
Lachlan Sneff
2019-03-02 14:16:02 -08:00
parent 9a90689b93
commit 57bfa9b0a4
4 changed files with 60 additions and 36 deletions

View File

@ -40,30 +40,51 @@ typedef struct {
visit_fde_t visit_fde; visit_fde_t visit_fde;
} callbacks_t; } callbacks_t;
class WasmException { struct WasmException {
public: public:
virtual std::string description() const noexcept = 0; virtual std::string description() const noexcept = 0;
}; };
struct UncatchableException : WasmException { struct UncatchableException : WasmException {
public: public:
enum class Type { virtual std::string description() const noexcept override {
Unreachable, return "Uncatchable exception";
IncorrectCallIndirectSignature, }
Unknown, };
} type;
UncatchableException(Type type) : type(type) {} struct UserException : UncatchableException {
public:
UserException(std::string msg) : msg(msg) {}
virtual std::string description() const noexcept override {
return std::string("user exception: ") + msg;
}
private:
std::string msg;
};
struct WasmTrap : UncatchableException {
public:
enum Type {
Unreachable = 0,
IncorrectCallIndirectSignature = 1,
MemoryOutOfBounds = 2,
Unknown,
};
WasmTrap(Type type) : type(type) {}
virtual std::string description() const noexcept override { virtual std::string description() const noexcept override {
std::ostringstream ss; std::ostringstream ss;
ss ss
<< "Uncatchable exception:" << '\n' << "WebAssembly trap:" << '\n'
<< " - type: " << type << '\n'; << " - type: " << type << '\n';
return ss.str(); return ss.str();
} }
Type type;
private: private:
friend std::ostream& operator<<(std::ostream& out, const Type& ty) { friend std::ostream& operator<<(std::ostream& out, const Type& ty) {
switch (ty) { switch (ty) {
@ -73,7 +94,11 @@ private:
case Type::IncorrectCallIndirectSignature: case Type::IncorrectCallIndirectSignature:
out << "incorrect call_indirect signature"; out << "incorrect call_indirect signature";
break; break;
case Type::MemoryOutOfBounds:
out << "memory access out-of-bounds";
break;
case Type::Unknown: case Type::Unknown:
default:
out << "unknown"; out << "unknown";
break; break;
} }
@ -93,7 +118,7 @@ public:
uint64_t values[]; uint64_t values[];
}; };
class WasmModule { struct WasmModule {
public: public:
WasmModule( WasmModule(
const uint8_t *object_start, const uint8_t *object_start,
@ -115,11 +140,8 @@ extern "C" {
return RESULT_OK; return RESULT_OK;
} }
void throw_unreachable_exception() { void throw_trap(WasmTrap::Type ty) {
throw UncatchableException(UncatchableException::Type::Unreachable); throw WasmTrap(ty);
}
void throw_incorrect_call_indirect_signature() {
throw UncatchableException(UncatchableException::Type::IncorrectCallIndirectSignature);
} }
void module_delete(WasmModule* module) { void module_delete(WasmModule* module) {

View File

@ -71,9 +71,9 @@ extern "C" {
) -> LLVMResult; ) -> LLVMResult;
fn module_delete(module: *mut LLVMModule); fn module_delete(module: *mut LLVMModule);
fn get_func_symbol(module: *mut LLVMModule, name: *const c_char) -> *const vm::Func; fn get_func_symbol(module: *mut LLVMModule, name: *const c_char) -> *const vm::Func;
fn throw_unreachable_exception();
fn throw_incorrect_call_indirect_signature(); fn throw_trap(ty: i32);
// invoke_trampoline(trampoline_t trampoline, void* ctx, void* func, void* params, void* results)
fn invoke_trampoline( fn invoke_trampoline(
trampoline: unsafe extern "C" fn(*mut vm::Ctx, *const vm::Func, *const u64, *mut u64), trampoline: unsafe extern "C" fn(*mut vm::Ctx, *const vm::Func, *const u64, *mut u64),
vmctx_ptr: *mut vm::Ctx, vmctx_ptr: *mut vm::Ctx,
@ -173,10 +173,8 @@ fn get_callbacks() -> Callbacks {
fn_name!("vm.memory.grow.static.local") => vmcalls::local_static_memory_grow as _, fn_name!("vm.memory.grow.static.local") => vmcalls::local_static_memory_grow as _,
fn_name!("vm.memory.size.static.local") => vmcalls::local_static_memory_size as _, fn_name!("vm.memory.size.static.local") => vmcalls::local_static_memory_size as _,
fn_name!("vm.exception.throw.unreachable") => throw_unreachable_exception as _, fn_name!("vm.exception.trap") => throw_trap as _,
fn_name!("vm.exception.throw.incorrect-call_indirect_signature") => {
throw_incorrect_call_indirect_signature as _
}
_ => ptr::null(), _ => ptr::null(),
} }
} }

View File

@ -540,9 +540,11 @@ fn parse_function(
// If llvm cannot prove that this is never touched, // If llvm cannot prove that this is never touched,
// it will emit a `ud2` instruction on x86_64 arches. // it will emit a `ud2` instruction on x86_64 arches.
builder.build_call(intrinsics.throw_unreachable, &[], "throw"); builder.build_call(
intrinsics.throw_trap,
ctx.build_trap(); &[intrinsics.trap_unreachable],
"throw",
);
builder.build_unreachable(); builder.build_unreachable();
state.reachable = false; state.reachable = false;
@ -767,8 +769,8 @@ fn parse_function(
builder.position_at_end(&sigindices_notequal_block); builder.position_at_end(&sigindices_notequal_block);
builder.build_call( builder.build_call(
intrinsics.throw_incorrect_call_indirect_signature, intrinsics.throw_trap,
&[], &[intrinsics.trap_call_indirect_sig],
"throw", "throw",
); );
builder.build_unreachable(); builder.build_unreachable();

View File

@ -90,6 +90,10 @@ pub struct Intrinsics {
pub f32_zero: FloatValue, pub f32_zero: FloatValue,
pub f64_zero: FloatValue, pub f64_zero: FloatValue,
pub trap_unreachable: BasicValueEnum,
pub trap_call_indirect_sig: BasicValueEnum,
pub trap_memory_oob: BasicValueEnum,
// VM intrinsics. // VM intrinsics.
pub memory_grow_dynamic_local: FunctionValue, pub memory_grow_dynamic_local: FunctionValue,
pub memory_grow_static_local: FunctionValue, pub memory_grow_static_local: FunctionValue,
@ -105,8 +109,7 @@ pub struct Intrinsics {
pub memory_size_static_import: FunctionValue, pub memory_size_static_import: FunctionValue,
pub memory_size_shared_import: FunctionValue, pub memory_size_shared_import: FunctionValue,
pub throw_unreachable: FunctionValue, pub throw_trap: FunctionValue,
pub throw_incorrect_call_indirect_signature: FunctionValue,
ctx_ty: StructType, ctx_ty: StructType,
pub ctx_ptr_ty: PointerType, pub ctx_ptr_ty: PointerType,
@ -285,6 +288,10 @@ impl Intrinsics {
f32_zero, f32_zero,
f64_zero, f64_zero,
trap_unreachable: i32_zero.as_basic_value_enum(),
trap_call_indirect_sig: i32_ty.const_int(1, false).as_basic_value_enum(),
trap_memory_oob: i32_ty.const_int(2, false).as_basic_value_enum(),
// VM intrinsics. // VM intrinsics.
memory_grow_dynamic_local: module.add_function( memory_grow_dynamic_local: module.add_function(
"vm.memory.grow.dynamic.local", "vm.memory.grow.dynamic.local",
@ -347,14 +354,9 @@ impl Intrinsics {
ret_i32_take_ctx_i32, ret_i32_take_ctx_i32,
None, None,
), ),
throw_unreachable: module.add_function( throw_trap: module.add_function(
"vm.exception.throw.unreachable", "vm.exception.trap",
void_ty.fn_type(&[], false), void_ty.fn_type(&[i32_ty_basic], false),
None,
),
throw_incorrect_call_indirect_signature: module.add_function(
"vm.exception.throw.incorrect-call_indirect_signature",
void_ty.fn_type(&[], false),
None, None,
), ),
ctx_ty, ctx_ty,