Complete refactor of the FFI to use handles instead of pointers.
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user