wasmtime: Implement global.{get,set} for externref globals (#1969)

* wasmtime: Implement `global.{get,set}` for externref globals

We use libcalls to implement these -- unlike `table.{get,set}`, for which we
create inline JIT fast paths -- because no known toolchain actually uses
externref globals.

Part of #929

* wasmtime: Enable `{extern,func}ref` globals in the API
This commit is contained in:
Nick Fitzgerald
2020-07-02 14:04:01 -07:00
committed by GitHub
parent 3fa3ff2ece
commit bffd54c016
19 changed files with 520 additions and 79 deletions

View File

@@ -1,6 +1,7 @@
//! This file declares `VMContext` and several related structs which contain
//! fields that compiled wasm code accesses directly.
use crate::externref::VMExternRef;
use crate::instance::Instance;
use std::any::Any;
use std::ptr::NonNull;
@@ -267,6 +268,7 @@ pub struct VMGlobalDefinition {
#[cfg(test)]
mod test_vmglobal_definition {
use super::VMGlobalDefinition;
use crate::externref::VMExternRef;
use more_asserts::assert_ge;
use std::mem::{align_of, size_of};
use wasmtime_environ::{Module, VMOffsets};
@@ -296,6 +298,11 @@ mod test_vmglobal_definition {
let offsets = VMOffsets::new(size_of::<*mut u8>() as u8, &module.local);
assert_eq!(offsets.vmctx_globals_begin() % 16, 0);
}
#[test]
fn check_vmglobal_can_contain_externref() {
assert!(size_of::<VMExternRef>() <= size_of::<VMGlobalDefinition>());
}
}
impl VMGlobalDefinition {
@@ -423,6 +430,30 @@ impl VMGlobalDefinition {
pub unsafe fn as_u128_bits_mut(&mut self) -> &mut [u8; 16] {
&mut *(self.storage.as_mut().as_mut_ptr() as *mut [u8; 16])
}
/// Return a reference to the value as an externref.
#[allow(clippy::cast_ptr_alignment)]
pub unsafe fn as_externref(&self) -> &Option<VMExternRef> {
&*(self.storage.as_ref().as_ptr() as *const Option<VMExternRef>)
}
/// Return a mutable reference to the value as an externref.
#[allow(clippy::cast_ptr_alignment)]
pub unsafe fn as_externref_mut(&mut self) -> &mut Option<VMExternRef> {
&mut *(self.storage.as_mut().as_mut_ptr() as *mut Option<VMExternRef>)
}
/// Return a reference to the value as an anyfunc.
#[allow(clippy::cast_ptr_alignment)]
pub unsafe fn as_anyfunc(&self) -> *const VMCallerCheckedAnyfunc {
*(self.storage.as_ref().as_ptr() as *const *const VMCallerCheckedAnyfunc)
}
/// Return a mutable reference to the value as an anyfunc.
#[allow(clippy::cast_ptr_alignment)]
pub unsafe fn as_anyfunc_mut(&mut self) -> &mut *const VMCallerCheckedAnyfunc {
&mut *(self.storage.as_mut().as_mut_ptr() as *mut *const VMCallerCheckedAnyfunc)
}
}
/// An index into the shared signature registry, usable for checking signatures
@@ -559,6 +590,10 @@ impl VMBuiltinFunctionsArray {
wasmtime_drop_externref as usize;
ptrs[BuiltinFunctionIndex::activations_table_insert_with_gc().index() as usize] =
wasmtime_activations_table_insert_with_gc as usize;
ptrs[BuiltinFunctionIndex::externref_global_get().index() as usize] =
wasmtime_externref_global_get as usize;
ptrs[BuiltinFunctionIndex::externref_global_set().index() as usize] =
wasmtime_externref_global_set as usize;
if cfg!(debug_assertions) {
for i in 0..ptrs.len() {