wasmtime: Initial, partial support for externref
This is enough to get an `externref -> externref` identity function passing. However, `externref`s that are dropped by compiled Wasm code are (safely) leaked. Follow up work will leverage cranelift's stack maps to resolve this issue.
This commit is contained in:
@@ -303,7 +303,7 @@ fn compile(env: CompileEnv<'_>) -> Result<ModuleCacheDataTupleType, CompileError
|
||||
let func_index = env.local.func_index(*i);
|
||||
let mut context = Context::new();
|
||||
context.func.name = get_func_name(func_index);
|
||||
context.func.signature = env.local.func_signature(func_index).clone();
|
||||
context.func.signature = env.local.native_func_signature(func_index).clone();
|
||||
if env.tunables.debug_info {
|
||||
context.func.collect_debug_info();
|
||||
}
|
||||
|
||||
@@ -24,6 +24,6 @@ pub mod wasm {
|
||||
pub use cranelift_wasm::{
|
||||
get_vmctx_value_label, DataIndex, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex,
|
||||
DefinedTableIndex, ElemIndex, FuncIndex, Global, GlobalIndex, GlobalInit, Memory,
|
||||
MemoryIndex, SignatureIndex, Table, TableElementType, TableIndex,
|
||||
MemoryIndex, SignatureIndex, Table, TableElementType, TableIndex, WasmFuncType, WasmType,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -549,7 +549,7 @@ impl lightbeam::ModuleContext for FuncEnvironment<'_> {
|
||||
}
|
||||
|
||||
fn signature(&self, index: u32) -> &Self::Signature {
|
||||
&self.module.signatures[SignatureIndex::from_u32(index)]
|
||||
&self.module.signatures[SignatureIndex::from_u32(index)].1
|
||||
}
|
||||
|
||||
fn defined_table_index(&self, table_index: u32) -> Option<u32> {
|
||||
@@ -658,6 +658,13 @@ impl<'module_environment> TargetEnvironment for FuncEnvironment<'module_environm
|
||||
fn target_config(&self) -> TargetFrontendConfig {
|
||||
self.target_config
|
||||
}
|
||||
|
||||
fn reference_type(&self) -> ir::Type {
|
||||
// For now, the only reference types we support are `externref`, which
|
||||
// don't require tracing GC and stack maps. So we just use the target's
|
||||
// pointer type. This will have to change once we move to tracing GC.
|
||||
self.pointer_type()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'module_environment> {
|
||||
@@ -915,7 +922,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
func: &mut ir::Function,
|
||||
index: SignatureIndex,
|
||||
) -> WasmResult<ir::SigRef> {
|
||||
Ok(func.import_signature(self.module.signatures[index].clone()))
|
||||
Ok(func.import_signature(self.module.signatures[index].1.clone()))
|
||||
}
|
||||
|
||||
fn make_direct_func(
|
||||
@@ -923,7 +930,7 @@ impl<'module_environment> cranelift_wasm::FuncEnvironment for FuncEnvironment<'m
|
||||
func: &mut ir::Function,
|
||||
index: FuncIndex,
|
||||
) -> WasmResult<ir::FuncRef> {
|
||||
let sig = self.module.func_signature(index);
|
||||
let sig = self.module.native_func_signature(index);
|
||||
let signature = func.import_signature(sig.clone());
|
||||
let name = get_func_name(index);
|
||||
Ok(func.import_function(ir::ExtFuncData {
|
||||
|
||||
@@ -7,7 +7,7 @@ use cranelift_entity::{EntityRef, PrimaryMap};
|
||||
use cranelift_wasm::{
|
||||
DataIndex, DefinedFuncIndex, DefinedGlobalIndex, DefinedMemoryIndex, DefinedTableIndex,
|
||||
ElemIndex, FuncIndex, Global, GlobalIndex, Memory, MemoryIndex, SignatureIndex, Table,
|
||||
TableIndex,
|
||||
TableIndex, WasmFuncType,
|
||||
};
|
||||
use indexmap::IndexMap;
|
||||
use more_asserts::assert_ge;
|
||||
@@ -181,7 +181,7 @@ pub struct Module {
|
||||
#[derive(Debug, Hash)]
|
||||
pub struct ModuleLocal {
|
||||
/// Unprocessed signatures exactly as provided by `declare_signature()`.
|
||||
pub signatures: PrimaryMap<SignatureIndex, ir::Signature>,
|
||||
pub signatures: PrimaryMap<SignatureIndex, (WasmFuncType, ir::Signature)>,
|
||||
|
||||
/// Number of imported functions in the module.
|
||||
pub num_imported_funcs: usize,
|
||||
@@ -332,8 +332,15 @@ impl ModuleLocal {
|
||||
index.index() < self.num_imported_globals
|
||||
}
|
||||
|
||||
/// Convenience method for looking up the signature of a function.
|
||||
pub fn func_signature(&self, func_index: FuncIndex) -> &ir::Signature {
|
||||
&self.signatures[self.functions[func_index]]
|
||||
/// Convenience method for looking up the native signature of a compiled
|
||||
/// Wasm function.
|
||||
pub fn native_func_signature(&self, func_index: FuncIndex) -> &ir::Signature {
|
||||
&self.signatures[self.functions[func_index]].1
|
||||
}
|
||||
|
||||
/// Convenience method for looking up the original Wasm signature of a
|
||||
/// function.
|
||||
pub fn wasm_func_type(&self, func_index: FuncIndex) -> &WasmFuncType {
|
||||
&self.signatures[self.functions[func_index]].0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,13 @@ impl<'data> TargetEnvironment for ModuleEnvironment<'data> {
|
||||
fn target_config(&self) -> TargetFrontendConfig {
|
||||
self.result.target_config
|
||||
}
|
||||
|
||||
fn reference_type(&self) -> ir::Type {
|
||||
// For now, the only reference types we support are `externref`, which
|
||||
// don't require tracing GC and stack maps. So we just use the target's
|
||||
// pointer type. This will have to change once we move to tracing GC.
|
||||
self.pointer_type()
|
||||
}
|
||||
}
|
||||
|
||||
/// This trait is useful for `translate_module` because it tells how to translate
|
||||
@@ -106,10 +113,14 @@ impl<'data> cranelift_wasm::ModuleEnvironment<'data> for ModuleEnvironment<'data
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn declare_signature(&mut self, _wasm: &WasmFuncType, sig: ir::Signature) -> WasmResult<()> {
|
||||
fn declare_signature(&mut self, wasm: &WasmFuncType, sig: ir::Signature) -> WasmResult<()> {
|
||||
let sig = translate_signature(sig, self.pointer_type());
|
||||
// TODO: Deduplicate signatures.
|
||||
self.result.module.local.signatures.push(sig);
|
||||
self.result
|
||||
.module
|
||||
.local
|
||||
.signatures
|
||||
.push((wasm.clone(), sig));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user