Skip to content

Instantly share code, notes, and snippets.

@alexcrichton
Created May 20, 2021 16:31
Show Gist options
  • Save alexcrichton/25df779540182eefb8a833d0f9141160 to your computer and use it in GitHub Desktop.
Save alexcrichton/25df779540182eefb8a833d0f9141160 to your computer and use it in GitHub Desktop.
diff --git a/crates/c-api/include/wasmtime/extern.h b/crates/c-api/include/wasmtime/extern.h
index 587f942dc..a96d8c8d0 100644
--- a/crates/c-api/include/wasmtime/extern.h
+++ b/crates/c-api/include/wasmtime/extern.h
@@ -21,7 +21,12 @@ extern "C" {
/// interoperate between #wasmtime_store_t instances and if the wrong function
/// is passed to the wrong store then it may trigger an assertion to abort the
/// process.
-typedef uint64_t wasmtime_func_t;
+typedef struct wasmtime_func {
+ /// Internal identifier of what store this belogns to, never zero.
+ uint64_t store_id;
+ /// Internal index within the store.
+ size_t index;
+} wasmtime_func_t;
/// \brief Representation of a table in Wasmtime.
///
@@ -30,7 +35,12 @@ typedef uint64_t wasmtime_func_t;
/// interoperate between #wasmtime_store_t instances and if the wrong table
/// is passed to the wrong store then it may trigger an assertion to abort the
/// process.
-typedef uint64_t wasmtime_table_t;
+typedef struct wasmtime_table {
+ /// Internal identifier of what store this belogns to, never zero.
+ uint64_t store_id;
+ /// Internal index within the store.
+ size_t index;
+} wasmtime_table_t;
/// \brief Representation of a memory in Wasmtime.
///
@@ -39,7 +49,12 @@ typedef uint64_t wasmtime_table_t;
/// interoperate between #wasmtime_store_t instances and if the wrong memory
/// is passed to the wrong store then it may trigger an assertion to abort the
/// process.
-typedef uint64_t wasmtime_memory_t;
+typedef struct wasmtime_memory {
+ /// Internal identifier of what store this belogns to, never zero.
+ uint64_t store_id;
+ /// Internal index within the store.
+ size_t index;
+} wasmtime_memory_t;
/// \brief Representation of a instance in Wasmtime.
///
@@ -48,7 +63,12 @@ typedef uint64_t wasmtime_memory_t;
/// interoperate between #wasmtime_store_t instances and if the wrong instance
/// is passed to the wrong store then it may trigger an assertion to abort the
/// process.
-typedef uint64_t wasmtime_instance_t;
+typedef struct wasmtime_instance {
+ /// Internal identifier of what store this belogns to, never zero.
+ uint64_t store_id;
+ /// Internal index within the store.
+ size_t index;
+} wasmtime_instance_t;
/// \brief Representation of a global in Wasmtime.
///
@@ -57,7 +77,12 @@ typedef uint64_t wasmtime_instance_t;
/// interoperate between #wasmtime_store_t instances and if the wrong global
/// is passed to the wrong store then it may trigger an assertion to abort the
/// process.
-typedef uint64_t wasmtime_global_t;
+typedef struct wasmtime_global {
+ /// Internal identifier of what store this belogns to, never zero.
+ uint64_t store_id;
+ /// Internal index within the store.
+ size_t index;
+} wasmtime_global_t;
/// \brief Disciminant of #wasmtime_extern_t
typedef uint8_t wasmtime_extern_kind_t;
diff --git a/crates/c-api/include/wasmtime/func.h b/crates/c-api/include/wasmtime/func.h
index 150f458cc..11edd5edf 100644
--- a/crates/c-api/include/wasmtime/func.h
+++ b/crates/c-api/include/wasmtime/func.h
@@ -77,12 +77,13 @@ typedef wasm_trap_t* (*wasmtime_func_callback_t)(
*
* The returned function can only be used with the specified `store`.
*/
-WASM_API_EXTERN wasmtime_func_t wasmtime_func_new(
+WASM_API_EXTERN void wasmtime_func_new(
wasmtime_context_t *store,
const wasm_functype_t* type,
wasmtime_func_callback_t callback,
void *env,
- void (*finalizer)(void*)
+ void (*finalizer)(void*),
+ wasmtime_func_t *ret
);
/**
@@ -92,7 +93,7 @@ WASM_API_EXTERN wasmtime_func_t wasmtime_func_new(
*/
WASM_API_EXTERN wasm_functype_t* wasmtime_func_type(
const wasmtime_context_t *store,
- wasmtime_func_t func
+ wasmtime_func_t *func
);
/**
@@ -132,7 +133,7 @@ WASM_API_EXTERN wasm_functype_t* wasmtime_func_type(
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_func_call(
wasmtime_context_t *store,
- wasmtime_func_t func,
+ wasmtime_func_t *func,
const wasmtime_val_t *args,
size_t nargs,
wasmtime_val_t *results,
diff --git a/crates/c-api/include/wasmtime/global.h b/crates/c-api/include/wasmtime/global.h
index 86631a1db..98c39b313 100644
--- a/crates/c-api/include/wasmtime/global.h
+++ b/crates/c-api/include/wasmtime/global.h
@@ -47,7 +47,7 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_global_new(
*/
WASM_API_EXTERN wasm_globaltype_t* wasmtime_global_type(
const wasmtime_context_t *store,
- wasmtime_global_t global
+ wasmtime_global_t *global
);
/**
@@ -62,7 +62,7 @@ WASM_API_EXTERN wasm_globaltype_t* wasmtime_global_type(
*/
WASM_API_EXTERN void wasmtime_global_get(
wasmtime_context_t *store,
- wasmtime_global_t global,
+ wasmtime_global_t *global,
wasmtime_val_t *out
);
@@ -80,7 +80,7 @@ WASM_API_EXTERN void wasmtime_global_get(
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_global_set(
wasmtime_context_t *store,
- wasmtime_global_t global,
+ wasmtime_global_t *global,
const wasmtime_val_t *val
);
diff --git a/crates/c-api/include/wasmtime/instance.h b/crates/c-api/include/wasmtime/instance.h
index 123752ad2..465e60fa1 100644
--- a/crates/c-api/include/wasmtime/instance.h
+++ b/crates/c-api/include/wasmtime/instance.h
@@ -98,7 +98,7 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_instance_new(
*/
WASM_API_EXTERN wasmtime_instancetype_t *wasmtime_instance_type(
const wasmtime_context_t *store,
- wasmtime_instance_t instance
+ wasmtime_instance_t *instance
);
/**
@@ -118,7 +118,7 @@ WASM_API_EXTERN wasmtime_instancetype_t *wasmtime_instance_type(
*/
WASM_API_EXTERN bool wasmtime_instance_export_get(
wasmtime_context_t *store,
- wasmtime_instance_t instance,
+ wasmtime_instance_t *instance,
const char *name,
size_t name_len,
wasmtime_extern_t *item
@@ -144,7 +144,7 @@ WASM_API_EXTERN bool wasmtime_instance_export_get(
*/
WASM_API_EXTERN bool wasmtime_instance_export_nth(
wasmtime_context_t *store,
- wasmtime_instance_t instance,
+ wasmtime_instance_t *instance,
size_t index,
char **name,
size_t *name_len,
diff --git a/crates/c-api/include/wasmtime/linker.h b/crates/c-api/include/wasmtime/linker.h
index 08344f6db..7c3710725 100644
--- a/crates/c-api/include/wasmtime/linker.h
+++ b/crates/c-api/include/wasmtime/linker.h
@@ -125,7 +125,7 @@ WASM_API_EXTERN wasmtime_error_t* wasmtime_linker_define_instance(
wasmtime_context_t *store,
const char *name,
size_t name_len,
- wasmtime_instance_t instance
+ wasmtime_instance_t *instance
);
/**
diff --git a/crates/c-api/include/wasmtime/memory.h b/crates/c-api/include/wasmtime/memory.h
index 83dd82e83..c6c142353 100644
--- a/crates/c-api/include/wasmtime/memory.h
+++ b/crates/c-api/include/wasmtime/memory.h
@@ -37,7 +37,7 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_memory_new(
*/
WASM_API_EXTERN wasm_memorytype_t* wasmtime_memory_type(
const wasmtime_context_t *store,
- wasmtime_memory_t memory
+ wasmtime_memory_t *memory
);
/**
@@ -45,7 +45,7 @@ WASM_API_EXTERN wasm_memorytype_t* wasmtime_memory_type(
*/
WASM_API_EXTERN uint8_t *wasmtime_memory_data(
const wasmtime_context_t *store,
- wasmtime_memory_t memory
+ wasmtime_memory_t *memory
);
/**
@@ -53,7 +53,7 @@ WASM_API_EXTERN uint8_t *wasmtime_memory_data(
*/
WASM_API_EXTERN size_t wasmtime_memory_data_size(
const wasmtime_context_t *store,
- wasmtime_memory_t memory
+ wasmtime_memory_t *memory
);
/**
@@ -61,7 +61,7 @@ WASM_API_EXTERN size_t wasmtime_memory_data_size(
*/
WASM_API_EXTERN uint32_t wasmtime_memory_size(
const wasmtime_context_t *store,
- wasmtime_memory_t memory
+ wasmtime_memory_t *memory
);
/**
@@ -78,7 +78,7 @@ WASM_API_EXTERN uint32_t wasmtime_memory_size(
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_memory_grow(
wasmtime_context_t *store,
- wasmtime_memory_t memory,
+ wasmtime_memory_t *memory,
uint32_t delta,
uint32_t *prev_size
);
diff --git a/crates/c-api/include/wasmtime/table.h b/crates/c-api/include/wasmtime/table.h
index 84a99e675..df7f27181 100644
--- a/crates/c-api/include/wasmtime/table.h
+++ b/crates/c-api/include/wasmtime/table.h
@@ -43,7 +43,7 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_table_new(
*/
WASM_API_EXTERN wasm_tabletype_t* wasmtime_table_type(
const wasmtime_context_t *store,
- wasmtime_table_t table
+ wasmtime_table_t *table
);
/**
@@ -60,7 +60,7 @@ WASM_API_EXTERN wasm_tabletype_t* wasmtime_table_type(
*/
WASM_API_EXTERN bool wasmtime_table_get(
wasmtime_context_t *store,
- wasmtime_table_t table,
+ wasmtime_table_t *table,
uint32_t index,
wasmtime_val_t *val
);
@@ -80,7 +80,7 @@ WASM_API_EXTERN bool wasmtime_table_get(
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_table_set(
wasmtime_context_t *store,
- wasmtime_table_t table,
+ wasmtime_table_t *table,
uint32_t index,
const wasmtime_val_t *value
);
@@ -90,7 +90,7 @@ WASM_API_EXTERN wasmtime_error_t *wasmtime_table_set(
*/
WASM_API_EXTERN uint32_t wasmtime_table_size(
const wasmtime_context_t *store,
- wasmtime_table_t table
+ wasmtime_table_t *table
);
/**
@@ -112,7 +112,7 @@ WASM_API_EXTERN uint32_t wasmtime_table_size(
*/
WASM_API_EXTERN wasmtime_error_t *wasmtime_table_grow(
wasmtime_context_t *store,
- wasmtime_table_t table,
+ wasmtime_table_t *table,
uint32_t delta,
const wasmtime_val_t *init,
uint32_t *prev_size
diff --git a/crates/c-api/include/wasmtime/val.h b/crates/c-api/include/wasmtime/val.h
index 6acacd61c..43b40ff77 100644
--- a/crates/c-api/include/wasmtime/val.h
+++ b/crates/c-api/include/wasmtime/val.h
@@ -104,8 +104,14 @@ typedef union wasmtime_valunion {
/// Field used if #wasmtime_val_t::kind is #WASMTIME_F64
float64_t f64;
/// Field used if #wasmtime_val_t::kind is #WASMTIME_FUNCREF
+ ///
+ /// If this value represents a `ref.null func` value then the `store_id` field
+ /// is set to zero.
wasmtime_func_t funcref;
/// Field used if #wasmtime_val_t::kind is #WASMTIME_EXTERNREF
+ ///
+ /// If this value represents a `ref.null extern` value then this pointer will
+ /// be `NULL`.
wasmtime_externref_t *externref;
/// Field used if #wasmtime_val_t::kind is #WASMTIME_V128
wasmtime_v128 v128;
@@ -131,10 +137,6 @@ typedef struct wasmtime_val {
wasmtime_valunion_t of;
} wasmtime_val_t;
-/// \brief value for #wasmtime_valunion::funcref indicating that the funcref is
-/// null.
-#define WASMTIME_FUNCREF_NULL ((uint64_t) 0xffffffffffffffff)
-
/**
* \brief Delets an owned #wasmtime_val_t.
*
diff --git a/crates/c-api/src/func.rs b/crates/c-api/src/func.rs
index 6792aebe0..ae76c3739 100644
--- a/crates/c-api/src/func.rs
+++ b/crates/c-api/src/func.rs
@@ -201,10 +201,11 @@ pub unsafe extern "C" fn wasmtime_func_new(
) -> Option<Box<wasm_trap_t>>,
data: *mut c_void,
finalizer: Option<extern "C" fn(*mut std::ffi::c_void)>,
-) -> Func {
+ func: &mut Func,
+) {
let foreign = crate::ForeignData { data, finalizer };
let ty = ty.ty().ty.clone();
- Func::new(store, ty, move |caller, params, results| {
+ let f = Func::new(store, ty, move |caller, params, results| {
let params = params
.iter()
.cloned()
@@ -233,13 +234,14 @@ pub unsafe extern "C" fn wasmtime_func_new(
results[i] = unsafe { result.to_val() };
}
Ok(())
- })
+ });
+ *func = f;
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_func_call(
store: CStoreContextMut<'_>,
- func: Func,
+ func: &Func,
args: *const wasmtime_val_t,
nargs: usize,
results: *mut MaybeUninit<wasmtime_val_t>,
@@ -291,7 +293,10 @@ pub unsafe extern "C" fn wasmtime_func_call(
}
#[no_mangle]
-pub extern "C" fn wasmtime_func_type(store: CStoreContext<'_>, func: Func) -> Box<wasm_functype_t> {
+pub extern "C" fn wasmtime_func_type(
+ store: CStoreContext<'_>,
+ func: &Func,
+) -> Box<wasm_functype_t> {
Box::new(wasm_functype_t::new(func.ty(store)))
}
diff --git a/crates/c-api/src/global.rs b/crates/c-api/src/global.rs
index 2bd33700b..653855b52 100644
--- a/crates/c-api/src/global.rs
+++ b/crates/c-api/src/global.rs
@@ -93,7 +93,7 @@ pub unsafe extern "C" fn wasmtime_global_new(
#[no_mangle]
pub extern "C" fn wasmtime_global_type(
store: CStoreContext<'_>,
- global: Global,
+ global: &Global,
) -> Box<wasm_globaltype_t> {
Box::new(wasm_globaltype_t::new(global.ty(store)))
}
@@ -101,7 +101,7 @@ pub extern "C" fn wasmtime_global_type(
#[no_mangle]
pub extern "C" fn wasmtime_global_get(
store: CStoreContextMut<'_>,
- global: Global,
+ global: &Global,
val: &mut MaybeUninit<wasmtime_val_t>,
) {
crate::initialize(val, wasmtime_val_t::from_val(global.get(store)))
@@ -110,7 +110,7 @@ pub extern "C" fn wasmtime_global_get(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_global_set(
store: CStoreContextMut<'_>,
- global: Global,
+ global: &Global,
val: &wasmtime_val_t,
) -> Option<Box<wasmtime_error_t>> {
handle_result(global.set(store, val.to_val()), |()| {})
diff --git a/crates/c-api/src/instance.rs b/crates/c-api/src/instance.rs
index e1bbf064e..4c17bc3a0 100644
--- a/crates/c-api/src/instance.rs
+++ b/crates/c-api/src/instance.rs
@@ -136,7 +136,7 @@ pub(crate) fn handle_instantiate(
#[no_mangle]
pub extern "C" fn wasmtime_instance_type(
store: CStoreContext<'_>,
- instance: Instance,
+ instance: &Instance,
) -> Box<wasmtime_instancetype_t> {
Box::new(wasmtime_instancetype_t::new(instance.ty(store)))
}
@@ -144,7 +144,7 @@ pub extern "C" fn wasmtime_instance_type(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_instance_export_get(
store: CStoreContextMut<'_>,
- instance: Instance,
+ instance: &Instance,
name: *const u8,
name_len: usize,
item: &mut MaybeUninit<wasmtime_extern_t>,
@@ -166,7 +166,7 @@ pub unsafe extern "C" fn wasmtime_instance_export_get(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_instance_export_nth(
store: CStoreContextMut<'_>,
- instance: Instance,
+ instance: &Instance,
index: usize,
name_ptr: &mut *const u8,
name_len: &mut usize,
diff --git a/crates/c-api/src/linker.rs b/crates/c-api/src/linker.rs
index 14c8b2853..9dac41cb1 100644
--- a/crates/c-api/src/linker.rs
+++ b/crates/c-api/src/linker.rs
@@ -71,11 +71,11 @@ pub unsafe extern "C" fn wasmtime_linker_define_instance(
store: CStoreContextMut<'_>,
name: *const u8,
name_len: usize,
- instance: Instance,
+ instance: &Instance,
) -> Option<Box<wasmtime_error_t>> {
let linker = &mut linker.linker;
let name = to_str!(name, name_len);
- handle_result(linker.instance(store, name, instance), |_linker| ())
+ handle_result(linker.instance(store, name, *instance), |_linker| ())
}
#[no_mangle]
diff --git a/crates/c-api/src/memory.rs b/crates/c-api/src/memory.rs
index 72c4c493a..7cc227fea 100644
--- a/crates/c-api/src/memory.rs
+++ b/crates/c-api/src/memory.rs
@@ -97,30 +97,30 @@ pub extern "C" fn wasmtime_memory_new(
#[no_mangle]
pub extern "C" fn wasmtime_memory_type(
store: CStoreContext<'_>,
- mem: Memory,
+ mem: &Memory,
) -> Box<wasm_memorytype_t> {
Box::new(wasm_memorytype_t::new(mem.ty(store)))
}
#[no_mangle]
-pub extern "C" fn wasmtime_memory_data(store: CStoreContext<'_>, mem: Memory) -> *const u8 {
+pub extern "C" fn wasmtime_memory_data(store: CStoreContext<'_>, mem: &Memory) -> *const u8 {
mem.data(store).as_ptr()
}
#[no_mangle]
-pub extern "C" fn wasmtime_memory_data_size(store: CStoreContext<'_>, mem: Memory) -> usize {
+pub extern "C" fn wasmtime_memory_data_size(store: CStoreContext<'_>, mem: &Memory) -> usize {
mem.data(store).len()
}
#[no_mangle]
-pub extern "C" fn wasmtime_memory_size(store: CStoreContext<'_>, mem: Memory) -> u32 {
+pub extern "C" fn wasmtime_memory_size(store: CStoreContext<'_>, mem: &Memory) -> u32 {
mem.size(store)
}
#[no_mangle]
pub extern "C" fn wasmtime_memory_grow(
store: CStoreContextMut<'_>,
- mem: Memory,
+ mem: &Memory,
delta: u32,
prev_size: &mut u32,
) -> Option<Box<wasmtime_error_t>> {
diff --git a/crates/c-api/src/table.rs b/crates/c-api/src/table.rs
index c2211046e..304754fd7 100644
--- a/crates/c-api/src/table.rs
+++ b/crates/c-api/src/table.rs
@@ -131,7 +131,7 @@ pub unsafe extern "C" fn wasmtime_table_new(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_table_type(
store: CStoreContext<'_>,
- table: Table,
+ table: &Table,
) -> Box<wasm_tabletype_t> {
Box::new(wasm_tabletype_t::new(table.ty(store)))
}
@@ -139,7 +139,7 @@ pub unsafe extern "C" fn wasmtime_table_type(
#[no_mangle]
pub extern "C" fn wasmtime_table_get(
store: CStoreContextMut<'_>,
- table: Table,
+ table: &Table,
index: u32,
ret: &mut MaybeUninit<wasmtime_val_t>,
) -> bool {
@@ -155,7 +155,7 @@ pub extern "C" fn wasmtime_table_get(
#[no_mangle]
pub unsafe extern "C" fn wasmtime_table_set(
store: CStoreContextMut<'_>,
- table: Table,
+ table: &Table,
index: u32,
val: &wasmtime_val_t,
) -> Option<Box<wasmtime_error_t>> {
@@ -163,14 +163,14 @@ pub unsafe extern "C" fn wasmtime_table_set(
}
#[no_mangle]
-pub extern "C" fn wasmtime_table_size(store: CStoreContext<'_>, table: Table) -> u32 {
+pub extern "C" fn wasmtime_table_size(store: CStoreContext<'_>, table: &Table) -> u32 {
table.size(store)
}
#[no_mangle]
pub unsafe extern "C" fn wasmtime_table_grow(
store: CStoreContextMut<'_>,
- table: Table,
+ table: &Table,
delta: u32,
val: &wasmtime_val_t,
prev_size: &mut u32,
diff --git a/crates/c-api/src/val.rs b/crates/c-api/src/val.rs
index e597cf4d2..c088390cb 100644
--- a/crates/c-api/src/val.rs
+++ b/crates/c-api/src/val.rs
@@ -161,11 +161,18 @@ pub union wasmtime_val_union {
pub i64: i64,
pub f32: u32,
pub f64: u64,
- pub funcref: u64,
+ pub funcref: wasmtime_func_t,
pub externref: ManuallyDrop<Option<ExternRef>>,
pub v128: [u8; 16],
}
+#[repr(C)]
+#[derive(Clone, Copy)]
+pub struct wasmtime_func_t {
+ pub store_id: u64,
+ pub index: usize,
+}
+
impl wasmtime_val_t {
pub fn from_val(val: Val) -> wasmtime_val_t {
match val {
@@ -195,8 +202,11 @@ impl wasmtime_val_t {
kind: crate::WASMTIME_FUNCREF,
of: wasmtime_val_union {
funcref: match i {
- Some(func) => unsafe { mem::transmute::<Func, u64>(func) },
- None => u64::max_value(),
+ Some(func) => unsafe { mem::transmute::<Func, wasmtime_func_t>(func) },
+ None => wasmtime_func_t {
+ store_id: 0,
+ index: 0,
+ },
},
},
},
@@ -216,11 +226,15 @@ impl wasmtime_val_t {
crate::WASMTIME_F32 => Val::F32(self.of.f32),
crate::WASMTIME_F64 => Val::F64(self.of.f64),
crate::WASMTIME_V128 => Val::V128(u128::from_le_bytes(self.of.v128)),
- crate::WASMTIME_FUNCREF => Val::FuncRef(if self.of.funcref == u64::max_value() {
- None
- } else {
- Some(mem::transmute::<u64, Func>(self.of.funcref))
- }),
+ crate::WASMTIME_FUNCREF => {
+ let store = self.of.funcref.store_id;
+ let index = self.of.funcref.index;
+ Val::FuncRef(if store == 0 && index == 0 {
+ None
+ } else {
+ Some(mem::transmute::<wasmtime_func_t, Func>(self.of.funcref))
+ })
+ }
crate::WASMTIME_EXTERNREF => Val::ExternRef((*self.of.externref).clone()),
other => panic!("unknown wasmtime_valkind_t: {}", other),
}
diff --git a/crates/wasmtime/src/store/data.rs b/crates/wasmtime/src/store/data.rs
index d920c0e98..01f2a8e62 100644
--- a/crates/wasmtime/src/store/data.rs
+++ b/crates/wasmtime/src/store/data.rs
@@ -3,6 +3,7 @@ use crate::{StoreContext, StoreContextMut};
use std::convert::TryFrom;
use std::fmt;
use std::marker;
+use std::num::NonZeroU64;
use std::ops::Index;
use std::sync::atomic::{AtomicU64, Ordering::SeqCst};
@@ -14,7 +15,7 @@ use std::sync::atomic::{AtomicU64, Ordering::SeqCst};
pub struct InstanceId(pub(super) usize);
pub struct StoreData {
- id: u64,
+ id: NonZeroU64,
funcs: Vec<crate::func::FuncData>,
tables: Vec<wasmtime_runtime::ExportTable>,
globals: Vec<wasmtime_runtime::ExportGlobal>,
@@ -63,30 +64,16 @@ impl StoreData {
pub fn new() -> StoreData {
static NEXT_ID: AtomicU64 = AtomicU64::new(0);
- // Currently we neither recycle ids nor do we allow overlap of ids (e.g.
- // the ABA problem). We also only allocate a certain number of bits
- // (controlled by INDEX_BITS below) for the id. Make sure that the id
- // fits in the allocated bits (currently 40 bits).
- //
- // Note that this is the maximal number of `Store` instances that a
- // process can make before it needs to be restarted. That means this
- // needs to be pretty reasonable. At the assumption of creating 10k
- // stores per second 40 bits allows that program to run for ~3.5 years.
- // Hopefully programs don't run that long.
- //
- // If a program does indeed run that long then we rest the counter back
- // to a known bad value (and it's basically impossible the counter will
- // wrap back to zero inbetween this time) and then panic the current
- // thread.
+ // Only allow 2^63 stores at which point we start panicking to prevent
+ // overflow. This should still last us to effectively the end of time.
let id = NEXT_ID.fetch_add(1, SeqCst);
- let upper_bits_used = (id >> (64 - INDEX_BITS)) != 0;
- if upper_bits_used {
- NEXT_ID.store(1 << (64 - INDEX_BITS), SeqCst);
+ if id & (1 << 63) != 0 {
+ NEXT_ID.store(1 << 63, SeqCst);
panic!("store id allocator overflow");
}
StoreData {
- id,
+ id: NonZeroU64::new(id + 1).unwrap(),
funcs: Vec::new(),
tables: Vec::new(),
globals: Vec::new(),
@@ -169,77 +156,27 @@ where
}
}
-// NB the repre(transparent) here is for the usage of this throughout the C API.
-// If the representation here changes then the C API will need changing as well.
-#[repr(transparent)]
pub struct Stored<T> {
- // See documentation below on `INDEX_BITS` for how this is interpreted.
- bits: u64,
+ store_id: NonZeroU64,
+ index: usize,
_marker: marker::PhantomData<fn() -> T>,
}
-// This is the maximal number of bits that the index of an item within a store
-// can take up. As this is set to 24 that allows for 16 million items. Note
-// that this is not a limit on something like the number of functions within an
-// instance, only a limit on the number of externally referenced items in a
-// Store. For example this is more equivalent to exported functions of a module
-// rather than functions themselves.
-//
-// The reason for this limitation is that we want `Stored<T>` to fit into a
-// 64-bit value (for the C API). This 64-bit value gives us limited, well, uh,
-// bits, to work with. We need to pack both a "store id" as well as an index
-// within the store into those 64 bits. Given that there's no implementation of
-// recycling store IDs at this time it also means that the number of bits
-// allocated to the store id represents the maximal number of stores that a
-// process can create for its entire lifetime.
-//
-// These factors led to the choice of bits here for this. This can be moved
-// around a bit, but the hope is that this is good enough for all practical
-// users.
-//
-// The choice of 24 means that the limitations of wasmtime are:
-//
-// * 24 bits for the index, meaning 16 million items maximum. As noted above
-// this is 16 million *host references* to wasm items, so this is akin to
-// creating 16 million instances within one store or creating an instance
-// that has 16 million exported function. If 24 bits isn't enough then we
-// may need to look into compile-time options to change this perhaps.
-//
-// * 40 bits for the store id. This is a whole lot more bits than the index,
-// but intentionally so. As the maximal number of stores for the entire
-// process that's far more limiting than the number of items within a store
-// (which are typically drastically lower than 16 million and/or limited via
-// other means, e.g. wasm module validation, instance limits, etc).
-//
-// So all-in-all we try to maximize the number of store bits without placing
-// too many restrictions on the number of items within a store. Using 40
-// bits practically means that if you create 10k stores a second your program
-// can run for ~3.5 years. Hopefully that's enough?
-//
-// If we didn't need to be clever in the C API and returned structs-by-value
-// instead of returning 64-bit integers then we could just change this to a
-// u64/usize pair which would solve all of these problems. Hopefully, though,
-// no one will ever run into these limits...
-const INDEX_BITS: usize = 24;
-
impl<T> Stored<T> {
- fn new(store_id: u64, index: usize) -> Stored<T> {
- let masked_index = ((1 << INDEX_BITS) - 1) & index;
- if masked_index != index {
- panic!("too many items have been allocated into the store");
- }
+ fn new(store_id: NonZeroU64, index: usize) -> Stored<T> {
Stored {
- bits: (store_id << INDEX_BITS) | u64::try_from(masked_index).unwrap(),
+ store_id,
+ index,
_marker: marker::PhantomData,
}
}
- fn store_id(&self) -> u64 {
- self.bits >> INDEX_BITS
+ fn store_id(&self) -> NonZeroU64 {
+ self.store_id
}
fn index(&self) -> usize {
- usize::try_from(self.bits & ((1 << INDEX_BITS) - 1)).unwrap()
+ self.index
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment