mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-12 13:28:49 +00:00
Merge branch 'master' into native-engine
# Conflicts: # Cargo.lock
This commit is contained in:
6
.github/workflows/main.yaml
vendored
6
.github/workflows/main.yaml
vendored
@@ -45,6 +45,12 @@ jobs:
|
||||
toolchain: ${{ matrix.rust }}
|
||||
override: true
|
||||
- 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
|
||||
run: |
|
||||
make capi
|
||||
|
||||
192
Cargo.lock
generated
192
Cargo.lock
generated
@@ -1,5 +1,11 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# 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]]
|
||||
name = "ahash"
|
||||
version = "0.3.2"
|
||||
@@ -97,6 +103,30 @@ dependencies = [
|
||||
"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]]
|
||||
name = "bitflags"
|
||||
version = "1.2.1"
|
||||
@@ -162,12 +192,32 @@ version = "1.0.50"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fce5b5fb86b0c57c20c834c1b412fd09c77c8a59b9473f86272709e78874cd1d"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "clap"
|
||||
version = "2.33.0"
|
||||
@@ -452,6 +502,19 @@ dependencies = [
|
||||
"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]]
|
||||
name = "erased-serde"
|
||||
version = "0.3.11"
|
||||
@@ -601,6 +664,15 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "ident_case"
|
||||
version = "1.0.1"
|
||||
@@ -684,6 +756,12 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b294d6fa9ee409a054354afc4352b0b9ef7ca222c69b8812cbea9e7d2bf3783f"
|
||||
|
||||
[[package]]
|
||||
name = "leb128"
|
||||
version = "0.2.4"
|
||||
@@ -696,6 +774,39 @@ version = "0.2.70"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "libloading"
|
||||
version = "0.6.2"
|
||||
@@ -745,6 +856,12 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "make-cmd"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8ca8afbe8af1785e09636acb5a41e08a765f5f0340568716c18a8700ba3c0d3"
|
||||
|
||||
[[package]]
|
||||
name = "maybe-uninit"
|
||||
version = "2.0.0"
|
||||
@@ -796,6 +913,16 @@ version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "num"
|
||||
version = "0.1.42"
|
||||
@@ -896,6 +1023,12 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "peeking_take_while"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.17"
|
||||
@@ -924,7 +1057,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"version_check",
|
||||
"version_check 0.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -937,7 +1070,7 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
"syn-mid",
|
||||
"version_check",
|
||||
"version_check 0.9.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -949,6 +1082,12 @@ dependencies = [
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.3"
|
||||
@@ -1206,6 +1345,12 @@ version = "0.1.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
@@ -1326,6 +1471,12 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.4.0"
|
||||
@@ -1431,6 +1582,15 @@ dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test-generator"
|
||||
version = "0.1.0"
|
||||
@@ -1592,6 +1752,12 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.1"
|
||||
@@ -1795,7 +1961,7 @@ dependencies = [
|
||||
"cfg-if",
|
||||
"faerie",
|
||||
"leb128",
|
||||
"libloading",
|
||||
"libloading 0.6.2",
|
||||
"serde",
|
||||
"serde_bytes",
|
||||
"tempfile",
|
||||
@@ -1830,6 +1996,8 @@ dependencies = [
|
||||
"cbindgen",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"libffi",
|
||||
"wasm-common",
|
||||
"wasmer",
|
||||
"wasmer-wasi",
|
||||
]
|
||||
@@ -1898,6 +2066,15 @@ dependencies = [
|
||||
"wast",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "3.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.8"
|
||||
@@ -1914,6 +2091,15 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
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]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Wasmer [](https://dev.azure.com/wasmerio/wasmer/_build/latest?definitionId=3&branchName=master) [](https://slack.wasmer.io) [](https://github.com/wasmerio/wasmer/blob/master/LICENSE)
|
||||
|
||||
[`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)
|
||||
compilation as well as mulitple compiler implementations.
|
||||
runtime for Rust (...and also [the fastest]()!). It supports JIT (Just in Time) and AOT (Ahead of time)
|
||||
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.
|
||||
|
||||
|
||||
@@ -543,8 +543,8 @@ impl Function {
|
||||
VMDynamicFunctionImportContext::from_context(VMDynamicFunctionWithoutEnv {
|
||||
func: Box::new(func),
|
||||
});
|
||||
let address = std::ptr::null() as *const () as *const VMFunctionBody;
|
||||
let vmctx = Box::leak(Box::new(dynamic_ctx)) as *mut _ as *mut VMContext;
|
||||
let address = std::ptr::null() as *const VMFunctionBody;
|
||||
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
|
||||
let signature = store.engine().register_signature(&ty);
|
||||
Self {
|
||||
store: store.clone(),
|
||||
@@ -569,8 +569,8 @@ impl Function {
|
||||
env,
|
||||
func: Box::new(func),
|
||||
});
|
||||
let address = std::ptr::null() as *const () as *const VMFunctionBody;
|
||||
let vmctx = Box::leak(Box::new(dynamic_ctx)) as *mut _ as *mut VMContext;
|
||||
let address = std::ptr::null() as *const VMFunctionBody;
|
||||
let vmctx = Box::into_raw(Box::new(dynamic_ctx)) as *mut VMContext;
|
||||
let signature = store.engine().register_signature(&ty);
|
||||
Self {
|
||||
store: store.clone(),
|
||||
|
||||
@@ -34,7 +34,7 @@ pub use wasmer_compiler::{Features, Target};
|
||||
pub use wasmer_engine::{
|
||||
DeserializeError, Engine, InstantiationError, LinkError, RuntimeError, SerializeError,
|
||||
};
|
||||
pub use wasmer_runtime::MemoryError;
|
||||
pub use wasmer_runtime::{raise_user_trap, MemoryError};
|
||||
|
||||
// The compilers are mutually exclusive
|
||||
#[cfg(any(
|
||||
|
||||
@@ -326,11 +326,11 @@ impl Module {
|
||||
&self.store
|
||||
}
|
||||
|
||||
// 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
|
||||
// extra information from the module.
|
||||
//
|
||||
// However, the usage is highly discouraged.
|
||||
/// 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
|
||||
/// extra information from the module.
|
||||
///
|
||||
/// However, the usage is highly discouraged.
|
||||
#[doc(hidden)]
|
||||
pub fn info(&self) -> &ModuleInfo {
|
||||
&self.compiled.module()
|
||||
|
||||
@@ -17,6 +17,7 @@ crate-type = ["cdylib", "staticlib"]
|
||||
[dependencies]
|
||||
lazy_static = "1"
|
||||
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
|
||||
# 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" }
|
||||
@@ -27,6 +28,11 @@ features = ["compiler", "engine", "jit", "cranelift"]
|
||||
path = "../api"
|
||||
version = "0.16.2"
|
||||
|
||||
[dependencies.wasm-common]
|
||||
default-features = false
|
||||
path = "../wasm-common"
|
||||
version = "0.16.2"
|
||||
|
||||
[dependencies.wasmer-wasi]
|
||||
default-features = false
|
||||
path = "../wasi"
|
||||
|
||||
@@ -5,6 +5,7 @@ use crate::{
|
||||
error::{update_last_error, CApiError},
|
||||
global::wasmer_global_t,
|
||||
import::wasmer_import_func_t,
|
||||
instance::CAPIInstance,
|
||||
memory::wasmer_memory_t,
|
||||
module::wasmer_module_t,
|
||||
table::wasmer_table_t,
|
||||
@@ -14,7 +15,7 @@ use crate::{
|
||||
use libc::{c_int, c_uint};
|
||||
use std::ptr::{self, NonNull};
|
||||
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
|
||||
/// exposed to C.
|
||||
@@ -23,7 +24,7 @@ pub(crate) struct NamedExport {
|
||||
pub(crate) export_type: ExportType,
|
||||
|
||||
/// The instance that holds the export.
|
||||
pub(crate) instance: NonNull<Instance>,
|
||||
pub(crate) instance: NonNull<CAPIInstance>,
|
||||
}
|
||||
|
||||
/// Opaque pointer to `ImportType`.
|
||||
@@ -403,6 +404,7 @@ pub unsafe extern "C" fn wasmer_export_to_memory(
|
||||
let instance = named_export.instance.as_ref();
|
||||
|
||||
if let Ok(exported_memory) = instance
|
||||
.instance
|
||||
.exports
|
||||
.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 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,
|
||||
Err(err) => {
|
||||
update_last_error(err);
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
//! Functions and types for dealing with Emscripten imports
|
||||
|
||||
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 wasmer::wasm::{Instance, Module};
|
||||
@@ -54,16 +58,16 @@ pub unsafe extern "C" fn wasmer_emscripten_set_up(
|
||||
if globals.is_null() || instance.is_null() {
|
||||
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 em_data = Box::into_raw(Box::new(EmscriptenData::new(
|
||||
instance,
|
||||
instance.instance,
|
||||
&globals.data,
|
||||
Default::default(),
|
||||
))) as *mut c_void;
|
||||
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,
|
||||
Err(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() {
|
||||
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_process_result: Result<Vec<&str>, _> =
|
||||
@@ -113,7 +117,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main(
|
||||
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,
|
||||
Err(e) => {
|
||||
update_last_error(e);
|
||||
|
||||
@@ -4,22 +4,23 @@
|
||||
use crate::{
|
||||
error::{update_last_error, CApiError},
|
||||
export::{wasmer_import_export_kind, wasmer_import_export_value},
|
||||
instance::wasmer_instance_context_t,
|
||||
instance::{wasmer_instance_context_t, CAPIInstance},
|
||||
module::wasmer_module_t,
|
||||
value::wasmer_value_tag,
|
||||
wasmer_byte_array, wasmer_result_t,
|
||||
};
|
||||
use libc::c_uint;
|
||||
use std::ptr::NonNull;
|
||||
use std::ptr::{self, NonNull};
|
||||
use std::{
|
||||
//convert::TryFrom,
|
||||
ffi::c_void,
|
||||
ffi::{c_void, CStr},
|
||||
os::raw::c_char,
|
||||
slice,
|
||||
//sync::Arc,
|
||||
};
|
||||
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_runtime_core::{
|
||||
@@ -440,7 +441,9 @@ pub unsafe extern "C" fn wasmer_import_object_extend(
|
||||
Extern::Memory((&*mem).clone())
|
||||
}
|
||||
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())
|
||||
}
|
||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||
@@ -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
|
||||
/// function pointer, where the first argument is the famous `vm::Ctx`
|
||||
/// (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_len: c_uint,
|
||||
) -> *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: 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: 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 {
|
||||
func: FuncPointer::new(func as _),
|
||||
ctx: Context::Internal,
|
||||
signature: Arc::new(FuncSig::new(params, returns)),
|
||||
let store = crate::get_global_store();
|
||||
|
||||
let env_ptr = Box::into_raw(Box::new(LegacyEnv::default()));
|
||||
|
||||
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
|
||||
@@ -648,19 +715,9 @@ pub unsafe extern "C" fn wasmer_import_func_new(
|
||||
#[no_mangle]
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe extern "C" fn wasmer_trap(
|
||||
ctx: *const wasmer_instance_context_t,
|
||||
_ctx: *const wasmer_instance_context_t,
|
||||
error_message: *const c_char,
|
||||
) -> 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() {
|
||||
update_last_error(CApiError {
|
||||
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;
|
||||
}
|
||||
|
||||
let ctx = &*(ctx as *const Ctx);
|
||||
let error_message = CStr::from_ptr(error_message).to_str().unwrap();
|
||||
|
||||
(&*ctx.module)
|
||||
.runnable_module
|
||||
.do_early_trap(Box::new(error_message)); // never returns
|
||||
wasmer::raise_user_trap(Box::new(RuntimeError::new(error_message))); // never returns
|
||||
|
||||
// cbindgen does not generate a binding for a function that
|
||||
// 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.
|
||||
#[allow(unreachable_code)]
|
||||
wasmer_result_t::WASMER_OK
|
||||
*/
|
||||
}
|
||||
|
||||
/// 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]
|
||||
pub unsafe extern "C" fn wasmer_import_func_destroy(func: Option<NonNull<wasmer_import_func_t>>) {
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use crate::{
|
||||
error::{update_last_error, CApiError},
|
||||
export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports},
|
||||
import::wasmer_import_t,
|
||||
import::{wasmer_import_t, FunctionWrapper},
|
||||
memory::wasmer_memory_t,
|
||||
value::{wasmer_value, wasmer_value_t, wasmer_value_tag},
|
||||
wasmer_result_t,
|
||||
@@ -13,18 +13,34 @@ use std::collections::HashMap;
|
||||
use std::ffi::CStr;
|
||||
use std::ptr::NonNull;
|
||||
use std::slice;
|
||||
use wasm_common::{entity::*, ExportIndex, MemoryIndex};
|
||||
use wasmer::{
|
||||
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
|
||||
/// the `wasmer_module_instantiate()` function for the most common paths.
|
||||
#[repr(C)]
|
||||
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.
|
||||
///
|
||||
/// 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;
|
||||
};
|
||||
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 mut import_object = ImportObject::new();
|
||||
let mut namespaces = HashMap::new();
|
||||
@@ -147,10 +165,14 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
let export = match import.tag {
|
||||
wasmer_import_export_kind::WASM_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())
|
||||
}
|
||||
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())
|
||||
}
|
||||
wasmer_import_export_kind::WASM_GLOBAL => {
|
||||
@@ -187,7 +209,16 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
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
|
||||
}
|
||||
|
||||
@@ -207,16 +238,13 @@ pub unsafe extern "C" fn wasmer_instantiate(
|
||||
/// It is often useful with `wasmer_instance_context_data_set()`.
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[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>>,
|
||||
) -> Option<&'static wasmer_instance_context_t> {
|
||||
unimplemented!("wasmer_instance_context_get: API changed")
|
||||
/*
|
||||
let instance = instance?.as_ref();
|
||||
let context: *const Ctx = instance.context() as *const _;
|
||||
// TODO: double check that `wasmer_instance_t` can be safely cast into CAPIInstance
|
||||
let instance: *mut CAPIInstance = instance?.cast::<CAPIInstance>().as_ptr();
|
||||
|
||||
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`
|
||||
@@ -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 instance = &*(instance as *mut Instance);
|
||||
let f: &Function = match instance.exports.get(func_name_r) {
|
||||
let instance = &*(instance as *mut CAPIInstance);
|
||||
let f: &Function = match instance.instance.exports.get(func_name_r) {
|
||||
Ok(f) => f,
|
||||
Err(err) => {
|
||||
update_last_error(err);
|
||||
@@ -405,7 +433,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
||||
exports: *mut *mut wasmer_exports_t,
|
||||
) {
|
||||
let instance = if let Some(instance) = instance {
|
||||
instance.cast::<Instance>()
|
||||
instance.cast::<CAPIInstance>()
|
||||
} else {
|
||||
return;
|
||||
};
|
||||
@@ -414,6 +442,7 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
||||
let instance_ref = instance_ref_copy.as_mut();
|
||||
|
||||
let exports_vec: Vec<NamedExport> = instance_ref
|
||||
.instance
|
||||
.module()
|
||||
.exports()
|
||||
.map(|export_type| NamedExport {
|
||||
@@ -457,22 +486,17 @@ pub unsafe extern "C" fn wasmer_instance_exports(
|
||||
/// ```
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_instance_context_data_set(
|
||||
instance: *mut wasmer_instance_t,
|
||||
pub unsafe extern "C" fn wasmer_instance_context_data_set(
|
||||
instance: Option<NonNull<wasmer_instance_t>>,
|
||||
data_ptr: *mut c_void,
|
||||
) {
|
||||
unimplemented!(
|
||||
"wasmer_instance_context_data_set: API changed in a way that this is non-obvious"
|
||||
)
|
||||
/*
|
||||
if instance.is_null() {
|
||||
let instance = if let Some(instance_inner) = instance {
|
||||
instance_inner
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
let instance = unsafe { &mut *(instance as *mut Instance) };
|
||||
|
||||
instance.context_mut().data = data_ptr;
|
||||
*/
|
||||
instance.cast::<CAPIInstance>().as_mut().ctx_data = NonNull::new(data_ptr);
|
||||
}
|
||||
|
||||
/// 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)]
|
||||
#[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,
|
||||
_memory_idx: u32,
|
||||
) -> *const wasmer_memory_t {
|
||||
unimplemented!("wasmer_instance_context_memory: API changed")
|
||||
/*let ctx = unsafe { &*(ctx as *const Ctx) };
|
||||
let memory = ctx.memory(0);
|
||||
memory as *const Memory as *const wasmer_memory_t
|
||||
*/
|
||||
) -> Option<&'static wasmer_memory_t> {
|
||||
let instance = &*(ctx as *const CAPIInstance);
|
||||
let module = instance.instance.module();
|
||||
let memory_index = MemoryIndex::new(0);
|
||||
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.
|
||||
@@ -519,19 +581,11 @@ pub extern "C" fn wasmer_instance_context_memory(
|
||||
/// This function returns nothing if `ctx` is a null pointer.
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wasmer_instance_context_data_get(
|
||||
ctx: *const wasmer_instance_context_t,
|
||||
) -> *mut c_void {
|
||||
unimplemented!("wasmer_instance_context_data_get: API changed")
|
||||
/*
|
||||
if ctx.is_null() {
|
||||
return ptr::null_mut() as _;
|
||||
}
|
||||
|
||||
let ctx = unsafe { &*(ctx as *const Ctx) };
|
||||
|
||||
ctx.data
|
||||
*/
|
||||
pub unsafe extern "C" fn wasmer_instance_context_data_get(
|
||||
ctx: Option<&'static wasmer_instance_context_t>,
|
||||
) -> Option<NonNull<c_void>> {
|
||||
let instance: &'static CAPIInstance = &*(ctx? as *const _ as *const CAPIInstance);
|
||||
instance.ctx_data
|
||||
}
|
||||
|
||||
/// Frees memory for the given `wasmer_instance_t`.
|
||||
@@ -555,6 +609,6 @@ pub extern "C" fn wasmer_instance_context_data_get(
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn wasmer_instance_destroy(instance: Option<NonNull<wasmer_instance_t>>) {
|
||||
if let Some(instance_inner) = instance {
|
||||
Box::from_raw(instance_inner.cast::<Instance>().as_ptr());
|
||||
Box::from_raw(instance_inner.cast::<CAPIInstance>().as_ptr());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::{
|
||||
error::{update_last_error, CApiError},
|
||||
export::wasmer_import_export_kind,
|
||||
import::{wasmer_import_object_t, wasmer_import_t},
|
||||
instance::wasmer_instance_t,
|
||||
instance::{wasmer_instance_t, CAPIInstance},
|
||||
wasmer_byte_array, wasmer_result_t,
|
||||
};
|
||||
use libc::c_int;
|
||||
@@ -86,6 +86,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
||||
imports_len: c_int,
|
||||
) -> wasmer_result_t {
|
||||
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 namespaces = HashMap::new();
|
||||
for import in imports {
|
||||
@@ -119,6 +120,7 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
|
||||
let export = match import.tag {
|
||||
wasmer_import_export_kind::WASM_MEMORY => {
|
||||
let mem = import.value.memory as *mut Memory;
|
||||
imported_memories.push(mem);
|
||||
Extern::Memory((&*mem).clone())
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -174,7 +182,13 @@ pub unsafe extern "C" fn wasmer_module_import_instantiate(
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ project (WasmerRuntimeCApiTests)
|
||||
add_executable(test-exported-memory test-exported-memory.c)
|
||||
add_executable(test-exports test-exports.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-trap test-import-trap.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})
|
||||
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_compile_options(test-import-function PRIVATE ${COMPILER_OPTIONS})
|
||||
#add_test(test-import-function test-import-function)
|
||||
|
||||
target_link_libraries(test-import-trap general ${WASMER_LIB})
|
||||
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_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_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_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_compile_options(test-module-import-instantiate PRIVATE ${COMPILER_OPTIONS})
|
||||
|
||||
@@ -69,7 +69,7 @@ int main()
|
||||
wasmer_last_error_message(error_str, error_len);
|
||||
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");
|
||||
wasmer_import_func_destroy(func);
|
||||
|
||||
@@ -141,6 +141,10 @@ int main()
|
||||
wasmer_value_t results[] = {result_one};
|
||||
wasmer_result_t call_result = wasmer_instance_call(instance, "_hello_wasm", params, 0, results, 1);
|
||||
printf("Call result: %d\n", call_result);
|
||||
if (compile_result != WASMER_OK)
|
||||
{
|
||||
print_wasmer_error();
|
||||
}
|
||||
assert(call_result == WASMER_OK);
|
||||
assert(print_str_called);
|
||||
|
||||
|
||||
@@ -138,9 +138,9 @@ typedef 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
|
||||
* 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.
|
||||
*/
|
||||
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.
|
||||
|
||||
@@ -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
|
||||
/// the `wasmer_module_instantiate()` function for the most common paths.
|
||||
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.
|
||||
///
|
||||
/// 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.
|
||||
///
|
||||
|
||||
@@ -65,15 +65,7 @@ impl Compiler for LLVMCompiler {
|
||||
//let data = Arc::new(Mutex::new(0));
|
||||
let mut func_names = SecondaryMap::new();
|
||||
|
||||
// We're going to "link" the sections by simply appending all compatible
|
||||
// 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![],
|
||||
};
|
||||
// TODO: merge constants in sections.
|
||||
|
||||
for (func_index, _) in &module.functions {
|
||||
func_names[func_index] = module
|
||||
@@ -153,6 +145,6 @@ impl Compiler for LLVMCompiler {
|
||||
module: &Module,
|
||||
) -> Result<PrimaryMap<FunctionIndex, FunctionBody>, CompileError> {
|
||||
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
@@ -20,18 +20,6 @@ use inkwell::{
|
||||
AddressSpace,
|
||||
};
|
||||
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::{
|
||||
FunctionIndex, FunctionType as FuncType, GlobalIndex, MemoryIndex, Mutability, Pages,
|
||||
@@ -271,65 +259,6 @@ impl<'ctx> Intrinsics<'ctx> {
|
||||
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_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.
|
||||
Dynamic {
|
||||
ptr_to_base_ptr: PointerValue<'ctx>,
|
||||
ptr_to_bounds: PointerValue<'ctx>,
|
||||
minimum: Pages,
|
||||
maximum: Option<Pages>,
|
||||
current_length_ptr: PointerValue<'ctx>,
|
||||
},
|
||||
/// The memory is always in the same place.
|
||||
Static {
|
||||
base_ptr: PointerValue<'ctx>,
|
||||
bounds: IntValue<'ctx>,
|
||||
minimum: Pages,
|
||||
maximum: Option<Pages>,
|
||||
},
|
||||
Static { base_ptr: PointerValue<'ctx> },
|
||||
}
|
||||
|
||||
struct TableCache<'ctx> {
|
||||
@@ -747,28 +669,7 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
pub fn basic(&self) -> BasicValueEnum<'ctx> {
|
||||
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(
|
||||
&mut self,
|
||||
index: MemoryIndex,
|
||||
@@ -783,129 +684,59 @@ impl<'ctx, 'a> CtxType<'ctx, 'a> {
|
||||
&self.cache_builder,
|
||||
&self.offsets,
|
||||
);
|
||||
let memory_plan = &memory_plans[index];
|
||||
*cached_memories.entry(index).or_insert_with(|| {
|
||||
let (memory_array_ptr_ptr, index, memory_type, minimum, maximum, field_name) = {
|
||||
let desc = memory_plans.get(index).unwrap();
|
||||
if let Some(local_mem_index) = wasm_module.local_memory_index(index) {
|
||||
let byte_offset = intrinsics.i64_ty.const_int(
|
||||
offsets
|
||||
.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",
|
||||
)
|
||||
let memory_definition_ptr =
|
||||
if let Some(local_memory_index) = wasm_module.local_memory_index(index) {
|
||||
let offset = offsets.vmctx_vmmemory_definition(local_memory_index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") }
|
||||
} else {
|
||||
let byte_offset = intrinsics.i64_ty.const_int(
|
||||
offsets.vmctx_vmmemory_import_definition(index).into(),
|
||||
false,
|
||||
);
|
||||
(
|
||||
unsafe {
|
||||
cache_builder
|
||||
.build_struct_gep(
|
||||
ctx_ptr_value,
|
||||
offset_to_index(offsets.vmctx_imported_memories_begin()),
|
||||
"memory_array_ptr_ptr",
|
||||
let offset = offsets.vmctx_vmmemory_import(index);
|
||||
let offset = intrinsics.i32_ty.const_int(offset.into(), false);
|
||||
let memory_definition_ptr_ptr =
|
||||
unsafe { cache_builder.build_gep(ctx_ptr_value, &[offset], "") };
|
||||
let memory_definition_ptr_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
memory_definition_ptr_ptr,
|
||||
intrinsics.i8_ptr_ty.ptr_type(AddressSpace::Generic),
|
||||
"",
|
||||
)
|
||||
.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",
|
||||
)
|
||||
cache_builder
|
||||
.build_load(memory_definition_ptr_ptr, "")
|
||||
.into_pointer_value()
|
||||
};
|
||||
let memory_ptr = cache_builder
|
||||
.build_load(memory_ptr_ptr, "memory_ptr")
|
||||
let memory_definition_ptr = cache_builder
|
||||
.build_bitcast(
|
||||
memory_definition_ptr,
|
||||
intrinsics.vmmemory_definition_ptr_ty,
|
||||
"",
|
||||
)
|
||||
.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();
|
||||
let bounds = cache_builder
|
||||
.build_load(ptr_to_bounds, "bounds")
|
||||
.into_int_value();
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
"static_memory_base",
|
||||
base_ptr.as_instruction_value().unwrap(),
|
||||
Some(index as u32),
|
||||
);
|
||||
tbaa_label(
|
||||
module,
|
||||
intrinsics,
|
||||
"static_memory_bounds",
|
||||
bounds.as_instruction_value().unwrap(),
|
||||
Some(index as u32),
|
||||
);
|
||||
MemoryCache::Static {
|
||||
base_ptr,
|
||||
bounds,
|
||||
minimum,
|
||||
maximum,
|
||||
}
|
||||
.build_struct_gep(
|
||||
memory_definition_ptr,
|
||||
intrinsics.vmmemory_definition_base_element,
|
||||
"",
|
||||
)
|
||||
.unwrap();
|
||||
if memory_plan.style == MemoryStyle::Dynamic {
|
||||
let current_length_ptr = cache_builder
|
||||
.build_struct_gep(
|
||||
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,
|
||||
);
|
||||
*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
|
||||
.i64_ty
|
||||
.const_int(offsets.vmctx_vmshared_signature_id(index).into(), false);
|
||||
|
||||
@@ -3,7 +3,6 @@ use inkwell::{
|
||||
values::{BasicValue, BasicValueEnum, PhiValue},
|
||||
};
|
||||
use smallvec::SmallVec;
|
||||
use std::cell::Cell;
|
||||
use std::ops::{BitAnd, BitOr, BitOrAssign};
|
||||
use wasmer_compiler::CompileError;
|
||||
|
||||
@@ -196,7 +195,6 @@ impl BitAnd for ExtraInfo {
|
||||
pub struct State<'ctx> {
|
||||
pub stack: Vec<(BasicValueEnum<'ctx>, ExtraInfo)>,
|
||||
control_stack: Vec<ControlFrame<'ctx>>,
|
||||
value_counter: Cell<usize>,
|
||||
|
||||
pub reachable: bool,
|
||||
}
|
||||
@@ -206,7 +204,6 @@ impl<'ctx> State<'ctx> {
|
||||
Self {
|
||||
stack: vec![],
|
||||
control_stack: vec![],
|
||||
value_counter: Cell::new(0),
|
||||
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) {
|
||||
self.push1_extra(value, Default::default());
|
||||
}
|
||||
|
||||
@@ -74,4 +74,12 @@ impl Compiler for SinglepassCompiler {
|
||||
"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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::x64_decl::{new_machine_state, X64Register};
|
||||
use smallvec::smallvec;
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::HashSet;
|
||||
use wasmparser::Type as WpType;
|
||||
use wasmer_compiler::wasmparser::Type as WpType;
|
||||
|
||||
struct MachineStackOffset(usize);
|
||||
|
||||
|
||||
@@ -29,8 +29,8 @@ pub struct TableElements {
|
||||
pub elements: Box<[FunctionIndex]>,
|
||||
}
|
||||
|
||||
/// Implemenation styles for WebAssembly linear memory.
|
||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
||||
/// Implementation styles for WebAssembly linear memory.
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub enum MemoryStyle {
|
||||
/// The actual memory can be resized and moved.
|
||||
Dynamic,
|
||||
@@ -53,7 +53,7 @@ pub struct MemoryPlan {
|
||||
pub offset_guard_size: u64,
|
||||
}
|
||||
|
||||
/// Implemenation styles for WebAssembly tables.
|
||||
/// Implementation styles for WebAssembly tables.
|
||||
#[derive(Debug, Clone, Hash, Serialize, Deserialize)]
|
||||
pub enum TableStyle {
|
||||
/// Signatures are stored in the table and checked in the caller.
|
||||
|
||||
Reference in New Issue
Block a user