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:
Dan Gohman
2020-01-21 14:50:59 -08:00
committed by GitHub
parent de72435576
commit 9a88d3d894
33 changed files with 362 additions and 330 deletions

View File

@@ -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> =