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:
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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::<Vec<_>>();
|
||||
|
||||
@@ -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<ValidatingParserConfig> for Features {
|
||||
pub struct Context {
|
||||
namespace: Namespace,
|
||||
compiler: Box<Compiler>,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>>,
|
||||
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<RefCell<HashMap<String, Option<wasmtime_runtime::Export>>>> {
|
||||
Rc::clone(&self.global_exports)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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<DefinedFuncIndex, *const VMFunctionBody>,
|
||||
data_initializers: Box<[OwnedDataInitializer]>,
|
||||
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
|
||||
dbg_jit_registration: Option<Rc<GdbJitImageRegistration>>,
|
||||
}
|
||||
|
||||
@@ -152,14 +149,12 @@ impl CompiledModule {
|
||||
compiler: &mut Compiler,
|
||||
data: &'data [u8],
|
||||
module_name: Option<&str>,
|
||||
global_exports: Rc<RefCell<HashMap<String, Option<Export>>>>,
|
||||
debug_info: bool,
|
||||
) -> Result<Self, SetupError> {
|
||||
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<RefCell<HashMap<String, Option<Export>>>>,
|
||||
finished_functions: BoxedSlice<DefinedFuncIndex, *const VMFunctionBody>,
|
||||
data_initializers: Box<[OwnedDataInitializer]>,
|
||||
signatures: BoxedSlice<SignatureIndex, VMSharedSignatureIndex>,
|
||||
@@ -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<RefCell<HashMap<String, Option<Export>>>>,
|
||||
debug_info: bool,
|
||||
) -> Result<InstanceHandle, SetupError> {
|
||||
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,
|
||||
|
||||
Reference in New Issue
Block a user