Complete refactor of the FFI to use handles instead of pointers.
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
2023-06-24 14:44:23 +02:00
parent 4c222cb753
commit 78bb91093b
76 changed files with 1510 additions and 1952 deletions

View File

@@ -146,10 +146,10 @@ fn effect_parameter_get_type(
) -> WasmResult<u8> {
let value = get_value_arc!(parameter, env);
wasm_ok(match value.deref() {
EffectParameter::Bool(_, _) => 1,
EffectParameter::Int(_, _) => 2,
EffectParameter::Float(_, _) => 3,
EffectParameter::String(_, _) => 4,
EffectParameter::Bool(_) => 1,
EffectParameter::Int(_) => 2,
EffectParameter::Float(_) => 3,
EffectParameter::String(_) => 4,
})
}
@@ -160,7 +160,7 @@ fn effect_parameter_as_bool(
) -> WasmResult<u8> {
let value = get_value_arc!(parameter, env);
match value.deref() {
EffectParameter::Bool(_, b) => wasm_ok(<u8 as From<bool>>::from(*b)),
EffectParameter::Bool(b) => wasm_ok(<u8 as From<bool>>::from(*b)),
_ => wasm_err::<u8>(anyhow!("Unexpected parameter type. Expected bool, got {}", value), &env),
}
}
@@ -172,7 +172,7 @@ fn effect_parameter_as_int(
) -> WasmResult<i64> {
let value = get_value_arc!(parameter, env);
match value.deref() {
EffectParameter::Int(_, i) => wasm_ok(*i),
EffectParameter::Int(i) => wasm_ok(*i),
_ => wasm_err::<i64>(anyhow!("Unexpected parameter type. Expected int, got {}", value), &env),
}
}
@@ -184,7 +184,7 @@ fn effect_parameter_as_float(
) -> WasmResult<f32> {
let value = get_value_arc!(parameter, env);
match value.deref() {
EffectParameter::Float(_, f) => wasm_ok(*f),
EffectParameter::Float(f) => wasm_ok(*f),
_ => wasm_err::<f32>(
anyhow!("Unexpected parameter type. Expected float, got {}", value),
&env,
@@ -199,7 +199,7 @@ fn effect_parameter_as_string(
) -> WasmResult<ExternRef<StringKey>> {
let value = get_value_arc!(parameter, env);
match value.deref() {
EffectParameter::String(_, s) => wasm_ok(ExternRef::<StringKey>::func_new(&env, s.clone().into())),
EffectParameter::String(s) => wasm_ok(ExternRef::<StringKey>::func_new(&env, s.clone().into())),
_ => wasm_err::<ExternRef<StringKey>>(
anyhow!("Unexpected parameter type. Expected string, got {}", value),
&env,

View File

@@ -1,4 +1,3 @@
use crate::ValueIdentifiable;
use anyhow_ext::Result;
use std::marker::PhantomData;
use std::mem::transmute;
@@ -41,7 +40,7 @@ impl<T: ?Sized> Default for ExternRef<T> {
}
}
impl<T: ValueIdentifiable + ?Sized> ExternRef<T> {
impl<T: ?Sized> ExternRef<T> {
/// Instantiates a new ExternRef for a bit of data. If we already have made an Extern Ref for
/// this data and type, we use that instead.
pub fn new(env: &WebAssemblyEnvironmentData, value: WasmObject) -> Self {

View File

@@ -1,3 +1,4 @@
use std::any::Any;
use std::fmt::{Debug, Formatter};
use std::mem::{align_of, forget, size_of};
use std::sync::{Arc, Weak};
@@ -19,19 +20,17 @@ use crate::script_implementations::wasm::script_function_cache::ScriptFunctionCa
use crate::script_implementations::wasm::temp_wasm_allocator::{AllocatedObject, TempWasmAllocator};
use crate::script_implementations::wasm::WebAssemblyScriptCapabilities;
use crate::static_data::Item;
use crate::{ScriptCategory, StringKey, ValueIdentifiable, ValueIdentifier, VecExt};
use crate::{ScriptCategory, StringKey, VecExt};
/// A WebAssembly script resolver implements the dynamic scripts functionality with WebAssembly.
pub struct WebAssemblyScriptResolver {
/// A unique identifier so we know what value this is.
identifier: ValueIdentifier,
/// The global state storage of WASM.
_store: *mut Store,
/// The WASM modules we have loaded.
modules: Vec<Module>,
modules: RwLock<Vec<Module>>,
/// Our currently loaded WASM instances. Empty until finalize() is called, after which the loaded modules get turned
/// into actual instances.
instances: Vec<Instance>,
instances: RwLock<Vec<Instance>>,
/// This is the WASM function to load a script.
load_script_fn: Option<TypedFunction<(u8, ExternRef<StringKey>), u32>>,
@@ -51,7 +50,7 @@ struct ScriptCapabilitiesKey {
impl WebAssemblyScriptResolver {
/// Instantiates a new WebAssemblyScriptResolver.
pub fn new() -> Box<WebAssemblyScriptResolver> {
pub fn new() -> Arc<WebAssemblyScriptResolver> {
let compiler = wasmer::LLVM::default();
let mut features = Features::new();
features.multi_value = true;
@@ -65,7 +64,6 @@ impl WebAssemblyScriptResolver {
environment.self_arc.write().replace(Arc::downgrade(&environment));
let s = Self {
identifier: Default::default(),
_store: store_ptr,
modules: Default::default(),
instances: Default::default(),
@@ -73,7 +71,7 @@ impl WebAssemblyScriptResolver {
environment_data: environment,
};
Box::new(s)
Arc::new(s)
}
/// Get an immutable reference to the current WASM Store.
@@ -93,15 +91,15 @@ impl WebAssemblyScriptResolver {
}
/// Load a compiled WASM module.
pub fn load_wasm_from_bytes(&mut self, bytes: &[u8]) -> Result<()> {
pub fn load_wasm_from_bytes(&self, bytes: &[u8]) -> Result<()> {
// FIXME: Error handling
let module = Module::new(&self.store_ref(), bytes)?;
self.modules.push(module);
self.modules.write().push(module);
Ok(())
}
/// Tells the script resolver we're done loading wasm modules, and to finalize the resolver.
pub fn finalize(&mut self) -> Result<()> {
pub fn finalize(&self) -> Result<()> {
let mut imports = Imports::new();
let env = FunctionEnv::new(
@@ -109,7 +107,8 @@ impl WebAssemblyScriptResolver {
WebAssemblyEnv::new(Arc::downgrade(&self.environment_data)),
);
register_webassembly_funcs(&mut imports, &mut self.store_mut(), &env);
for module in &self.modules {
let modules = self.modules.read();
for module in modules.iter() {
for import in module.imports() {
if imports.get_export("env", import.name()).is_none() {
println!(
@@ -143,8 +142,12 @@ impl WebAssemblyScriptResolver {
if let Some(m) = &self.environment_data.memory.read().as_ref() {
m.grow(&mut self.store_mut(), 32)?;
}
if let Some(f) = exported_functions.get::<StringKey>(&"load_script".into()) {
self.load_script_fn = Some(f.typed(&self.store_ref())?)
unsafe {
#[allow(clippy::unwrap_used)] // We know this is valid.
if let Some(f) = exported_functions.get::<StringKey>(&"load_script".into()) {
let self_mut = (self as *const Self as *mut Self).as_mut().unwrap();
self_mut.load_script_fn = Some(f.typed(&self.store_ref())?)
}
}
if let Some(f) = exported_functions.get::<StringKey>(&"allocate_mem".into()) {
let _ = self
@@ -160,7 +163,7 @@ impl WebAssemblyScriptResolver {
.write()
.insert(TempWasmAllocator::new(temp_memory_slab.0, temp_memory_slab.1));
}
self.instances.push(instance);
self.instances.write().push(instance);
}
Ok(())
}
@@ -171,12 +174,6 @@ impl WebAssemblyScriptResolver {
}
}
impl ValueIdentifiable for WebAssemblyScriptResolver {
fn value_identifier(&self) -> ValueIdentifier {
self.identifier
}
}
impl ScriptResolver for WebAssemblyScriptResolver {
fn load_script(
&self,
@@ -199,6 +196,10 @@ impl ScriptResolver for WebAssemblyScriptResolver {
fn load_item_script(&self, _key: &dyn Item) -> Result<Option<Arc<dyn ItemScript>>> {
todo!()
}
fn as_any(&self) -> &dyn Any {
self
}
}
impl Debug for WebAssemblyScriptResolver {