Merge branch 'master' into native-engine

# Conflicts:
#	Cargo.lock
This commit is contained in:
Syrus
2020-05-19 13:45:39 -07:00
24 changed files with 3536 additions and 3328 deletions

View File

@@ -45,6 +45,12 @@ jobs:
toolchain: ${{ matrix.rust }} toolchain: ${{ matrix.rust }}
override: true override: true
- run: cargo test --release - run: cargo test --release
- name: Set up dependencies for Mac OS
run: brew install automake
if: matrix.os == 'macos-latest'
- name: Set up dependencies for Windows
run: choco install llvm
if: matrix.os == 'windows-latest'
- name: Build and Test C API - name: Build and Test C API
run: | run: |
make capi make capi

192
Cargo.lock generated
View File

@@ -1,5 +1,11 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
[[package]]
name = "abort_on_panic"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "955f37ac58af2416bac687c8ab66a4ccba282229bd7422a28d2281a5e66a6116"
[[package]] [[package]]
name = "ahash" name = "ahash"
version = "0.3.2" version = "0.3.2"
@@ -97,6 +103,30 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "bindgen"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1c85344eb535a31b62f0af37be84441ba9e7f0f4111eb0530f43d15e513fe57"
dependencies = [
"bitflags",
"cexpr",
"cfg-if",
"clang-sys",
"clap",
"env_logger",
"lazy_static",
"lazycell",
"log",
"peeking_take_while",
"proc-macro2",
"quote",
"regex",
"rustc-hash",
"shlex",
"which",
]
[[package]] [[package]]
name = "bitflags" name = "bitflags"
version = "1.2.1" version = "1.2.1"
@@ -162,12 +192,32 @@ version = "1.0.50"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
[[package]]
name = "cexpr"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
dependencies = [
"nom",
]
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
version = "0.1.10" version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "clang-sys"
version = "0.28.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "81de550971c976f176130da4b2978d3b524eaa0fd9ac31f3ceb5ae1231fb4853"
dependencies = [
"glob",
"libc",
"libloading 0.5.2",
]
[[package]] [[package]]
name = "clap" name = "clap"
version = "2.33.0" version = "2.33.0"
@@ -452,6 +502,19 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "env_logger"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
dependencies = [
"atty",
"humantime",
"log",
"regex",
"termcolor",
]
[[package]] [[package]]
name = "erased-serde" name = "erased-serde"
version = "0.3.11" version = "0.3.11"
@@ -601,6 +664,15 @@ version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35" checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
[[package]]
name = "humantime"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
dependencies = [
"quick-error",
]
[[package]] [[package]]
name = "ident_case" name = "ident_case"
version = "1.0.1" version = "1.0.1"
@@ -684,6 +756,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "lazycell"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
[[package]] [[package]]
name = "leb128" name = "leb128"
version = "0.2.4" version = "0.2.4"
@@ -696,6 +774,39 @@ version = "0.2.70"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
[[package]]
name = "libffi"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c18efe55925cc7f83bf60a61394696a734ae90e668d1f2bbd954354416fec6f2"
dependencies = [
"abort_on_panic",
"libc",
"libffi-sys",
]
[[package]]
name = "libffi-sys"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f00e48ce437c5741a4da3b51738498343b5158c37bfa02bcb969efcc44e4e06"
dependencies = [
"bindgen",
"cc",
"make-cmd",
"pkg-config",
]
[[package]]
name = "libloading"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
dependencies = [
"cc",
"winapi",
]
[[package]] [[package]]
name = "libloading" name = "libloading"
version = "0.6.2" version = "0.6.2"
@@ -745,6 +856,12 @@ dependencies = [
"libc", "libc",
] ]
[[package]]
name = "make-cmd"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3"
[[package]] [[package]]
name = "maybe-uninit" name = "maybe-uninit"
version = "2.0.0" version = "2.0.0"
@@ -796,6 +913,16 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238" checksum = "0debeb9fcf88823ea64d64e4a815ab1643f33127d995978e099942ce38f25238"
[[package]]
name = "nom"
version = "4.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ad2a91a8e869eeb30b9cb3119ae87773a8f4ae617f41b1eb9c154b2905f7bd6"
dependencies = [
"memchr",
"version_check 0.1.5",
]
[[package]] [[package]]
name = "num" name = "num"
version = "0.1.42" version = "0.1.42"
@@ -896,6 +1023,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "peeking_take_while"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
[[package]] [[package]]
name = "pkg-config" name = "pkg-config"
version = "0.3.17" version = "0.3.17"
@@ -924,7 +1057,7 @@ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
"syn", "syn",
"version_check", "version_check 0.9.1",
] ]
[[package]] [[package]]
@@ -937,7 +1070,7 @@ dependencies = [
"quote", "quote",
"syn", "syn",
"syn-mid", "syn-mid",
"version_check", "version_check 0.9.1",
] ]
[[package]] [[package]]
@@ -949,6 +1082,12 @@ dependencies = [
"unicode-xid", "unicode-xid",
] ]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]] [[package]]
name = "quote" name = "quote"
version = "1.0.3" version = "1.0.3"
@@ -1206,6 +1345,12 @@ version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
[[package]]
name = "rustc-hash"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
[[package]] [[package]]
name = "rustc_version" name = "rustc_version"
version = "0.2.3" version = "0.2.3"
@@ -1326,6 +1471,12 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "shlex"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
[[package]] [[package]]
name = "smallvec" name = "smallvec"
version = "1.4.0" version = "1.4.0"
@@ -1431,6 +1582,15 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "termcolor"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
dependencies = [
"winapi-util",
]
[[package]] [[package]]
name = "test-generator" name = "test-generator"
version = "0.1.0" version = "0.1.0"
@@ -1592,6 +1752,12 @@ version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
[[package]]
name = "version_check"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
[[package]] [[package]]
name = "version_check" name = "version_check"
version = "0.9.1" version = "0.9.1"
@@ -1795,7 +1961,7 @@ dependencies = [
"cfg-if", "cfg-if",
"faerie", "faerie",
"leb128", "leb128",
"libloading", "libloading 0.6.2",
"serde", "serde",
"serde_bytes", "serde_bytes",
"tempfile", "tempfile",
@@ -1830,6 +1996,8 @@ dependencies = [
"cbindgen", "cbindgen",
"lazy_static", "lazy_static",
"libc", "libc",
"libffi",
"wasm-common",
"wasmer", "wasmer",
"wasmer-wasi", "wasmer-wasi",
] ]
@@ -1898,6 +2066,15 @@ dependencies = [
"wast", "wast",
] ]
[[package]]
name = "which"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
dependencies = [
"libc",
]
[[package]] [[package]]
name = "winapi" name = "winapi"
version = "0.3.8" version = "0.3.8"
@@ -1914,6 +2091,15 @@ version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-util"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
dependencies = [
"winapi",
]
[[package]] [[package]]
name = "winapi-x86_64-pc-windows-gnu" name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0" version = "0.4.0"

View File

