mirror of
https://github.com/fluencelabs/wasmer
synced 2025-06-17 19:01:20 +00:00
Add preliminary support for throwing and catching uncatchable exceptions.
Additional info: - WebAssembly "traps" are uncatchable, but are still caught by the trampoline caller.
This commit is contained in:
@ -71,6 +71,16 @@ extern "C" {
|
||||
) -> LLVMResult;
|
||||
fn module_delete(module: *mut LLVMModule);
|
||||
fn get_func_symbol(module: *mut LLVMModule, name: *const c_char) -> *const vm::Func;
|
||||
fn throw_unreachable_exception();
|
||||
fn throw_incorrect_call_indirect_signature();
|
||||
// invoke_trampoline(trampoline_t trampoline, void* ctx, void* func, void* params, void* results)
|
||||
fn invoke_trampoline(
|
||||
trampoline: unsafe extern "C" fn(*mut vm::Ctx, *const vm::Func, *const u64, *mut u64),
|
||||
vmctx_ptr: *mut vm::Ctx,
|
||||
func_ptr: *const vm::Func,
|
||||
params: *const u64,
|
||||
results: *mut u64,
|
||||
);
|
||||
}
|
||||
|
||||
fn get_callbacks() -> Callbacks {
|
||||
@ -162,6 +172,11 @@ fn get_callbacks() -> Callbacks {
|
||||
fn_name!("vm.memory.size.dynamic.local") => vmcalls::local_dynamic_memory_size 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.exception.throw.unreachable") => throw_unreachable_exception as _,
|
||||
fn_name!("vm.exception.throw.incorrect-call_indirect_signature") => {
|
||||
throw_incorrect_call_indirect_signature as _
|
||||
}
|
||||
_ => ptr::null(),
|
||||
}
|
||||
}
|
||||
@ -343,7 +358,8 @@ impl ProtectedCaller for LLVMProtectedCaller {
|
||||
|
||||
// Here we go.
|
||||
unsafe {
|
||||
trampoline(
|
||||
invoke_trampoline(
|
||||
trampoline,
|
||||
vmctx_ptr,
|
||||
func_ptr,
|
||||
param_vec.as_ptr(),
|
||||
|
@ -539,6 +539,9 @@ fn parse_function(
|
||||
// Emit an unreachable instruction.
|
||||
// If llvm cannot prove that this is never touched,
|
||||
// it will emit a `ud2` instruction on x86_64 arches.
|
||||
|
||||
builder.build_call(intrinsics.throw_unreachable, &[], "throw");
|
||||
|
||||
ctx.build_trap();
|
||||
builder.build_unreachable();
|
||||
|
||||
@ -731,13 +734,12 @@ fn parse_function(
|
||||
)
|
||||
};
|
||||
|
||||
// let sigindices_equal = builder.build_int_compare(
|
||||
// IntPredicate::EQ,
|
||||
// expected_dynamic_sigindex,
|
||||
// found_dynamic_sigindex,
|
||||
// "sigindices_equal",
|
||||
// );
|
||||
let sigindices_equal = intrinsics.i1_ty.const_int(1, false);
|
||||
let sigindices_equal = builder.build_int_compare(
|
||||
IntPredicate::EQ,
|
||||
expected_dynamic_sigindex,
|
||||
found_dynamic_sigindex,
|
||||
"sigindices_equal",
|
||||
);
|
||||
|
||||
// Tell llvm that `expected_dynamic_sigindex` should equal `found_dynamic_sigindex`.
|
||||
let sigindices_equal = builder
|
||||
@ -764,7 +766,11 @@ fn parse_function(
|
||||
);
|
||||
|
||||
builder.position_at_end(&sigindices_notequal_block);
|
||||
ctx.build_trap();
|
||||
builder.build_call(
|
||||
intrinsics.throw_incorrect_call_indirect_signature,
|
||||
&[],
|
||||
"throw",
|
||||
);
|
||||
builder.build_unreachable();
|
||||
builder.position_at_end(&continue_block);
|
||||
|
||||
|
@ -105,6 +105,9 @@ pub struct Intrinsics {
|
||||
pub memory_size_static_import: FunctionValue,
|
||||
pub memory_size_shared_import: FunctionValue,
|
||||
|
||||
pub throw_unreachable: FunctionValue,
|
||||
pub throw_incorrect_call_indirect_signature: FunctionValue,
|
||||
|
||||
ctx_ty: StructType,
|
||||
pub ctx_ptr_ty: PointerType,
|
||||
}
|
||||
@ -344,7 +347,16 @@ impl Intrinsics {
|
||||
ret_i32_take_ctx_i32,
|
||||
None,
|
||||
),
|
||||
|
||||
throw_unreachable: module.add_function(
|
||||
"vm.exception.throw.unreachable",
|
||||
void_ty.fn_type(&[], false),
|
||||
None,
|
||||
),
|
||||
throw_incorrect_call_indirect_signature: module.add_function(
|
||||
"vm.exception.throw.incorrect-call_indirect_signature",
|
||||
void_ty.fn_type(&[], false),
|
||||
None,
|
||||
),
|
||||
ctx_ty,
|
||||
ctx_ptr_ty,
|
||||
}
|
||||
|
Reference in New Issue
Block a user