mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-12 05:18:43 +00:00
Get 2 C API tests using ImportObject::extend working
This commit is contained in:
@@ -8,7 +8,7 @@ use std::{
|
|||||||
ffi::c_void,
|
ffi::c_void,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
};
|
};
|
||||||
use wasmer_engine::{ChainableResolver, NamedResolver};
|
use wasmer_engine::NamedResolver;
|
||||||
use wasmer_runtime::Export;
|
use wasmer_runtime::Export;
|
||||||
|
|
||||||
/// The `LikeNamespace` trait represents objects that act as a namespace for imports.
|
/// The `LikeNamespace` trait represents objects that act as a namespace for imports.
|
||||||
@@ -157,8 +157,6 @@ impl NamedResolver for ImportObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ChainableResolver for ImportObject {}
|
|
||||||
|
|
||||||
/// Iterator for an `ImportObject`'s exports.
|
/// Iterator for an `ImportObject`'s exports.
|
||||||
pub struct ImportObjectIterator {
|
pub struct ImportObjectIterator {
|
||||||
elements: VecDeque<((String, String), Export)>,
|
elements: VecDeque<((String, String), Export)>,
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ pub use wasm_common::{Bytes, Pages, ValueType, WasmExternType, WasmTypeList};
|
|||||||
pub use wasmer_compiler::CompilerConfig;
|
pub use wasmer_compiler::CompilerConfig;
|
||||||
pub use wasmer_compiler::{Features, Target};
|
pub use wasmer_compiler::{Features, Target};
|
||||||
pub use wasmer_engine::{
|
pub use wasmer_engine::{
|
||||||
ChainableResolver, DeserializeError, Engine, InstantiationError, LinkError, NamedResolver,
|
ChainableNamedResolver, DeserializeError, Engine, InstantiationError, LinkError, NamedResolver,
|
||||||
Resolver, ResolverChain, RuntimeError, SerializeError,
|
NamedResolverChain, Resolver, RuntimeError, SerializeError,
|
||||||
};
|
};
|
||||||
pub use wasmer_runtime::{raise_user_trap, MemoryError};
|
pub use wasmer_runtime::{raise_user_trap, MemoryError};
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use wasmer::wasm::{Instance, Module};
|
use wasmer::{Instance, Module, NamedResolver};
|
||||||
use wasmer_emscripten::{EmscriptenData, EmscriptenGlobals};
|
use wasmer_emscripten::{EmscriptenData, EmscriptenGlobals};
|
||||||
|
|
||||||
/// Type used to construct an import_object_t with Emscripten imports.
|
/// Type used to construct an import_object_t with Emscripten imports.
|
||||||
@@ -143,7 +143,13 @@ pub unsafe extern "C" fn wasmer_emscripten_generate_import_object(
|
|||||||
}
|
}
|
||||||
// TODO: figure out if we should be using UnsafeCell here or something
|
// TODO: figure out if we should be using UnsafeCell here or something
|
||||||
let g = &mut *(globals as *mut EmscriptenGlobals);
|
let g = &mut *(globals as *mut EmscriptenGlobals);
|
||||||
let import_object = Box::new(wasmer_emscripten::generate_emscripten_env(g));
|
let import_object_inner: Box<dyn NamedResolver> =
|
||||||
|
Box::new(wasmer_emscripten::generate_emscripten_env(g));
|
||||||
|
let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject {
|
||||||
|
import_object: import_object_inner,
|
||||||
|
imported_memories: vec![],
|
||||||
|
instance_pointers_to_update: vec![],
|
||||||
|
});
|
||||||
|
|
||||||
Box::into_raw(import_object) as *mut wasmer_import_object_t
|
Box::into_raw(import_object) as *mut wasmer_import_object_t
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,23 +10,18 @@ use crate::{
|
|||||||
wasmer_byte_array, wasmer_result_t,
|
wasmer_byte_array, wasmer_result_t,
|
||||||
};
|
};
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
use std::ffi::{c_void, CStr};
|
||||||
|
use std::os::raw::c_char;
|
||||||
use std::ptr::{self, NonNull};
|
use std::ptr::{self, NonNull};
|
||||||
use std::{
|
use std::slice;
|
||||||
//convert::TryFrom,
|
// use std::sync::Arc;
|
||||||
ffi::{c_void, CStr},
|
// use std::convert::TryFrom,
|
||||||
os::raw::c_char,
|
use std::collections::HashMap;
|
||||||
slice,
|
|
||||||
//sync::Arc,
|
|
||||||
};
|
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
Function, FunctionType, Global, ImportObject, ImportObjectIterator, ImportType, Memory, Module,
|
ChainableNamedResolver, Exports, Extern, Function, FunctionType, Global, ImportObject,
|
||||||
RuntimeError, Table, Val, ValType,
|
ImportObjectIterator, ImportType, Memory, Module, NamedResolver, RuntimeError, Table, Val,
|
||||||
|
ValType,
|
||||||
};
|
};
|
||||||
//use wasmer::wasm::{Export, FuncSig, Global, Memory, Module, Table, Type};
|
|
||||||
/*use wasmer_runtime_core::{
|
|
||||||
export::{Context, FuncPointer},
|
|
||||||
module::ImportName,
|
|
||||||
};*/
|
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasmer_import_t {
|
pub struct wasmer_import_t {
|
||||||
@@ -36,9 +31,25 @@ pub struct wasmer_import_t {
|
|||||||
pub value: wasmer_import_export_value,
|
pub value: wasmer_import_export_value,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// An opaque wrapper around `CAPIImportObject`
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasmer_import_object_t;
|
pub struct wasmer_import_object_t;
|
||||||
|
|
||||||
|
/// A wrapper around a Wasmer ImportObject with extra data to maintain the existing API
|
||||||
|
pub(crate) struct CAPIImportObject {
|
||||||
|
/// The real wasmer `ImportObject`-like thing.
|
||||||
|
pub(crate) import_object: Box<dyn NamedResolver>,
|
||||||
|
/// List of pointers of memories that are imported into this import object. This is
|
||||||
|
/// required because the old Wasmer API allowed accessing these from the Instance
|
||||||
|
/// but the new/current API does not. So we store them here to pass them to the Instance
|
||||||
|
/// to allow functions to access this data for backwards compatibilty.
|
||||||
|
pub(crate) imported_memories: Vec<*mut Memory>,
|
||||||
|
/// List of pointers to `LegacyEnv`s used to patch imported functions to be able to
|
||||||
|
/// pass a the "vmctx" as the first argument.
|
||||||
|
/// Needed here because of extending import objects.
|
||||||
|
pub(crate) instance_pointers_to_update: Vec<NonNull<LegacyEnv>>,
|
||||||
|
}
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct wasmer_import_func_t;
|
pub struct wasmer_import_func_t;
|
||||||
@@ -60,7 +71,12 @@ pub struct wasmer_import_object_iter_t;
|
|||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn wasmer_import_object_new() -> NonNull<wasmer_import_object_t> {
|
pub extern "C" fn wasmer_import_object_new() -> NonNull<wasmer_import_object_t> {
|
||||||
let import_object = Box::new(ImportObject::new());
|
let import_object_inner: Box<dyn NamedResolver> = Box::new(ImportObject::new());
|
||||||
|
let import_object = Box::new(CAPIImportObject {
|
||||||
|
import_object: import_object_inner,
|
||||||
|
imported_memories: vec![],
|
||||||
|
instance_pointers_to_update: vec![],
|
||||||
|
});
|
||||||
|
|
||||||
// TODO: use `Box::into_raw_non_null` when it becomes stable
|
// TODO: use `Box::into_raw_non_null` when it becomes stable
|
||||||
unsafe { NonNull::new_unchecked(Box::into_raw(import_object) as *mut wasmer_import_object_t) }
|
unsafe { NonNull::new_unchecked(Box::into_raw(import_object) as *mut wasmer_import_object_t) }
|
||||||
@@ -379,6 +395,7 @@ pub unsafe extern "C" fn wasmer_import_object_imports_destroy(
|
|||||||
);
|
);
|
||||||
match import.tag {
|
match import.tag {
|
||||||
wasmer_import_export_kind::WASM_FUNCTION => {
|
wasmer_import_export_kind::WASM_FUNCTION => {
|
||||||
|
// TODO: Wrapped function
|
||||||
let _: Box<Function> = Box::from_raw(import.value.func as *mut _);
|
let _: Box<Function> = Box::from_raw(import.value.func as *mut _);
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||||
@@ -402,12 +419,9 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
imports: *const wasmer_import_t,
|
imports: *const wasmer_import_t,
|
||||||
imports_len: c_uint,
|
imports_len: c_uint,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
todo!("Disabled until import object APIs change")
|
let import_object: &mut CAPIImportObject = &mut *(import_object as *mut CAPIImportObject);
|
||||||
/*
|
|
||||||
let import_object: &mut ImportObject = &mut *(import_object as *mut ImportObject);
|
|
||||||
|
|
||||||
let mut extensions: Vec<((String, String), Export)> = Vec::new();
|
|
||||||
|
|
||||||
|
let mut import_data: HashMap<String, Exports> = HashMap::new();
|
||||||
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
let imports: &[wasmer_import_t] = slice::from_raw_parts(imports, imports_len as usize);
|
||||||
for import in imports {
|
for import in imports {
|
||||||
let module_name = slice::from_raw_parts(
|
let module_name = slice::from_raw_parts(
|
||||||
@@ -438,12 +452,16 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
let export = match import.tag {
|
let export = match import.tag {
|
||||||
wasmer_import_export_kind::WASM_MEMORY => {
|
wasmer_import_export_kind::WASM_MEMORY => {
|
||||||
let mem = import.value.memory as *mut Memory;
|
let mem = import.value.memory as *mut Memory;
|
||||||
|
import_object.imported_memories.push(mem);
|
||||||
Extern::Memory((&*mem).clone())
|
Extern::Memory((&*mem).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_FUNCTION => {
|
wasmer_import_export_kind::WASM_FUNCTION => {
|
||||||
// TODO: investigate consistent usage of `FunctionWrapper` in this context
|
// TODO: investigate consistent usage of `FunctionWrapper` in this context
|
||||||
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
let func_wrapper = import.value.func as *mut FunctionWrapper;
|
||||||
let func_export = func_wrapper.func.as_ptr();
|
let func_export = (*func_wrapper).func.as_ptr();
|
||||||
|
import_object
|
||||||
|
.instance_pointers_to_update
|
||||||
|
.push((*func_wrapper).legacy_env);
|
||||||
Extern::Function((&*func_export).clone())
|
Extern::Function((&*func_export).clone())
|
||||||
}
|
}
|
||||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||||
@@ -456,14 +474,34 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let extension = ((module_name.to_string(), import_name.to_string()), export);
|
let export_entry = import_data
|
||||||
extensions.push(extension)
|
.entry(module_name.to_string())
|
||||||
|
.or_insert_with(Exports::new);
|
||||||
|
export_entry.insert(import_name.to_string(), export);
|
||||||
}
|
}
|
||||||
|
|
||||||
import_object.extend(extensions);
|
let mut new_import_object = ImportObject::new();
|
||||||
|
for (k, v) in import_data {
|
||||||
|
new_import_object.register(k, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use `Option<Box<T>>` here to perform a swap (move value out and move a new value in)
|
||||||
|
// Thus this code will break if `size_of::<Option<Box<T>>>` != `size_of::<Box<T>>`.
|
||||||
|
debug_assert_eq!(
|
||||||
|
std::mem::size_of::<Option<Box<dyn NamedResolver>>>(),
|
||||||
|
std::mem::size_of::<Box<dyn NamedResolver>>()
|
||||||
|
);
|
||||||
|
|
||||||
|
let import_object_inner: &mut Option<Box<dyn NamedResolver>> =
|
||||||
|
&mut *(&mut import_object.import_object as *mut Box<dyn NamedResolver>
|
||||||
|
as *mut Option<Box<dyn NamedResolver>>);
|
||||||
|
|
||||||
|
let import_object_value = import_object_inner.take().unwrap();
|
||||||
|
let new_resolver: Box<dyn NamedResolver> =
|
||||||
|
Box::new(import_object_value.chain_front(new_import_object));
|
||||||
|
*import_object_inner = Some(new_resolver);
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_OK;
|
return wasmer_result_t::WASMER_OK;
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Gets import descriptors for the given module
|
/// Gets import descriptors for the given module
|
||||||
@@ -834,6 +872,7 @@ pub unsafe extern "C" fn wasmer_import_object_destroy(
|
|||||||
import_object: Option<NonNull<wasmer_import_object_t>>,
|
import_object: Option<NonNull<wasmer_import_object_t>>,
|
||||||
) {
|
) {
|
||||||
if let Some(import_object) = import_object {
|
if let Some(import_object) = import_object {
|
||||||
Box::from_raw(import_object.cast::<ImportObject>().as_ptr());
|
let _resolver_box: Box<Box<dyn NamedResolver>> =
|
||||||
|
Box::from_raw(import_object.cast::<Box<dyn NamedResolver>>().as_ptr());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use super::*;
|
|||||||
use crate::get_slice_checked;
|
use crate::get_slice_checked;
|
||||||
use libc::c_uchar;
|
use libc::c_uchar;
|
||||||
use std::{path::PathBuf, ptr, str};
|
use std::{path::PathBuf, ptr, str};
|
||||||
use wasmer::{Memory, MemoryType};
|
use wasmer::{Memory, MemoryType, NamedResolver};
|
||||||
use wasmer_wasi as wasi;
|
use wasmer_wasi as wasi;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
@@ -190,11 +190,11 @@ fn wasmer_wasi_generate_import_object_inner(
|
|||||||
let memory = Memory::new(store, memory_type);
|
let memory = Memory::new(store, memory_type);
|
||||||
wasi_env.set_memory(&memory);
|
wasi_env.set_memory(&memory);
|
||||||
|
|
||||||
let import_object = Box::new(wasi::generate_import_object_from_env(
|
let import_object: Box<Box<dyn NamedResolver>> = Box::new(Box::new(wasi::generate_import_object_from_env(
|
||||||
store,
|
store,
|
||||||
&mut wasi_env,
|
&mut wasi_env,
|
||||||
version,
|
version,
|
||||||
));
|
)));
|
||||||
Ok(Box::into_raw(import_object) as *mut wasmer_import_object_t)
|
Ok(Box::into_raw(import_object) as *mut wasmer_import_object_t)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
@@ -216,11 +216,14 @@ pub unsafe extern "C" fn wasmer_wasi_generate_default_import_object() -> *mut wa
|
|||||||
let memory = Memory::new(store, memory_type).expect("create memory");
|
let memory = Memory::new(store, memory_type).expect("create memory");
|
||||||
wasi_env.set_memory(&memory);
|
wasi_env.set_memory(&memory);
|
||||||
// TODO(mark): review lifetime of `Memory` here
|
// TODO(mark): review lifetime of `Memory` here
|
||||||
let import_object = Box::new(wasi::generate_import_object_from_env(
|
let import_object_inner: Box<dyn NamedResolver> = Box::new(
|
||||||
store,
|
wasi::generate_import_object_from_env(store, &mut wasi_env, wasi::WasiVersion::Latest),
|
||||||
&mut wasi_env,
|
);
|
||||||
wasi::WasiVersion::Latest,
|
let import_object: Box<CAPIImportObject> = Box::new(CAPIImportObject {
|
||||||
));
|
import_object: import_object_inner,
|
||||||
|
imported_memories: vec![],
|
||||||
|
instance_pointers_to_update: vec![],
|
||||||
|
});
|
||||||
|
|
||||||
Box::into_raw(import_object) as *mut wasmer_import_object_t
|
Box::into_raw(import_object) as *mut wasmer_import_object_t
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,13 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
error::{update_last_error, CApiError},
|
error::{update_last_error, CApiError},
|
||||||
export::wasmer_import_export_kind,
|
export::wasmer_import_export_kind,
|
||||||
import::{wasmer_import_object_t, wasmer_import_t},
|
import::{wasmer_import_object_t, wasmer_import_t, CAPIImportObject},
|
||||||
instance::{wasmer_instance_t, CAPIInstance},
|
instance::{wasmer_instance_t, CAPIInstance},
|
||||||
wasmer_byte_array, wasmer_result_t,
|
wasmer_byte_array, wasmer_result_t,
|
||||||
};
|
};
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::ptr::NonNull;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
use wasmer::{Exports, Extern, Function, Global, ImportObject, Instance, Memory, Module, Table};
|
use wasmer::{Exports, Extern, Function, Global, ImportObject, Instance, Memory, Module, Table};
|
||||||
|
|
||||||
@@ -172,23 +173,27 @@ pub unsafe extern "C" fn wasmer_module_import_instantiate(
|
|||||||
module: *const wasmer_module_t,
|
module: *const wasmer_module_t,
|
||||||
import_object: *const wasmer_import_object_t,
|
import_object: *const wasmer_import_object_t,
|
||||||
) -> wasmer_result_t {
|
) -> wasmer_result_t {
|
||||||
let import_object: &ImportObject = &*(import_object as *const ImportObject);
|
// mutable to mutate through `instance_pointers_to_update` to make host functions work
|
||||||
|
let import_object: &mut CAPIImportObject = &mut *(import_object as *mut CAPIImportObject);
|
||||||
let module: &Module = &*(module as *const Module);
|
let module: &Module = &*(module as *const Module);
|
||||||
|
|
||||||
let new_instance: Instance = match Instance::new(module, import_object) {
|
let new_instance: Instance = match Instance::new(module, &import_object.import_object) {
|
||||||
Ok(instance) => instance,
|
Ok(instance) => instance,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
update_last_error(error);
|
update_last_error(error);
|
||||||
return wasmer_result_t::WASMER_ERROR;
|
return wasmer_result_t::WASMER_ERROR;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let imported_memories = todo!("get imported memories");
|
|
||||||
let c_api_instance = CAPIInstance {
|
let c_api_instance = CAPIInstance {
|
||||||
instance: new_instance,
|
instance: new_instance,
|
||||||
imported_memories,
|
imported_memories: import_object.imported_memories.clone(),
|
||||||
ctx_data: None,
|
ctx_data: None,
|
||||||
};
|
};
|
||||||
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
|
let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance));
|
||||||
|
for to_update in import_object.instance_pointers_to_update.iter_mut() {
|
||||||
|
to_update.as_mut().instance_ptr = Some(NonNull::new_unchecked(c_api_instance_pointer));
|
||||||
|
}
|
||||||
|
*instance = c_api_instance_pointer as *mut wasmer_instance_t;
|
||||||
|
|
||||||
return wasmer_result_t::WASMER_OK;
|
return wasmer_result_t::WASMER_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ add_test(test-imports test-imports)
|
|||||||
|
|
||||||
target_link_libraries(test-import-object general ${WASMER_LIB})
|
target_link_libraries(test-import-object general ${WASMER_LIB})
|
||||||
target_compile_options(test-import-object PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-import-object PRIVATE ${COMPILER_OPTIONS})
|
||||||
#add_test(test-import-object test-import-object)
|
add_test(test-import-object test-import-object)
|
||||||
|
|
||||||
|
|
||||||
if (DEFINED WASI_TESTS)
|
if (DEFINED WASI_TESTS)
|
||||||
@@ -140,8 +140,7 @@ add_test(test-context test-context)
|
|||||||
|
|
||||||
target_link_libraries(test-module-import-instantiate general ${WASMER_LIB})
|
target_link_libraries(test-module-import-instantiate general ${WASMER_LIB})
|
||||||
target_compile_options(test-module-import-instantiate PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(test-module-import-instantiate PRIVATE ${COMPILER_OPTIONS})
|
||||||
# TODO: reenable this test
|
add_test(test-module-import-instantiate test-module-import-instantiate)
|
||||||
#add_test(test-module-import-instantiate test-module-import-instantiate)
|
|
||||||
|
|
||||||
# Commented out until we can find a solution to the exported function problem
|
# Commented out until we can find a solution to the exported function problem
|
||||||
#
|
#
|
||||||
|
|||||||
@@ -119,7 +119,13 @@ int main()
|
|||||||
wasmer_import_t imports[] = {func_import, global_import, memory_import, table_import};
|
wasmer_import_t imports[] = {func_import, global_import, memory_import, table_import};
|
||||||
int imports_len = sizeof(imports) / sizeof(imports[0]);
|
int imports_len = sizeof(imports) / sizeof(imports[0]);
|
||||||
// Add our imports to the import object
|
// Add our imports to the import object
|
||||||
wasmer_import_object_extend(import_object, imports, imports_len);
|
wasmer_result_t extend_result = wasmer_import_object_extend(import_object, imports, imports_len);
|
||||||
|
if (extend_result != WASMER_OK)
|
||||||
|
{
|
||||||
|
print_wasmer_error();
|
||||||
|
}
|
||||||
|
assert(extend_result == WASMER_OK);
|
||||||
|
printf("Set up import object\n");
|
||||||
|
|
||||||
// Read the wasm file bytes
|
// Read the wasm file bytes
|
||||||
FILE *file = fopen("assets/hello_wasm.wasm", "r");
|
FILE *file = fopen("assets/hello_wasm.wasm", "r");
|
||||||
|
|||||||
@@ -35,7 +35,8 @@ pub use crate::error::{
|
|||||||
DeserializeError, ImportError, InstantiationError, LinkError, SerializeError,
|
DeserializeError, ImportError, InstantiationError, LinkError, SerializeError,
|
||||||
};
|
};
|
||||||
pub use crate::resolver::{
|
pub use crate::resolver::{
|
||||||
resolve_imports, ChainableResolver, NamedResolver, NullResolver, Resolver, ResolverChain,
|
resolve_imports, ChainableNamedResolver, NamedResolver, NamedResolverChain, NullResolver,
|
||||||
|
Resolver,
|
||||||
};
|
};
|
||||||
pub use crate::serialize::SerializableFunctionFrameInfo;
|
pub use crate::serialize::SerializableFunctionFrameInfo;
|
||||||
pub use crate::trap::*;
|
pub use crate::trap::*;
|
||||||
|
|||||||
@@ -59,12 +59,24 @@ impl<T: NamedResolver> Resolver for T {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: NamedResolver> NamedResolver for &T {
|
||||||
|
fn resolve_by_name(&self, module: &str, field: &str) -> Option<Export> {
|
||||||
|
(**self).resolve_by_name(module, field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl NamedResolver for Box<dyn NamedResolver> {
|
||||||
|
fn resolve_by_name(&self, module: &str, field: &str) -> Option<Export> {
|
||||||
|
(**self).resolve_by_name(module, field)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `Resolver` implementation that always resolves to `None`.
|
/// `Resolver` implementation that always resolves to `None`.
|
||||||
pub struct NullResolver {}
|
pub struct NullResolver {}
|
||||||
|
|
||||||
impl Resolver for NullResolver {
|
impl Resolver for NullResolver {
|
||||||
fn resolve(&self, _idx: u32, _module: &str, _field: &str) -> Result<Export, u32> {
|
fn resolve(&self, _idx: u32, _module: &str, _field: &str) -> Option<Export> {
|
||||||
Err(0)
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,7 +148,7 @@ pub fn resolve_imports(
|
|||||||
for ((module_name, field, import_idx), import_index) in module.imports.iter() {
|
for ((module_name, field, import_idx), import_index) in module.imports.iter() {
|
||||||
let resolved = resolver.resolve(*import_idx, module_name, field);
|
let resolved = resolver.resolve(*import_idx, module_name, field);
|
||||||
let import_extern = get_extern_from_import(module, import_index);
|
let import_extern = get_extern_from_import(module, import_index);
|
||||||
let resolved = match resolved.ok() {
|
let resolved = match resolved {
|
||||||
None => {
|
None => {
|
||||||
return Err(LinkError::Import(
|
return Err(LinkError::Import(
|
||||||
module_name.to_string(),
|
module_name.to_string(),
|
||||||
@@ -231,7 +243,7 @@ pub fn resolve_imports(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// A [`Resolver`] that links two resolvers together in a chain.
|
/// A [`Resolver`] that links two resolvers together in a chain.
|
||||||
pub struct ResolverChain<A: Resolver, B: Resolver> {
|
pub struct NamedResolverChain<A: NamedResolver, B: NamedResolver> {
|
||||||
a: A,
|
a: A,
|
||||||
b: B,
|
b: B,
|
||||||
}
|
}
|
||||||
@@ -239,17 +251,17 @@ pub struct ResolverChain<A: Resolver, B: Resolver> {
|
|||||||
/// A trait for chaining resolvers together.
|
/// A trait for chaining resolvers together.
|
||||||
///
|
///
|
||||||
/// TODO: add example
|
/// TODO: add example
|
||||||
pub trait ChainableResolver: Resolver + Sized {
|
pub trait ChainableNamedResolver: NamedResolver + Sized {
|
||||||
/// Chain a resolver in front of the current resolver.
|
/// Chain a resolver in front of the current resolver.
|
||||||
///
|
///
|
||||||
/// This will cause the second resolver to override the first.
|
/// This will cause the second resolver to override the first.
|
||||||
///
|
///
|
||||||
/// TODO: add example
|
/// TODO: add example
|
||||||
fn chain_front<U>(self, other: U) -> ResolverChain<U, Self>
|
fn chain_front<U>(self, other: U) -> NamedResolverChain<U, Self>
|
||||||
where
|
where
|
||||||
U: Resolver,
|
U: NamedResolver,
|
||||||
{
|
{
|
||||||
ResolverChain { a: other, b: self }
|
NamedResolverChain { a: other, b: self }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Chain a resolver behind the current resolver.
|
/// Chain a resolver behind the current resolver.
|
||||||
@@ -257,44 +269,33 @@ pub trait ChainableResolver: Resolver + Sized {
|
|||||||
/// This will cause the first resolver to override the second.
|
/// This will cause the first resolver to override the second.
|
||||||
///
|
///
|
||||||
/// TODO: add example
|
/// TODO: add example
|
||||||
fn chain_back<U>(self, other: U) -> ResolverChain<Self, U>
|
fn chain_back<U>(self, other: U) -> NamedResolverChain<Self, U>
|
||||||
where
|
where
|
||||||
U: Resolver,
|
U: NamedResolver,
|
||||||
{
|
{
|
||||||
ResolverChain { a: self, b: other }
|
NamedResolverChain { a: self, b: other }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> ChainableResolver for ResolverChain<A, B>
|
// We give these chain methods to all types implementing NamedResolver
|
||||||
where
|
impl<T: NamedResolver> ChainableNamedResolver for T {}
|
||||||
A: Resolver,
|
|
||||||
B: Resolver,
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<A, B> Resolver for ResolverChain<A, B>
|
impl<A, B> NamedResolver for NamedResolverChain<A, B>
|
||||||
where
|
where
|
||||||
A: Resolver,
|
A: NamedResolver,
|
||||||
B: Resolver,
|
B: NamedResolver,
|
||||||
{
|
{
|
||||||
fn resolve(&self, index: u32, module: &str, field: &str) -> Result<Export, u32> {
|
fn resolve_by_name(&self, module: &str, field: &str) -> Option<Export> {
|
||||||
if index == 0 {
|
|
||||||
self.a
|
self.a
|
||||||
.resolve(0, module, field)
|
.resolve_by_name(module, field)
|
||||||
.or_else(|e1| self.b.resolve(0, module, field).map_err(|e2| e1 + e2))
|
.or_else(|| self.b.resolve_by_name(module, field))
|
||||||
} else {
|
|
||||||
match self.a.resolve(index, module, field) {
|
|
||||||
Ok(_) => self.b.resolve(index - 1, module, field).map_err(|e| e + 1),
|
|
||||||
Err(e1) => self.b.resolve(index, module, field).map_err(|e2| e1 + e2),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> Clone for ResolverChain<A, B>
|
impl<A, B> Clone for NamedResolverChain<A, B>
|
||||||
where
|
where
|
||||||
A: Resolver + Clone,
|
A: NamedResolver + Clone,
|
||||||
B: Resolver + Clone,
|
B: NamedResolver + Clone,
|
||||||
{
|
{
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|||||||
Reference in New Issue
Block a user