Improved wasmer-js api

This commit is contained in:
Syrus Akbary
2021-09-14 14:57:39 +02:00
parent d7e7c0d375
commit e2d1c3679c
8 changed files with 78 additions and 30 deletions

View File

@@ -113,25 +113,32 @@ impl ImportObject {
}
out
}
}
impl Into<js_sys::Object> for ImportObject {
fn into(self) -> js_sys::Object {
let guard = self.map.lock().unwrap();
/// Returns the `ImportObject` as a Javascript `Object`
pub fn as_jsobject(&self) -> js_sys::Object {
let guard = self.map.lock().expect("Can't get the map");
let map = guard.borrow();
let imports = js_sys::Object::new();
for (module, ns) in map.iter() {
let import_namespace = js_sys::Object::new();
for (name, exp) in ns.get_namespace_exports() {
js_sys::Reflect::set(&import_namespace, &name.into(), exp.as_jsvalue()).unwrap();
js_sys::Reflect::set(&import_namespace, &name.into(), exp.as_jsvalue())
.expect("Error while setting into the js namespace object");
}
js_sys::Reflect::set(&imports, &module.into(), &import_namespace.into()).unwrap();
js_sys::Reflect::set(&imports, &module.into(), &import_namespace.into())
.expect("Error while setting into the js imports object");
}
imports
}
}
impl Into<js_sys::Object> for ImportObject {
fn into(self) -> js_sys::Object {
self.as_jsobject()
}
}
impl NamedResolver for ImportObject {
fn resolve_by_name(&self, module: &str, name: &str) -> Option<Export> {
self.get_export(module, name)

View File

@@ -93,10 +93,24 @@ impl Instance {
/// * Link errors that happen when plugging the imports into the instance
/// * Runtime errors that happen when running the module `start` function.
pub fn new(module: &Module, resolver: &dyn Resolver) -> Result<Self, InstantiationError> {
let store = module.store();
let (instance, functions) = module
let (instance, imports) = module
.instantiate(resolver)
.map_err(|e| InstantiationError::Start(e))?;
let self_instance = Self::from_module_and_instance(module, instance);
self_instance.init_envs(&imports)?;
Ok(self_instance)
}
/// Creates a Wasmer `Instance` from a Wasmer `Module` and a WebAssembly Instance
///
/// # Important
///
/// Is expected that the function [`Instance::init_envs`] is run manually
/// by the user in case the instance has any Wasmer imports, so the function
/// environments are properly initiated.
pub fn from_module_and_instance(module: &Module, instance: WebAssembly::Instance) -> Self {
let store = module.store();
let instance_exports = instance.exports();
let exports = module
.exports()
@@ -110,16 +124,22 @@ impl Instance {
})
.collect::<Exports>();
let self_instance = Self {
module: module.clone(),
Self {
instance,
module: module.clone(),
exports,
};
for func in functions {
func.init_envs(&self_instance)
.map_err(|e| InstantiationError::HostEnvInitialization(e))?;
}
Ok(self_instance)
}
/// Initialize the given extern imports with the Instance
pub fn init_envs(&self, imports: &[Export]) -> Result<(), InstantiationError> {
for import in imports {
if let Export::Function(func) = import {
func.init_envs(&self)
.map_err(|e| InstantiationError::HostEnvInitialization(e))?;
}
}
Ok(())
}
/// Gets the [`Module`] associated with this instance.

View File

@@ -1,4 +1,4 @@
use crate::js::export::{Export, VMFunction};
use crate::js::export::Export;
use crate::js::resolver::Resolver;
use crate::js::store::Store;
use crate::js::types::{ExportType, ImportType};
@@ -214,9 +214,9 @@ impl Module {
pub(crate) fn instantiate(
&self,
resolver: &dyn Resolver,
) -> Result<(WebAssembly::Instance, Vec<VMFunction>), RuntimeError> {
) -> Result<(WebAssembly::Instance, Vec<Export>), RuntimeError> {
let imports = js_sys::Object::new();
let mut functions: Vec<VMFunction> = vec![];
let mut import_externs: Vec<Export> = vec![];
for (i, import_type) in self.imports().enumerate() {
let resolved_import =
resolver.resolve(i as u32, import_type.module(), import_type.name());
@@ -239,9 +239,7 @@ impl Module {
&import_namespace.into(),
)?;
}
if let Export::Function(func) = import {
functions.push(func);
}
import_externs.push(import);
}
// in case the import is not found, the JS Wasm VM will handle
// the error for us, so we don't need to handle it
@@ -249,7 +247,7 @@ impl Module {
Ok((
WebAssembly::Instance::new(&self.module, &imports)
.map_err(|e: JsValue| -> RuntimeError { e.into() })?,
functions,
import_externs,
))
}