Replace the global-exports mechanism with a caller-vmctx mechanism. (#789)
* Replace the global-exports mechanism with a caller-vmctx mechanism. This eliminates the global exports mechanism, and instead adds a caller-vmctx argument to wasm functions so that WASI can obtain the memory and other things from the caller rather than looking them up in a global registry. This replaces #390. * Fixup some merge conflicts * Rustfmt * Ensure VMContext is aligned to 16 bytes With the removal of `global_exports` it "just so happens" that this isn't happening naturally any more. * Fixup some bugs with double vmctx in wasmtime crate * Trampoline stub needed adjusting * Use pointer type instead of always using I64 for caller vmctx * Don't store `ir::Signature` in `Func` since we don't know the pointer size at creation time. * Skip the first 2 arguments in IR signatures since that's the two vmctx parameters. * Update cranelift to 0.56.0 * Handle more merge conflicts * Rustfmt Co-authored-by: Alex Crichton <alex@alexcrichton.com>
This commit is contained in:
@@ -64,7 +64,12 @@ impl Drop for TrampolineState {
|
||||
}
|
||||
}
|
||||
|
||||
unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *mut i128) -> u32 {
|
||||
unsafe extern "C" fn stub_fn(
|
||||
vmctx: *mut VMContext,
|
||||
_caller_vmctx: *mut VMContext,
|
||||
call_id: u32,
|
||||
values_vec: *mut i128,
|
||||
) -> u32 {
|
||||
let mut instance = InstanceHandle::from_vmctx(vmctx);
|
||||
|
||||
let (args, returns_len) = {
|
||||
@@ -72,9 +77,9 @@ unsafe extern "C" fn stub_fn(vmctx: *mut VMContext, call_id: u32, values_vec: *m
|
||||
let signature = &module.signatures[module.functions[FuncIndex::new(call_id as usize)]];
|
||||
|
||||
let mut args = Vec::new();
|
||||
for i in 1..signature.params.len() {
|
||||
for i in 2..signature.params.len() {
|
||||
args.push(Val::read_value_from(
|
||||
values_vec.offset(i as isize - 1),
|
||||
values_vec.offset(i as isize - 2),
|
||||
signature.params[i].value_type,
|
||||
))
|
||||
}
|
||||
@@ -116,12 +121,15 @@ fn make_trampoline(
|
||||
let pointer_type = isa.pointer_type();
|
||||
let mut stub_sig = ir::Signature::new(isa.frontend_config().default_call_conv);
|
||||
|
||||
// Add the `vmctx` parameter.
|
||||
// Add the caller/callee `vmctx` parameters.
|
||||
stub_sig.params.push(ir::AbiParam::special(
|
||||
pointer_type,
|
||||
ir::ArgumentPurpose::VMContext,
|
||||
));
|
||||
|
||||
// Add the caller `vmctx` parameter.
|
||||
stub_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||
|
||||
// Add the `call_id` parameter.
|
||||
stub_sig.params.push(ir::AbiParam::new(types::I32));
|
||||
|
||||
@@ -131,9 +139,10 @@ fn make_trampoline(
|
||||
// Add error/trap return.
|
||||
stub_sig.returns.push(ir::AbiParam::new(types::I32));
|
||||
|
||||
// Compute the size of the values vector. The vmctx and caller vmctx are passed separately.
|
||||
let value_size = 16;
|
||||
let values_vec_len = ((value_size as usize)
|
||||
* cmp::max(signature.params.len() - 1, signature.returns.len()))
|
||||
* cmp::max(signature.params.len() - 2, signature.returns.len()))
|
||||
as u32;
|
||||
|
||||
let mut context = Context::new();
|
||||
@@ -155,7 +164,7 @@ fn make_trampoline(
|
||||
|
||||
let values_vec_ptr_val = builder.ins().stack_addr(pointer_type, ss, 0);
|
||||
let mflags = MemFlags::trusted();
|
||||
for i in 1..signature.params.len() {
|
||||
for i in 2..signature.params.len() {
|
||||
if i == 0 {
|
||||
continue;
|
||||
}
|
||||
@@ -165,14 +174,21 @@ fn make_trampoline(
|
||||
mflags,
|
||||
val,
|
||||
values_vec_ptr_val,
|
||||
((i - 1) * value_size) as i32,
|
||||
((i - 2) * value_size) as i32,
|
||||
);
|
||||
}
|
||||
|
||||
let vmctx_ptr_val = builder.func.dfg.ebb_params(block0)[0];
|
||||
let ebb_params = builder.func.dfg.ebb_params(block0);
|
||||
let vmctx_ptr_val = ebb_params[0];
|
||||
let caller_vmctx_ptr_val = ebb_params[1];
|
||||
let call_id_val = builder.ins().iconst(types::I32, call_id as i64);
|
||||
|
||||
let callee_args = vec![vmctx_ptr_val, call_id_val, values_vec_ptr_val];
|
||||
let callee_args = vec![
|
||||
vmctx_ptr_val,
|
||||
caller_vmctx_ptr_val,
|
||||
call_id_val,
|
||||
values_vec_ptr_val,
|
||||
];
|
||||
|
||||
let new_sig = builder.import_signature(stub_sig);
|
||||
|
||||
@@ -236,17 +252,18 @@ pub fn create_handle_with_function(
|
||||
func: &Rc<dyn Callable + 'static>,
|
||||
store: &Store,
|
||||
) -> Result<InstanceHandle> {
|
||||
let sig = match ft.get_wasmtime_signature() {
|
||||
Some(sig) => sig.clone(),
|
||||
None => bail!("not a supported core wasm signature {:?}", ft),
|
||||
};
|
||||
|
||||
let isa = {
|
||||
let isa_builder = native::builder();
|
||||
let flag_builder = settings::builder();
|
||||
isa_builder.finish(settings::Flags::new(flag_builder))
|
||||
};
|
||||
|
||||
let pointer_type = isa.pointer_type();
|
||||
let sig = match ft.get_wasmtime_signature(pointer_type) {
|
||||
Some(sig) => sig.clone(),
|
||||
None => bail!("not a supported core wasm signature {:?}", ft),
|
||||
};
|
||||
|
||||
let mut fn_builder_ctx = FunctionBuilderContext::new();
|
||||
let mut module = Module::new();
|
||||
let mut finished_functions: PrimaryMap<DefinedFuncIndex, *const VMFunctionBody> =
|
||||
|
||||
Reference in New Issue
Block a user