@@ -1,8 +1,8 @@
# Wasmer [![Build Status](https://img.shields.io/azure-devops/build/wasmerio/wasmer/3.svg?style=flat-square)](https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE) # Wasmer [![Build Status](https://img.shields.io/azure-devops/build/wasmerio/wasmer/3.svg?style=flat-square)](https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master) [![Join Wasmer Slack](https://img.shields.io/static/v1?label=Slack&message=join%20chat&color=brighgreen&style=flat-square)](https://slack.wasmer.io) [![MIT License](https://img.shields.io/github/license/wasmerio/wasmer.svg?style=flat-square)](https://github.com/wasmerio/wasmer/blob/master/LICENSE)
[`Wasmer`](https://wasmer.io/) is the most popular [WebAssembly](https://webassembly.org/) [`Wasmer`](https://wasmer.io/) is the most popular [WebAssembly](https://webassembly.org/)
runtime for Rust. It supports JIT (Just in Time) and AOT (Ahead of time) runtime for Rust (...and also [the fastest]()!). It supports JIT (Just in Time) and AOT (Ahead of time)
compilation as well as mulitple compiler implementations. compilation as well as pluggable compilers suited to your needs.
It's designed to be safe and secure, and runnable in any kind of environment. It's designed to be safe and secure, and runnable in any kind of environment.

View File

@@ -543,8 +543,8 @@ impl Function {
VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithoutEnv { VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithoutEnv {
func: Box::new(func), func: Box::new(func),
}); });
let address = std::ptr::null() as *const () as *const VMFunctionBody; let address = std::ptr::null() as *const VMFunctionBody;
let vmctx = Box::leak(Box::new(dynamic_ctx)) as *mut _ as *mut VMContext; let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
let signature = store.engine().register_signature(&ty); let signature = store.engine().register_signature(&ty);
Self { Self {
store: store.clone(), store: store.clone(),
@@ -569,8 +569,8 @@ impl Function {
env, env,
func: Box::new(func), func: Box::new(func),
}); });
let address = std::ptr::null() as *const () as *const VMFunctionBody; let address = std::ptr::null() as *const VMFunctionBody;
let vmctx = Box::leak(Box::new(dynamic_ctx)) as *mut _ as *mut VMContext; let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
let signature = store.engine().register_signature(&ty); let signature = store.engine().register_signature(&ty);
Self { Self {
store: store.clone(), store: store.clone(),

View File

@@ -34,7 +34,7 @@ pub use wasmer_compiler::{Features, Target};
pub use wasmer_engine::{ pub use wasmer_engine::{
DeserializeError, Engine, InstantiationError, LinkError, RuntimeError, SerializeError, DeserializeError, Engine, InstantiationError, LinkError, RuntimeError, SerializeError,
}; };
pub use wasmer_runtime::MemoryError; pub use wasmer_runtime::{raise_user_trap, MemoryError};
// The compilers are mutually exclusive // The compilers are mutually exclusive
#[cfg(any( #[cfg(any(

View File

@@ -326,11 +326,11 @@ impl Module {
&self.store &self.store
} }
// The ABI of the ModuleInfo is very unstable, we refactor it very often. /// The ABI of the ModuleInfo is very unstable, we refactor it very often.
// This funciton is public because in some cases it can be useful to get some /// This funciton is public because in some cases it can be useful to get some
// extra information from the module. /// extra information from the module.
// ///
// However, the usage is highly discouraged. /// However, the usage is highly discouraged.
#[doc(hidden)] #[doc(hidden)]
pub fn info(&self) -> &ModuleInfo { pub fn info(&self) -> &ModuleInfo {
&self.compiled.module() &self.compiled.module()

View File

@@ -17,6 +17,7 @@ crate-type = ["cdylib", "staticlib"]
[dependencies] [dependencies]
lazy_static = "1" lazy_static = "1"
libc = { version = "0.2.70", default-features = false } libc = { version = "0.2.70", default-features = false }
libffi = { version = "0.9" }
# for generating code in the same way thot the wasm-c-api does # for generating code in the same way thot the wasm-c-api does
# Commented out for now until we can find a solution to the exported function problem # Commented out for now until we can find a solution to the exported function problem
# wasmer-wasm-c-api = { version = "0.16.2", path = "crates/wasm-c-api" } # wasmer-wasm-c-api = { version = "0.16.2", path = "crates/wasm-c-api" }
@@ -27,6 +28,11 @@ features = ["compiler", "engine", "jit", "cranelift"]
path = "../api" path = "../api"
version = "0.16.2" version = "0.16.2"
[dependencies.wasm-common]
default-features = false
path = "../wasm-common"
version = "0.16.2"
[dependencies.wasmer-wasi] [dependencies.wasmer-wasi]
default-features = false default-features = false
path = "../wasi" path = "../wasi"

View File

@@ -5,6 +5,7 @@ use crate::{
error::{update_last_error, CApiError}, error::{update_last_error, CApiError},
global::wasmer_global_t, global::wasmer_global_t,
import::wasmer_import_func_t, import::wasmer_import_func_t,
instance::CAPIInstance,
memory::wasmer_memory_t, memory::wasmer_memory_t,
module::wasmer_module_t, module::wasmer_module_t,
table::wasmer_table_t, table::wasmer_table_t,
@@ -14,7 +15,7 @@ use crate::{
use libc::{c_int, c_uint}; use libc::{c_int, c_uint};
use std::ptr::{self, NonNull}; use std::ptr::{self, NonNull};
use std::slice; use std::slice;
use wasmer::{ExportType, ExternType, Function, ImportType, Instance, Memory, Module, Val}; use wasmer::{ExportType, ExternType, Function, ImportType, Memory, Module, Val};
/// Intermediate representation of an `Export` instance that is /// Intermediate representation of an `Export` instance that is
/// exposed to C. /// exposed to C.
@@ -23,7 +24,7 @@ pub(crate) struct NamedExport {
pub(crate) export_type: ExportType, pub(crate) export_type: ExportType,
/// The instance that holds the export. /// The instance that holds the export.
pub(crate) instance: NonNull<Instance>, pub(crate) instance: NonNull<CAPIInstance>,
} }
/// Opaque pointer to `ImportType`. /// Opaque pointer to `ImportType`.
@@ -403,6 +404,7 @@ pub unsafe extern "C" fn wasmer_export_to_memory(
let instance = named_export.instance.as_ref(); let instance = named_export.instance.as_ref();
if let Ok(exported_memory) = instance if let Ok(exported_memory) = instance
.instance
.exports .exports
.get::<Memory>(&named_export.export_type.name()) .get::<Memory>(&named_export.export_type.name())
{ {
@@ -477,7 +479,11 @@ pub unsafe extern "C" fn wasmer_export_func_call(
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize); let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
let instance = named_export.instance.as_ref(); let instance = named_export.instance.as_ref();
let f: &Function = match instance.exports.get(&named_export.export_type.name()) { let f: &Function = match instance
.instance
.exports
.get(&named_export.export_type.name())
{
Ok(f) => f, Ok(f) => f,
Err(err) => { Err(err) => {
update_last_error(err); update_last_error(err);

View File

@@ -1,7 +1,11 @@
//! Functions and types for dealing with Emscripten imports //! Functions and types for dealing with Emscripten imports
use super::*; use super::*;
use crate::{get_slice_checked, instance::wasmer_instance_t, module::wasmer_module_t}; use crate::{
get_slice_checked,
instance::{wasmer_instance_t, CAPIInstance},
module::wasmer_module_t,
};
use std::ptr; use std::ptr;
use wasmer::wasm::{Instance, Module}; use wasmer::wasm::{Instance, Module};
@@ -54,16 +58,16 @@ pub unsafe extern "C" fn wasmer_emscripten_set_up(
if globals.is_null() || instance.is_null() { if globals.is_null() || instance.is_null() {
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
let instance = &mut *(instance as *mut Instance); let instance = &mut *(instance as *mut CAPIInstance);
let globals = &*(globals as *mut EmscriptenGlobals); let globals = &*(globals as *mut EmscriptenGlobals);
let em_data = Box::into_raw(Box::new(EmscriptenData::new( let em_data = Box::into_raw(Box::new(EmscriptenData::new(
instance, instance.instance,
&globals.data, &globals.data,
Default::default(), Default::default(),
))) as *mut c_void; ))) as *mut c_void;
instance.context_mut().data = em_data; instance.context_mut().data = em_data;
match wasmer_emscripten::set_up_emscripten(instance) { match wasmer_emscripten::set_up_emscripten(instance.instance) {
Ok(_) => wasmer_result_t::WASMER_OK, Ok(_) => wasmer_result_t::WASMER_OK,
Err(e) => { Err(e) => {
update_last_error(e); update_last_error(e);
@@ -90,7 +94,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main(
if instance.is_null() || args.is_null() { if instance.is_null() || args.is_null() {
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
let instance = &mut *(instance as *mut Instance); let instance = &mut *(instance as *mut CAPIInstance);
let arg_list = get_slice_checked(args, args_len as usize); let arg_list = get_slice_checked(args, args_len as usize);
let arg_process_result: Result<Vec<&str>, _> = let arg_process_result: Result<Vec<&str>, _> =
@@ -113,7 +117,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main(
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };
match wasmer_emscripten::emscripten_call_main(instance, prog_name, &arg_vec[1..]) { match wasmer_emscripten::emscripten_call_main(instance.instance, prog_name, &arg_vec[1..]) {
Ok(_) => wasmer_result_t::WASMER_OK, Ok(_) => wasmer_result_t::WASMER_OK,
Err(e) => { Err(e) => {
update_last_error(e); update_last_error(e);

View File

@@ -4,22 +4,23 @@
use crate::{ use crate::{
error::{update_last_error, CApiError}, error::{update_last_error, CApiError},
export::{wasmer_import_export_kind, wasmer_import_export_value}, export::{wasmer_import_export_kind, wasmer_import_export_value},
instance::wasmer_instance_context_t, instance::{wasmer_instance_context_t, CAPIInstance},
module::wasmer_module_t, module::wasmer_module_t,
value::wasmer_value_tag, value::wasmer_value_tag,
wasmer_byte_array, wasmer_result_t, wasmer_byte_array, wasmer_result_t,
}; };
use libc::c_uint; use libc::c_uint;
use std::ptr::NonNull; use std::ptr::{self, NonNull};
use std::{ use std::{
//convert::TryFrom, //convert::TryFrom,
ffi::c_void, ffi::{c_void, CStr},
os::raw::c_char, os::raw::c_char,
slice, slice,
//sync::Arc, //sync::Arc,
}; };
use wasmer::{ use wasmer::{
Function, Global, ImportObject, ImportObjectIterator, ImportType, Memory, Module, Table, Function, FunctionType, Global, ImportObject, ImportObjectIterator, ImportType, Memory, Module,
RuntimeError, Table, Val, ValType,
}; };
//use wasmer::wasm::{Export, FuncSig, Global, Memory, Module, Table, Type}; //use wasmer::wasm::{Export, FuncSig, Global, Memory, Module, Table, Type};
/*use wasmer_runtime_core::{ /*use wasmer_runtime_core::{
@@ -440,7 +441,9 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
Extern::Memory((&*mem).clone()) Extern::Memory((&*mem).clone())
} }
wasmer_import_export_kind::WASM_FUNCTION => { wasmer_import_export_kind::WASM_FUNCTION => {
let func_export = import.value.func as *mut Function; // TODO: investigate consistent usage of `FunctionWrapper` in this context
let func_wrapper = import.value.func as *mut FunctionWrapper;
let func_export = func_wrapper.func.as_ptr();
Extern::Function((&*func_export).clone()) Extern::Function((&*func_export).clone())
} }
wasmer_import_export_kind::WASM_GLOBAL => { wasmer_import_export_kind::WASM_GLOBAL => {
@@ -460,7 +463,7 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
import_object.extend(extensions); import_object.extend(extensions);
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
@@ -589,6 +592,29 @@ pub unsafe extern "C" fn wasmer_import_func_params_arity(
*/ */
} }
/// struct used to pass in context to functions (which must be back-patched)
#[derive(Debug, Default)]
pub(crate) struct LegacyEnv {
pub(crate) instance_ptr: Option<NonNull<CAPIInstance>>,
}
impl LegacyEnv {
pub(crate) fn ctx_ptr(&self) -> *mut CAPIInstance {
self.instance_ptr
.map(|p| p.as_ptr())
.unwrap_or(ptr::null_mut())
}
}
/// struct used to hold on to `LegacyEnv` pointer as well as the function.
/// we need to do this to initialize the context ptr inside of `LegacyEnv` when
/// instantiating the module.
#[derive(Debug)]
pub(crate) struct FunctionWrapper {
pub(crate) func: NonNull<Function>,
pub(crate) legacy_env: NonNull<LegacyEnv>,
}
/// Creates new host function, aka imported function. `func` is a /// Creates new host function, aka imported function. `func` is a
/// function pointer, where the first argument is the famous `vm::Ctx` /// function pointer, where the first argument is the famous `vm::Ctx`
/// (in Rust), or `wasmer_instance_context_t` (in C). All arguments /// (in Rust), or `wasmer_instance_context_t` (in C). All arguments
@@ -615,20 +641,61 @@ pub unsafe extern "C" fn wasmer_import_func_new(
returns: *const wasmer_value_tag, returns: *const wasmer_value_tag,
returns_len: c_uint, returns_len: c_uint,
) -> *mut wasmer_import_func_t { ) -> *mut wasmer_import_func_t {
unimplemented!("`wasmer_import_func_new` cannot be implemented yet")
/*
let params: &[wasmer_value_tag] = slice::from_raw_parts(params, params_len as usize); let params: &[wasmer_value_tag] = slice::from_raw_parts(params, params_len as usize);
let params: Vec<Type> = params.iter().cloned().map(|x| x.into()).collect(); let params: Vec<ValType> = params.iter().cloned().map(|x| x.into()).collect();
let returns: &[wasmer_value_tag] = slice::from_raw_parts(returns, returns_len as usize); let returns: &[wasmer_value_tag] = slice::from_raw_parts(returns, returns_len as usize);
let returns: Vec<Type> = returns.iter().cloned().map(|x| x.into()).collect(); let returns: Vec<ValType> = returns.iter().cloned().map(|x| x.into()).collect();
let func_type = FunctionType::new(params, &returns[..]);
let export = Box::new(Extern::Function { let store = crate::get_global_store();
func: FuncPointer::new(func as _),
ctx: Context::Internal, let env_ptr = Box::into_raw(Box::new(LegacyEnv::default()));
signature: Arc::new(FuncSig::new(params, returns)),
let func = Function::new_dynamic_env(store, &func_type, &mut *env_ptr, move |env, args| {
use libffi::high::call::{call, Arg};
use libffi::low::CodePtr;
let ctx_ptr = env.ctx_ptr();
let ctx_ptr_val = ctx_ptr as *const _ as isize as i64;
let ffi_args: Vec<Arg> = {
let mut ffi_args = Vec::with_capacity(args.len() + 1);
ffi_args.push(Arg::new::<i64>(&ctx_ptr_val));
ffi_args.extend(args.iter().map(|ty| match ty {
Val::I32(v) => Arg::new::<i32>(v),
Val::I64(v) => Arg::new::<i64>(v),
Val::F32(v) => Arg::new::<f32>(v),
Val::F64(v) => Arg::new::<f64>(v),
_ => todo!("Unsupported type in C API"),
}));
ffi_args
};
let code_ptr = CodePtr::from_ptr(func as _);
assert!(returns.len() <= 1);
let return_value = if returns.len() == 1 {
vec![match returns[0] {
ValType::I32 => Val::I32(call::<i32>(code_ptr, &ffi_args)),
ValType::I64 => Val::I64(call::<i64>(code_ptr, &ffi_args)),
ValType::F32 => Val::F32(call::<f32>(code_ptr, &ffi_args)),
ValType::F64 => Val::F64(call::<f64>(code_ptr, &ffi_args)),
_ => todo!("Unsupported type in C API"),
}]
} else {
call::<()>(code_ptr, &ffi_args);
vec![]
};
Ok(return_value)
}); });
Box::into_raw(export) as *mut wasmer_import_func_t
*/ let function_wrapper = FunctionWrapper {
func: NonNull::new_unchecked(Box::into_raw(Box::new(func))),
legacy_env: NonNull::new_unchecked(env_ptr),
};
Box::into_raw(Box::new(function_wrapper)) as *mut wasmer_import_func_t
} }
/// Stop the execution of a host function, aka imported function. The /// Stop the execution of a host function, aka imported function. The
@@ -648,19 +715,9 @@ pub unsafe extern "C" fn wasmer_import_func_new(
#[no_mangle] #[no_mangle]
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
pub unsafe extern "C" fn wasmer_trap( pub unsafe extern "C" fn wasmer_trap(
ctx: *const wasmer_instance_context_t, _ctx: *const wasmer_instance_context_t,
error_message: *const c_char, error_message: *const c_char,
) -> wasmer_result_t { ) -> wasmer_result_t {
todo!("wasmer_trap: manually trap without Ctx")
/*
if ctx.is_null() {
update_last_error(CApiError {
msg: "ctx ptr is null in wasmer_trap".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
if error_message.is_null() { if error_message.is_null() {
update_last_error(CApiError { update_last_error(CApiError {
msg: "error_message is null in wasmer_trap".to_string(), msg: "error_message is null in wasmer_trap".to_string(),
@@ -669,12 +726,9 @@ pub unsafe extern "C" fn wasmer_trap(
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
let ctx = &*(ctx as *const Ctx);
let error_message = CStr::from_ptr(error_message).to_str().unwrap(); let error_message = CStr::from_ptr(error_message).to_str().unwrap();
(&*ctx.module) wasmer::raise_user_trap(Box::new(RuntimeError::new(error_message))); // never returns
.runnable_module
.do_early_trap(Box::new(error_message)); // never returns
// cbindgen does not generate a binding for a function that // cbindgen does not generate a binding for a function that
// returns `!`. Since we also need to error in some cases, the // returns `!`. Since we also need to error in some cases, the
@@ -684,7 +738,6 @@ pub unsafe extern "C" fn wasmer_trap(
// cbindgen, and get an acceptable clean code. // cbindgen, and get an acceptable clean code.
#[allow(unreachable_code)] #[allow(unreachable_code)]
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
*/
} }
/// Sets the params buffer to the parameter types of the given wasmer_import_func_t /// Sets the params buffer to the parameter types of the given wasmer_import_func_t
@@ -769,7 +822,9 @@ pub unsafe extern "C" fn wasmer_import_func_returns_arity(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wasmer_import_func_destroy(func: Option<NonNull<wasmer_import_func_t>>) { pub unsafe extern "C" fn wasmer_import_func_destroy(func: Option<NonNull<wasmer_import_func_t>>) {
if let Some(func) = func { if let Some(func) = func {
Box::from_raw(func.cast::<Function>().as_ptr()); let function_wrapper = Box::from_raw(func.cast::<FunctionWrapper>().as_ptr());
let _legacy_env = Box::from_raw(function_wrapper.legacy_env.as_ptr());
let _function = Box::from_raw(function_wrapper.func.as_ptr());
} }
} }

View File

@@ -3,7 +3,7 @@
use crate::{ use crate::{
error::{update_last_error, CApiError}, error::{update_last_error, CApiError},
export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports}, export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports},
import::wasmer_import_t, import::{wasmer_import_t, FunctionWrapper},
memory::wasmer_memory_t, memory::wasmer_memory_t,
value::{wasmer_value, wasmer_value_t, wasmer_value_tag}, value::{wasmer_value, wasmer_value_t, wasmer_value_tag},
wasmer_result_t, wasmer_result_t,
@@ -13,18 +13,34 @@ use std::collections::HashMap;
use std::ffi::CStr; use std::ffi::CStr;
use std::ptr::NonNull; use std::ptr::NonNull;
use std::slice; use std::slice;
use wasm_common::{entity::*, ExportIndex, MemoryIndex};
use wasmer::{ use wasmer::{
Exports, Extern, Function, Global, ImportObject, Instance, Memory, Module, Table, Val, Exports, Extern, Function, Global, ImportObject, Instance, Memory, Module, Table, Val,
}; };
/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust. /// Opaque pointer to an Instance type plus metadata.
/// ///
/// A `wasmer_runtime::Instance` represents a WebAssembly instance. It /// This type represents a WebAssembly instance. It
/// is generally generated by the `wasmer_instantiate()` function, or by /// is generally generated by the `wasmer_instantiate()` function, or by
/// the `wasmer_module_instantiate()` function for the most common paths. /// the `wasmer_module_instantiate()` function for the most common paths.
#[repr(C)] #[repr(C)]
pub struct wasmer_instance_t; pub struct wasmer_instance_t;
/// A wrapper around a Wasmer instance with extra data to maintain the existing API
pub(crate) struct CAPIInstance {
/// The real wasmer `Instance`
pub(crate) instance: Instance,
/// List of pointers of memories that are imported into this Instance. 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 allow functions to
/// access this data for backwards compatibilty.
pub(crate) imported_memories: Vec<*mut Memory>,
/// The Instance/Ctx wide data. Previously the Ctx Instance were separate, but
/// given the internal API changes this is no longer true: this is a single global
/// void pointer like the old Wasmer API used to have.
pub(crate) ctx_data: Option<NonNull<c_void>>,
}
/// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust. /// Opaque pointer to a `wasmer_runtime::Ctx` value in Rust.
/// ///
/// An instance context is passed to any host function (aka imported /// An instance context is passed to any host function (aka imported
@@ -112,6 +128,8 @@ pub unsafe extern "C" fn wasmer_instantiate(
}); });
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
}; };
let mut imported_memories = vec![];
let mut instance_pointers_to_update = vec![];
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);
let mut import_object = ImportObject::new(); let mut import_object = ImportObject::new();
let mut namespaces = HashMap::new(); let mut namespaces = HashMap::new();
@@ -147,10 +165,14 @@ pub unsafe extern "C" fn wasmer_instantiate(
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;
// TODO: review ownership here, probably need to clone Memory for imported_meomries
imported_memories.push(mem);
Extern::Memory((&*mem).clone()) Extern::Memory((&*mem).clone())
} }
wasmer_import_export_kind::WASM_FUNCTION => { wasmer_import_export_kind::WASM_FUNCTION => {
let func_export = import.value.func as *mut Function; let func_wrapper = import.value.func as *mut FunctionWrapper;
let func_export = (*func_wrapper).func.as_ptr();
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 => {
@@ -187,7 +209,16 @@ pub unsafe extern "C" fn wasmer_instantiate(
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
}; };
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t; let c_api_instance = CAPIInstance {
instance: new_instance,
imported_memories,
ctx_data: None,
};
let c_api_instance_pointer = Box::into_raw(Box::new(c_api_instance));
for mut to_update in instance_pointers_to_update {
to_update.as_mut().instance_ptr = Some(NonNull::new_unchecked(c_api_instance_pointer));
}
*instance = c_api_instance_pointer as *mut wasmer_instance_t;
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
} }
@@ -207,16 +238,13 @@ pub unsafe extern "C" fn wasmer_instantiate(
/// It is often useful with `wasmer_instance_context_data_set()`. /// It is often useful with `wasmer_instance_context_data_set()`.
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_instance_context_get( pub unsafe extern "C" fn wasmer_instance_context_get(
instance: Option<NonNull<wasmer_instance_t>>, instance: Option<NonNull<wasmer_instance_t>>,
) -> Option<&'static wasmer_instance_context_t> { ) -> Option<&'static wasmer_instance_context_t> {
unimplemented!("wasmer_instance_context_get: API changed") // TODO: double check that `wasmer_instance_t` can be safely cast into CAPIInstance
/* let instance: *mut CAPIInstance = instance?.cast::<CAPIInstance>().as_ptr();
let instance = instance?.as_ref();
let context: *const Ctx = instance.context() as *const _;
context as *const wasmer_instance_context_t Some(&*(instance as *const wasmer_instance_context_t))
*/
} }
/// Calls an exported function of a WebAssembly instance by `name` /// Calls an exported function of a WebAssembly instance by `name`
@@ -310,8 +338,8 @@ pub unsafe extern "C" fn wasmer_instance_call(
let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize); let results: &mut [wasmer_value_t] = slice::from_raw_parts_mut(results, results_len as usize);
let instance = &*(instance as *mut Instance); let instance = &*(instance as *mut CAPIInstance);
let f: &Function = match instance.exports.get(func_name_r) { let f: &Function = match instance.instance.exports.get(func_name_r) {
Ok(f) => f, Ok(f) => f,
Err(err) => { Err(err) => {
update_last_error(err); update_last_error(err);
@@ -405,7 +433,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
exports: *mut *mut wasmer_exports_t, exports: *mut *mut wasmer_exports_t,
) { ) {
let instance = if let Some(instance) = instance { let instance = if let Some(instance) = instance {
instance.cast::<Instance>() instance.cast::<CAPIInstance>()
} else { } else {
return; return;
}; };
@@ -414,6 +442,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
let instance_ref = instance_ref_copy.as_mut(); let instance_ref = instance_ref_copy.as_mut();
let exports_vec: Vec<NamedExport> = instance_ref let exports_vec: Vec<NamedExport> = instance_ref
.instance
.module() .module()
.exports() .exports()
.map(|export_type| NamedExport { .map(|export_type| NamedExport {
@@ -457,22 +486,17 @@ pub unsafe extern "C" fn wasmer_instance_exports(
/// ``` /// ```
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_instance_context_data_set( pub unsafe extern "C" fn wasmer_instance_context_data_set(
instance: *mut wasmer_instance_t, instance: Option<NonNull<wasmer_instance_t>>,
data_ptr: *mut c_void, data_ptr: *mut c_void,
) { ) {
unimplemented!( let instance = if let Some(instance_inner) = instance {
"wasmer_instance_context_data_set: API changed in a way that this is non-obvious" instance_inner
) } else {
/*
if instance.is_null() {
return; return;
} };
let instance = unsafe { &mut *(instance as *mut Instance) }; instance.cast::<CAPIInstance>().as_mut().ctx_data = NonNull::new(data_ptr);
instance.context_mut().data = data_ptr;
*/
} }
/// Gets the `memory_idx`th memory of the instance. /// Gets the `memory_idx`th memory of the instance.
@@ -498,15 +522,53 @@ pub extern "C" fn wasmer_instance_context_data_set(
/// ``` /// ```
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_instance_context_memory( pub unsafe extern "C" fn wasmer_instance_context_memory(
ctx: *const wasmer_instance_context_t, ctx: *const wasmer_instance_context_t,
_memory_idx: u32, _memory_idx: u32,
) -> *const wasmer_memory_t { ) -> Option<&'static wasmer_memory_t> {
unimplemented!("wasmer_instance_context_memory: API changed") let instance = &*(ctx as *const CAPIInstance);
/*let ctx = unsafe { &*(ctx as *const Ctx) }; let module = instance.instance.module();
let memory = ctx.memory(0); let memory_index = MemoryIndex::new(0);
memory as *const Memory as *const wasmer_memory_t if module.info().is_imported_memory(memory_index) {
*/ if let Some(memory) = instance.imported_memories.first() {
let memory: &Memory = &**memory;
return Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t));
} else {
update_last_error(CApiError {
msg:
"Internal error: memory is imported but the list of imported memories is empty"
.to_string(),
});
return None;
}
} else {
let exported_memory_name = if let Some(name) = module
.info()
.exports
.iter()
.filter_map(|(name, export_index)| match export_index {
ExportIndex::Memory(idx) if *idx == memory_index => Some(name),
_ => None,
})
.next()
{
name
} else {
update_last_error(CApiError {
msg: "Could not find an exported memory".to_string(),
});
return None;
};
let memory = instance
.instance
.exports
.get_memory(exported_memory_name)
.expect(&format!(
"Module exports memory named `{}` but it's inaccessible",
&exported_memory_name
));
Some(&*(Box::into_raw(Box::new(memory.clone())) as *const wasmer_memory_t))
}
} }
/// Gets the data that can be hold by an instance. /// Gets the data that can be hold by an instance.
@@ -519,19 +581,11 @@ pub extern "C" fn wasmer_instance_context_memory(
/// This function returns nothing if `ctx` is a null pointer. /// This function returns nothing if `ctx` is a null pointer.
#[allow(clippy::cast_ptr_alignment)] #[allow(clippy::cast_ptr_alignment)]
#[no_mangle] #[no_mangle]
pub extern "C" fn wasmer_instance_context_data_get( pub unsafe extern "C" fn wasmer_instance_context_data_get(
ctx: *const wasmer_instance_context_t, ctx: Option<&'static wasmer_instance_context_t>,
) -> *mut c_void { ) -> Option<NonNull<c_void>> {
unimplemented!("wasmer_instance_context_data_get: API changed") let instance: &'static CAPIInstance = &*(ctx? as *const _ as *const CAPIInstance);
/* instance.ctx_data
if ctx.is_null() {
return ptr::null_mut() as _;
}
let ctx = unsafe { &*(ctx as *const Ctx) };
ctx.data
*/
} }
/// Frees memory for the given `wasmer_instance_t`. /// Frees memory for the given `wasmer_instance_t`.
@@ -555,6 +609,6 @@ pub extern "C" fn wasmer_instance_context_data_get(
#[no_mangle] #[no_mangle]
pub unsafe extern "C" fn wasmer_instance_destroy(instance: Option<NonNull<wasmer_instance_t>>) { pub unsafe extern "C" fn wasmer_instance_destroy(instance: Option<NonNull<wasmer_instance_t>>) {
if let Some(instance_inner) = instance { if let Some(instance_inner) = instance {
Box::from_raw(instance_inner.cast::<Instance>().as_ptr()); Box::from_raw(instance_inner.cast::<CAPIInstance>().as_ptr());
} }
} }

View File

@@ -4,7 +4,7 @@ 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},
instance::wasmer_instance_t, 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;
@@ -86,6 +86,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
imports_len: c_int, imports_len: c_int,
) -> wasmer_result_t { ) -> wasmer_result_t {
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);
let mut imported_memories = vec![];
let mut import_object = ImportObject::new(); let mut import_object = ImportObject::new();
let mut namespaces = HashMap::new(); let mut namespaces = HashMap::new();
for import in imports { for import in imports {
@@ -119,6 +120,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
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;
imported_memories.push(mem);
Extern::Memory((&*mem).clone()) Extern::Memory((&*mem).clone())
} }
wasmer_import_export_kind::WASM_FUNCTION => { wasmer_import_export_kind::WASM_FUNCTION => {
@@ -149,7 +151,13 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
} }
}; };
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t; let c_api_instance = CAPIInstance {
instance: new_instance,
imported_memories,
ctx_data: None,
};
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
wasmer_result_t::WASMER_OK wasmer_result_t::WASMER_OK
} }
@@ -174,7 +182,13 @@ pub unsafe extern "C" fn wasmer_module_import_instantiate(
return wasmer_result_t::WASMER_ERROR; return wasmer_result_t::WASMER_ERROR;
} }
}; };
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t; let imported_memories = todo!("get imported memories");
let c_api_instance = CAPIInstance {
instance: new_instance,
imported_memories,
ctx_data: None,
};
*instance = Box::into_raw(Box::new(c_api_instance)) as *mut wasmer_instance_t;
return wasmer_result_t::WASMER_OK; return wasmer_result_t::WASMER_OK;
} }

View File

@@ -4,7 +4,7 @@ project (WasmerRuntimeCApiTests)
add_executable(test-exported-memory test-exported-memory.c) add_executable(test-exported-memory test-exported-memory.c)
add_executable(test-exports test-exports.c) add_executable(test-exports test-exports.c)
add_executable(test-globals test-globals.c) add_executable(test-globals test-globals.c)
# functionality not yet implemented in wasmer reborn # trampoline functionality not yet implemented in wasmer reborn
#add_executable(test-import-function test-import-function.c) #add_executable(test-import-function test-import-function.c)
add_executable(test-import-trap test-import-trap.c) add_executable(test-import-trap test-import-trap.c)
add_executable(test-imports test-imports.c) add_executable(test-imports test-imports.c)
@@ -71,20 +71,18 @@ target_link_libraries(test-globals general ${WASMER_LIB})
target_compile_options(test-globals PRIVATE ${COMPILER_OPTIONS}) target_compile_options(test-globals PRIVATE ${COMPILER_OPTIONS})
add_test(test-globals test-globals) add_test(test-globals test-globals)
# functionality not yet implemented in wasmer reborn # trampoline functionality not yet implemented in wasmer reborn
#target_link_libraries(test-import-function general ${WASMER_LIB}) #target_link_libraries(test-import-function general ${WASMER_LIB})
#target_compile_options(test-import-function PRIVATE ${COMPILER_OPTIONS}) #target_compile_options(test-import-function PRIVATE ${COMPILER_OPTIONS})
#add_test(test-import-function test-import-function) #add_test(test-import-function test-import-function)
target_link_libraries(test-import-trap general ${WASMER_LIB}) target_link_libraries(test-import-trap general ${WASMER_LIB})
target_compile_options(test-import-trap PRIVATE ${COMPILER_OPTIONS}) target_compile_options(test-import-trap PRIVATE ${COMPILER_OPTIONS})
# TODO: reenable this test add_test(test-import-trap test-import-trap)
#add_test(test-import-trap test-import-trap)
target_link_libraries(test-imports general ${WASMER_LIB}) target_link_libraries(test-imports general ${WASMER_LIB})
target_compile_options(test-imports PRIVATE ${COMPILER_OPTIONS}) target_compile_options(test-imports PRIVATE ${COMPILER_OPTIONS})
# TODO: reenable this test add_test(test-imports test-imports)
#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})
@@ -139,8 +137,7 @@ add_test(test-validate test-validate)
target_link_libraries(test-context general ${WASMER_LIB}) target_link_libraries(test-context general ${WASMER_LIB})
target_compile_options(test-context PRIVATE ${COMPILER_OPTIONS}) target_compile_options(test-context PRIVATE ${COMPILER_OPTIONS})
# TODO: reenable this test add_test(test-context test-context)
#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})

View File

@@ -69,7 +69,7 @@ int main()
wasmer_last_error_message(error_str, error_len); wasmer_last_error_message(error_str, error_len);
printf("Error str: `%s`\n", error_str); printf("Error str: `%s`\n", error_str);
assert(0 == strcmp(error_str, "Call error: \"Hello\"")); assert(0 == strcmp(error_str, "RuntimeError: Hello"));
printf("Destroying func\n"); printf("Destroying func\n");
wasmer_import_func_destroy(func); wasmer_import_func_destroy(func);

View File

@@ -141,6 +141,10 @@ int main()
wasmer_value_t results[] = {result_one}; wasmer_value_t results[] = {result_one};
wasmer_result_t call_result = wasmer_instance_call(instance, "_hello_wasm", params, 0, results, 1); wasmer_result_t call_result = wasmer_instance_call(instance, "_hello_wasm", params, 0, results, 1);
printf("Call result: %d\n", call_result); printf("Call result: %d\n", call_result);
if (compile_result != WASMER_OK)
{
print_wasmer_error();
}
assert(call_result == WASMER_OK); assert(call_result == WASMER_OK);
assert(print_str_called); assert(print_str_called);

View File

@@ -138,9 +138,9 @@ typedef struct {
} wasmer_module_t; } wasmer_module_t;
/** /**
* Opaque pointer to a `wasmer_runtime::Instance` value in Rust. * Opaque pointer to an Instance type plus metadata.
* *
* A `wasmer_runtime::Instance` represents a WebAssembly instance. It * This type represents a WebAssembly instance. It
* is generally generated by the `wasmer_instantiate()` function, or by * is generally generated by the `wasmer_instantiate()` function, or by
* the `wasmer_module_instantiate()` function for the most common paths. * the `wasmer_module_instantiate()` function for the most common paths.
*/ */
@@ -1389,7 +1389,7 @@ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits)
* *
* This function never returns otherwise. * This function never returns otherwise.
*/ */
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message); wasmer_result_t wasmer_trap(const wasmer_instance_context_t *_ctx, const char *error_message);
/** /**
* Validates a sequence of bytes hoping it represents a valid WebAssembly module. * Validates a sequence of bytes hoping it represents a valid WebAssembly module.

View File

@@ -100,9 +100,9 @@ struct wasmer_module_t {
}; };
/// Opaque pointer to a `wasmer_runtime::Instance` value in Rust. /// Opaque pointer to an Instance type plus metadata.
/// ///
/// A `wasmer_runtime::Instance` represents a WebAssembly instance. It /// This type represents a WebAssembly instance. It
/// is generally generated by the `wasmer_instantiate()` function, or by /// is generally generated by the `wasmer_instantiate()` function, or by
/// the `wasmer_module_instantiate()` function for the most common paths. /// the `wasmer_module_instantiate()` function for the most common paths.
struct wasmer_instance_t { struct wasmer_instance_t {
@@ -1148,7 +1148,7 @@ wasmer_result_t wasmer_table_new(wasmer_table_t **table, wasmer_limits_t limits)
/// `error_message` are null. /// `error_message` are null.
/// ///
/// This function never returns otherwise. /// This function never returns otherwise.
wasmer_result_t wasmer_trap(const wasmer_instance_context_t *ctx, const char *error_message); wasmer_result_t wasmer_trap(const wasmer_instance_context_t *_ctx, const char *error_message);
/// Validates a sequence of bytes hoping it represents a valid WebAssembly module. /// Validates a sequence of bytes hoping it represents a valid WebAssembly module.
/// ///

View File

@@ -65,15 +65,7 @@ impl Compiler for LLVMCompiler {
//let data = Arc::new(Mutex::new(0)); //let data = Arc::new(Mutex::new(0));
let mut func_names = SecondaryMap::new(); let mut func_names = SecondaryMap::new();
// We're going to "link" the sections by simply appending all compatible // TODO: merge constants in sections.
// sections, then building the new relocations.
// TODO: merge constants.
let mut used_readonly_section = false;
let mut readonly_section = CustomSection {
protection: CustomSectionProtection::Read,
bytes: SectionBody::default(),
relocations: vec![],
};
for (func_index, _) in &module.functions { for (func_index, _) in &module.functions {
func_names[func_index] = module func_names[func_index] = module
@@ -153,6 +145,6 @@ impl Compiler for LLVMCompiler {
module: &Module, module: &Module,
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> { ) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
Ok(PrimaryMap::new()) Ok(PrimaryMap::new())
// unimplemented!("Dynamic funciton trampolines not yet implemented"); // unimplemented!("Dynamic function trampolines not yet implemented");
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -20,18 +20,6 @@ use inkwell::{
AddressSpace, AddressSpace,
}; };
use std::collections::HashMap; use std::collections::HashMap;
/*
use wasmer_runtime_core::{
memory::MemoryType,
module::ModuleInfo,
structures::TypedIndex,
types::{
GlobalIndex, ImportedFunctionIndex, LocalOrImport, MemoryIndex, SignatureIndex, TableIndex, Type,
},
units::Pages,
vm::{Ctx, INTERNALS_SIZE},
};
*/
use wasm_common::entity::{EntityRef, PrimaryMap}; use wasm_common::entity::{EntityRef, PrimaryMap};
use wasm_common::{ use wasm_common::{
FunctionIndex, FunctionType as FuncType, GlobalIndex, MemoryIndex, Mutability, Pages, FunctionIndex, FunctionType as FuncType, GlobalIndex, MemoryIndex, Mutability, Pages,
@@ -271,65 +259,6 @@ impl<'ctx> Intrinsics<'ctx> {
false, false,
); );
/*
ctx_ty.set_body(
&[
local_memory_ty
.ptr_type(AddressSpace::Generic)
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
local_table_ty
.ptr_type(AddressSpace::Generic)
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
local_global_ty
.ptr_type(AddressSpace::Generic)
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
local_memory_ty
.ptr_type(AddressSpace::Generic)
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
local_table_ty
.ptr_type(AddressSpace::Generic)
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
local_global_ty
.ptr_type(AddressSpace::Generic)
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
imported_func_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
sigindex_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
rt_intrinsics_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
stack_lower_bound_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
memory_base_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
memory_bound_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
internals_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
interrupt_signal_mem_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
local_function_ty
.ptr_type(AddressSpace::Generic)
.as_basic_type_enum(),
],
false,
);
*/
let ret_i8x16_take_i8x16_i8x16 = i8x16_ty.fn_type(&[i8x16_ty_basic, i8x16_ty_basic], false); let ret_i8x16_take_i8x16_i8x16 = i8x16_ty.fn_type(&[i8x16_ty_basic, i8x16_ty_basic], false);
let ret_i16x8_take_i16x8_i16x8 = i16x8_ty.fn_type(&[i16x8_ty_basic, i16x8_ty_basic], false); let ret_i16x8_take_i16x8_i16x8 = i16x8_ty.fn_type(&[i16x8_ty_basic, i16x8_ty_basic], false);
@@ -669,17 +598,10 @@ pub enum MemoryCache<'ctx> {
/// The memory moves around. /// The memory moves around.
Dynamic { Dynamic {
ptr_to_base_ptr: PointerValue<'ctx>, ptr_to_base_ptr: PointerValue<'ctx>,
ptr_to_bounds: PointerValue<'ctx>, current_length_ptr: PointerValue<'ctx>,
minimum: Pages,
maximum: Option<Pages>,
}, },
/// The memory is always in the same place. /// The memory is always in the same place.
Static { Static { base_ptr: PointerValue<'ctx> },
base_ptr: PointerValue<'ctx>,
bounds: IntValue<'ctx>,
minimum: Pages,
maximum: Option<Pages>,
},
} }
struct TableCache<'ctx> { struct TableCache<'ctx> {
@@ -747,28 +669,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
pub fn basic(&self) -> BasicValueEnum<'ctx> { pub fn basic(&self) -> BasicValueEnum<'ctx> {
self.ctx_ptr_value.as_basic_value_enum() self.ctx_ptr_value.as_basic_value_enum()
} }
/*
pub fn signal_mem(&mut self) -> PointerValue<'ctx> {
if let Some(x) = self.cached_signal_mem {
return x;
}
let (ctx_ptr_value, cache_builder) = (self.ctx_ptr_value, &self.cache_builder);
let ptr_ptr = unsafe {
cache_builder.build_struct_gep(
ctx_ptr_value,
offset_to_index(Ctx::offset_interrupt_signal_mem()),
"interrupt_signal_mem_ptr",
)
};
let ptr = cache_builder
.build_load(ptr_ptr, "interrupt_signal_mem")
.into_pointer_value();
self.cached_signal_mem = Some(ptr);
ptr
}
*/
pub fn memory( pub fn memory(
&mut self, &mut self,
index: MemoryIndex, index: MemoryIndex,
@@ -783,129 +684,59 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
&self.cache_builder, &self.cache_builder,
&self.offsets, &self.offsets,
); );
let memory_plan = &memory_plans[index];
*cached_memories.entry(index).or_insert_with(|| { *cached_memories.entry(index).or_insert_with(|| {
let (memory_array_ptr_ptr, index, memory_type, minimum, maximum, field_name) = { let memory_definition_ptr =
let desc = memory_plans.get(index).unwrap(); if let Some(local_memory_index) = wasm_module.local_memory_index(index) {
if let Some(local_mem_index) = wasm_module.local_memory_index(index) { let offset = offsets.vmctx_vmmemory_definition(local_memory_index);
let byte_offset = intrinsics.i64_ty.const_int( let offset = intrinsics.i32_ty.const_int(offset.into(), false);
offsets unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") }
.vmctx_vmmemory_definition_base(local_mem_index)
.into(),
false,
);
(
unsafe {
cache_builder.build_gep(
ctx_ptr_value,
&[byte_offset],
"memory_base_ptr_ptr",
)
},
local_mem_index.index() as u64,
desc.style.clone(),
desc.memory.minimum,
desc.memory.maximum,
"context_field_ptr_to_local_memory",
)
} else { } else {
let byte_offset = intrinsics.i64_ty.const_int( let offset = offsets.vmctx_vmmemory_import(index);
offsets.vmctx_vmmemory_import_definition(index).into(), let offset = intrinsics.i32_ty.const_int(offset.into(), false);
false, let memory_definition_ptr_ptr =
); unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") };
( let memory_definition_ptr_ptr = cache_builder
unsafe { .build_bitcast(
cache_builder memory_definition_ptr_ptr,
.build_struct_gep( intrinsics.i8_ptr_ty.ptr_type(AddressSpace::Generic),
ctx_ptr_value, "",
offset_to_index(offsets.vmctx_imported_memories_begin()), )
"memory_array_ptr_ptr",
)
.unwrap()
},
index.index() as u64,
desc.style.clone(),
desc.memory.minimum,
desc.memory.maximum,
"context_field_ptr_to_imported_memory",
)
}
};
let memory_array_ptr = cache_builder
.build_load(memory_array_ptr_ptr, "memory_array_ptr")
.into_pointer_value();
tbaa_label(
module,
intrinsics,
field_name,
memory_array_ptr.as_instruction_value().unwrap(),
None,
);
let const_index = intrinsics.i32_ty.const_int(index, false);
let memory_ptr_ptr = unsafe {
cache_builder.build_in_bounds_gep(
memory_array_ptr,
&[const_index],
"memory_ptr_ptr",
)
};
let memory_ptr = cache_builder
.build_load(memory_ptr_ptr, "memory_ptr")
.into_pointer_value();
tbaa_label(
module,
intrinsics,
"memory_ptr",
memory_ptr.as_instruction_value().unwrap(),
Some(index as u32),
);
let (ptr_to_base_ptr, ptr_to_bounds) = unsafe {
(
cache_builder
.build_struct_gep(memory_ptr, 0, "base_ptr")
.unwrap(),
cache_builder
.build_struct_gep(memory_ptr, 1, "bounds_ptr")
.unwrap(),
)
};
match memory_type {
MemoryStyle::Dynamic => MemoryCache::Dynamic {
ptr_to_base_ptr,
ptr_to_bounds,
minimum,
maximum,
},
MemoryStyle::Static { bound: _ } => {
let base_ptr = cache_builder
.build_load(ptr_to_base_ptr, "base")
.into_pointer_value(); .into_pointer_value();
let bounds = cache_builder cache_builder
.build_load(ptr_to_bounds, "bounds") .build_load(memory_definition_ptr_ptr, "")
.into_int_value(); .into_pointer_value()
tbaa_label( };
module, let memory_definition_ptr = cache_builder
intrinsics, .build_bitcast(
"static_memory_base", memory_definition_ptr,
base_ptr.as_instruction_value().unwrap(), intrinsics.vmmemory_definition_ptr_ty,
Some(index as u32), "",
); )
tbaa_label( .into_pointer_value();
module, let base_ptr = cache_builder
intrinsics, .build_struct_gep(
"static_memory_bounds", memory_definition_ptr,
bounds.as_instruction_value().unwrap(), intrinsics.vmmemory_definition_base_element,
Some(index as u32), "",
); )
MemoryCache::Static { .unwrap();
base_ptr, if memory_plan.style == MemoryStyle::Dynamic {
bounds, let current_length_ptr = cache_builder
minimum, .build_struct_gep(
maximum, memory_definition_ptr,
} intrinsics.vmmemory_definition_current_length_element,
"",
)
.unwrap();
MemoryCache::Dynamic {
ptr_to_base_ptr: base_ptr,
current_length_ptr,
} }
} else {
let base_ptr = cache_builder.build_load(base_ptr, "").into_pointer_value();
// TODO: tbaa
MemoryCache::Static { base_ptr }
} }
}) })
} }
@@ -1051,27 +882,6 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
&self.offsets, &self.offsets,
); );
*cached_sigindices.entry(index).or_insert_with(|| { *cached_sigindices.entry(index).or_insert_with(|| {
/*
let sigindex_array_ptr_ptr = unsafe {
cache_builder.build_struct_gep(
ctx_ptr_value,
offset_to_index(offsets.vmctx_signature_ids_begin()),
"sigindex_array_ptr_ptr",
)
};
let sigindex_array_ptr = cache_builder
.build_load(sigindex_array_ptr_ptr, "sigindex_array_ptr")
.into_pointer_value();
let const_index = intrinsics.i32_ty.const_int(index.index() as u64, false);
let sigindex_ptr = unsafe {
cache_builder.build_in_bounds_gep(
sigindex_array_ptr,
&[const_index],
"sigindex_ptr",
)
};
*/
let byte_offset = intrinsics let byte_offset = intrinsics
.i64_ty .i64_ty
.const_int(offsets.vmctx_vmshared_signature_id(index).into(), false); .const_int(offsets.vmctx_vmshared_signature_id(index).into(), false);

View File

@@ -3,7 +3,6 @@ use inkwell::{
values::{BasicValue, BasicValueEnum, PhiValue}, values::{BasicValue, BasicValueEnum, PhiValue},
}; };
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::Cell;
use std::ops::{BitAnd, BitOr, BitOrAssign}; use std::ops::{BitAnd, BitOr, BitOrAssign};
use wasmer_compiler::CompileError; use wasmer_compiler::CompileError;
@@ -196,7 +195,6 @@ impl BitAnd for ExtraInfo {
pub struct State<'ctx> { pub struct State<'ctx> {
pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>,
control_stack: Vec<ControlFrame<'ctx>>, control_stack: Vec<ControlFrame<'ctx>>,
value_counter: Cell<usize>,
pub reachable: bool, pub reachable: bool,
} }
@@ -206,7 +204,6 @@ impl<'ctx> State<'ctx> {
Self { Self {
stack: vec![], stack: vec![],
control_stack: vec![], control_stack: vec![],
value_counter: Cell::new(0),
reachable: true, reachable: true,
} }
} }
@@ -270,13 +267,6 @@ impl<'ctx> State<'ctx> {
)) ))
} }
pub fn var_name(&self) -> String {
let counter = self.value_counter.get();
let s = format!("s{}", counter);
self.value_counter.set(counter + 1);
s
}
pub fn push1<T: BasicValue<'ctx>>(&mut self, value: T) { pub fn push1<T: BasicValue<'ctx>>(&mut self, value: T) {
self.push1_extra(value, Default::default()); self.push1_extra(value, Default::default());
} }

View File

@@ -74,4 +74,12 @@ impl Compiler for SinglepassCompiler {
"Singlepass trampoline compilation not supported yet".to_owned(), "Singlepass trampoline compilation not supported yet".to_owned(),
)) ))
} }
fn compile_dynamic_function_trampolines(
&self,
module: &Module,
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
Ok(PrimaryMap::new())
// unimplemented!("Dynamic function trampolines not yet implemented");
}
} }

