From 9a88d3d8941ef5c03dfd156956dd045ab3d8ce2b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Tue, 21 Jan 2020 14:50:59 -0800 Subject: [PATCH] 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 --- Cargo.lock | 32 ++-- crates/api/src/callable.rs | 2 + crates/api/src/module.rs | 2 - crates/api/src/runtime.rs | 10 - crates/api/src/trampoline/create_handle.rs | 7 +- crates/api/src/trampoline/func.rs | 45 +++-- crates/api/src/types.rs | 62 +++--- crates/environ/Cargo.toml | 8 +- crates/environ/src/func_environ.rs | 22 ++- crates/environ/src/module_environ.rs | 2 + crates/jit/Cargo.toml | 10 +- crates/jit/src/action.rs | 4 +- crates/jit/src/compiler.rs | 33 ++-- crates/jit/src/context.rs | 22 +-- crates/jit/src/instantiate.rs | 12 +- crates/lightbeam/Cargo.toml | 2 +- crates/misc/rust/macro/src/lib.rs | 1 - crates/runtime/signalhandlers/Trampolines.cpp | 13 +- crates/runtime/src/instance.rs | 40 +--- crates/runtime/src/traphandlers.rs | 15 +- crates/runtime/src/vmcontext.rs | 10 +- .../test-programs/tests/wasm_tests/runtime.rs | 2 - crates/wasi-c/Cargo.toml | 6 +- crates/wasi-c/src/instantiate.rs | 2 - crates/wasi-c/src/syscalls.rs | 66 ++++++- crates/wasi-common/wig/src/wasi.rs | 3 +- crates/wasi/Cargo.toml | 6 +- crates/wasi/src/instantiate.rs | 47 +++-- crates/wasi/src/old/snapshot_0/instantiate.rs | 10 +- crates/wasi/src/old/snapshot_0/syscalls.rs | 177 ++++++++++++------ scripts/cranelift-version.sh | 2 +- src/commands/run.rs | 4 +- tests/instantiate.rs | 13 +- 33 files changed, 362 insertions(+), 330 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d049f82a53..40021a5ca6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -350,18 +350,18 @@ dependencies = [ [[package]] name = "cranelift-bforest" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40af6e6f7419110906d0f7b4b8084d3216be64d7da77aa12887885ebe0fc2776" +checksum = "1dfb4890b4075d5c39a581c0cf6354b43c8f8273d232cbc2a5e6c7e0f1027edc" dependencies = [ "cranelift-entity", ] [[package]] name = "cranelift-codegen" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88583eb22e5cd0fe1ef66f0b80d0063d21d30e84e887d08b3d369def3ea7b4be" +checksum = "7600b2e36e28ecb0872e803d794b05c7a000273af8f7ac7d7cc32362e082e647" dependencies = [ "byteorder", "cranelift-bforest", @@ -378,9 +378,9 @@ dependencies = [ [[package]] name = "cranelift-codegen-meta" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353872c984943b9134d7c835eb9d12932bd90f4992dbe666593771bee920d673" +checksum = "65e50e5d5ffd37ec65b347cfbc653d64d0593b0ef7ff1eaf159f9fe1e1947207" dependencies = [ "cranelift-codegen-shared", "cranelift-entity", @@ -388,24 +388,24 @@ dependencies = [ [[package]] name = "cranelift-codegen-shared" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd1e96479a56981cce5c8f14d26773195d662ccdbbeca39fb8eba22b5ca8ea6a" +checksum = "dc3de82e8bbd74f58dd8791c09cea215ba775f0bed780cbe4269ba3138848a51" [[package]] name = "cranelift-entity" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37bc8dc3d4274ededc687d84821f491a8a03447dbb7481983936220892cf55b4" +checksum = "35fd5d8705013678bdcd21d607b6fe70d6d5a8f8a954820cf16a19275331478c" dependencies = [ "serde", ] [[package]] name = "cranelift-frontend" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea33e55bda8c425f3f533355b03e3a43cf29b4e228b35b868b6a1c43b6a139e" +checksum = "1c948841f008f5f147e9a7527e144e1014b979f77e4190ade8080070436dd208" dependencies = [ "cranelift-codegen", "log", @@ -415,9 +415,9 @@ dependencies = [ [[package]] name = "cranelift-native" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c22cfaaa5e69eddaddd6cfa7a76233de964b9b2245e81a5f47dae739931ad0d" +checksum = "7f9da354ffc3b9dd1c244eb23cc49048a7117bf685bc2a8fb5b3d4a3f6661d80" dependencies = [ "cranelift-codegen", "raw-cpuid", @@ -426,9 +426,9 @@ dependencies = [ [[package]] name = "cranelift-wasm" -version = "0.55.0" +version = "0.56.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "038f8fd636abc83ccd6f110e0891766521c3599b52173c0f37e61c684f19a15d" +checksum = "2f48052598a13f46fa6fe1490e460bd6c9c61e81823b2e527165566f8d76755a" dependencies = [ "cranelift-codegen", "cranelift-entity", diff --git a/crates/api/src/callable.rs b/crates/api/src/callable.rs index 732f958981..5b77ec00a4 100644 --- a/crates/api/src/callable.rs +++ b/crates/api/src/callable.rs @@ -3,6 +3,7 @@ use crate::trampoline::{generate_func_export, take_api_trap}; use crate::trap::Trap; use crate::types::FuncType; use crate::values::Val; +use std::ptr; use std::rc::Rc; use wasmtime_environ::ir; use wasmtime_jit::InstanceHandle; @@ -150,6 +151,7 @@ impl WrappedCallable for WasmtimeFn { self.instance.with_signals_on(|| { wasmtime_runtime::wasmtime_call_trampoline( vmctx, + ptr::null_mut(), exec_code_buf, values_vec.as_mut_ptr() as *mut u8, ) diff --git a/crates/api/src/module.rs b/crates/api/src/module.rs index 25c9403600..43edc21acf 100644 --- a/crates/api/src/module.rs +++ b/crates/api/src/module.rs @@ -395,12 +395,10 @@ impl Module { } fn compile(store: &Store, binary: &[u8], module_name: Option<&str>) -> Result { - let exports = store.global_exports().clone(); let compiled_module = CompiledModule::new( &mut store.compiler_mut(), binary, module_name, - exports, store.engine().config().debug_info, )?; diff --git a/crates/api/src/runtime.rs b/crates/api/src/runtime.rs index 5563be02b0..415e633c21 100644 --- a/crates/api/src/runtime.rs +++ b/crates/api/src/runtime.rs @@ -342,7 +342,6 @@ pub struct Store { struct StoreInner { engine: Engine, compiler: RefCell, - global_exports: Rc>>>, signature_cache: RefCell>, } @@ -355,7 +354,6 @@ impl Store { inner: Rc::new(StoreInner { engine: engine.clone(), compiler: RefCell::new(compiler), - global_exports: Rc::new(RefCell::new(HashMap::new())), signature_cache: RefCell::new(HashMap::new()), }), } @@ -370,14 +368,6 @@ impl Store { self.inner.compiler.borrow_mut() } - // Specific to wasmtime: hack to pass memory around to wasi - #[doc(hidden)] - pub fn global_exports( - &self, - ) -> &Rc>>> { - &self.inner.global_exports - } - pub(crate) fn register_wasmtime_signature( &self, signature: &ir::Signature, diff --git a/crates/api/src/trampoline/create_handle.rs b/crates/api/src/trampoline/create_handle.rs index 864ec3a612..3b3834d57b 100644 --- a/crates/api/src/trampoline/create_handle.rs +++ b/crates/api/src/trampoline/create_handle.rs @@ -3,8 +3,7 @@ use crate::runtime::Store; use anyhow::Result; use std::any::Any; -use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::rc::Rc; use wasmtime_environ::entity::PrimaryMap; use wasmtime_environ::wasm::DefinedFuncIndex; @@ -17,9 +16,6 @@ pub(crate) fn create_handle( finished_functions: PrimaryMap, state: Box, ) -> Result { - let global_exports: Rc>>> = - Rc::new(RefCell::new(HashMap::new())); - let imports = Imports::new( HashSet::new(), PrimaryMap::new(), @@ -42,7 +38,6 @@ pub(crate) fn create_handle( Ok(InstanceHandle::new( Rc::new(module), - global_exports, finished_functions.into_boxed_slice(), imports, &data_initializers, diff --git a/crates/api/src/trampoline/func.rs b/crates/api/src/trampoline/func.rs index f5d7dde5c3..641050e565 100644 --- a/crates/api/src/trampoline/func.rs +++ b/crates/api/src/trampoline/func.rs @@ -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, store: &Store, ) -> Result { - 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 = diff --git a/crates/api/src/types.rs b/crates/api/src/types.rs index b5f9086875..6c82114bba 100644 --- a/crates/api/src/types.rs +++ b/crates/api/src/types.rs @@ -191,12 +191,6 @@ fn from_wasmtime_abiparam(param: &ir::AbiParam) -> Option { pub struct FuncType { params: Box<[ValType]>, results: Box<[ValType]>, - // `None` if params/results aren't wasm-compatible (e.g. use wasm interface - // types), or if they're not implemented (like anyref at the time of this - // writing) - // - // `Some` if they're all wasm-compatible. - signature: Option, } impl FuncType { @@ -205,34 +199,7 @@ impl FuncType { /// The function descriptor returned will represent a function which takes /// `params` as arguments and returns `results` when it is finished. pub fn new(params: Box<[ValType]>, results: Box<[ValType]>) -> FuncType { - use wasmtime_environ::ir::{types, AbiParam, ArgumentPurpose, Signature}; - use wasmtime_jit::native; - let call_conv = native::call_conv(); - let signature = params - .iter() - .map(|p| p.get_wasmtime_type().map(AbiParam::new)) - .collect::>>() - .and_then(|params| { - results - .iter() - .map(|p| p.get_wasmtime_type().map(AbiParam::new)) - .collect::>>() - .map(|results| (params, results)) - }) - .map(|(mut params, returns)| { - params.insert(0, AbiParam::special(types::I64, ArgumentPurpose::VMContext)); - - Signature { - params, - returns, - call_conv, - } - }); - FuncType { - params, - results, - signature, - } + FuncType { params, results } } /// Returns the list of parameter types for this function. @@ -248,8 +215,28 @@ impl FuncType { /// Returns `Some` if this function signature was compatible with cranelift, /// or `None` if one of the types/results wasn't supported or compatible /// with cranelift. - pub(crate) fn get_wasmtime_signature(&self) -> Option<&ir::Signature> { - self.signature.as_ref() + pub(crate) fn get_wasmtime_signature(&self, pointer_type: ir::Type) -> Option { + use wasmtime_environ::ir::{types, AbiParam, ArgumentPurpose, Signature}; + use wasmtime_jit::native; + let call_conv = native::call_conv(); + let mut params = self + .params + .iter() + .map(|p| p.get_wasmtime_type().map(AbiParam::new)) + .collect::>>()?; + let returns = self + .results + .iter() + .map(|p| p.get_wasmtime_type().map(AbiParam::new)) + .collect::>>()?; + params.insert(0, AbiParam::special(types::I64, ArgumentPurpose::VMContext)); + params.insert(1, AbiParam::new(pointer_type)); + + Some(Signature { + params, + returns, + call_conv, + }) } /// Returns `None` if any types in the signature can't be converted to the @@ -259,7 +246,7 @@ impl FuncType { let params = signature .params .iter() - .filter(|p| p.purpose == ir::ArgumentPurpose::Normal) + .skip(2) // skip the caller/callee vmctx .map(|p| from_wasmtime_abiparam(p)) .collect::>>()?; let results = signature @@ -270,7 +257,6 @@ impl FuncType { Some(FuncType { params: params.into_boxed_slice(), results: results.into_boxed_slice(), - signature: Some(signature), }) } } diff --git a/crates/environ/Cargo.toml b/crates/environ/Cargo.toml index b8a1a0c7ed..94f5bcbe57 100644 --- a/crates/environ/Cargo.toml +++ b/crates/environ/Cargo.toml @@ -13,9 +13,9 @@ edition = "2018" [dependencies] anyhow = "1.0" -cranelift-codegen = { version = "0.55", features = ["enable-serde"] } -cranelift-entity = { version = "0.55", features = ["enable-serde"] } -cranelift-wasm = { version = "0.55", features = ["enable-serde"] } +cranelift-codegen = { version = "0.56", features = ["enable-serde"] } +cranelift-entity = { version = "0.56", features = ["enable-serde"] } +cranelift-wasm = { version = "0.56", features = ["enable-serde"] } wasmparser = "0.47.0" lightbeam = { path = "../lightbeam", optional = true, version = "0.9.0" } indexmap = "1.0.2" @@ -46,7 +46,7 @@ tempfile = "3" target-lexicon = { version = "0.10.0", default-features = false } pretty_env_logger = "0.3.0" rand = { version = "0.7.0", default-features = false, features = ["small_rng"] } -cranelift-codegen = { version = "0.55", features = ["enable-serde", "all-arch"] } +cranelift-codegen = { version = "0.56", features = ["enable-serde", "all-arch"] } filetime = "0.2.7" [badges] diff --git a/crates/environ/src/func_environ.rs b/crates/environ/src/func_environ.rs index c33a2d5c15..9808907d1f 100644 --- a/crates/environ/src/func_environ.rs +++ b/crates/environ/src/func_environ.rs @@ -362,8 +362,10 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm } impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> { - fn is_wasm_parameter(&self, signature: &ir::Signature, index: usize) -> bool { - signature.params[index].purpose == ir::ArgumentPurpose::Normal + fn is_wasm_parameter(&self, _signature: &ir::Signature, index: usize) -> bool { + // The first two parameters are the vmctx and caller vmctx. The rest are + // the wasm parameters. + index >= 2 } fn make_table(&mut self, func: &mut ir::Function, index: TableIndex) -> WasmResult { @@ -615,7 +617,8 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m } } - let mut real_call_args = Vec::with_capacity(call_args.len() + 1); + let mut real_call_args = Vec::with_capacity(call_args.len() + 2); + let caller_vmctx = pos.func.special_param(ArgumentPurpose::VMContext).unwrap(); // First append the callee vmctx address. let vmctx = pos.ins().load( @@ -625,6 +628,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m i32::from(self.offsets.vmcaller_checked_anyfunc_vmctx()), ); real_call_args.push(vmctx); + real_call_args.push(caller_vmctx); // Then append the regular call arguments. real_call_args.extend_from_slice(call_args); @@ -639,12 +643,17 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m callee: ir::FuncRef, call_args: &[ir::Value], ) -> WasmResult { - let mut real_call_args = Vec::with_capacity(call_args.len() + 1); + let mut real_call_args = Vec::with_capacity(call_args.len() + 2); + let caller_vmctx = pos.func.special_param(ArgumentPurpose::VMContext).unwrap(); // Handle direct calls to locally-defined functions. if !self.module.is_imported_function(callee_index) { - // First append the callee vmctx address. - real_call_args.push(pos.func.special_param(ArgumentPurpose::VMContext).unwrap()); + // First append the callee vmctx address, which is the same as the caller vmctx in + // this case. + real_call_args.push(caller_vmctx); + + // Then append the caller vmctx address. + real_call_args.push(caller_vmctx); // Then append the regular call arguments. real_call_args.extend_from_slice(call_args); @@ -671,6 +680,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m i32::try_from(self.offsets.vmctx_vmfunction_import_vmctx(callee_index)).unwrap(); let vmctx = pos.ins().load(pointer_type, mem_flags, base, vmctx_offset); real_call_args.push(vmctx); + real_call_args.push(caller_vmctx); // Then append the regular call arguments. real_call_args.extend_from_slice(call_args); diff --git a/crates/environ/src/module_environ.rs b/crates/environ/src/module_environ.rs index a02db6465d..c169ef9e48 100644 --- a/crates/environ/src/module_environ.rs +++ b/crates/environ/src/module_environ.rs @@ -383,6 +383,8 @@ pub fn translate_signature(mut sig: ir::Signature, pointer_type: ir::Type) -> ir 0, AbiParam::special(pointer_type, ArgumentPurpose::VMContext), ); + // Prepend the caller vmctx argument. + sig.params.insert(1, AbiParam::new(pointer_type)); sig } diff --git a/crates/jit/Cargo.toml b/crates/jit/Cargo.toml index 4c4901c1ed..2670bb7564 100644 --- a/crates/jit/Cargo.toml +++ b/crates/jit/Cargo.toml @@ -11,11 +11,11 @@ readme = "README.md" edition = "2018" [dependencies] -cranelift-codegen = { version = "0.55", features = ["enable-serde"] } -cranelift-entity = { version = "0.55", features = ["enable-serde"] } -cranelift-wasm = { version = "0.55", features = ["enable-serde"] } -cranelift-native = "0.55" -cranelift-frontend = "0.55" +cranelift-codegen = { version = "0.56", features = ["enable-serde"] } +cranelift-entity = { version = "0.56", features = ["enable-serde"] } +cranelift-wasm = { version = "0.56", features = ["enable-serde"] } +cranelift-native = "0.56" +cranelift-frontend = "0.56" wasmtime-environ = { path = "../environ", version = "0.9.0" } wasmtime-runtime = { path = "../runtime", version = "0.9.0" } wasmtime-debug = { path = "../debug", version = "0.9.0" } diff --git a/crates/jit/src/action.rs b/crates/jit/src/action.rs index c836da8b26..dd35e4868b 100644 --- a/crates/jit/src/action.rs +++ b/crates/jit/src/action.rs @@ -187,11 +187,13 @@ pub fn invoke( // Make all JIT code produced thus far executable. compiler.publish_compiled_code(); - // Call the trampoline. + // Call the trampoline. Pass a null `caller_vmctx` argument as `invoke` is + // all about calling from the outside world rather than from an instance. if let Err(trap) = unsafe { instance.with_signals_on(|| { wasmtime_call_trampoline( callee_vmctx, + ptr::null_mut(), exec_code_buf, values_vec.as_mut_ptr() as *mut u8, ) diff --git a/crates/jit/src/compiler.rs b/crates/jit/src/compiler.rs index 4a212f5608..c03687827b 100644 --- a/crates/jit/src/compiler.rs +++ b/crates/jit/src/compiler.rs @@ -282,11 +282,15 @@ fn make_trampoline( let pointer_type = isa.pointer_type(); let mut wrapper_sig = ir::Signature::new(isa.frontend_config().default_call_conv); - // Add the `vmctx` parameter. + // Add the callee `vmctx` parameter. wrapper_sig.params.push(ir::AbiParam::special( pointer_type, ir::ArgumentPurpose::VMContext, )); + + // Add the caller `vmctx` parameter. + wrapper_sig.params.push(ir::AbiParam::new(pointer_type)); + // Add the `values_vec` parameter. wrapper_sig.params.push(ir::AbiParam::new(pointer_type)); @@ -302,9 +306,9 @@ fn make_trampoline( builder.switch_to_block(block0); builder.seal_block(block0); - let (vmctx_ptr_val, values_vec_ptr_val) = { + let (vmctx_ptr_val, caller_vmctx_ptr_val, values_vec_ptr_val) = { let params = builder.func.dfg.ebb_params(block0); - (params[0], params[1]) + (params[0], params[1], params[2]) }; // Load the argument values out of `values_vec`. @@ -314,16 +318,19 @@ fn make_trampoline( .iter() .enumerate() .map(|(i, r)| { - match r.purpose { - // i - 1 because vmctx isn't passed through `values_vec`. - ir::ArgumentPurpose::Normal => builder.ins().load( - r.value_type, - mflags, - values_vec_ptr_val, - ((i - 1) * value_size) as i32, - ), - ir::ArgumentPurpose::VMContext => vmctx_ptr_val, - other => panic!("unsupported argument purpose {}", other), + match i { + 0 => vmctx_ptr_val, + 1 => caller_vmctx_ptr_val, + _ => + // i - 2 because vmctx and caller vmctx aren't passed through `values_vec`. + { + builder.ins().load( + r.value_type, + mflags, + values_vec_ptr_val, + ((i - 2) * value_size) as i32, + ) + } } }) .collect::>(); diff --git a/crates/jit/src/context.rs b/crates/jit/src/context.rs index 98f5d17682..7c31c49d08 100644 --- a/crates/jit/src/context.rs +++ b/crates/jit/src/context.rs @@ -3,9 +3,6 @@ use crate::{ instantiate, ActionError, ActionOutcome, CompilationStrategy, CompiledModule, Compiler, InstanceHandle, Namespace, RuntimeValue, SetupError, }; -use std::cell::RefCell; -use std::collections::HashMap; -use std::rc::Rc; use thiserror::Error; use wasmparser::{validate, OperatorValidatorConfig, ValidatingParserConfig}; use wasmtime_environ::isa::TargetIsa; @@ -61,7 +58,6 @@ impl Into for Features { pub struct Context { namespace: Namespace, compiler: Box, - global_exports: Rc>>>, debug_info: bool, features: Features, } @@ -72,7 +68,6 @@ impl Context { Self { namespace: Namespace::new(), compiler, - global_exports: Rc::new(RefCell::new(HashMap::new())), debug_info: false, features: Default::default(), } @@ -119,7 +114,6 @@ impl Context { &data, None, &mut self.namespace, - Rc::clone(&self.global_exports), debug_info, ) } @@ -152,13 +146,7 @@ impl Context { self.validate(&data).map_err(SetupError::Validate)?; let debug_info = self.debug_info(); - CompiledModule::new( - &mut *self.compiler, - data, - None, - Rc::clone(&self.global_exports), - debug_info, - ) + CompiledModule::new(&mut *self.compiler, data, None, debug_info) } /// If `name` isn't None, register it for the given instance. @@ -239,12 +227,4 @@ impl Context { ) -> Result<&'instance [u8], ActionError> { inspect_memory(instance, field_name, start, len) } - - /// Return a handle to the global_exports mapping, needed by some modules - /// for instantiation. - pub fn get_global_exports( - &mut self, - ) -> Rc>>> { - Rc::clone(&self.global_exports) - } } diff --git a/crates/jit/src/instantiate.rs b/crates/jit/src/instantiate.rs index c303266c43..f6aa2fe9ca 100644 --- a/crates/jit/src/instantiate.rs +++ b/crates/jit/src/instantiate.rs @@ -7,8 +7,6 @@ use crate::compiler::Compiler; use crate::imports::resolve_imports; use crate::link::link_module; use crate::resolver::Resolver; -use std::cell::RefCell; -use std::collections::HashMap; use std::io::Write; use std::rc::Rc; use thiserror::Error; @@ -20,7 +18,7 @@ use wasmtime_environ::{ ModuleSyncString, }; use wasmtime_runtime::{ - Export, GdbJitImageRegistration, InstanceHandle, InstantiationError, VMFunctionBody, + GdbJitImageRegistration, InstanceHandle, InstantiationError, VMFunctionBody, VMSharedSignatureIndex, }; @@ -142,7 +140,6 @@ pub struct CompiledModule { finished_functions: BoxedSlice, data_initializers: Box<[OwnedDataInitializer]>, signatures: BoxedSlice, - global_exports: Rc>>>, dbg_jit_registration: Option>, } @@ -152,14 +149,12 @@ impl CompiledModule { compiler: &mut Compiler, data: &'data [u8], module_name: Option<&str>, - global_exports: Rc>>>, debug_info: bool, ) -> Result { let raw = RawCompiledModule::<'data>::new(compiler, data, module_name, debug_info)?; Ok(Self::from_parts( raw.module, - global_exports, raw.finished_functions, raw.data_initializers .iter() @@ -174,7 +169,6 @@ impl CompiledModule { /// Construct a `CompiledModule` from component parts. pub fn from_parts( module: Module, - global_exports: Rc>>>, finished_functions: BoxedSlice, data_initializers: Box<[OwnedDataInitializer]>, signatures: BoxedSlice, @@ -182,7 +176,6 @@ impl CompiledModule { ) -> Self { Self { module: Rc::new(module), - global_exports: Rc::clone(&global_exports), finished_functions, data_initializers, signatures, @@ -210,7 +203,6 @@ impl CompiledModule { let imports = resolve_imports(&self.module, resolver)?; InstanceHandle::new( Rc::clone(&self.module), - Rc::clone(&self.global_exports), self.finished_functions.clone(), imports, &data_initializers, @@ -260,7 +252,6 @@ pub fn instantiate( data: &[u8], module_name: Option<&str>, resolver: &mut dyn Resolver, - global_exports: Rc>>>, debug_info: bool, ) -> Result { let raw = RawCompiledModule::new(compiler, data, module_name, debug_info)?; @@ -268,7 +259,6 @@ pub fn instantiate( .map_err(|err| SetupError::Instantiate(InstantiationError::Link(err)))?; InstanceHandle::new( Rc::new(raw.module), - global_exports, raw.finished_functions, imports, &*raw.data_initializers, diff --git a/crates/lightbeam/Cargo.toml b/crates/lightbeam/Cargo.toml index f3e140f070..685785c08c 100644 --- a/crates/lightbeam/Cargo.toml +++ b/crates/lightbeam/Cargo.toml @@ -19,7 +19,7 @@ memoffset = "0.5.3" itertools = "0.8.2" capstone = "0.6.0" thiserror = "1.0.9" -cranelift-codegen = "0.55" +cranelift-codegen = "0.56" multi_mut = "0.1" either = "1.5" typemap = "0.3" diff --git a/crates/misc/rust/macro/src/lib.rs b/crates/misc/rust/macro/src/lib.rs index 75198534fa..ffc9fc1009 100644 --- a/crates/misc/rust/macro/src/lib.rs +++ b/crates/misc/rust/macro/src/lib.rs @@ -53,7 +53,6 @@ fn generate_load(item: &syn::ItemTrait) -> syn::Result { let engine = Engine::new(Config::new().wasm_multi_value(true)); let store = Store::new(&engine); - let global_exports = store.global_exports().clone(); let data = #root::wasmtime_interface_types::ModuleData::new(&bytes)?; diff --git a/crates/runtime/signalhandlers/Trampolines.cpp b/crates/runtime/signalhandlers/Trampolines.cpp index 4c6bbcc310..d74f094280 100644 --- a/crates/runtime/signalhandlers/Trampolines.cpp +++ b/crates/runtime/signalhandlers/Trampolines.cpp @@ -3,7 +3,12 @@ #include "SignalHandlers.hpp" extern "C" -int WasmtimeCallTrampoline(void *vmctx, void (*body)(void*, void*), void *args) { +int WasmtimeCallTrampoline( + void *vmctx, + void *caller_vmctx, + void (*body)(void*, void*, void*), + void *args) +{ jmp_buf buf; void *volatile prev; if (setjmp(buf) != 0) { @@ -11,13 +16,13 @@ int WasmtimeCallTrampoline(void *vmctx, void (*body)(void*, void*), void *args) return 0; } prev = EnterScope(&buf); - body(vmctx, args); + body(vmctx, caller_vmctx, args); LeaveScope(prev); return 1; } extern "C" -int WasmtimeCall(void *vmctx, void (*body)(void*)) { +int WasmtimeCall(void *vmctx, void *caller_vmctx, void (*body)(void*, void*)) { jmp_buf buf; void *volatile prev; if (setjmp(buf) != 0) { @@ -25,7 +30,7 @@ int WasmtimeCall(void *vmctx, void (*body)(void*)) { return 0; } prev = EnterScope(&buf); - body(vmctx); + body(vmctx, caller_vmctx); LeaveScope(prev); return 1; } diff --git a/crates/runtime/src/instance.rs b/crates/runtime/src/instance.rs index d6032faec5..8678702256 100644 --- a/crates/runtime/src/instance.rs +++ b/crates/runtime/src/instance.rs @@ -18,9 +18,8 @@ use crate::vmcontext::{ use memoffset::offset_of; use more_asserts::assert_lt; use std::any::Any; -use std::borrow::Borrow; use std::cell::RefCell; -use std::collections::{HashMap, HashSet}; +use std::collections::HashSet; use std::convert::TryFrom; use std::ptr::NonNull; use std::rc::Rc; @@ -294,11 +293,6 @@ pub(crate) struct Instance { /// Offsets in the `vmctx` region. offsets: VMOffsets, - /// A global namespace of exports. This is a temporary mechanism to avoid - /// cyclic dependencies when one module wants to import from another and - /// make its memory available too, that will be obviated by host-bindings. - global_exports: Rc>>>, - /// WebAssembly linear memory data. memories: BoxedSlice, @@ -567,7 +561,7 @@ impl Instance { }; // Make the call. - unsafe { wasmtime_call(callee_vmctx, callee_address) } + unsafe { wasmtime_call(callee_vmctx, self.vmctx_mut_ptr(), callee_address) } .map_err(InstantiationError::StartTrap) } @@ -689,15 +683,6 @@ impl Instance { foreign_instance.memory_size(foreign_index) } - pub(crate) fn lookup_global_export(&self, field: &str) -> Option { - let cell: &RefCell>> = self.global_exports.borrow(); - let map: &mut HashMap> = &mut cell.borrow_mut(); - if let Some(Some(export)) = map.get(field) { - return Some(export.clone()); - } - None - } - /// Grow table by the specified amount of elements. /// /// Returns `None` if table can't be grown by the specified amount @@ -772,7 +757,6 @@ impl InstanceHandle { /// Create a new `InstanceHandle` pointing at a new `Instance`. pub fn new( module: Rc, - global_exports: Rc>>>, finished_functions: BoxedSlice, imports: Imports, data_initializers: &[DataInitializer<'_>], @@ -814,7 +798,6 @@ impl InstanceHandle { dependencies: imports.dependencies, mmap: instance_mmap, module, - global_exports, offsets, memories, tables, @@ -886,25 +869,6 @@ impl InstanceHandle { initialize_memories(instance, data_initializers)?; initialize_globals(instance); - // Collect the exports for the global export map. - for (field, decl) in &instance.module.exports { - use std::collections::hash_map::Entry::*; - let cell: &RefCell>> = instance.global_exports.borrow(); - let map: &mut HashMap> = &mut cell.borrow_mut(); - match map.entry(field.to_string()) { - Vacant(entry) => { - entry.insert(Some(lookup_by_declaration( - &instance.module, - &mut instance.vmctx, - &instance.offsets, - &instance.finished_functions, - &decl, - ))); - } - Occupied(ref mut entry) => *entry.get_mut() = None, - } - } - // Ensure that our signal handlers are ready for action. // TODO: Move these calls out of `InstanceHandle`. wasmtime_init_eager(); diff --git a/crates/runtime/src/traphandlers.rs b/crates/runtime/src/traphandlers.rs index a055ebc722..afc15282fb 100644 --- a/crates/runtime/src/traphandlers.rs +++ b/crates/runtime/src/traphandlers.rs @@ -13,10 +13,11 @@ use wasmtime_environ::ir; extern "C" { fn WasmtimeCallTrampoline( vmctx: *mut u8, + caller_vmctx: *mut u8, callee: *const VMFunctionBody, values_vec: *mut u8, ) -> i32; - fn WasmtimeCall(vmctx: *mut u8, callee: *const VMFunctionBody) -> i32; + fn WasmtimeCall(vmctx: *mut u8, caller_vmctx: *mut u8, callee: *const VMFunctionBody) -> i32; } thread_local! { @@ -165,10 +166,17 @@ fn trap_code_to_expected_string(trap_code: ir::TrapCode) -> String { #[no_mangle] pub unsafe extern "C" fn wasmtime_call_trampoline( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, callee: *const VMFunctionBody, values_vec: *mut u8, ) -> Result<(), Trap> { - if WasmtimeCallTrampoline(vmctx as *mut u8, callee, values_vec) == 0 { + if WasmtimeCallTrampoline( + vmctx as *mut u8, + caller_vmctx as *mut u8, + callee, + values_vec, + ) == 0 + { Err(last_trap()) } else { Ok(()) @@ -180,9 +188,10 @@ pub unsafe extern "C" fn wasmtime_call_trampoline( #[no_mangle] pub unsafe extern "C" fn wasmtime_call( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, callee: *const VMFunctionBody, ) -> Result<(), Trap> { - if WasmtimeCall(vmctx as *mut u8, callee) == 0 { + if WasmtimeCall(vmctx as *mut u8, caller_vmctx as *mut u8, callee) == 0 { Err(last_trap()) } else { Ok(()) diff --git a/crates/runtime/src/vmcontext.rs b/crates/runtime/src/vmcontext.rs index b680bb52a2..e0a5046bde 100644 --- a/crates/runtime/src/vmcontext.rs +++ b/crates/runtime/src/vmcontext.rs @@ -595,7 +595,7 @@ impl VMInvokeArgument { /// /// TODO: We could move the globals into the `vmctx` allocation too. #[derive(Debug)] -#[repr(C)] +#[repr(C, align(16))] // align 16 since globals are aligned to that and contained inside pub struct VMContext {} impl VMContext { @@ -617,12 +617,4 @@ impl VMContext { pub unsafe fn host_state(&mut self) -> &mut dyn Any { self.instance().host_state() } - - /// Lookup an export in the global exports namespace. - /// # Safety - /// This is unsafe because it doesn't work on just any `VMContext`, it must - /// be a `VMContext` allocated as part of an `Instance`. - pub unsafe fn lookup_global_export(&mut self, field: &str) -> Option { - self.instance().lookup_global_export(field) - } } diff --git a/crates/test-programs/tests/wasm_tests/runtime.rs b/crates/test-programs/tests/wasm_tests/runtime.rs index 7836b1ed22..53cd3b0f20 100644 --- a/crates/test-programs/tests/wasm_tests/runtime.rs +++ b/crates/test-programs/tests/wasm_tests/runtime.rs @@ -6,7 +6,6 @@ use wasmtime::{Instance, Module, Store}; pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> anyhow::Result<()> { let store = Store::default(); - let global_exports = store.global_exports().clone(); let get_preopens = |workspace: Option<&Path>| -> anyhow::Result> { if let Some(workspace) = workspace { let preopen_dir = wasi_common::preopen_dir(workspace) @@ -37,7 +36,6 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any let snapshot1 = Instance::from_handle( &store, wasmtime_wasi::instantiate_wasi_with_context( - global_exports.clone(), builder.build().context("failed to build wasi context")?, ) .context("failed to instantiate wasi")?, diff --git a/crates/wasi-c/Cargo.toml b/crates/wasi-c/Cargo.toml index c52e5244db..5fd07b2f54 100644 --- a/crates/wasi-c/Cargo.toml +++ b/crates/wasi-c/Cargo.toml @@ -14,9 +14,9 @@ edition = "2018" wasmtime-runtime = { path = "../runtime", version = "0.9.0" } wasmtime-environ = { path = "../environ", version = "0.9.0" } wasmtime-jit = { path = "../jit", version = "0.9.0" } -cranelift-codegen = { version = "0.55", features = ["enable-serde"] } -cranelift-entity = { version = "0.55", features = ["enable-serde"] } -cranelift-wasm = { version = "0.55", features = ["enable-serde"] } +cranelift-codegen = { version = "0.56", features = ["enable-serde"] } +cranelift-entity = { version = "0.56", features = ["enable-serde"] } +cranelift-wasm = { version = "0.56", features = ["enable-serde"] } target-lexicon = "0.10.0" log = { version = "0.4.8", default-features = false } libc = "0.2.60" diff --git a/crates/wasi-c/src/instantiate.rs b/crates/wasi-c/src/instantiate.rs index 21d3f908d5..235e47615b 100644 --- a/crates/wasi-c/src/instantiate.rs +++ b/crates/wasi-c/src/instantiate.rs @@ -27,7 +27,6 @@ pub(crate) struct WASIState { /// Return an instance implementing the "wasi" interface. pub fn instantiate_wasi_c( prefix: &str, - global_exports: Rc>>>, preopened_dirs: &[(String, File)], argv: &[String], environ: &[(String, String)], @@ -160,7 +159,6 @@ pub fn instantiate_wasi_c( InstanceHandle::new( Rc::new(module), - global_exports, finished_functions.into_boxed_slice(), imports, &data_initializers, diff --git a/crates/wasi-c/src/syscalls.rs b/crates/wasi-c/src/syscalls.rs index 7a084e855f..450c9c9ca4 100644 --- a/crates/wasi-c/src/syscalls.rs +++ b/crates/wasi-c/src/syscalls.rs @@ -114,7 +114,11 @@ impl AbiRet for () { } macro_rules! syscalls { - ($(pub unsafe extern "C" fn $name:ident($ctx:ident: *mut VMContext $(, $arg:ident: $ty:ty)*,) -> $ret:ty { + ($(pub unsafe extern "C" fn $name:ident( + $ctx:ident: *mut VMContext, + caller_vmctx: *mut VMContext, + $(, $arg:ident: $ty:ty)*, + ) -> $ret:ty { $($body:tt)* })*) => ($( pub mod $name { @@ -137,12 +141,14 @@ macro_rules! syscalls { /// NB: ideally we'd expose `shim` below, but it seems like there's /// a compiler bug which prvents that from being cast to a `usize`. pub static SHIM: unsafe extern "C" fn( + *mut VMContext, *mut VMContext, $(<$ty as AbiParam>::Abi),* ) -> <$ret as AbiRet>::Abi = shim; unsafe extern "C" fn shim( $ctx: *mut VMContext, + $caller_ctx: *mut VMContext, $($arg: <$ty as AbiParam>::Abi,)* ) -> <$ret as AbiRet>::Abi { let r = super::$name($ctx, $(<$ty as AbiParam>::convert($arg),)*); @@ -150,7 +156,11 @@ macro_rules! syscalls { } } - pub unsafe extern "C" fn $name($ctx: *mut VMContext, $($arg: $ty,)*) -> $ret { + pub unsafe extern "C" fn $name( + $ctx: *mut VMContext, + $caller_ctx: *mut VMContext, + $($arg: $ty,)* + ) -> $ret { $($body)* } )*) @@ -160,6 +170,7 @@ syscalls! { pub unsafe extern "C" fn args_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, argv: wasm32::uintptr_t, argv_buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -201,6 +212,7 @@ syscalls! { pub unsafe extern "C" fn args_sizes_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, argc: wasm32::uintptr_t, argv_buf_size: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -238,6 +250,7 @@ syscalls! { pub unsafe extern "C" fn clock_res_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, clock_id: wasm32::__wasi_clockid_t, resolution: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -266,6 +279,7 @@ syscalls! { pub unsafe extern "C" fn clock_time_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, clock_id: wasm32::__wasi_clockid_t, precision: wasm32::__wasi_timestamp_t, time: wasm32::uintptr_t, @@ -297,6 +311,7 @@ syscalls! { pub unsafe extern "C" fn environ_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, environ: wasm32::uintptr_t, environ_buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -338,6 +353,7 @@ syscalls! { pub unsafe extern "C" fn environ_sizes_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, environ_count: wasm32::uintptr_t, environ_buf_size: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -375,6 +391,7 @@ syscalls! { pub unsafe extern "C" fn fd_prestat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -397,6 +414,7 @@ syscalls! { pub unsafe extern "C" fn fd_prestat_dir_name( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -419,6 +437,7 @@ syscalls! { pub unsafe extern "C" fn fd_close( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { trace!("fd_close(fd={:?})", fd); @@ -435,6 +454,7 @@ syscalls! { pub unsafe extern "C" fn fd_datasync( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { trace!("fd_datasync(fd={:?})", fd); @@ -450,6 +470,7 @@ syscalls! { pub unsafe extern "C" fn fd_pread( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -497,6 +518,7 @@ syscalls! { pub unsafe extern "C" fn fd_pwrite( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -544,6 +566,7 @@ syscalls! { pub unsafe extern "C" fn fd_read( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -581,6 +604,7 @@ syscalls! { pub unsafe extern "C" fn fd_renumber( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, from: wasm32::__wasi_fd_t, to: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { @@ -599,6 +623,7 @@ syscalls! { pub unsafe extern "C" fn fd_seek( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filedelta_t, whence: wasm32::__wasi_whence_t, @@ -634,6 +659,7 @@ syscalls! { pub unsafe extern "C" fn fd_tell( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, newoffset: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -659,6 +685,7 @@ syscalls! { pub unsafe extern "C" fn fd_fdstat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -684,6 +711,7 @@ syscalls! { pub unsafe extern "C" fn fd_fdstat_set_flags( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, flags: wasm32::__wasi_fdflags_t, ) -> wasm32::__wasi_errno_t { @@ -705,6 +733,7 @@ syscalls! { pub unsafe extern "C" fn fd_fdstat_set_rights( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, fs_rights_base: wasm32::__wasi_rights_t, fs_rights_inheriting: wasm32::__wasi_rights_t, @@ -729,6 +758,7 @@ syscalls! { pub unsafe extern "C" fn fd_sync( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, ) -> wasm32::__wasi_errno_t { trace!("fd_sync(fd={:?})", fd); @@ -744,6 +774,7 @@ syscalls! { pub unsafe extern "C" fn fd_write( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, iovs: wasm32::uintptr_t, iovs_len: wasm32::size_t, @@ -781,6 +812,7 @@ syscalls! { pub unsafe extern "C" fn fd_advise( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t, @@ -808,6 +840,7 @@ syscalls! { pub unsafe extern "C" fn fd_allocate( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, offset: wasm32::__wasi_filesize_t, len: wasm32::__wasi_filesize_t, @@ -827,6 +860,7 @@ syscalls! { pub unsafe extern "C" fn path_create_directory( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -855,6 +889,7 @@ syscalls! { pub unsafe extern "C" fn path_link( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd0: wasm32::__wasi_fd_t, flags0: wasm32::__wasi_lookupflags_t, path0: wasm32::uintptr_t, @@ -901,6 +936,7 @@ syscalls! { // the `fd` by reference? pub unsafe extern "C" fn path_open( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, dirfd: wasm32::__wasi_fd_t, dirflags: wasm32::__wasi_lookupflags_t, path: wasm32::uintptr_t, @@ -964,6 +1000,7 @@ syscalls! { pub unsafe extern "C" fn fd_readdir( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, buf: wasm32::uintptr_t, buf_len: wasm32::size_t, @@ -1013,6 +1050,7 @@ syscalls! { pub unsafe extern "C" fn path_readlink( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1069,6 +1107,7 @@ syscalls! { pub unsafe extern "C" fn path_rename( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd0: wasm32::__wasi_fd_t, path0: wasm32::uintptr_t, path_len0: wasm32::size_t, @@ -1109,6 +1148,7 @@ syscalls! { pub unsafe extern "C" fn fd_filestat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, buf: wasm32::uintptr_t, ) -> wasm32::__wasi_errno_t { @@ -1134,6 +1174,7 @@ syscalls! { pub unsafe extern "C" fn fd_filestat_set_times( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, st_atim: wasm32::__wasi_timestamp_t, st_mtim: wasm32::__wasi_timestamp_t, @@ -1160,6 +1201,7 @@ syscalls! { pub unsafe extern "C" fn fd_filestat_set_size( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, size: wasm32::__wasi_filesize_t, ) -> wasm32::__wasi_errno_t { @@ -1181,6 +1223,7 @@ syscalls! { pub unsafe extern "C" fn path_filestat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, flags: wasm32::__wasi_lookupflags_t, path: wasm32::uintptr_t, @@ -1223,6 +1266,7 @@ syscalls! { pub unsafe extern "C" fn path_filestat_set_times( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, flags: wasm32::__wasi_lookupflags_t, path: wasm32::uintptr_t, @@ -1262,6 +1306,7 @@ syscalls! { pub unsafe extern "C" fn path_symlink( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, path0: wasm32::uintptr_t, path_len0: wasm32::size_t, fd: wasm32::__wasi_fd_t, @@ -1299,6 +1344,7 @@ syscalls! { pub unsafe extern "C" fn path_unlink_file( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1327,6 +1373,7 @@ syscalls! { pub unsafe extern "C" fn path_remove_directory( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasm32::__wasi_fd_t, path: wasm32::uintptr_t, path_len: wasm32::size_t, @@ -1355,6 +1402,7 @@ syscalls! { pub unsafe extern "C" fn poll_oneoff( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, in_: wasm32::uintptr_t, out: wasm32::uintptr_t, nsubscriptions: wasm32::size_t, @@ -1412,7 +1460,9 @@ syscalls! { return_encoded_errno(e) } - pub unsafe extern "C" fn proc_exit(_vmctx: *mut VMContext, rval: u32,) -> () { + pub unsafe extern "C" fn proc_exit(_vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, + rval: u32,) -> () { trace!("proc_exit(rval={:?})", rval); let rval = decode_exitcode(rval); @@ -1424,6 +1474,7 @@ syscalls! { pub unsafe extern "C" fn proc_raise( _vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, _sig: wasm32::__wasi_signal_t, ) -> wasm32::__wasi_errno_t { unimplemented!("__wasi_proc_raise"); @@ -1431,6 +1482,7 @@ syscalls! { pub unsafe extern "C" fn random_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, buf: wasm32::uintptr_t, buf_len: wasm32::size_t, ) -> wasm32::__wasi_errno_t { @@ -1447,7 +1499,9 @@ syscalls! { return_encoded_errno(e) } - pub unsafe extern "C" fn sched_yield(_vmctx: *mut VMContext,) -> wasm32::__wasi_errno_t { + pub unsafe extern "C" fn sched_yield(_vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, + ) -> wasm32::__wasi_errno_t { let e = host::wasmtime_ssp_sched_yield(); return_encoded_errno(e) @@ -1455,6 +1509,7 @@ syscalls! { pub unsafe extern "C" fn sock_recv( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sock: wasm32::__wasi_fd_t, ri_data: wasm32::uintptr_t, ri_data_len: wasm32::size_t, @@ -1502,6 +1557,7 @@ syscalls! { pub unsafe extern "C" fn sock_send( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sock: wasm32::__wasi_fd_t, si_data: wasm32::uintptr_t, si_data_len: wasm32::size_t, @@ -1539,6 +1595,8 @@ syscalls! { pub unsafe extern "C" fn sock_shutdown( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sock: wasm32::__wasi_fd_t, how: wasm32::__wasi_sdflags_t, ) -> wasm32::__wasi_errno_t { diff --git a/crates/wasi-common/wig/src/wasi.rs b/crates/wasi-common/wig/src/wasi.rs index fe4d4141b4..a54652b840 100644 --- a/crates/wasi-common/wig/src/wasi.rs +++ b/crates/wasi-common/wig/src/wasi.rs @@ -193,6 +193,7 @@ pub fn add_wrappers_to_module(args: TokenStream) -> TokenStream { unsafe extern "C" fn #name_ident( ctx: *mut wasmtime_runtime::VMContext, + caller_ctx: *mut wasmtime_runtime::VMContext, #(#shim_arg_decls),* ) -> #ret_ty { log::trace!( @@ -203,7 +204,7 @@ pub fn add_wrappers_to_module(args: TokenStream) -> TokenStream { Ok(e) => e, Err(e) => #handle_early_error, }; - let memory = match get_memory(&mut *ctx) { + let memory = match get_memory(&mut *caller_ctx) { Ok(e) => e, Err(e) => #handle_early_error, }; diff --git a/crates/wasi/Cargo.toml b/crates/wasi/Cargo.toml index 1ea8761523..be3bb76c80 100644 --- a/crates/wasi/Cargo.toml +++ b/crates/wasi/Cargo.toml @@ -16,9 +16,9 @@ wasmtime-runtime = { path = "../runtime", version = "0.9.0" } wasmtime-environ = { path = "../environ", version = "0.9.0" } wasmtime-jit = { path = "../jit", version = "0.9.0" } wasi-common = { path = "../wasi-common", version = "0.9.0" } -cranelift-codegen = { version = "0.55", features = ["enable-serde"] } -cranelift-entity = { version = "0.55", features = ["enable-serde"] } -cranelift-wasm = { version = "0.55", features = ["enable-serde"] } +cranelift-codegen = { version = "0.56", features = ["enable-serde"] } +cranelift-entity = { version = "0.56", features = ["enable-serde"] } +cranelift-wasm = { version = "0.56", features = ["enable-serde"] } target-lexicon = "0.10.0" log = { version = "0.4.8", default-features = false } wig = { path = "../wasi-common/wig", version = "0.9.2" } diff --git a/crates/wasi/src/instantiate.rs b/crates/wasi/src/instantiate.rs index 4bbfdbbde8..205130f382 100644 --- a/crates/wasi/src/instantiate.rs +++ b/crates/wasi/src/instantiate.rs @@ -2,8 +2,6 @@ use cranelift_codegen::ir::types; use cranelift_codegen::{ir, isa}; use cranelift_entity::PrimaryMap; use cranelift_wasm::DefinedFuncIndex; -use std::cell::RefCell; -use std::collections::HashMap; use std::fs::File; use std::rc::Rc; use target_lexicon::HOST; @@ -19,15 +17,13 @@ pub fn create_wasi_instance( argv: &[String], environ: &[(String, String)], ) -> Result { - let global_exports = store.global_exports().clone(); - let wasi = instantiate_wasi(global_exports, preopened_dirs, argv, environ)?; + let wasi = instantiate_wasi(preopened_dirs, argv, environ)?; let instance = wasmtime::Instance::from_handle(&store, wasi); Ok(instance) } /// Return an instance implementing the "wasi" interface. pub fn instantiate_wasi( - global_exports: Rc>>>, preopened_dirs: &[(String, File)], argv: &[String], environ: &[(String, String)], @@ -52,14 +48,13 @@ pub fn instantiate_wasi( let wasi_ctx = wasi_ctx_builder.build().map_err(|err| { InstantiationError::Resource(format!("couldn't assemble WASI context object: {}", err)) })?; - instantiate_wasi_with_context(global_exports, wasi_ctx) + instantiate_wasi_with_context(wasi_ctx) } /// Return an instance implementing the "wasi" interface. /// /// The wasi context is configured by pub fn instantiate_wasi_with_context( - global_exports: Rc>>>, wasi_ctx: WasiCtx, ) -> Result { let pointer_type = types::Type::triple_pointer_type(&HOST); @@ -84,7 +79,6 @@ pub fn instantiate_wasi_with_context( InstanceHandle::new( Rc::new(module), - global_exports, finished_functions.into_boxed_slice(), imports, &data_initializers, @@ -109,24 +103,25 @@ fn get_wasi_ctx(vmctx: &mut VMContext) -> Result<&mut WasiCtx, wasi::__wasi_errn } // Used by `add_wrappers_to_module` defined in the macro above -fn get_memory(vmctx: &mut VMContext) -> Result<&mut [u8], wasi::__wasi_errno_t> { - unsafe { - match vmctx.lookup_global_export("memory") { - Some(wasmtime_runtime::Export::Memory { - definition, - vmctx: _, - memory: _, - }) => Ok(std::slice::from_raw_parts_mut( - (*definition).base, - (*definition).current_length, - )), - x => { - log::error!( - "no export named \"memory\", or the export isn't a mem: {:?}", - x - ); - Err(wasi::__WASI_ERRNO_INVAL) - } +fn get_memory(caller_vmctx: &mut VMContext) -> Result<&mut [u8], wasi::__wasi_errno_t> { + match unsafe { InstanceHandle::from_vmctx(caller_vmctx) }.lookup("memory") { + Some(wasmtime_runtime::Export::Memory { + definition, + vmctx: _, + memory: _, + }) => unsafe { + let definition = &*definition; + let ptr = definition.base; + let len = definition.current_length; + Ok(std::slice::from_raw_parts_mut(ptr, len)) + }, + Some(export) => { + log::error!("export named \"memory\" isn't a memory: {:?}", export); + Err(wasi::__WASI_ERRNO_INVAL) + } + None => { + log::error!("no export named \"memory\" available from caller"); + Err(wasi::__WASI_ERRNO_INVAL) } } } diff --git a/crates/wasi/src/old/snapshot_0/instantiate.rs b/crates/wasi/src/old/snapshot_0/instantiate.rs index 10e42f89c6..4631966437 100644 --- a/crates/wasi/src/old/snapshot_0/instantiate.rs +++ b/crates/wasi/src/old/snapshot_0/instantiate.rs @@ -3,8 +3,6 @@ use cranelift_codegen::ir::types; use cranelift_codegen::{ir, isa}; use cranelift_entity::PrimaryMap; use cranelift_wasm::DefinedFuncIndex; -use std::cell::RefCell; -use std::collections::HashMap; use std::fs::File; use std::rc::Rc; use target_lexicon::HOST; @@ -19,15 +17,13 @@ pub fn create_wasi_instance( argv: &[String], environ: &[(String, String)], ) -> Result { - let global_exports = store.global_exports().clone(); - let wasi = instantiate_wasi(global_exports, preopened_dirs, argv, environ)?; + let wasi = instantiate_wasi(preopened_dirs, argv, environ)?; let instance = wasmtime::Instance::from_handle(&store, wasi); Ok(instance) } /// Return an instance implementing the "wasi" interface. pub fn instantiate_wasi( - global_exports: Rc>>>, preopened_dirs: &[(String, File)], argv: &[String], environ: &[(String, String)], @@ -52,14 +48,13 @@ pub fn instantiate_wasi( let wasi_ctx = wasi_ctx_builder.build().map_err(|err| { InstantiationError::Resource(format!("couldn't assemble WASI context object: {}", err)) })?; - instantiate_wasi_with_context(global_exports, wasi_ctx) + instantiate_wasi_with_context(wasi_ctx) } /// Return an instance implementing the "wasi" interface. /// /// The wasi context is configured by pub fn instantiate_wasi_with_context( - global_exports: Rc>>>, wasi_ctx: WasiCtx, ) -> Result { let pointer_type = types::Type::triple_pointer_type(&HOST); @@ -144,7 +139,6 @@ pub fn instantiate_wasi_with_context( InstanceHandle::new( Rc::new(module), - global_exports, finished_functions.into_boxed_slice(), imports, &data_initializers, diff --git a/crates/wasi/src/old/snapshot_0/syscalls.rs b/crates/wasi/src/old/snapshot_0/syscalls.rs index d62b46a78e..9bb5fe43d1 100644 --- a/crates/wasi/src/old/snapshot_0/syscalls.rs +++ b/crates/wasi/src/old/snapshot_0/syscalls.rs @@ -1,7 +1,7 @@ use cranelift_codegen::ir::types::{Type, I32, I64}; -use log::{error, trace}; +use log::trace; use wasi_common::old::snapshot_0::{hostcalls, wasi, wasi32, WasiCtx}; -use wasmtime_runtime::{Export, VMContext}; +use wasmtime_runtime::{InstanceHandle, VMContext}; pub trait AbiRet { type Abi; @@ -83,28 +83,28 @@ fn get_wasi_ctx(vmctx: &mut VMContext) -> Result<&mut WasiCtx, wasi::__wasi_errn } } -fn get_memory(vmctx: &mut VMContext) -> Result<&mut [u8], wasi::__wasi_errno_t> { - unsafe { - match vmctx.lookup_global_export("memory") { - Some(Export::Memory { - definition, - vmctx: _, - memory: _, - }) => Ok(std::slice::from_raw_parts_mut( - (*definition).base, - (*definition).current_length, - )), - x => { - error!( - "no export named \"memory\", or the export isn't a mem: {:?}", - x - ); - Err(wasi::__WASI_ERRNO_INVAL) - } +fn get_memory(caller_vmctx: &mut VMContext) -> Result<&mut [u8], wasi::__wasi_errno_t> { + match unsafe { InstanceHandle::from_vmctx(caller_vmctx) }.lookup("memory") { + Some(wasmtime_runtime::Export::Memory { + definition, + vmctx: _, + memory: _, + }) => unsafe { + let definition = &*definition; + let ptr = definition.base; + let len = definition.current_length; + Ok(std::slice::from_raw_parts_mut(ptr, len)) + }, + Some(export) => { + log::error!("export named \"memory\" isn't a memory: {:?}", export); + Err(wasi::__WASI_ERRNO_INVAL) + } + None => { + log::error!("no export named \"memory\" available from caller"); + Err(wasi::__WASI_ERRNO_INVAL) } } } - macro_rules! ok_or_errno { ($expr:expr) => { match $expr { @@ -118,7 +118,11 @@ macro_rules! ok_or_errno { } macro_rules! syscalls { - ($(pub unsafe extern "C" fn $name:ident($ctx:ident: *mut VMContext $(, $arg:ident: $ty:ty)*,) -> $ret:ty { + ($(pub unsafe extern "C" fn $name:ident( + $ctx:ident: *mut VMContext, + $caller_ctx:ident: *mut VMContext + $(, $arg:ident: $ty:ty)*, + ) -> $ret:ty { $($body:tt)* })*) => ($( pub mod $name { @@ -141,20 +145,26 @@ macro_rules! syscalls { /// NB: ideally we'd expose `shim` below, but it seems like there's /// a compiler bug which prvents that from being cast to a `usize`. pub static SHIM: unsafe extern "C" fn( + *mut VMContext, *mut VMContext, $(<$ty as AbiParam>::Abi),* ) -> <$ret as AbiRet>::Abi = shim; unsafe extern "C" fn shim( $ctx: *mut VMContext, + $caller_ctx: *mut VMContext, $($arg: <$ty as AbiParam>::Abi,)* ) -> <$ret as AbiRet>::Abi { - let r = super::$name($ctx, $(<$ty as AbiParam>::convert($arg),)*); + let r = super::$name($ctx, $caller_ctx, $(<$ty as AbiParam>::convert($arg),)*); <$ret as AbiRet>::convert(r) } } - pub unsafe extern "C" fn $name($ctx: *mut VMContext, $($arg: $ty,)*) -> $ret { + pub unsafe extern "C" fn $name( + $ctx: *mut VMContext, + $caller_ctx: *mut VMContext, + $($arg: $ty,)* + ) -> $ret { $($body)* } )*) @@ -163,6 +173,7 @@ macro_rules! syscalls { syscalls! { pub unsafe extern "C" fn args_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, argv: wasi32::uintptr_t, argv_buf: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { @@ -172,12 +183,13 @@ syscalls! { argv_buf, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::args_get(wasi_ctx, memory, argv, argv_buf) } pub unsafe extern "C" fn args_sizes_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, argc: wasi32::uintptr_t, argv_buf_size: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { @@ -187,12 +199,13 @@ syscalls! { argv_buf_size, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::args_sizes_get(wasi_ctx, memory, argc, argv_buf_size) } pub unsafe extern "C" fn clock_res_get( - vmctx: *mut VMContext, + _vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, clock_id: wasi::__wasi_clockid_t, resolution: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { @@ -201,12 +214,13 @@ syscalls! { clock_id, resolution, ); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::clock_res_get(memory, clock_id, resolution) } pub unsafe extern "C" fn clock_time_get( - vmctx: *mut VMContext, + _vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, clock_id: wasi::__wasi_clockid_t, precision: wasi::__wasi_timestamp_t, time: wasi32::uintptr_t, @@ -217,12 +231,13 @@ syscalls! { precision, time, ); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::clock_time_get(memory, clock_id, precision, time) } pub unsafe extern "C" fn environ_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, environ: wasi32::uintptr_t, environ_buf: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { @@ -232,12 +247,13 @@ syscalls! { environ_buf, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::environ_get(wasi_ctx, memory, environ, environ_buf) } pub unsafe extern "C" fn environ_sizes_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, environ_count: wasi32::uintptr_t, environ_buf_size: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { @@ -247,35 +263,38 @@ syscalls! { environ_buf_size, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::environ_sizes_get(wasi_ctx, memory, environ_count, environ_buf_size) } pub unsafe extern "C" fn fd_prestat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, buf: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { trace!("fd_prestat_get(fd={:?}, buf={:#x?})", fd, buf); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_prestat_get(wasi_ctx, memory, fd, buf) } pub unsafe extern "C" fn fd_prestat_dir_name( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, path: wasi32::uintptr_t, path_len: wasi32::size_t, ) -> wasi::__wasi_errno_t { trace!("fd_prestat_dir_name(fd={:?}, path={:#x?}, path_len={})", fd, path, path_len); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_prestat_dir_name(wasi_ctx, memory, fd, path, path_len) } pub unsafe extern "C" fn fd_close( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, ) -> wasi::__wasi_errno_t { trace!("fd_close(fd={:?})", fd); @@ -285,6 +304,7 @@ syscalls! { pub unsafe extern "C" fn fd_datasync( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, ) -> wasi::__wasi_errno_t { trace!("fd_datasync(fd={:?})", fd); @@ -294,6 +314,7 @@ syscalls! { pub unsafe extern "C" fn fd_pread( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, iovs: wasi32::uintptr_t, iovs_len: wasi32::size_t, @@ -309,7 +330,7 @@ syscalls! { nread ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_pread( wasi_ctx, memory, @@ -323,6 +344,7 @@ syscalls! { pub unsafe extern "C" fn fd_pwrite( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, iovs: wasi32::uintptr_t, iovs_len: wasi32::size_t, @@ -338,7 +360,7 @@ syscalls! { nwritten ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_pwrite( wasi_ctx, memory, @@ -352,6 +374,7 @@ syscalls! { pub unsafe extern "C" fn fd_read( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, iovs: wasi32::uintptr_t, iovs_len: wasi32::size_t, @@ -365,12 +388,13 @@ syscalls! { nread ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_read(wasi_ctx, memory, fd, iovs, iovs_len, nread) } pub unsafe extern "C" fn fd_renumber( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, from: wasi::__wasi_fd_t, to: wasi::__wasi_fd_t, ) -> wasi::__wasi_errno_t { @@ -381,6 +405,7 @@ syscalls! { pub unsafe extern "C" fn fd_seek( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, offset: wasi::__wasi_filedelta_t, whence: wasi::__wasi_whence_t, @@ -394,34 +419,37 @@ syscalls! { newoffset ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_seek(wasi_ctx, memory, fd, offset, whence, newoffset) } pub unsafe extern "C" fn fd_tell( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, newoffset: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { trace!("fd_tell(fd={:?}, newoffset={:#x?})", fd, newoffset); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_tell(wasi_ctx, memory, fd, newoffset) } pub unsafe extern "C" fn fd_fdstat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, buf: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { trace!("fd_fdstat_get(fd={:?}, buf={:#x?})", fd, buf); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_fdstat_get(wasi_ctx, memory, fd, buf) } pub unsafe extern "C" fn fd_fdstat_set_flags( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, flags: wasi::__wasi_fdflags_t, ) -> wasi::__wasi_errno_t { @@ -436,6 +464,7 @@ syscalls! { pub unsafe extern "C" fn fd_fdstat_set_rights( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, fs_rights_base: wasi::__wasi_rights_t, fs_rights_inheriting: wasi::__wasi_rights_t, @@ -457,6 +486,7 @@ syscalls! { pub unsafe extern "C" fn fd_sync( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, ) -> wasi::__wasi_errno_t { trace!("fd_sync(fd={:?})", fd); @@ -466,6 +496,7 @@ syscalls! { pub unsafe extern "C" fn fd_write( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, iovs: wasi32::uintptr_t, iovs_len: wasi32::size_t, @@ -479,12 +510,13 @@ syscalls! { nwritten ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_write(wasi_ctx, memory, fd, iovs, iovs_len, nwritten) } pub unsafe extern "C" fn fd_advise( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, offset: wasi::__wasi_filesize_t, len: wasi::__wasi_filesize_t, @@ -503,6 +535,7 @@ syscalls! { pub unsafe extern "C" fn fd_allocate( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, offset: wasi::__wasi_filesize_t, len: wasi::__wasi_filesize_t, @@ -514,6 +547,7 @@ syscalls! { pub unsafe extern "C" fn path_create_directory( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, path: wasi32::uintptr_t, path_len: wasi32::size_t, @@ -525,12 +559,13 @@ syscalls! { path_len, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_create_directory(wasi_ctx, memory, fd, path, path_len) } pub unsafe extern "C" fn path_link( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd0: wasi::__wasi_fd_t, flags0: wasi::__wasi_lookupflags_t, path0: wasi32::uintptr_t, @@ -550,7 +585,7 @@ syscalls! { path_len1 ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_link( wasi_ctx, memory, @@ -568,6 +603,7 @@ syscalls! { // the `fd` by reference? pub unsafe extern "C" fn path_open( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, dirfd: wasi::__wasi_fd_t, dirflags: wasi::__wasi_lookupflags_t, path: wasi32::uintptr_t, @@ -591,7 +627,7 @@ syscalls! { fd ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_open( wasi_ctx, memory, @@ -609,6 +645,7 @@ syscalls! { pub unsafe extern "C" fn fd_readdir( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, buf: wasi32::uintptr_t, buf_len: wasi32::size_t, @@ -624,7 +661,7 @@ syscalls! { buf_used, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_readdir( wasi_ctx, memory, @@ -638,6 +675,7 @@ syscalls! { pub unsafe extern "C" fn path_readlink( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, path: wasi32::uintptr_t, path_len: wasi32::size_t, @@ -655,7 +693,7 @@ syscalls! { buf_used, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_readlink( wasi_ctx, memory, @@ -670,6 +708,7 @@ syscalls! { pub unsafe extern "C" fn path_rename( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd0: wasi::__wasi_fd_t, path0: wasi32::uintptr_t, path_len0: wasi32::size_t, @@ -687,7 +726,7 @@ syscalls! { path_len1, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_rename( wasi_ctx, memory, @@ -702,17 +741,19 @@ syscalls! { pub unsafe extern "C" fn fd_filestat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, buf: wasi32::uintptr_t, ) -> wasi::__wasi_errno_t { trace!("fd_filestat_get(fd={:?}, buf={:#x?})", fd, buf); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::fd_filestat_get(wasi_ctx, memory, fd, buf) } pub unsafe extern "C" fn fd_filestat_set_times( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, st_atim: wasi::__wasi_timestamp_t, st_mtim: wasi::__wasi_timestamp_t, @@ -730,6 +771,7 @@ syscalls! { pub unsafe extern "C" fn fd_filestat_set_size( vmctx: *mut VMContext, + _caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, size: wasi::__wasi_filesize_t, ) -> wasi::__wasi_errno_t { @@ -744,6 +786,7 @@ syscalls! { pub unsafe extern "C" fn path_filestat_get( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, flags: wasi::__wasi_lookupflags_t, path: wasi32::uintptr_t, @@ -759,12 +802,13 @@ syscalls! { buf ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_filestat_get(wasi_ctx, memory, fd, flags, path, path_len, buf) } pub unsafe extern "C" fn path_filestat_set_times( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, flags: wasi::__wasi_lookupflags_t, path: wasi32::uintptr_t, @@ -783,7 +827,7 @@ syscalls! { fstflags ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_filestat_set_times( wasi_ctx, memory, @@ -799,6 +843,7 @@ syscalls! { pub unsafe extern "C" fn path_symlink( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, path0: wasi32::uintptr_t, path_len0: wasi32::size_t, fd: wasi::__wasi_fd_t, @@ -814,7 +859,7 @@ syscalls! { path_len1 ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_symlink( wasi_ctx, memory, @@ -828,6 +873,7 @@ syscalls! { pub unsafe extern "C" fn path_unlink_file( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, path: wasi32::uintptr_t, path_len: wasi32::size_t, @@ -839,12 +885,13 @@ syscalls! { path_len ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_unlink_file(wasi_ctx, memory, fd, path, path_len) } pub unsafe extern "C" fn path_remove_directory( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, fd: wasi::__wasi_fd_t, path: wasi32::uintptr_t, path_len: wasi32::size_t, @@ -856,12 +903,13 @@ syscalls! { path_len ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::path_remove_directory(wasi_ctx, memory, fd, path, path_len) } pub unsafe extern "C" fn poll_oneoff( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, in_: wasi32::uintptr_t, out: wasi32::uintptr_t, nsubscriptions: wasi32::size_t, @@ -875,42 +923,45 @@ syscalls! { nevents, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::poll_oneoff(wasi_ctx, memory, in_, out, nsubscriptions, nevents) } - pub unsafe extern "C" fn proc_exit(_vmctx: *mut VMContext, rval: u32,) -> () { + pub unsafe extern "C" fn proc_exit(_vmctx: *mut VMContext, _caller_vmctx: *mut VMContext, rval: u32,) -> () { trace!("proc_exit(rval={:?})", rval); hostcalls::proc_exit(rval) } pub unsafe extern "C" fn proc_raise( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sig: wasi::__wasi_signal_t, ) -> wasi::__wasi_errno_t { trace!("proc_raise(sig={:?})", sig); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::proc_raise(wasi_ctx, memory, sig) } pub unsafe extern "C" fn random_get( - vmctx: *mut VMContext, + _vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, buf: wasi32::uintptr_t, buf_len: wasi32::size_t, ) -> wasi::__wasi_errno_t { trace!("random_get(buf={:#x?}, buf_len={:?})", buf, buf_len); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::random_get(memory, buf, buf_len) } - pub unsafe extern "C" fn sched_yield(_vmctx: *mut VMContext,) -> wasi::__wasi_errno_t { + pub unsafe extern "C" fn sched_yield(_vmctx: *mut VMContext, _caller_vmctx: *mut VMContext,) -> wasi::__wasi_errno_t { trace!("sched_yield(void)"); hostcalls::sched_yield() } pub unsafe extern "C" fn sock_recv( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sock: wasi::__wasi_fd_t, ri_data: wasi32::uintptr_t, ri_data_len: wasi32::size_t, @@ -925,7 +976,7 @@ syscalls! { ro_datalen, ro_flags ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::sock_recv( wasi_ctx, memory, @@ -940,6 +991,7 @@ syscalls! { pub unsafe extern "C" fn sock_send( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sock: wasi::__wasi_fd_t, si_data: wasi32::uintptr_t, si_data_len: wasi32::size_t, @@ -952,7 +1004,7 @@ syscalls! { si_data, si_data_len, si_flags, so_datalen, ); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::sock_send( wasi_ctx, memory, @@ -966,12 +1018,13 @@ syscalls! { pub unsafe extern "C" fn sock_shutdown( vmctx: *mut VMContext, + caller_vmctx: *mut VMContext, sock: wasi::__wasi_fd_t, how: wasi::__wasi_sdflags_t, ) -> wasi::__wasi_errno_t { trace!("sock_shutdown(sock={:?}, how={:?})", sock, how); let wasi_ctx = ok_or_errno!(get_wasi_ctx(&mut *vmctx)); - let memory = ok_or_errno!(get_memory(&mut *vmctx)); + let memory = ok_or_errno!(get_memory(&mut *caller_vmctx)); hostcalls::sock_shutdown(wasi_ctx, memory, sock, how) } } diff --git a/scripts/cranelift-version.sh b/scripts/cranelift-version.sh index 8bcba364fa..eece64a652 100755 --- a/scripts/cranelift-version.sh +++ b/scripts/cranelift-version.sh @@ -9,7 +9,7 @@ topdir=$(dirname "$0")/.. cd "$topdir" # All the cranelift-* crates have the same version number -version="0.55" +version="0.56" # Update all of the Cargo.toml files. echo "Updating crate versions to $version" diff --git a/src/commands/run.rs b/src/commands/run.rs index 3d0ce4df7a..469f96336b 100644 --- a/src/commands/run.rs +++ b/src/commands/run.rs @@ -150,9 +150,7 @@ impl RunCommand { let wasi_unstable = if self.enable_wasi_c { #[cfg(feature = "wasi-c")] { - let global_exports = store.global_exports().clone(); - let handle = - instantiate_wasi_c("", global_exports, &preopen_dirs, &argv, &self.vars)?; + let handle = instantiate_wasi_c("", &preopen_dirs, &argv, &self.vars)?; Instance::from_handle(&store, handle) } #[cfg(not(feature = "wasi-c"))] diff --git a/tests/instantiate.rs b/tests/instantiate.rs index 1d5a2d38b8..7dee909362 100644 --- a/tests/instantiate.rs +++ b/tests/instantiate.rs @@ -1,8 +1,5 @@ use more_asserts::assert_gt; -use std::cell::RefCell; -use std::collections::HashMap; use std::path::PathBuf; -use std::rc::Rc; use wasmtime_environ::settings; use wasmtime_environ::settings::Configurable; use wasmtime_jit::{instantiate, native, CompilationStrategy, Compiler, NullResolver}; @@ -24,14 +21,6 @@ fn test_environ_translate() { let mut resolver = NullResolver {}; let mut compiler = Compiler::new(isa, CompilationStrategy::Auto); - let global_exports = Rc::new(RefCell::new(HashMap::new())); - let instance = instantiate( - &mut compiler, - &data, - None, - &mut resolver, - global_exports, - false, - ); + let instance = instantiate(&mut compiler, &data, None, &mut resolver, false); assert!(instance.is_ok()); }