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:
@@ -15,6 +15,7 @@
|
||||
// tables: [VMTableDefinition; module.num_defined_tables],
|
||||
// memories: [VMMemoryDefinition; module.num_defined_memories],
|
||||
// globals: [VMGlobalDefinition; module.num_defined_globals],
|
||||
// anyfuncs: [VMCallerCheckedAnyfunc; module.num_imported_functions + module.num_defined_functions],
|
||||
// builtins: VMBuiltinFunctionsArray,
|
||||
// }
|
||||
|
||||
@@ -62,6 +63,8 @@ pub struct VMOffsets {
|
||||
pub num_imported_memories: u32,
|
||||
/// The number of imported globals in the module.
|
||||
pub num_imported_globals: u32,
|
||||
/// The number of defined functions in the module.
|
||||
pub num_defined_functions: u32,
|
||||
/// The number of defined tables in the module.
|
||||
pub num_defined_tables: u32,
|
||||
/// The number of defined memories in the module.
|
||||
@@ -80,6 +83,7 @@ impl VMOffsets {
|
||||
num_imported_tables: cast_to_u32(module.num_imported_tables),
|
||||
num_imported_memories: cast_to_u32(module.num_imported_memories),
|
||||
num_imported_globals: cast_to_u32(module.num_imported_globals),
|
||||
num_defined_functions: cast_to_u32(module.functions.len()),
|
||||
num_defined_tables: cast_to_u32(module.table_plans.len()),
|
||||
num_defined_memories: cast_to_u32(module.memory_plans.len()),
|
||||
num_defined_globals: cast_to_u32(module.globals.len()),
|
||||
@@ -390,8 +394,8 @@ impl VMOffsets {
|
||||
align(offset, 16)
|
||||
}
|
||||
|
||||
/// The offset of the builtin functions array.
|
||||
pub fn vmctx_builtin_functions_begin(&self) -> u32 {
|
||||
/// The offset of the `anyfuncs` array.
|
||||
pub fn vmctx_anyfuncs_begin(&self) -> u32 {
|
||||
self.vmctx_globals_begin()
|
||||
.checked_add(
|
||||
self.num_defined_globals
|
||||
@@ -401,6 +405,19 @@ impl VMOffsets {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// The offset of the builtin functions array.
|
||||
pub fn vmctx_builtin_functions_begin(&self) -> u32 {
|
||||
self.vmctx_anyfuncs_begin()
|
||||
.checked_add(
|
||||
self.num_imported_functions
|
||||
.checked_add(self.num_defined_functions)
|
||||
.unwrap()
|
||||
.checked_mul(u32::from(self.size_of_vmcaller_checked_anyfunc()))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Return the size of the `VMContext` allocation.
|
||||
pub fn size_of_vmctx(&self) -> u32 {
|
||||
self.vmctx_builtin_functions_begin()
|
||||
@@ -516,6 +533,19 @@ impl VMOffsets {
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Return the offset to the `VMCallerCheckedAnyfunc` for the given function
|
||||
/// index (either imported or defined).
|
||||
pub fn vmctx_anyfunc(&self, index: FuncIndex) -> u32 {
|
||||
self.vmctx_anyfuncs_begin()
|
||||
.checked_add(
|
||||
index
|
||||
.as_u32()
|
||||
.checked_mul(u32::from(self.size_of_vmcaller_checked_anyfunc()))
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// Return the offset to the `body` field in `*const VMFunctionBody` index `index`.
|
||||
pub fn vmctx_vmfunction_import_body(&self, index: FuncIndex) -> u32 {
|
||||
self.vmctx_vmfunction_import(index)
|
||||
|
||||
Reference in New Issue
Block a user