wasmtime: Add support for func.ref and table.grow with funcrefs

`funcref`s are implemented as `NonNull<VMCallerCheckedAnyfunc>`.

This should be more efficient than using a `VMExternRef` that points at a
`VMCallerCheckedAnyfunc` because it gets rid of an indirection, dynamic
allocation, and some reference counting.

Note that the null function reference is *NOT* a null pointer; it is a
`VMCallerCheckedAnyfunc` that has a null `func_ptr` member.

Part of #929
This commit is contained in:
Nick Fitzgerald
2020-06-18 11:04:40 -07:00
parent ddc2ce8080
commit 58bb5dd953
37 changed files with 603 additions and 305 deletions

View File

@@ -32,7 +32,9 @@ pub fn resolve_imports(
match (import, &export) {
(EntityIndex::Function(func_index), Some(Export::Function(f))) => {
let import_signature = module.local.native_func_signature(*func_index);
let signature = signatures.lookup_native(f.signature).unwrap();
let signature = signatures
.lookup_native(unsafe { f.anyfunc.as_ref().type_index })
.unwrap();
if signature != *import_signature {
// TODO: If the difference is in the calling convention,
// we could emit a wrapper function to fix it up.
@@ -43,8 +45,8 @@ pub fn resolve_imports(
)));
}
function_imports.push(VMFunctionImport {
body: f.address,
vmctx: f.vmctx,
body: unsafe { f.anyfunc.as_ref().func_ptr },
vmctx: unsafe { f.anyfunc.as_ref().vmctx },
});
}
(EntityIndex::Function(_), Some(_)) => {
@@ -169,16 +171,20 @@ fn is_global_compatible(exported: &Global, imported: &Global) -> bool {
}
let Global {
wasm_ty: exported_wasm_ty,
ty: exported_ty,
mutability: exported_mutability,
initializer: _exported_initializer,
} = exported;
let Global {
wasm_ty: imported_wasm_ty,
ty: imported_ty,
mutability: imported_mutability,
initializer: _imported_initializer,
} = imported;
exported_ty == imported_ty && imported_mutability == exported_mutability
exported_wasm_ty == imported_wasm_ty
&& exported_ty == imported_ty
&& imported_mutability == exported_mutability
}
fn is_table_element_type_compatible(