mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-06 20:58:28 +00:00
Add Tables to C API; clean up
This commit is contained in:
5
lib/api/src/externals/table.rs
vendored
5
lib/api/src/externals/table.rs
vendored
@@ -120,6 +120,11 @@ impl Table {
|
|||||||
exported: wasmer_export,
|
exported: wasmer_export,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether or not these two tables refer to the same data.
|
||||||
|
pub fn same(&self, other: &Self) -> bool {
|
||||||
|
self.exported.same(&other.exported)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Exportable<'a> for Table {
|
impl<'a> Exportable<'a> for Table {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ mod import_object;
|
|||||||
mod instance;
|
mod instance;
|
||||||
mod memory_view;
|
mod memory_view;
|
||||||
mod module;
|
mod module;
|
||||||
|
mod ordered_resolver;
|
||||||
mod ptr;
|
mod ptr;
|
||||||
mod store;
|
mod store;
|
||||||
mod tunables;
|
mod tunables;
|
||||||
@@ -18,6 +19,7 @@ pub use crate::import_object::{ImportObject, ImportObjectIterator, LikeNamespace
|
|||||||
pub use crate::instance::Instance;
|
pub use crate::instance::Instance;
|
||||||
pub use crate::memory_view::{Atomically, MemoryView};
|
pub use crate::memory_view::{Atomically, MemoryView};
|
||||||
pub use crate::module::Module;
|
pub use crate::module::Module;
|
||||||
|
pub use crate::ordered_resolver::OrderedResolver;
|
||||||
pub use crate::ptr::{Array, Item, WasmPtr};
|
pub use crate::ptr::{Array, Item, WasmPtr};
|
||||||
pub use crate::store::{Store, StoreObject};
|
pub use crate::store::{Store, StoreObject};
|
||||||
pub use crate::tunables::Tunables;
|
pub use crate::tunables::Tunables;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
//! entrypoints for the standard C API
|
//! entrypoints for the standard C API
|
||||||
|
|
||||||
use std::collections::HashMap;
|
|
||||||
use std::convert::{TryFrom, TryInto};
|
use std::convert::{TryFrom, TryInto};
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
@@ -9,11 +8,30 @@ use std::slice;
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use wasmer::{
|
use wasmer::{
|
||||||
CompilerConfig, Engine, Exports, Extern, ExternType, Function, FunctionType, Global,
|
CompilerConfig, Engine, Extern, Function, FunctionType, Global, GlobalType, Instance,
|
||||||
GlobalType, ImportObject, Instance, JITEngine, Memory, MemoryType, Module, Mutability, Pages,
|
JITEngine, Memory, MemoryType, Module, Mutability, OrderedResolver, Pages, RuntimeError, Store,
|
||||||
RuntimeError, Store, Tunables, Val, ValType,
|
Table, TableType, Tunables, Val, ValType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::error::update_last_error;
|
||||||
|
|
||||||
|
macro_rules! c_try {
|
||||||
|
($expr:expr) => {{
|
||||||
|
let res: Result<_, _> = $expr;
|
||||||
|
match res {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => {
|
||||||
|
update_last_error(err);
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}};
|
||||||
|
($expr:expr, $e:expr) => {{
|
||||||
|
let opt: Option<_> = $expr;
|
||||||
|
c_try!(opt.ok_or_else(|| $e))
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
/// this can be a wasmer-specific type with wasmer-specific functions for manipulating it
|
/// this can be a wasmer-specific type with wasmer-specific functions for manipulating it
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasm_config_t {}
|
pub struct wasm_config_t {}
|
||||||
@@ -78,58 +96,14 @@ pub unsafe extern "C" fn wasm_instance_new(
|
|||||||
let module_imports = wasm_module.imports();
|
let module_imports = wasm_module.imports();
|
||||||
let module_import_count = module_imports.len();
|
let module_import_count = module_imports.len();
|
||||||
let imports = argument_import_iter(imports);
|
let imports = argument_import_iter(imports);
|
||||||
let mut imports_processed = 0;
|
let resolver: OrderedResolver = imports
|
||||||
let mut org_map: HashMap<String, Exports> = HashMap::new();
|
.map(|imp| &imp.inner)
|
||||||
for (import_type, import) in module_imports.into_iter().zip(imports) {
|
.take(module_import_count)
|
||||||
imports_processed += 1;
|
.cloned()
|
||||||
let entry = org_map
|
.collect();
|
||||||
.entry(import_type.module().to_string())
|
|
||||||
.or_insert_with(Exports::new);
|
|
||||||
|
|
||||||
match (import_type.ty(), &import.inner) {
|
|
||||||
(ExternType::Function(expected_signature), Extern::Function(f)) => {
|
|
||||||
if expected_signature != f.ty() {
|
|
||||||
// TODO: report error
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(ExternType::Global(global_ty), Extern::Global(extern_global)) => {
|
|
||||||
if global_ty != extern_global.ty() {
|
|
||||||
// TODO: report error
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(ExternType::Memory(memory_ty), Extern::Memory(extern_memory)) => {
|
|
||||||
if memory_ty != extern_memory.ty() {
|
|
||||||
// TODO: report error
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
(ExternType::Table(table_ty), Extern::Table(extern_table)) => {
|
|
||||||
if table_ty != extern_table.ty() {
|
|
||||||
// TODO: report error
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
// type mismatch: report error here
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
entry.insert(import_type.name(), import.inner.clone())
|
|
||||||
}
|
|
||||||
if module_import_count != imports_processed {
|
|
||||||
// handle this error
|
|
||||||
return None;
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut import_object = ImportObject::new();
|
|
||||||
for (ns, exports) in org_map {
|
|
||||||
import_object.register(ns, exports);
|
|
||||||
}
|
|
||||||
|
|
||||||
let instance = Arc::new(
|
let instance = Arc::new(
|
||||||
Instance::new(wasm_module, &import_object)
|
Instance::new(wasm_module, &resolver)
|
||||||
.expect("failed to instantiate: TODO handle this error"),
|
.expect("failed to instantiate: TODO handle this error"),
|
||||||
);
|
);
|
||||||
Some(Box::new(wasm_instance_t { inner: instance }))
|
Some(Box::new(wasm_instance_t { inner: instance }))
|
||||||
@@ -356,6 +330,20 @@ pub unsafe extern "C" fn wasm_memory_as_extern(
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_table_as_extern(
|
||||||
|
table_ptr: Option<NonNull<wasm_table_t>>,
|
||||||
|
) -> Option<Box<wasm_extern_t>> {
|
||||||
|
let table_ptr = table_ptr?;
|
||||||
|
let table = table_ptr.as_ref();
|
||||||
|
|
||||||
|
Some(Box::new(wasm_extern_t {
|
||||||
|
// update this if global does hold onto an `instance`
|
||||||
|
instance: None,
|
||||||
|
inner: Extern::Table(table.inner.clone()),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_extern_as_func(
|
pub unsafe extern "C" fn wasm_extern_as_func(
|
||||||
extern_ptr: Option<NonNull<wasm_extern_t>>,
|
extern_ptr: Option<NonNull<wasm_extern_t>>,
|
||||||
@@ -398,6 +386,19 @@ pub unsafe extern "C" fn wasm_extern_as_memory(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_extern_as_table(
|
||||||
|
extern_ptr: Option<NonNull<wasm_extern_t>>,
|
||||||
|
) -> Option<Box<wasm_table_t>> {
|
||||||
|
let extern_ptr = extern_ptr?;
|
||||||
|
let r#extern = extern_ptr.as_ref();
|
||||||
|
if let Extern::Table(t) = &r#extern.inner {
|
||||||
|
Some(Box::new(wasm_table_t { inner: t.clone() }))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub type wasm_mutability_t = u8;
|
pub type wasm_mutability_t = u8;
|
||||||
|
|
||||||
@@ -785,16 +786,13 @@ pub struct wasm_memory_t {
|
|||||||
pub unsafe extern "C" fn wasm_memory_new(
|
pub unsafe extern "C" fn wasm_memory_new(
|
||||||
store_ptr: Option<NonNull<wasm_store_t>>,
|
store_ptr: Option<NonNull<wasm_store_t>>,
|
||||||
mt_ptr: *const wasm_memorytype_t,
|
mt_ptr: *const wasm_memorytype_t,
|
||||||
) -> Option<NonNull<wasm_memory_t>> {
|
) -> Option<Box<wasm_memory_t>> {
|
||||||
let md = (&*(mt_ptr as *const MemoryType)).clone();
|
let md = (&*(mt_ptr as *const MemoryType)).clone();
|
||||||
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
|
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
|
||||||
let store = store_ptr.as_ref();
|
let store = store_ptr.as_ref();
|
||||||
|
|
||||||
// TODO: report this error
|
let memory = c_try!(Memory::new(store, md));
|
||||||
let memory = Memory::new(store, md).ok()?;
|
Some(Box::new(wasm_memory_t { inner: memory }))
|
||||||
Some(NonNull::new_unchecked(Box::into_raw(Box::new(
|
|
||||||
wasm_memory_t { inner: memory },
|
|
||||||
))))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
@@ -847,6 +845,52 @@ pub unsafe extern "C" fn wasm_memory_same(
|
|||||||
wasm_memory1.inner.same(&wasm_memory2.inner)
|
wasm_memory1.inner.same(&wasm_memory2.inner)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_table_t {
|
||||||
|
// maybe needs to hold onto instance
|
||||||
|
inner: Table,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_table_new(
|
||||||
|
store_ptr: Option<NonNull<wasm_store_t>>,
|
||||||
|
mt_ptr: *const wasm_tabletype_t,
|
||||||
|
init: *const wasm_ref_t,
|
||||||
|
) -> Option<Box<wasm_table_t>> {
|
||||||
|
let tt = (&*(mt_ptr as *const TableType)).clone();
|
||||||
|
let store_ptr: NonNull<Store> = store_ptr?.cast::<Store>();
|
||||||
|
let store = store_ptr.as_ref();
|
||||||
|
|
||||||
|
let init_val = todo!("get val from init somehow");
|
||||||
|
|
||||||
|
let table = c_try!(Table::new(store, tt, init_val));
|
||||||
|
Some(Box::new(wasm_table_t { inner: table }))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_table_delete(_table: Option<Box<wasm_table_t>>) {}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_table_copy(wasm_table: &wasm_table_t) -> Box<wasm_table_t> {
|
||||||
|
// do shallow copy
|
||||||
|
Box::new(wasm_table_t {
|
||||||
|
inner: wasm_table.inner.clone(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_table_same(
|
||||||
|
wasm_table1: &wasm_table_t,
|
||||||
|
wasm_table2: &wasm_table_t,
|
||||||
|
) -> bool {
|
||||||
|
wasm_table1.inner.same(&wasm_table2.inner)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_table_size(wasm_table: &wasm_table_t) -> usize {
|
||||||
|
wasm_table.inner.size() as _
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! wasm_declare_own {
|
macro_rules! wasm_declare_own {
|
||||||
($name:ident) => {
|
($name:ident) => {
|
||||||
paste::item! {
|
paste::item! {
|
||||||
@@ -1095,6 +1139,41 @@ unsafe fn wasm_globaltype_new_inner(
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// opaque type wrapping `GlobalType`
|
||||||
|
#[repr(C)]
|
||||||
|
pub struct wasm_tabletype_t {}
|
||||||
|
|
||||||
|
wasm_declare_vec!(tabletype);
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_new(
|
||||||
|
// own
|
||||||
|
valtype: Box<wasm_valtype_t>,
|
||||||
|
limits: &wasm_limits_t,
|
||||||
|
) -> NonNull<wasm_tabletype_t> {
|
||||||
|
// TODO: investigate if `0` is in fact a sentinel value here
|
||||||
|
let max_elements = if limits.max == 0 {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(limits.max as _)
|
||||||
|
};
|
||||||
|
let out = NonNull::new_unchecked(Box::into_raw(Box::new(TableType::new(
|
||||||
|
(*valtype).into(),
|
||||||
|
limits.min as _,
|
||||||
|
max_elements,
|
||||||
|
))) as *mut wasm_tabletype_t);
|
||||||
|
wasm_valtype_delete(Some(valtype));
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
|
|
||||||
|
#[no_mangle]
|
||||||
|
pub unsafe extern "C" fn wasm_tabletype_delete(tabletype: Option<NonNull<wasm_tabletype_t>>) {
|
||||||
|
if let Some(g_inner) = tabletype {
|
||||||
|
let _ = Box::from_raw(g_inner.cast::<TableType>().as_ptr());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// opaque type wrapping `MemoryType`
|
// opaque type wrapping `MemoryType`
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct wasm_memorytype_t {}
|
pub struct wasm_memorytype_t {}
|
||||||
@@ -1109,10 +1188,7 @@ pub struct wasm_limits_t {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn wasm_memorytype_new(
|
pub unsafe extern "C" fn wasm_memorytype_new(limits: &wasm_limits_t) -> NonNull<wasm_memorytype_t> {
|
||||||
limits: *const wasm_limits_t,
|
|
||||||
) -> NonNull<wasm_memorytype_t> {
|
|
||||||
let limits = *limits;
|
|
||||||
let min_pages = Pages(limits.min as _);
|
let min_pages = Pages(limits.min as _);
|
||||||
// TODO: investigate if `0` is in fact a sentinel value here
|
// TODO: investigate if `0` is in fact a sentinel value here
|
||||||
let max_pages = if limits.max == 0 {
|
let max_pages = if limits.max == 0 {
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ add_executable(test-module-import-instantiate test-module-import-instantiate.c)
|
|||||||
add_executable(wasm-c-api-hello wasm-c-api/example/hello.c)
|
add_executable(wasm-c-api-hello wasm-c-api/example/hello.c)
|
||||||
add_executable(wasm-c-api-memory wasm-c-api/example/memory.c)
|
add_executable(wasm-c-api-memory wasm-c-api/example/memory.c)
|
||||||
add_executable(wasm-c-api-global wasm-c-api/example/global.c)
|
add_executable(wasm-c-api-global wasm-c-api/example/global.c)
|
||||||
|
#add_executable(wasm-c-api-table wasm-c-api/example/table.c)
|
||||||
add_executable(wasm-c-api-serialize wasm-c-api/example/serialize.c)
|
add_executable(wasm-c-api-serialize wasm-c-api/example/serialize.c)
|
||||||
|
|
||||||
if (DEFINED WASI_TESTS)
|
if (DEFINED WASI_TESTS)
|
||||||
@@ -162,6 +163,13 @@ add_test(NAME wasm-c-api-global
|
|||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example
|
||||||
)
|
)
|
||||||
|
|
||||||
|
#target_link_libraries(wasm-c-api-table general ${WASMER_LIB})
|
||||||
|
#target_compile_options(wasm-c-api-table PRIVATE ${COMPILER_OPTIONS})
|
||||||
|
#add_test(NAME wasm-c-api-table
|
||||||
|
# COMMAND wasm-c-api-table
|
||||||
|
# WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/wasm-c-api/example
|
||||||
|
#)
|
||||||
|
|
||||||
target_link_libraries(wasm-c-api-serialize general ${WASMER_LIB})
|
target_link_libraries(wasm-c-api-serialize general ${WASMER_LIB})
|
||||||
target_compile_options(wasm-c-api-serialize PRIVATE ${COMPILER_OPTIONS})
|
target_compile_options(wasm-c-api-serialize PRIVATE ${COMPILER_OPTIONS})
|
||||||
add_test(NAME wasm-c-api-serialize
|
add_test(NAME wasm-c-api-serialize
|
||||||
|
|||||||
@@ -56,6 +56,11 @@ impl ExportTable {
|
|||||||
pub fn plan(&self) -> &TablePlan {
|
pub fn plan(&self) -> &TablePlan {
|
||||||
unsafe { self.from.as_ref().unwrap() }.plan()
|
unsafe { self.from.as_ref().unwrap() }.plan()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns whether or not the two `ExportTable`s refer to the same Memory.
|
||||||
|
pub fn same(&self, other: &Self) -> bool {
|
||||||
|
self.definition == other.definition && self.from == other.from
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ExportTable> for Export {
|
impl From<ExportTable> for Export {
|
||||||
|
|||||||
Reference in New Issue
Block a user