mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 05:38:19 +00:00
Added jsobjectresolver
This commit is contained in:
@@ -118,6 +118,7 @@ pub enum Export {
|
||||
}
|
||||
|
||||
impl Export {
|
||||
/// Return the export as a `JSValue`.
|
||||
pub fn as_jsvalue(&self) -> &JsValue {
|
||||
match self {
|
||||
Export::Memory(js_wasm_memory) => js_wasm_memory.memory.as_ref(),
|
||||
|
||||
@@ -100,7 +100,7 @@ impl Instance {
|
||||
.instantiate(resolver)
|
||||
.map_err(|e| InstantiationError::Start(e))?;
|
||||
|
||||
let self_instance = Self::from_module_and_instance(module, instance);
|
||||
let self_instance = Self::from_module_and_instance(module, instance)?;
|
||||
self_instance.init_envs(&imports)?;
|
||||
Ok(self_instance)
|
||||
}
|
||||
@@ -112,7 +112,11 @@ impl Instance {
|
||||
/// 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 {
|
||||
#[doc(hidden)]
|
||||
pub fn from_module_and_instance(
|
||||
module: &Module,
|
||||
instance: WebAssembly::Instance,
|
||||
) -> Result<Self, InstantiationError> {
|
||||
let store = module.store();
|
||||
let instance_exports = instance.exports();
|
||||
let exports = module
|
||||
@@ -120,21 +124,28 @@ impl Instance {
|
||||
.map(|export_type| {
|
||||
let name = export_type.name();
|
||||
let extern_type = export_type.ty().clone();
|
||||
let js_export = js_sys::Reflect::get(&instance_exports, &name.into()).unwrap();
|
||||
let js_export =
|
||||
js_sys::Reflect::get(&instance_exports, &name.into()).map_err(|_e| {
|
||||
InstantiationError::Link(format!(
|
||||
"Can't get {} from the instance exports",
|
||||
&name
|
||||
))
|
||||
})?;
|
||||
let export: Export = (js_export, extern_type).into();
|
||||
let extern_ = Extern::from_vm_export(store, export);
|
||||
(name.to_string(), extern_)
|
||||
Ok((name.to_string(), extern_))
|
||||
})
|
||||
.collect::<Exports>();
|
||||
.collect::<Result<Exports, InstantiationError>>()?;
|
||||
|
||||
Self {
|
||||
Ok(Self {
|
||||
instance,
|
||||
module: module.clone(),
|
||||
exports,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Initialize the given extern imports with the Instance
|
||||
#[doc(hidden)]
|
||||
pub fn init_envs(&self, imports: &[Export]) -> Result<(), InstantiationError> {
|
||||
for import in imports {
|
||||
if let Export::Function(func) = import {
|
||||
|
||||
83
lib/api/src/js/jsobjectresolver.rs
Normal file
83
lib/api/src/js/jsobjectresolver.rs
Normal file
@@ -0,0 +1,83 @@
|
||||
use crate::js::{Export, ExternType, Module, NamedResolver};
|
||||
use std::collections::HashMap;
|
||||
|
||||
/// All of the import data used when instantiating.
|
||||
///
|
||||
/// It's suggested that you use the [`imports!`] macro
|
||||
/// instead of creating an `ImportObject` by hand.
|
||||
///
|
||||
/// [`imports!`]: macro.imports.html
|
||||
///
|
||||
/// # Usage:
|
||||
/// ```ignore
|
||||
/// use wasmer::{Exports, ImportObject, Function};
|
||||
///
|
||||
/// let mut import_object = ImportObject::new();
|
||||
/// let mut env = Exports::new();
|
||||
///
|
||||
/// env.insert("foo", Function::new_native(foo));
|
||||
/// import_object.register("env", env);
|
||||
///
|
||||
/// fn foo(n: i32) -> i32 {
|
||||
/// n
|
||||
/// }
|
||||
/// ```
|
||||
#[derive(Clone, Default)]
|
||||
pub struct JSObjectResolver {
|
||||
module_imports: HashMap<(String, String), ExternType>,
|
||||
object: js_sys::Object,
|
||||
}
|
||||
|
||||
unsafe impl Send for JSObjectResolver {}
|
||||
unsafe impl Sync for JSObjectResolver {}
|
||||
|
||||
impl JSObjectResolver {
|
||||
/// Create a new `ImportObject`.
|
||||
pub fn new(module: &Module, object: js_sys::Object) -> Self {
|
||||
let module_imports = module
|
||||
.imports()
|
||||
.map(|import| {
|
||||
(
|
||||
(import.module().to_string(), import.name().to_string()),
|
||||
import.ty().clone(),
|
||||
)
|
||||
})
|
||||
.collect::<HashMap<(String, String), ExternType>>();
|
||||
Self {
|
||||
module_imports,
|
||||
object,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets an export given a module and a name
|
||||
///
|
||||
/// # Usage
|
||||
/// ```ignore
|
||||
/// # use wasmer::{ImportObject, Instance, Namespace};
|
||||
/// let mut import_object = ImportObject::new();
|
||||
/// import_object.get_export("module", "name");
|
||||
/// ```
|
||||
pub fn get_export(&self, module: &str, name: &str) -> Option<Export> {
|
||||
let namespace = js_sys::Reflect::get(&self.object, &name.into()).ok()?;
|
||||
let js_export = js_sys::Reflect::get(&namespace, &name.into()).ok()?;
|
||||
match self
|
||||
.module_imports
|
||||
.get(&(module.to_string(), name.to_string()))
|
||||
{
|
||||
Some(extern_type) => Some((js_export, extern_type.clone()).into()),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<js_sys::Object> for JSObjectResolver {
|
||||
fn into(self) -> js_sys::Object {
|
||||
self.object
|
||||
}
|
||||
}
|
||||
|
||||
impl NamedResolver for JSObjectResolver {
|
||||
fn resolve_by_name(&self, module: &str, name: &str) -> Option<Export> {
|
||||
self.get_export(module, name)
|
||||
}
|
||||
}
|
||||
@@ -31,6 +31,7 @@ mod exports;
|
||||
mod externals;
|
||||
mod import_object;
|
||||
mod instance;
|
||||
mod jsobjectresolver;
|
||||
mod module;
|
||||
#[cfg(feature = "wasm-types-polyfill")]
|
||||
mod module_info_polyfill;
|
||||
@@ -50,6 +51,7 @@ pub use wasmer_derive::WasmerEnv;
|
||||
|
||||
pub use crate::js::cell::WasmCell;
|
||||
pub use crate::js::env::{HostEnvInitError, LazyInit, WasmerEnv};
|
||||
pub use crate::js::export::Export;
|
||||
pub use crate::js::exports::{ExportError, Exportable, Exports, ExportsIterator};
|
||||
pub use crate::js::externals::{
|
||||
Extern, FromToNativeWasmType, Function, Global, HostFunction, Memory, MemoryError, Table,
|
||||
@@ -57,6 +59,7 @@ pub use crate::js::externals::{
|
||||
};
|
||||
pub use crate::js::import_object::{ImportObject, ImportObjectIterator, LikeNamespace};
|
||||
pub use crate::js::instance::{Instance, InstantiationError};
|
||||
pub use crate::js::jsobjectresolver::JSObjectResolver;
|
||||
pub use crate::js::module::{Module, ModuleTypeHints};
|
||||
pub use crate::js::native::NativeFunc;
|
||||
pub use crate::js::ptr::{Array, Item, WasmPtr};
|
||||
|
||||
Reference in New Issue
Block a user