mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-10 14:48:27 +00:00
Added jsobjectresolver
This commit is contained in:
@@ -118,6 +118,7 @@ pub enum Export {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Export {
|
impl Export {
|
||||||
|
/// Return the export as a `JSValue`.
|
||||||
pub fn as_jsvalue(&self) -> &JsValue {
|
pub fn as_jsvalue(&self) -> &JsValue {
|
||||||
match self {
|
match self {
|
||||||
Export::Memory(js_wasm_memory) => js_wasm_memory.memory.as_ref(),
|
Export::Memory(js_wasm_memory) => js_wasm_memory.memory.as_ref(),
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ impl Instance {
|
|||||||
.instantiate(resolver)
|
.instantiate(resolver)
|
||||||
.map_err(|e| InstantiationError::Start(e))?;
|
.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)?;
|
self_instance.init_envs(&imports)?;
|
||||||
Ok(self_instance)
|
Ok(self_instance)
|
||||||
}
|
}
|
||||||
@@ -112,7 +112,11 @@ impl Instance {
|
|||||||
/// Is expected that the function [`Instance::init_envs`] is run manually
|
/// 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
|
/// by the user in case the instance has any Wasmer imports, so the function
|
||||||
/// environments are properly initiated.
|
/// 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 store = module.store();
|
||||||
let instance_exports = instance.exports();
|
let instance_exports = instance.exports();
|
||||||
let exports = module
|
let exports = module
|
||||||
@@ -120,21 +124,28 @@ impl Instance {
|
|||||||
.map(|export_type| {
|
.map(|export_type| {
|
||||||
let name = export_type.name();
|
let name = export_type.name();
|
||||||
let extern_type = export_type.ty().clone();
|
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 export: Export = (js_export, extern_type).into();
|
||||||
let extern_ = Extern::from_vm_export(store, export);
|
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,
|
instance,
|
||||||
module: module.clone(),
|
module: module.clone(),
|
||||||
exports,
|
exports,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialize the given extern imports with the Instance
|
/// Initialize the given extern imports with the Instance
|
||||||
|
#[doc(hidden)]
|
||||||
pub fn init_envs(&self, imports: &[Export]) -> Result<(), InstantiationError> {
|
pub fn init_envs(&self, imports: &[Export]) -> Result<(), InstantiationError> {
|
||||||
for import in imports {
|
for import in imports {
|
||||||
if let Export::Function(func) = import {
|
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 externals;
|
||||||
mod import_object;
|
mod import_object;
|
||||||
mod instance;
|
mod instance;
|
||||||
|
mod jsobjectresolver;
|
||||||
mod module;
|
mod module;
|
||||||
#[cfg(feature = "wasm-types-polyfill")]
|
#[cfg(feature = "wasm-types-polyfill")]
|
||||||
mod module_info_polyfill;
|
mod module_info_polyfill;
|
||||||
@@ -50,6 +51,7 @@ pub use wasmer_derive::WasmerEnv;
|
|||||||
|
|
||||||
pub use crate::js::cell::WasmCell;
|
pub use crate::js::cell::WasmCell;
|
||||||
pub use crate::js::env::{HostEnvInitError, LazyInit, WasmerEnv};
|
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::exports::{ExportError, Exportable, Exports, ExportsIterator};
|
||||||
pub use crate::js::externals::{
|
pub use crate::js::externals::{
|
||||||
Extern, FromToNativeWasmType, Function, Global, HostFunction, Memory, MemoryError, Table,
|
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::import_object::{ImportObject, ImportObjectIterator, LikeNamespace};
|
||||||
pub use crate::js::instance::{Instance, InstantiationError};
|
pub use crate::js::instance::{Instance, InstantiationError};
|
||||||
|
pub use crate::js::jsobjectresolver::JSObjectResolver;
|
||||||
pub use crate::js::module::{Module, ModuleTypeHints};
|
pub use crate::js::module::{Module, ModuleTypeHints};
|
||||||
pub use crate::js::native::NativeFunc;
|
pub use crate::js::native::NativeFunc;
|
||||||
pub use crate::js::ptr::{Array, Item, WasmPtr};
|
pub use crate::js::ptr::{Array, Item, WasmPtr};
|
||||||
|
|||||||
Reference in New Issue
Block a user