reference types: Implement the table.size and table.grow instructions (#1894)

Part of #929
This commit is contained in:
Nick Fitzgerald
2020-06-18 06:57:18 -07:00
committed by GitHub
parent 06a69d18fa
commit bbd99c5bfa
8 changed files with 441 additions and 383 deletions

View File

@@ -31,8 +31,33 @@
//! }
//! }
//! ```
//!
//! * When receiving a raw `*mut u8` that is actually a `VMExternRef` reference,
//! convert it into a proper `VMExternRef` with `VMExternRef::clone_from_raw`
//! as soon as apossible. Any GC before raw pointer is converted into a
//! reference can potentially collect the referenced object, which could lead
//! to use after free. Avoid this by eagerly converting into a proper
//! `VMExternRef`!
//!
//! ```ignore
//! pub unsafe extern "C" my_lib_takes_ref(raw_extern_ref: *mut u8) {
//! // Before `clone_from_raw`, `raw_extern_ref` is potentially unrooted,
//! // and doing GC here could lead to use after free!
//!
//! let my_extern_ref = if raw_extern_ref.is_null() {
//! None
//! } else {
//! Some(VMExternRef::clone_from_raw(raw_extern_ref))
//! };
//!
//! // Now that we did `clone_from_raw`, it is safe to do a GC (or do
//! // anything else that might transitively GC, like call back into
//! // Wasm!)
//! }
//! ```
use crate::table::Table;
use crate::externref::VMExternRef;
use crate::table::{Table, TableElement};
use crate::traphandlers::raise_lib_trap;
use crate::vmcontext::VMContext;
use wasmtime_environ::wasm::{DataIndex, DefinedMemoryIndex, ElemIndex, MemoryIndex, TableIndex};
@@ -201,6 +226,26 @@ pub unsafe extern "C" fn wasmtime_imported_memory32_size(
instance.imported_memory_size(memory_index)
}
/// Implementation of `table.grow` for `externref`s.
pub unsafe extern "C" fn wasmtime_table_grow_extern_ref(
vmctx: *mut VMContext,
table_index: u32,
delta: u32,
init_value: *mut u8,
) -> u32 {
let init_value = if init_value.is_null() {
None
} else {
Some(VMExternRef::clone_from_raw(init_value))
};
let instance = (&mut *vmctx).instance();
let table_index = TableIndex::from_u32(table_index);
instance
.table_grow(table_index, delta, TableElement::ExternRef(init_value))
.unwrap_or(-1_i32 as u32)
}
/// Implementation of `table.copy`.
pub unsafe extern "C" fn wasmtime_table_copy(
vmctx: *mut VMContext,