-
-
Save alexcrichton/25df779540182eefb8a833d0f9141160 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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