View File

@@ -4,7 +4,7 @@ use crate::x64_decl::{new_machine_state, X64Register};
use smallvec::smallvec; use smallvec::smallvec;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::collections::HashSet; use std::collections::HashSet;
use wasmparser::Type as WpType; use wasmer_compiler::wasmparser::Type as WpType;
struct MachineStackOffset(usize); struct MachineStackOffset(usize);

View File

@@ -29,8 +29,8 @@ pub struct TableElements {
pub elements: Box<[FunctionIndex]>, pub elements: Box<[FunctionIndex]>,
} }
/// Implemenation styles for WebAssembly linear memory. /// Implementation styles for WebAssembly linear memory.
#[derive(Debug, Clone, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum MemoryStyle { pub enum MemoryStyle {
/// The actual memory can be resized and moved. /// The actual memory can be resized and moved.
Dynamic, Dynamic,
@@ -53,7 +53,7 @@ pub struct MemoryPlan {
pub offset_guard_size: u64, pub offset_guard_size: u64,
} }
/// Implemenation styles for WebAssembly tables. /// Implementation styles for WebAssembly tables.
#[derive(Debug, Clone, Hash, Serialize, Deserialize)] #[derive(Debug, Clone, Hash, Serialize, Deserialize)]
pub enum TableStyle { pub enum TableStyle {
/// Signatures are stored in the table and checked in the caller. /// Signatures are stored in the table and checked in the caller.