Switch to passing the vmctx hidden argument at the beginning.
This switches to passing the vmctx hidden argument at the beginning of the argument list, rather than the end.
This commit is contained in:
@@ -108,9 +108,9 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
fn get_memory_grow_sig(&self, func: &mut Function) -> ir::SigRef {
|
||||
func.import_signature(Signature {
|
||||
params: vec![
|
||||
AbiParam::new(I32),
|
||||
AbiParam::new(I32),
|
||||
AbiParam::special(self.pointer_type(), ArgumentPurpose::VMContext),
|
||||
AbiParam::new(I32),
|
||||
AbiParam::new(I32),
|
||||
],
|
||||
returns: vec![AbiParam::new(I32)],
|
||||
call_conv: self.target_config.default_call_conv,
|
||||
@@ -159,8 +159,8 @@ impl<'module_environment> FuncEnvironment<'module_environment> {
|
||||
fn get_memory32_size_sig(&self, func: &mut Function) -> ir::SigRef {
|
||||
func.import_signature(Signature {
|
||||
params: vec![
|
||||
AbiParam::new(I32),
|
||||
AbiParam::special(self.pointer_type(), ArgumentPurpose::VMContext),
|
||||
AbiParam::new(I32),
|
||||
],
|
||||
returns: vec![AbiParam::new(I32)],
|
||||
call_conv: self.target_config.default_call_conv,
|
||||
@@ -446,9 +446,8 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
);
|
||||
|
||||
let mut real_call_args = Vec::with_capacity(call_args.len() + 1);
|
||||
real_call_args.extend_from_slice(call_args);
|
||||
|
||||
// Append the callee vmctx address.
|
||||
// First append the callee vmctx address.
|
||||
let vmctx = pos.ins().load(
|
||||
pointer_type,
|
||||
mem_flags,
|
||||
@@ -457,6 +456,9 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
);
|
||||
real_call_args.push(vmctx);
|
||||
|
||||
// Then append the regular call arguments.
|
||||
real_call_args.extend_from_slice(call_args);
|
||||
|
||||
Ok(pos.ins().call_indirect(sig_ref, func_addr, &real_call_args))
|
||||
}
|
||||
|
||||
@@ -468,11 +470,15 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
call_args: &[ir::Value],
|
||||
) -> WasmResult<ir::Inst> {
|
||||
let mut real_call_args = Vec::with_capacity(call_args.len() + 1);
|
||||
real_call_args.extend_from_slice(call_args);
|
||||
|
||||
// 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());
|
||||
|
||||
// Then append the regular call arguments.
|
||||
real_call_args.extend_from_slice(call_args);
|
||||
|
||||
return Ok(pos.ins().call(callee, &real_call_args));
|
||||
}
|
||||
|
||||
@@ -490,12 +496,15 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
cast::i32(self.offsets.vmctx_vmfunction_import_body(callee_index)).unwrap();
|
||||
let func_addr = pos.ins().load(pointer_type, mem_flags, base, body_offset);
|
||||
|
||||
// Append the callee vmctx address.
|
||||
// First append the callee vmctx address.
|
||||
let vmctx_offset =
|
||||
cast::i32(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);
|
||||
|
||||
// Then append the regular call arguments.
|
||||
real_call_args.extend_from_slice(call_args);
|
||||
|
||||
Ok(pos.ins().call_indirect(sig_ref, func_addr, &real_call_args))
|
||||
}
|
||||
|
||||
@@ -511,7 +520,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
let vmctx = pos.func.special_param(ArgumentPurpose::VMContext).unwrap();
|
||||
let call_inst = pos
|
||||
.ins()
|
||||
.call(memory_grow_func, &[val, memory_index, vmctx]);
|
||||
.call(memory_grow_func, &[vmctx, val, memory_index]);
|
||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||
}
|
||||
|
||||
@@ -524,7 +533,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
let (memory_size_func, index_arg) = self.get_memory_size_func(&mut pos.func, index);
|
||||
let memory_index = pos.ins().iconst(I32, index_arg as i64);
|
||||
let vmctx = pos.func.special_param(ArgumentPurpose::VMContext).unwrap();
|
||||
let call_inst = pos.ins().call(memory_size_func, &[memory_index, vmctx]);
|
||||
let call_inst = pos.ins().call(memory_size_func, &[vmctx, memory_index]);
|
||||
Ok(*pos.func.dfg.inst_results(call_inst).first().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -235,8 +235,11 @@ impl<'data> cranelift_wasm::ModuleEnvironment<'data> for ModuleEnvironment<'data
|
||||
|
||||
/// Add environment-specific function parameters.
|
||||
pub fn translate_signature(mut sig: ir::Signature, pointer_type: ir::Type) -> ir::Signature {
|
||||
sig.params
|
||||
.push(AbiParam::special(pointer_type, ArgumentPurpose::VMContext));
|
||||
// Prepend the vmctx argument.
|
||||
sig.params.insert(
|
||||
0,
|
||||
AbiParam::special(pointer_type, ArgumentPurpose::VMContext),
|
||||
);
|
||||
sig
|
||||
}
|
||||
|
||||
|
||||
@@ -153,13 +153,16 @@ pub fn invoke(
|
||||
};
|
||||
|
||||
for (index, value) in args.iter().enumerate() {
|
||||
assert_eq!(value.value_type(), signature.params[index].value_type);
|
||||
// Add one to account for the leading vmctx argument.
|
||||
assert_eq!(value.value_type(), signature.params[index + 1].value_type);
|
||||
}
|
||||
|
||||
// TODO: Support values larger than u64. And pack the values into memory
|
||||
// instead of just using fixed-sized slots.
|
||||
// Subtract one becase we don't pass the vmctx argument in `values_vec`.
|
||||
let value_size = mem::size_of::<u64>();
|
||||
let mut values_vec: Vec<u64> = vec![0; max(signature.params.len(), signature.returns.len())];
|
||||
let mut values_vec: Vec<u64> =
|
||||
vec![0; max(signature.params.len() - 1, signature.returns.len())];
|
||||
|
||||
// Store the argument values into `values_vec`.
|
||||
for (index, arg) in args.iter().enumerate() {
|
||||
@@ -186,9 +189,9 @@ pub fn invoke(
|
||||
// Call the trampoline.
|
||||
if let Err(message) = unsafe {
|
||||
wasmtime_call_trampoline(
|
||||
callee_vmctx,
|
||||
exec_code_buf,
|
||||
values_vec.as_mut_ptr() as *mut u8,
|
||||
callee_vmctx,
|
||||
)
|
||||
} {
|
||||
return Ok(ActionOutcome::Trapped { message });
|
||||
|
||||
@@ -135,13 +135,13 @@ fn make_trampoline(
|
||||
let pointer_type = isa.pointer_type();
|
||||
let mut wrapper_sig = ir::Signature::new(isa.frontend_config().default_call_conv);
|
||||
|
||||
// Add the `values_vec` parameter.
|
||||
wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||
// Add the `vmctx` parameter.
|
||||
wrapper_sig.params.push(ir::AbiParam::special(
|
||||
pointer_type,
|
||||
ir::ArgumentPurpose::VMContext,
|
||||
));
|
||||
// Add the `values_vec` parameter.
|
||||
wrapper_sig.params.push(ir::AbiParam::new(pointer_type));
|
||||
|
||||
let mut context = Context::new();
|
||||
context.func = ir::Function::with_name_signature(ir::ExternalName::user(0, 0), wrapper_sig);
|
||||
@@ -155,7 +155,7 @@ fn make_trampoline(
|
||||
builder.seal_block(block0);
|
||||
|
||||
let mut callee_args = Vec::new();
|
||||
let (values_vec_ptr_val, vmctx_ptr_val) = {
|
||||
let (vmctx_ptr_val, values_vec_ptr_val) = {
|
||||
let params = builder.func.dfg.ebb_params(block0);
|
||||
(params[0], params[1])
|
||||
};
|
||||
@@ -164,11 +164,12 @@ fn make_trampoline(
|
||||
let mflags = ir::MemFlags::trusted();
|
||||
for (i, r) in signature.params.iter().enumerate() {
|
||||
let value = 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 * value_size) as i32,
|
||||
((i - 1) * value_size) as i32,
|
||||
),
|
||||
ir::ArgumentPurpose::VMContext => vmctx_ptr_val,
|
||||
other => panic!("unsupported argument purpose {}", other),
|
||||
|
||||
@@ -387,7 +387,7 @@ impl InstanceContents {
|
||||
};
|
||||
|
||||
// Make the call.
|
||||
unsafe { wasmtime_call(callee_address, callee_vmctx) }
|
||||
unsafe { wasmtime_call(callee_vmctx, callee_address) }
|
||||
.map_err(InstantiationError::StartTrap)
|
||||
}
|
||||
|
||||
|
||||
@@ -90,9 +90,9 @@ pub extern "C" fn wasmtime_f64_nearest(x: f64) -> f64 {
|
||||
/// Implementation of memory.grow for locally-defined 32-bit memories.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmtime_memory32_grow(
|
||||
vmctx: *mut VMContext,
|
||||
delta: u32,
|
||||
memory_index: u32,
|
||||
vmctx: *mut VMContext,
|
||||
) -> u32 {
|
||||
let instance_contents = (&mut *vmctx).instance_contents();
|
||||
let memory_index = DefinedMemoryIndex::from_u32(memory_index);
|
||||
@@ -105,9 +105,9 @@ pub unsafe extern "C" fn wasmtime_memory32_grow(
|
||||
/// Implementation of memory.grow for imported 32-bit memories.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmtime_imported_memory32_grow(
|
||||
vmctx: *mut VMContext,
|
||||
delta: u32,
|
||||
memory_index: u32,
|
||||
vmctx: *mut VMContext,
|
||||
) -> u32 {
|
||||
let instance_contents = (&mut *vmctx).instance_contents();
|
||||
let memory_index = MemoryIndex::from_u32(memory_index);
|
||||
@@ -119,7 +119,7 @@ pub unsafe extern "C" fn wasmtime_imported_memory32_grow(
|
||||
|
||||
/// Implementation of memory.size for locally-defined 32-bit memories.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmtime_memory32_size(memory_index: u32, vmctx: *mut VMContext) -> u32 {
|
||||
pub unsafe extern "C" fn wasmtime_memory32_size(vmctx: *mut VMContext, memory_index: u32) -> u32 {
|
||||
let instance_contents = (&mut *vmctx).instance_contents();
|
||||
let memory_index = DefinedMemoryIndex::from_u32(memory_index);
|
||||
|
||||
@@ -129,8 +129,8 @@ pub unsafe extern "C" fn wasmtime_memory32_size(memory_index: u32, vmctx: *mut V
|
||||
/// Implementation of memory.size for imported 32-bit memories.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmtime_imported_memory32_size(
|
||||
memory_index: u32,
|
||||
vmctx: *mut VMContext,
|
||||
memory_index: u32,
|
||||
) -> u32 {
|
||||
let instance_contents = (&mut *vmctx).instance_contents();
|
||||
let memory_index = MemoryIndex::from_u32(memory_index);
|
||||
|
||||
@@ -91,9 +91,9 @@ fn push_jmp_buf(buf: jmp_buf) {
|
||||
/// return values will be written.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmtime_call_trampoline(
|
||||
vmctx: *mut VMContext,
|
||||
callee: *const VMFunctionBody,
|
||||
values_vec: *mut u8,
|
||||
vmctx: *mut VMContext,
|
||||
) -> Result<(), String> {
|
||||
// Reset JMP_BUFS if the stack is unwound through this point.
|
||||
let _guard = ScopeGuard::new();
|
||||
@@ -106,8 +106,8 @@ pub unsafe extern "C" fn wasmtime_call_trampoline(
|
||||
push_jmp_buf(buf);
|
||||
|
||||
// Call the function!
|
||||
let func: fn(*mut u8, *mut VMContext) = mem::transmute(callee);
|
||||
func(values_vec, vmctx);
|
||||
let func: fn(*mut VMContext, *mut u8) = mem::transmute(callee);
|
||||
func(vmctx, values_vec);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -116,8 +116,8 @@ pub unsafe extern "C" fn wasmtime_call_trampoline(
|
||||
/// return values.
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmtime_call(
|
||||
callee: *const VMFunctionBody,
|
||||
vmctx: *mut VMContext,
|
||||
callee: *const VMFunctionBody,
|
||||
) -> Result<(), String> {
|
||||
// Reset JMP_BUFS if the stack is unwound through this point.
|
||||
let _guard = ScopeGuard::new();
|
||||
|
||||
Reference in New Issue
Block a user