Merge branch 'master' into fix/imported-functions-must-be-send

This commit is contained in:
Mark McCaskey
2020-01-21 09:47:46 -08:00
committed by GitHub
29 changed files with 1421 additions and 844 deletions

12
.github/CODEOWNERS vendored
View File

@ -3,15 +3,15 @@ src/ @syrusakbary @MarkMcCaskey
# Backends
lib/singlepass-backend @losfair @nlewycky
lib/clif-backend @nlewycky @bjfish
lib/clif-backend @nlewycky
lib/llvm-backend @nlewycky @losfair
# Runtime
lib/runtime-core @Hywan @bjfish
lib/runtime @MarkMcCaskey @Hywan @bjfish
lib/runtime-c-api @bjfish @Hywan
lib/win-exception-handler @bjfish @losfair
lib/middleware-common @bjfish @losfair
lib/runtime-core @Hywan
lib/runtime @MarkMcCaskey @Hywan
lib/runtime-c-api @Hywan
lib/win-exception-handler @losfair
lib/middleware-common @losfair
# Frontend integrations

View File

@ -3,6 +3,8 @@
## **[Unreleased]**
- [#1161](https://github.com/wasmerio/wasmer/pull/1161) Require imported functions to be `Send`. This is a breaking change that fixes a soundness issue in the API.
- [#1129](https://github.com/wasmerio/wasmer/pull/1129) Standard exception types for singlepass backend.
- [#1140](https://github.com/wasmerio/wasmer/pull/1140) Use [`blake3`](https://github.com/BLAKE3-team/BLAKE3) as default hashing algorithm for caching.
## 0.13.1 - 2020-01-16
- Fix bug in wapm related to the `package.wasmer_extra_flags` entry in the manifest

57
Cargo.lock generated
View File

@ -46,6 +46,12 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d49d90015b3c36167a20fe2810c5cd875ad504b39cff3d4eae7977e6b7c1cb2"
[[package]]
name = "autocfg"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d"
[[package]]
name = "bincode"
version = "1.2.1"
@ -63,13 +69,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "blake2b_simd"
version = "0.5.10"
name = "blake3"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a"
checksum = "b8c90bf4a07dd0b816948d0915ba1b110e7ce54169797feb5b39d6139a0a81ca"
dependencies = [
"arrayref",
"arrayvec",
"cc",
"cfg-if",
"constant_time_eq",
]
@ -312,7 +320,7 @@ version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5064ebdbf05ce3cb95e45c8b086f72263f4166b29b97f6baff7ef7fe047b55ac"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"cfg-if",
"crossbeam-utils",
"lazy_static",
@ -335,7 +343,7 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce446db02cdc3165b94ae73111e570793400d0794e46125cc4056c81cbb039f4"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"cfg-if",
"lazy_static",
]
@ -549,17 +557,17 @@ dependencies = [
[[package]]
name = "hex"
version = "0.3.2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
checksum = "023b39be39e3a2da62a94feb433e91e8bcd37676fbc8bea371daf52b7a769a3e"
[[package]]
name = "indexmap"
version = "1.3.0"
version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712d7b3ea5827fcb9d4fda14bf4da5f136f0db2ae9c8f4bd4e2d1c6fde4e6db2"
checksum = "0b54058f0a6ff80b6803da8faf8997cde53872b38f4023728f6830b06cd3c0dc"
dependencies = [
"autocfg",
"autocfg 1.0.0",
"serde",
]
@ -755,7 +763,7 @@ version = "0.1.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b85e541ef8255f6cf42bbfe4ef361305c6c135d10919ecc26126c4e5ae94bc09"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"num-traits",
]
@ -765,7 +773,7 @@ version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76bd5272412d173d6bf9afdf98db8612bbabc9a7a830b7bfc9c188911716132e"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"num-integer",
"num-traits",
]
@ -776,7 +784,7 @@ version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d4c81ffc11c212fa327657cb19dd85eb7419e163b5b076bede2bdb5c974c07e4"
dependencies = [
"autocfg",
"autocfg 0.1.7",
]
[[package]]
@ -982,7 +990,7 @@ version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d71dacdc3c88c1fde3885a3be3fbab9f35724e6ce99467f7d9c5026132184ca"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"libc",
"rand_chacha 0.1.1",
"rand_core 0.4.2",
@ -1014,7 +1022,7 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "556d3a1ca6600bfcbab7c7c91ccb085ac7fbbcd70e008a98742e7847f4f7bcef"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"rand_core 0.3.1",
]
@ -1110,7 +1118,7 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "abf9b09b01790cfe0364f52bf32995ea3c39f4d2dd011eac241d2914146d0b44"
dependencies = [
"autocfg",
"autocfg 0.1.7",
"rand_core 0.4.2",
]
@ -1405,19 +1413,20 @@ checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
[[package]]
name = "structopt"
version = "0.3.7"
version = "0.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "884ae79d6aad1e738f4a70dff314203fd498490a63ebc4d03ea83323c40b7b72"
checksum = "df136b42d76b1fbea72e2ab3057343977b04b4a2e00836c3c7c0673829572713"
dependencies = [
"clap",
"lazy_static",
"structopt-derive",
]
[[package]]
name = "structopt-derive"
version = "0.4.0"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a97f829a34a0a9d5b353a881025a23b8c9fd09d46be6045df6b22920dbd7a93"
checksum = "fd50a87d2f7b8958055f3e73a963d78feaccca3836767a9069844e34b5b03c0a"
dependencies = [
"heck",
"proc-macro-error",
@ -1790,7 +1799,7 @@ dependencies = [
"regex",
"rustc_version",
"semver",
"smallvec 0.6.13",
"smallvec 1.1.0",
"wabt",
"wasmer-runtime-core",
"wasmparser",
@ -1861,7 +1870,7 @@ name = "wasmer-runtime-core"
version = "0.13.1"
dependencies = [
"bincode",
"blake2b_simd",
"blake3",
"cc",
"digest",
"errno",
@ -1877,7 +1886,7 @@ dependencies = [
"serde-bench",
"serde_bytes",
"serde_derive",
"smallvec 0.6.13",
"smallvec 1.1.0",
"wasmparser",
"winapi",
]
@ -1906,7 +1915,7 @@ dependencies = [
"nix",
"serde",
"serde_derive",
"smallvec 0.6.13",
"smallvec 1.1.0",
"wasmer-runtime-core",
]

View File

@ -17,18 +17,36 @@ jobs:
- template: .azure/install-rust.yml
- script: |
rustup component add rustfmt
rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy
displayName: Lint dependencies
- script: cargo fmt --all -- --check
displayName: Lint
variables:
rust_toolchain: '1.39.0'
- job: clippy_lint
pool:
vmImage: "ubuntu-18.04"
steps:
- checkout: self
submodules: true
- template: .azure/install-rust.yml
- template: .azure/install-llvm.yml
- template: .azure/install-sccache.yml
- template: .azure/install-cmake.yml
- script: |
rustup component add rustfmt
rustup component add clippy || cargo install --git https://github.com/rust-lang/rust-clippy/ --force clippy
displayName: Lint dependencies with clippy
- script: cargo clippy --workspace
displayName: Clippy Lint
variables:
rust_toolchain: nightly-2019-12-19
- job: Test
strategy:
matrix:
linux:
imageName: "ubuntu-16.04"
imageName: "ubuntu-18.04"
rust_toolchain: nightly-2019-12-19
mac:
imageName: "macos-10.14"
@ -73,7 +91,7 @@ jobs:
- job: Check
pool:
vmImage: "ubuntu-16.04"
vmImage: "ubuntu-18.04"
variables:
rust_toolchain: nightly-2019-12-19
condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
@ -92,7 +110,7 @@ jobs:
strategy:
matrix:
linux:
imageName: "ubuntu-16.04"
imageName: "ubuntu-18.04"
rust_toolchain: nightly-2019-12-19
mac:
imageName: "macos-10.14"
@ -159,7 +177,7 @@ jobs:
strategy:
matrix:
linux:
imageName: "ubuntu-16.04"
imageName: "ubuntu-18.04"
rust_toolchain: nightly-2019-12-19
mac:
imageName: "macos-10.14"
@ -212,7 +230,7 @@ jobs:
- job: Build_Docs
pool:
vmImage: "ubuntu-16.04"
vmImage: "ubuntu-18.04"
variables:
rust_toolchain: nightly-2019-08-15
condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
@ -287,7 +305,7 @@ jobs:
- Build_Docs
displayName: Deploy API Documentation to GitHub
pool:
vmImage: "ubuntu-16.04"
vmImage: "ubuntu-18.04"
condition: in(variables['Build.SourceBranch'], 'refs/heads/master')
steps:
- checkout: self

View File

@ -1171,9 +1171,10 @@ pub fn tbaa_label<'ctx>(
// TODO: ContextRef can't return us the lifetime from module through Deref.
// This could be fixed once generic_associated_types is stable.
let context2 = &*context;
let context = unsafe { std::mem::transmute::<&Context, &'ctx Context>(context2) };
std::mem::forget(context2);
let context = {
let context2 = &*context;
unsafe { std::mem::transmute::<&Context, &'ctx Context>(context2) }
};
// `!wasmer_tbaa_root = {}`, the TBAA root node for wasmer.
let tbaa_root = module

View File

@ -22,16 +22,12 @@ pub(crate) fn take_last_error() -> Option<Box<dyn Error>> {
LAST_ERROR.with(|prev| prev.borrow_mut().take())
}
/// Gets the length in bytes of the last error.
/// Gets the length in bytes of the last error if any.
///
/// This can be used to dynamically allocate a buffer with the correct number of
/// bytes needed to store a message.
///
/// # Example
///
/// ```c
/// int error_len = wasmer_last_error_length();
/// char *error_str = malloc(error_len);
/// ```
/// See `wasmer_last_error_message()` to get a full example.
#[no_mangle]
pub extern "C" fn wasmer_last_error_length() -> c_int {
LAST_ERROR.with(|prev| match *prev.borrow() {
@ -40,19 +36,33 @@ pub extern "C" fn wasmer_last_error_length() -> c_int {
})
}
/// Stores the last error message into the provided buffer up to the given `length`.
/// The `length` parameter must be large enough to store the last error message.
/// Gets the last error message if any into the provided buffer
/// `buffer` up to the given `length`.
///
/// Returns the length of the string in bytes.
/// Returns `-1` if an error occurs.
/// The `length` parameter must be large enough to store the last
/// error message. Ideally, the value should come from
/// `wasmer_last_error_length()`.
///
/// # Example
/// The function returns the length of the string in bytes, `-1` if an
/// error occurs. Potential errors are:
///
/// * The buffer is a null pointer,
/// * The buffer is too smal to hold the error message.
///
/// Note: The error message always has a trailing null character.
///
/// Example:
///
/// ```c
/// int error_len = wasmer_last_error_length();
/// char *error_str = malloc(error_len);
/// wasmer_last_error_message(error_str, error_len);
/// printf("Error str: `%s`\n", error_str);
/// int error_length = wasmer_last_error_length();
///
/// if (error_length > 0) {
/// char *error_message = malloc(error_length);
/// wasmer_last_error_message(error_message, error_length);
/// printf("Error message: `%s`\n", error_message);
/// } else {
/// printf("No error message\n");
/// }
/// ```
#[no_mangle]
pub unsafe extern "C" fn wasmer_last_error_message(buffer: *mut c_char, length: c_int) -> c_int {

View File

@ -43,7 +43,11 @@ pub struct wasmer_export_func_t;
/// exposed to C.
pub(crate) struct NamedExports(pub Vec<NamedExport>);
/// Opaque pointer to `NamedExports`.
/// Opaque pointer to the opaque structure `crate::NamedExports`,
/// which is a wrapper around a vector of the opaque structure
/// `crate::NamedExport`.
///
/// Check the `wasmer_instance_exports()` function to learn more.
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_exports_t;
@ -91,9 +95,16 @@ pub union wasmer_import_export_value {
// ================
// Do not modify these values without updating the `TryFrom` implementation below
pub enum wasmer_import_export_kind {
/// The export/import is a function.
WASM_FUNCTION = 0,
/// The export/import is a global.
WASM_GLOBAL = 1,
/// The export/import is a memory.
WASM_MEMORY = 2,
/// The export/import is a table.
WASM_TABLE = 3,
}
@ -201,7 +212,23 @@ pub unsafe extern "C" fn wasmer_export_descriptor_kind(
named_export_descriptor.kind.clone()
}
/// Frees the memory for the given exports
/// Frees the memory for the given exports.
///
/// Check the `wasmer_instance_exports()` function to get a complete
/// example.
///
/// If `exports` is a null pointer, this function does nothing.
///
/// Example:
///
/// ```c
/// // Get some exports.
/// wasmer_exports_t *exports = NULL;
/// wasmer_instance_exports(instance, &exports);
///
/// // Destroy the exports.
/// wasmer_exports_destroy(exports);
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub extern "C" fn wasmer_exports_destroy(exports: *mut wasmer_exports_t) {
@ -439,7 +466,7 @@ pub unsafe extern "C" fn wasmer_export_func_call(
}
let params: Vec<Value> = {
if params_len <= 0 {
if params_len == 0 {
vec![]
} else {
slice::from_raw_parts::<wasmer_value_t>(params, params_len as usize)

View File

@ -3,15 +3,14 @@
use crate::{
error::{update_last_error, CApiError},
export::{wasmer_exports_t, wasmer_import_export_kind, NamedExport, NamedExports},
import::{wasmer_import_object_t, wasmer_import_t},
import::wasmer_import_t,
memory::wasmer_memory_t,
module::wasmer_module_t,
value::{wasmer_value, wasmer_value_t, wasmer_value_tag},
wasmer_result_t,
};
use libc::{c_char, c_int, c_void};
use std::{collections::HashMap, ffi::CStr, slice};
use wasmer_runtime::{Ctx, Global, Instance, Memory, Module, Table, Value};
use std::{collections::HashMap, ffi::CStr, ptr, slice};
use wasmer_runtime::{Ctx, Global, Instance, Memory, Table, Value};
use wasmer_runtime_core::{
export::Export,
import::{ImportObject, Namespace},
@ -34,7 +33,9 @@ pub struct wasmer_instance_t;
/// `wasmer_instance_context_memory()` function.
///
/// It is also possible to get the instance context outside a host
/// function by using the `wasmer_instance_context_get()` function.
/// function by using the `wasmer_instance_context_get()`
/// function. See also `wasmer_instance_context_data_set()` to set the
/// instance context data.
///
/// Example:
///
@ -60,6 +61,9 @@ pub struct wasmer_instance_context_t;
/// `wasmer_last_error_length()` with `wasmer_last_error_message()` must
/// be used to read the error message.
///
/// The caller is responsible to free the instance with
/// `wasmer_instance_destroy()`.
///
/// Example:
///
/// ```c
@ -86,6 +90,9 @@ pub struct wasmer_instance_context_t;
/// wasmer_last_error_message(error, error_length);
/// // Do something with `error`…
/// }
///
/// // 5. Free the memory!
/// wasmer_instance_destroy(instance);
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
@ -171,52 +178,84 @@ pub unsafe extern "C" fn wasmer_instantiate(
wasmer_result_t::WASMER_OK
}
/// Given:
/// * A prepared `wasmer` import-object
/// * A compiled wasmer module
/// Returns the instance context. Learn more by looking at the
/// `wasmer_instance_context_t` struct.
///
/// Instantiates a wasmer instance
#[no_mangle]
pub unsafe extern "C" fn wasmer_module_import_instantiate(
instance: *mut *mut wasmer_instance_t,
module: *const wasmer_module_t,
import_object: *const wasmer_import_object_t,
) -> wasmer_result_t {
let import_object: &ImportObject = &*(import_object as *const ImportObject);
let module: &Module = &*(module as *const Module);
let new_instance: Instance = match module.instantiate(import_object) {
Ok(instance) => instance,
Err(error) => {
update_last_error(error);
return wasmer_result_t::WASMER_ERROR;
}
};
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t;
return wasmer_result_t::WASMER_OK;
}
/// Extracts the instance's context and returns it.
/// This function returns `null` if `instance` is a null pointer.
///
/// Example:
///
/// ```c
/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance);
/// my_data *data = (my_data *) wasmer_instance_context_data_get(context);
/// // Do something with `my_data`.
/// ```
///
/// It is often useful with `wasmer_instance_context_data_set()`.
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub unsafe extern "C" fn wasmer_instance_context_get(
pub extern "C" fn wasmer_instance_context_get(
instance: *mut wasmer_instance_t,
) -> *const wasmer_instance_context_t {
let instance_ref = &*(instance as *const Instance);
if instance.is_null() {
return ptr::null() as _;
}
let ctx: *const Ctx = instance_ref.context() as *const _;
let instance = unsafe { &*(instance as *const Instance) };
let context: *const Ctx = instance.context() as *const _;
ctx as *const wasmer_instance_context_t
context as *const wasmer_instance_context_t
}
/// Calls an instances exported function by `name` with the provided parameters.
/// Results are set using the provided `results` pointer.
/// Calls an exported function of a WebAssembly instance by `name`
/// with the provided parameters. The exported function results are
/// stored on the provided `results` pointer.
///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
/// This function returns `wasmer_result_t::WASMER_OK` upon success,
/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use
/// `wasmer_last_error_message()` to get the generated error message.
///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
/// Potential errors are the following:
///
/// * `instance` is a null pointer,
/// * `name` is a null pointer,
/// * `params` is a null pointer.
///
/// Example of calling an exported function that needs two parameters, and returns one value:
///
/// ```c
/// // First argument.
/// wasmer_value_t argument_one = {
/// .tag = WASM_I32,
/// .value.I32 = 3,
/// };
///
/// // Second argument.
/// wasmer_value_t argument_two = {
/// .tag = WASM_I32,
/// .value.I32 = 4,
/// };
///
/// // First result.
/// wasmer_value_t result_one;
///
/// // All arguments and results.
/// wasmer_value_t arguments[] = {argument_one, argument_two};
/// wasmer_value_t results[] = {result_one};
///
/// wasmer_result_t call_result = wasmer_instance_call(
/// instance, // instance pointer
/// "sum", // the exported function name
/// arguments, // the arguments
/// 2, // the number of arguments
/// results, // the results
/// 1 // the number of results
/// );
///
/// if (call_result == WASMER_OK) {
/// printf("Result is: %d\n", results[0].value.I32);
/// }
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub unsafe extern "C" fn wasmer_instance_call(
@ -231,18 +270,23 @@ pub unsafe extern "C" fn wasmer_instance_call(
update_last_error(CApiError {
msg: "instance ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
if name.is_null() {
update_last_error(CApiError {
msg: "name ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
if params.is_null() {
update_last_error(CApiError {
msg: "params ptr is null".to_string(),
});
return wasmer_result_t::WASMER_ERROR;
}
@ -288,17 +332,61 @@ pub unsafe extern "C" fn wasmer_instance_call(
}
}
/// Gets Exports for the given instance
/// Gets all the exports of the given WebAssembly instance.
///
/// The caller owns the object and should call `wasmer_exports_destroy` to free it.
/// This function stores a Rust vector of exports into `exports` as an
/// opaque pointer of kind `wasmer_exports_t`.
///
/// As is, you can do anything with `exports` except using the
/// companion functions, like `wasmer_exports_len()`,
/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below.
///
/// **Warning**: The caller owns the object and should call
/// `wasmer_exports_destroy()` to free it.
///
/// Example:
///
/// ```c
/// // Get the exports.
/// wasmer_exports_t *exports = NULL;
/// wasmer_instance_exports(instance, &exports);
///
/// // Get the number of exports.
/// int exports_length = wasmer_exports_len(exports);
/// printf("Number of exports: %d\n", exports_length);
///
/// // Read the first export.
/// wasmer_export_t *export = wasmer_exports_get(exports, 0);
///
/// // Get the kind of the export.
/// wasmer_import_export_kind export_kind = wasmer_export_kind(export);
///
/// // Assert it is a function (why not).
/// assert(export_kind == WASM_FUNCTION);
///
/// // Read the export name.
/// wasmer_byte_array name_bytes = wasmer_export_name(export);
///
/// assert(name_bytes.bytes_len == sizeof("sum") - 1);
/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0);
///
/// // Destroy the exports.
/// wasmer_exports_destroy(exports);
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub unsafe extern "C" fn wasmer_instance_exports(
instance: *mut wasmer_instance_t,
exports: *mut *mut wasmer_exports_t,
) {
if instance.is_null() {
return;
}
let instance_ref = &mut *(instance as *mut Instance);
let mut exports_vec: Vec<NamedExport> = Vec::with_capacity(instance_ref.exports().count());
for (name, export) in instance_ref.exports() {
exports_vec.push(NamedExport {
name: name.clone(),
@ -306,24 +394,76 @@ pub unsafe extern "C" fn wasmer_instance_exports(
instance: instance as *mut Instance,
});
}
let named_exports: Box<NamedExports> = Box::new(NamedExports(exports_vec));
*exports = Box::into_raw(named_exports) as *mut wasmer_exports_t;
}
/// Sets the `data` field of the instance context. This context will be
/// passed to all imported function for instance.
/// Sets the data that can be hold by an instance context.
///
/// An instance context (represented by the opaque
/// `wasmer_instance_context_t` structure) can hold user-defined
/// data. This function sets the data. This function is complementary
/// of `wasmer_instance_context_data_get()`.
///
/// This function does nothing if `instance` is a null pointer.
///
/// Example:
///
/// ```c
/// // Define your own data.
/// typedef struct {
/// // …
/// } my_data;
///
/// // Allocate them and set them on the given instance.
/// my_data *data = malloc(sizeof(my_data));
/// data->… = …;
/// wasmer_instance_context_data_set(instance, (void*) my_data);
///
/// // You can read your data.
/// {
/// my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance));
/// // …
/// }
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub extern "C" fn wasmer_instance_context_data_set(
instance: *mut wasmer_instance_t,
data_ptr: *mut c_void,
) {
let instance_ref = unsafe { &mut *(instance as *mut Instance) };
instance_ref.context_mut().data = data_ptr;
if instance.is_null() {
return;
}
let instance = unsafe { &mut *(instance as *mut Instance) };
instance.context_mut().data = data_ptr;
}
/// Gets the memory within the context at the index `memory_idx`.
/// The index is always 0 until multiple memories are supported.
/// Gets the `memory_idx`th memory of the instance.
///
/// Note that the index is always `0` until multiple memories are supported.
///
/// This function is mostly used inside host functions (aka imported
/// functions) to read the instance memory.
///
/// Example of a _host function_ that reads and prints a string based on a pointer and a length:
///
/// ```c
/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
/// // Get the 0th memory.
/// const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
///
/// // Get the memory data as a pointer.
/// uint8_t *memory_bytes = wasmer_memory_data(memory);
///
/// // Print what we assumed to be a string!
/// printf("%.*s", length, memory_bytes + pointer);
/// }
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub extern "C" fn wasmer_instance_context_memory(
@ -335,17 +475,45 @@ pub extern "C" fn wasmer_instance_context_memory(
memory as *const Memory as *const wasmer_memory_t
}
/// Gets the `data` field within the context.
/// Gets the data that can be hold by an instance.
///
/// This function is complementary of
/// `wasmer_instance_context_data_set()`. Please read its
/// documentation. You can also read the documentation of
/// `wasmer_instance_context_t` to get other examples.
///
/// 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 {
if ctx.is_null() {
return ptr::null_mut() as _;
}
let ctx = unsafe { &*(ctx as *const Ctx) };
ctx.data
}
/// Frees memory for the given Instance
/// Frees memory for the given `wasmer_instance_t`.
///
/// Check the `wasmer_instantiate()` function to get a complete
/// example.
///
/// If `instance` is a null pointer, this function does nothing.
///
/// Example:
///
/// ```c
/// // Get an instance.
/// wasmer_instance_t *instance = NULL;
/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
///
/// // Destroy the instance.
/// wasmer_instance_destroy(instance);
/// ```
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
pub extern "C" fn wasmer_instance_destroy(instance: *mut wasmer_instance_t) {

View File

@ -107,10 +107,15 @@ pub mod table;
pub mod trampoline;
pub mod value;
/// The `wasmer_result_t` struct is a type that represents either a
/// success, or a failure.
#[allow(non_camel_case_types)]
#[repr(C)]
pub enum wasmer_result_t {
/// Represents a success.
WASMER_OK = 1,
/// Represents a failure.
WASMER_ERROR = 2,
}

View File

@ -3,13 +3,15 @@
use crate::{
error::{update_last_error, CApiError},
export::wasmer_import_export_kind,
import::wasmer_import_t,
import::{wasmer_import_object_t, wasmer_import_t},
instance::wasmer_instance_t,
wasmer_byte_array, wasmer_result_t,
};
use libc::c_int;
use std::{collections::HashMap, slice};
use wasmer_runtime::{compile, default_compiler, Global, ImportObject, Memory, Module, Table};
use wasmer_runtime::{
compile, default_compiler, Global, ImportObject, Instance, Memory, Module, Table,
};
use wasmer_runtime_core::{cache::Artifact, export::Export, import::Namespace, load_cache_with};
#[repr(C)]
@ -151,6 +153,32 @@ pub unsafe extern "C" fn wasmer_module_instantiate(
wasmer_result_t::WASMER_OK
}
/// Given:
/// * A prepared `wasmer` import-object
/// * A compiled wasmer module
///
/// Instantiates a wasmer instance
#[no_mangle]
pub unsafe extern "C" fn wasmer_module_import_instantiate(
instance: *mut *mut wasmer_instance_t,
module: *const wasmer_module_t,
import_object: *const wasmer_import_object_t,
) -> wasmer_result_t {
let import_object: &ImportObject = &*(import_object as *const ImportObject);
let module: &Module = &*(module as *const Module);
let new_instance: Instance = match module.instantiate(import_object) {
Ok(instance) => instance,
Err(error) => {
update_last_error(error);
return wasmer_result_t::WASMER_ERROR;
}
};
*instance = Box::into_raw(Box::new(new_instance)) as *mut wasmer_instance_t;
return wasmer_result_t::WASMER_OK;
}
/// Serialize the given Module.
///
/// The caller owns the object and should call `wasmer_serialized_module_destroy` to free it.

View File

@ -21,12 +21,14 @@ int main()
printf("Compile result: %d\n", compile_result);
assert(compile_result == WASMER_OK);
wasmer_value_t param_one;
param_one.tag = WASM_I32;
param_one.value.I32 = 7;
wasmer_value_t param_two;
param_two.tag = WASM_I32;
param_two.value.I32 = 8;
wasmer_value_t param_one = {
.tag = WASM_I32,
.value.I32 = 7,
};
wasmer_value_t param_two = {
.tag = WASM_I32,
.value.I32 = 8,
};
wasmer_value_t params[] = {param_one, param_two};
wasmer_value_t result_one;

View File

@ -66,15 +66,37 @@ typedef uint8_t Version;
* List of export/import kinds.
*/
enum wasmer_import_export_kind {
/**
* The export/import is a function.
*/
WASM_FUNCTION = 0,
/**
* The export/import is a global.
*/
WASM_GLOBAL = 1,
/**
* The export/import is a memory.
*/
WASM_MEMORY = 2,
/**
* The export/import is a table.
*/
WASM_TABLE = 3,
};
typedef uint32_t wasmer_import_export_kind;
/**
* The `wasmer_result_t` struct is a type that represents either a
* success, or a failure.
*/
typedef enum {
/**
* Represents a success.
*/
WASMER_OK = 1,
/**
* Represents a failure.
*/
WASMER_ERROR = 2,
} wasmer_result_t;
@ -164,7 +186,11 @@ typedef struct {
} wasmer_memory_t;
/**
* Opaque pointer to `NamedExports`.
* Opaque pointer to the opaque structure `crate::NamedExports`,
* which is a wrapper around a vector of the opaque structure
* `crate::NamedExport`.
*
* Check the `wasmer_instance_exports()` function to learn more.
*/
typedef struct {
@ -226,7 +252,9 @@ typedef struct {
* `wasmer_instance_context_memory()` function.
*
* It is also possible to get the instance context outside a host
* function by using the `wasmer_instance_context_get()` function.
* function by using the `wasmer_instance_context_get()`
* function. See also `wasmer_instance_context_data_set()` to set the
* instance context data.
*
* Example:
*
@ -484,7 +512,23 @@ const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_
wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory);
/**
* Frees the memory for the given exports
* Frees the memory for the given exports.
*
* Check the `wasmer_instance_exports()` function to get a complete
* example.
*
* If `exports` is a null pointer, this function does nothing.
*
* Example:
*
* ```c
* // Get some exports.
* wasmer_exports_t *exports = NULL;
* wasmer_instance_exports(instance, &exports);
*
* // Destroy the exports.
* wasmer_exports_destroy(exports);
* ```
*/
void wasmer_exports_destroy(wasmer_exports_t *exports);
@ -708,13 +752,55 @@ wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer
wasmer_import_object_t *wasmer_import_object_new(void);
/**
* Calls an instances exported function by `name` with the provided parameters.
* Results are set using the provided `results` pointer.
* Calls an exported function of a WebAssembly instance by `name`
* with the provided parameters. The exported function results are
* stored on the provided `results` pointer.
*
* Returns `wasmer_result_t::WASMER_OK` upon success.
* This function returns `wasmer_result_t::WASMER_OK` upon success,
* `wasmer_result_t::WASMER_ERROR` otherwise. You can use
* `wasmer_last_error_message()` to get the generated error message.
*
* Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
* and `wasmer_last_error_message` to get an error message.
* Potential errors are the following:
*
* * `instance` is a null pointer,
* * `name` is a null pointer,
* * `params` is a null pointer.
*
* Example of calling an exported function that needs two parameters, and returns one value:
*
* ```c
* // First argument.
* wasmer_value_t argument_one = {
* .tag = WASM_I32,
* .value.I32 = 3,
* };
*
* // Second argument.
* wasmer_value_t argument_two = {
* .tag = WASM_I32,
* .value.I32 = 4,
* };
*
* // First result.
* wasmer_value_t result_one;
*
* // All arguments and results.
* wasmer_value_t arguments[] = {argument_one, argument_two};
* wasmer_value_t results[] = {result_one};
*
* wasmer_result_t call_result = wasmer_instance_call(
* instance, // instance pointer
* "sum", // the exported function name
* arguments, // the arguments
* 2, // the number of arguments
* results, // the results
* 1 // the number of results
* );
*
* if (call_result == WASMER_OK) {
* printf("Result is: %d\n", results[0].value.I32);
* }
* ```
*/
wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
const char *name,
@ -724,37 +810,157 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
uint32_t results_len);
/**
* Gets the `data` field within the context.
* Gets the data that can be hold by an instance.
*
* This function is complementary of
* `wasmer_instance_context_data_set()`. Please read its
* documentation. You can also read the documentation of
* `wasmer_instance_context_t` to get other examples.
*
* This function returns nothing if `ctx` is a null pointer.
*/
void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
/**
* Sets the `data` field of the instance context. This context will be
* passed to all imported function for instance.
* Sets the data that can be hold by an instance context.
*
* An instance context (represented by the opaque
* `wasmer_instance_context_t` structure) can hold user-defined
* data. This function sets the data. This function is complementary
* of `wasmer_instance_context_data_get()`.
*
* This function does nothing if `instance` is a null pointer.
*
* Example:
*
* ```c
* // Define your own data.
* typedef struct {
* // …
* } my_data;
*
* // Allocate them and set them on the given instance.
* my_data *data = malloc(sizeof(my_data));
* data->… = …;
* wasmer_instance_context_data_set(instance, (void*) my_data);
*
* // You can read your data.
* {
* my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance));
* // …
* }
* ```
*/
void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr);
void wasmer_instance_context_data_set(wasmer_instance_t *instance,
void *data_ptr);
/**
* Extracts the instance's context and returns it.
* Returns the instance context. Learn more by looking at the
* `wasmer_instance_context_t` struct.
*
* This function returns `null` if `instance` is a null pointer.
*
* Example:
*
* ```c
* const wasmer_instance_context_get *context = wasmer_instance_context_get(instance);
* my_data *data = (my_data *) wasmer_instance_context_data_get(context);
* // Do something with `my_data`.
* ```
*
* It is often useful with `wasmer_instance_context_data_set()`.
*/
const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
/**
* Gets the memory within the context at the index `memory_idx`.
* The index is always 0 until multiple memories are supported.
* Gets the `memory_idx`th memory of the instance.
*
* Note that the index is always `0` until multiple memories are supported.
*
* This function is mostly used inside host functions (aka imported
* functions) to read the instance memory.
*
* Example of a _host function_ that reads and prints a string based on a pointer and a length:
*
* ```c
* void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
* // Get the 0th memory.
* const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
*
* // Get the memory data as a pointer.
* uint8_t *memory_bytes = wasmer_memory_data(memory);
*
* // Print what we assumed to be a string!
* printf("%.*s", length, memory_bytes + pointer);
* }
* ```
*/
const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
uint32_t _memory_idx);
/**
* Frees memory for the given Instance
* Frees memory for the given `wasmer_instance_t`.
*
* Check the `wasmer_instantiate()` function to get a complete
* example.
*
* If `instance` is a null pointer, this function does nothing.
*
* Example:
*
* ```c
* // Get an instance.
* wasmer_instance_t *instance = NULL;
* wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
*
* // Destroy the instance.
* wasmer_instance_destroy(instance);
* ```
*/
void wasmer_instance_destroy(wasmer_instance_t *instance);
/**
* Gets Exports for the given instance
* Gets all the exports of the given WebAssembly instance.
*
* The caller owns the object and should call `wasmer_exports_destroy` to free it.
* This function stores a Rust vector of exports into `exports` as an
* opaque pointer of kind `wasmer_exports_t`.
*
* As is, you can do anything with `exports` except using the
* companion functions, like `wasmer_exports_len()`,
* `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below.
*
* **Warning**: The caller owns the object and should call
* `wasmer_exports_destroy()` to free it.
*
* Example:
*
* ```c
* // Get the exports.
* wasmer_exports_t *exports = NULL;
* wasmer_instance_exports(instance, &exports);
*
* // Get the number of exports.
* int exports_length = wasmer_exports_len(exports);
* printf("Number of exports: %d\n", exports_length);
*
* // Read the first export.
* wasmer_export_t *export = wasmer_exports_get(exports, 0);
*
* // Get the kind of the export.
* wasmer_import_export_kind export_kind = wasmer_export_kind(export);
*
* // Assert it is a function (why not).
* assert(export_kind == WASM_FUNCTION);
*
* // Read the export name.
* wasmer_byte_array name_bytes = wasmer_export_name(export);
*
* assert(name_bytes.bytes_len == sizeof("sum") - 1);
* assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0);
*
* // Destroy the exports.
* wasmer_exports_destroy(exports);
* ```
*/
void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
@ -768,6 +974,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
* `wasmer_last_error_length()` with `wasmer_last_error_message()` must
* be used to read the error message.
*
* The caller is responsible to free the instance with
* `wasmer_instance_destroy()`.
*
* Example:
*
* ```c
@ -794,6 +1003,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
* wasmer_last_error_message(error, error_length);
* // Do something with `error`…
* }
*
* // 5. Free the memory!
* wasmer_instance_destroy(instance);
* ```
*/
wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
@ -803,33 +1015,43 @@ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
int imports_len);
/**
* Gets the length in bytes of the last error.
* Gets the length in bytes of the last error if any.
*
* This can be used to dynamically allocate a buffer with the correct number of
* bytes needed to store a message.
*
* # Example
*
* ```c
* int error_len = wasmer_last_error_length();
* char *error_str = malloc(error_len);
* ```
* See `wasmer_last_error_message()` to get a full example.
*/
int wasmer_last_error_length(void);
/**
* Stores the last error message into the provided buffer up to the given `length`.
* The `length` parameter must be large enough to store the last error message.
* Gets the last error message if any into the provided buffer
* `buffer` up to the given `length`.
*
* Returns the length of the string in bytes.
* Returns `-1` if an error occurs.
* The `length` parameter must be large enough to store the last
* error message. Ideally, the value should come from
* `wasmer_last_error_length()`.
*
* # Example
* The function returns the length of the string in bytes, `-1` if an
* error occurs. Potential errors are:
*
* * The buffer is a null pointer,
* * The buffer is too smal to hold the error message.
*
* Note: The error message always has a trailing null character.
*
* Example:
*
* ```c
* int error_len = wasmer_last_error_length();
* char *error_str = malloc(error_len);
* wasmer_last_error_message(error_str, error_len);
* printf("Error str: `%s`\n", error_str);
* int error_length = wasmer_last_error_length();
*
* if (error_length > 0) {
* char *error_message = malloc(error_length);
* wasmer_last_error_message(error_message, error_length);
* printf("Error message: `%s`\n", error_message);
* } else {
* printf("No error message\n");
* }
* ```
*/
int wasmer_last_error_message(char *buffer, int length);

View File

@ -55,14 +55,22 @@ enum class Version : uint8_t {
/// List of export/import kinds.
enum class wasmer_import_export_kind : uint32_t {
/// The export/import is a function.
WASM_FUNCTION = 0,
/// The export/import is a global.
WASM_GLOBAL = 1,
/// The export/import is a memory.
WASM_MEMORY = 2,
/// The export/import is a table.
WASM_TABLE = 3,
};
/// The `wasmer_result_t` struct is a type that represents either a
/// success, or a failure.
enum class wasmer_result_t {
/// Represents a success.
WASMER_OK = 1,
/// Represents a failure.
WASMER_ERROR = 2,
};
@ -138,7 +146,11 @@ struct wasmer_memory_t {
};
/// Opaque pointer to `NamedExports`.
/// Opaque pointer to the opaque structure `crate::NamedExports`,
/// which is a wrapper around a vector of the opaque structure
/// `crate::NamedExport`.
///
/// Check the `wasmer_instance_exports()` function to learn more.
struct wasmer_exports_t {
};
@ -196,7 +208,9 @@ struct wasmer_import_object_iter_t {
/// `wasmer_instance_context_memory()` function.
///
/// It is also possible to get the instance context outside a host
/// function by using the `wasmer_instance_context_get()` function.
/// function by using the `wasmer_instance_context_get()`
/// function. See also `wasmer_instance_context_data_set()` to set the
/// instance context data.
///
/// Example:
///
@ -406,7 +420,23 @@ const wasmer_export_func_t *wasmer_export_to_func(const wasmer_export_t *export_
/// and `wasmer_last_error_message` to get an error message.
wasmer_result_t wasmer_export_to_memory(const wasmer_export_t *export_, wasmer_memory_t **memory);
/// Frees the memory for the given exports
/// Frees the memory for the given exports.
///
/// Check the `wasmer_instance_exports()` function to get a complete
/// example.
///
/// If `exports` is a null pointer, this function does nothing.
///
/// Example:
///
/// ```c
/// // Get some exports.
/// wasmer_exports_t *exports = NULL;
/// wasmer_instance_exports(instance, &exports);
///
/// // Destroy the exports.
/// wasmer_exports_destroy(exports);
/// ```
void wasmer_exports_destroy(wasmer_exports_t *exports);
/// Gets wasmer_export by index
@ -570,13 +600,55 @@ wasmer_import_object_iter_t *wasmer_import_object_iterate_functions(const wasmer
/// See also `wasmer_import_object_append`
wasmer_import_object_t *wasmer_import_object_new();
/// Calls an instances exported function by `name` with the provided parameters.
/// Results are set using the provided `results` pointer.
/// Calls an exported function of a WebAssembly instance by `name`
/// with the provided parameters. The exported function results are
/// stored on the provided `results` pointer.
///
/// Returns `wasmer_result_t::WASMER_OK` upon success.
/// This function returns `wasmer_result_t::WASMER_OK` upon success,
/// `wasmer_result_t::WASMER_ERROR` otherwise. You can use
/// `wasmer_last_error_message()` to get the generated error message.
///
/// Returns `wasmer_result_t::WASMER_ERROR` upon failure. Use `wasmer_last_error_length`
/// and `wasmer_last_error_message` to get an error message.
/// Potential errors are the following:
///
/// * `instance` is a null pointer,
/// * `name` is a null pointer,
/// * `params` is a null pointer.
///
/// Example of calling an exported function that needs two parameters, and returns one value:
///
/// ```c
/// // First argument.
/// wasmer_value_t argument_one = {
/// .tag = WASM_I32,
/// .value.I32 = 3,
/// };
///
/// // Second argument.
/// wasmer_value_t argument_two = {
/// .tag = WASM_I32,
/// .value.I32 = 4,
/// };
///
/// // First result.
/// wasmer_value_t result_one;
///
/// // All arguments and results.
/// wasmer_value_t arguments[] = {argument_one, argument_two};
/// wasmer_value_t results[] = {result_one};
///
/// wasmer_result_t call_result = wasmer_instance_call(
/// instance, // instance pointer
/// "sum", // the exported function name
/// arguments, // the arguments
/// 2, // the number of arguments
/// results, // the results
/// 1 // the number of results
/// );
///
/// if (call_result == WASMER_OK) {
/// printf("Result is: %d\n", results[0].value.I32);
/// }
/// ```
wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
const char *name,
const wasmer_value_t *params,
@ -584,27 +656,147 @@ wasmer_result_t wasmer_instance_call(wasmer_instance_t *instance,
wasmer_value_t *results,
uint32_t results_len);
/// Gets the `data` field within the context.
/// Gets the data that can be hold by an instance.
///
/// This function is complementary of
/// `wasmer_instance_context_data_set()`. Please read its
/// documentation. You can also read the documentation of
/// `wasmer_instance_context_t` to get other examples.
///
/// This function returns nothing if `ctx` is a null pointer.
void *wasmer_instance_context_data_get(const wasmer_instance_context_t *ctx);
/// Sets the `data` field of the instance context. This context will be
/// passed to all imported function for instance.
void wasmer_instance_context_data_set(wasmer_instance_t *instance, void *data_ptr);
/// Sets the data that can be hold by an instance context.
///
/// An instance context (represented by the opaque
/// `wasmer_instance_context_t` structure) can hold user-defined
/// data. This function sets the data. This function is complementary
/// of `wasmer_instance_context_data_get()`.
///
/// This function does nothing if `instance` is a null pointer.
///
/// Example:
///
/// ```c
/// // Define your own data.
/// typedef struct {
/// // …
/// } my_data;
///
/// // Allocate them and set them on the given instance.
/// my_data *data = malloc(sizeof(my_data));
/// data->… = …;
/// wasmer_instance_context_data_set(instance, (void*) my_data);
///
/// // You can read your data.
/// {
/// my_data *data = (my_data*) wasmer_instance_context_data_get(wasmer_instance_context_get(instance));
/// // …
/// }
/// ```
void wasmer_instance_context_data_set(wasmer_instance_t *instance,
void *data_ptr);
/// Extracts the instance's context and returns it.
/// Returns the instance context. Learn more by looking at the
/// `wasmer_instance_context_t` struct.
///
/// This function returns `null` if `instance` is a null pointer.
///
/// Example:
///
/// ```c
/// const wasmer_instance_context_get *context = wasmer_instance_context_get(instance);
/// my_data *data = (my_data *) wasmer_instance_context_data_get(context);
/// // Do something with `my_data`.
/// ```
///
/// It is often useful with `wasmer_instance_context_data_set()`.
const wasmer_instance_context_t *wasmer_instance_context_get(wasmer_instance_t *instance);
/// Gets the memory within the context at the index `memory_idx`.
/// The index is always 0 until multiple memories are supported.
/// Gets the `memory_idx`th memory of the instance.
///
/// Note that the index is always `0` until multiple memories are supported.
///
/// This function is mostly used inside host functions (aka imported
/// functions) to read the instance memory.
///
/// Example of a _host function_ that reads and prints a string based on a pointer and a length:
///
/// ```c
/// void print_string(const wasmer_instance_context_t *context, int32_t pointer, int32_t length) {
/// // Get the 0th memory.
/// const wasmer_memory_t *memory = wasmer_instance_context_memory(context, 0);
///
/// // Get the memory data as a pointer.
/// uint8_t *memory_bytes = wasmer_memory_data(memory);
///
/// // Print what we assumed to be a string!
/// printf("%.*s", length, memory_bytes + pointer);
/// }
/// ```
const wasmer_memory_t *wasmer_instance_context_memory(const wasmer_instance_context_t *ctx,
uint32_t _memory_idx);
/// Frees memory for the given Instance
/// Frees memory for the given `wasmer_instance_t`.
///
/// Check the `wasmer_instantiate()` function to get a complete
/// example.
///
/// If `instance` is a null pointer, this function does nothing.
///
/// Example:
///
/// ```c
/// // Get an instance.
/// wasmer_instance_t *instance = NULL;
/// wasmer_instantiate(&instance, bytes, bytes_length, imports, 0);
///
/// // Destroy the instance.
/// wasmer_instance_destroy(instance);
/// ```
void wasmer_instance_destroy(wasmer_instance_t *instance);
/// Gets Exports for the given instance
/// Gets all the exports of the given WebAssembly instance.
///
/// The caller owns the object and should call `wasmer_exports_destroy` to free it.
/// This function stores a Rust vector of exports into `exports` as an
/// opaque pointer of kind `wasmer_exports_t`.
///
/// As is, you can do anything with `exports` except using the
/// companion functions, like `wasmer_exports_len()`,
/// `wasmer_exports_get()` or `wasmer_export_kind()`. See the example below.
///
/// **Warning**: The caller owns the object and should call
/// `wasmer_exports_destroy()` to free it.
///
/// Example:
///
/// ```c
/// // Get the exports.
/// wasmer_exports_t *exports = NULL;
/// wasmer_instance_exports(instance, &exports);
///
/// // Get the number of exports.
/// int exports_length = wasmer_exports_len(exports);
/// printf("Number of exports: %d\n", exports_length);
///
/// // Read the first export.
/// wasmer_export_t *export = wasmer_exports_get(exports, 0);
///
/// // Get the kind of the export.
/// wasmer_import_export_kind export_kind = wasmer_export_kind(export);
///
/// // Assert it is a function (why not).
/// assert(export_kind == WASM_FUNCTION);
///
/// // Read the export name.
/// wasmer_byte_array name_bytes = wasmer_export_name(export);
///
/// assert(name_bytes.bytes_len == sizeof("sum") - 1);
/// assert(memcmp(name_bytes.bytes, "sum", sizeof("sum") - 1) == 0);
///
/// // Destroy the exports.
/// wasmer_exports_destroy(exports);
/// ```
void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exports);
/// Creates a new WebAssembly instance from the given bytes and imports.
@ -616,6 +808,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
/// `wasmer_last_error_length()` with `wasmer_last_error_message()` must
/// be used to read the error message.
///
/// The caller is responsible to free the instance with
/// `wasmer_instance_destroy()`.
///
/// Example:
///
/// ```c
@ -642,6 +837,9 @@ void wasmer_instance_exports(wasmer_instance_t *instance, wasmer_exports_t **exp
/// wasmer_last_error_message(error, error_length);
/// // Do something with `error`…
/// }
///
/// // 5. Free the memory!
/// wasmer_instance_destroy(instance);
/// ```
wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
uint8_t *wasm_bytes,
@ -649,31 +847,41 @@ wasmer_result_t wasmer_instantiate(wasmer_instance_t **instance,
wasmer_import_t *imports,
int imports_len);
/// Gets the length in bytes of the last error.
/// Gets the length in bytes of the last error if any.
///
/// This can be used to dynamically allocate a buffer with the correct number of
/// bytes needed to store a message.
///
/// # Example
///
/// ```c
/// int error_len = wasmer_last_error_length();
/// char *error_str = malloc(error_len);
/// ```
/// See `wasmer_last_error_message()` to get a full example.
int wasmer_last_error_length();
/// Stores the last error message into the provided buffer up to the given `length`.
/// The `length` parameter must be large enough to store the last error message.
/// Gets the last error message if any into the provided buffer
/// `buffer` up to the given `length`.
///
/// Returns the length of the string in bytes.
/// Returns `-1` if an error occurs.
/// The `length` parameter must be large enough to store the last
/// error message. Ideally, the value should come from
/// `wasmer_last_error_length()`.
///
/// # Example
/// The function returns the length of the string in bytes, `-1` if an
/// error occurs. Potential errors are:
///
/// * The buffer is a null pointer,
/// * The buffer is too smal to hold the error message.
///
/// Note: The error message always has a trailing null character.
///
/// Example:
///
/// ```c
/// int error_len = wasmer_last_error_length();
/// char *error_str = malloc(error_len);
/// wasmer_last_error_message(error_str, error_len);
/// printf("Error str: `%s`\n", error_str);
/// int error_length = wasmer_last_error_length();
///
/// if (error_length > 0) {
/// char *error_message = malloc(error_length);
/// wasmer_last_error_message(error_message, error_length);
/// printf("Error message: `%s`\n", error_message);
/// } else {
/// printf("No error message\n");
/// }
/// ```
int wasmer_last_error_message(char *buffer, int length);

View File

@ -13,11 +13,11 @@ edition = "2018"
nix = "0.15"
page_size = "0.4"
wasmparser = "0.45.0"
parking_lot = "0.9"
parking_lot = "0.10.0"
lazy_static = "1.4"
errno = "0.2"
libc = "0.2.60"
hex = "0.3"
hex = "0.4"
smallvec = "0.6"
bincode = "1.1"
@ -36,8 +36,8 @@ version = "1.0"
version = "0.11"
[dependencies.serde-bench]
version = "0.0.7"
[dependencies.blake2b_simd]
version = "0.5"
[dependencies.blake3]
version = "0.1.0"
[dependencies.digest]
version = "0.8"
@ -45,7 +45,7 @@ version = "0.8"
winapi = { version = "0.3", features = ["memoryapi"] }
[build-dependencies]
blake2b_simd = "0.5"
blake3 = "0.1.0"
rustc_version = "0.2"
cc = "1.0"

View File

@ -1,13 +1,12 @@
use blake2b_simd::blake2bp;
use std::{env, fs, io::Write, path::PathBuf};
const WASMER_VERSION: &'static str = env!("CARGO_PKG_VERSION");
fn main() {
let mut state = blake2bp::State::new();
state.update(WASMER_VERSION.as_bytes());
let mut hasher = blake3::Hasher::new();
hasher.update(WASMER_VERSION.as_bytes());
let hasher = state.finalize();
let hasher = hasher.finalize();
let hash_string = hasher.to_hex().as_str().to_owned();
let crate_dir = env::var("OUT_DIR").unwrap();

View File

@ -76,9 +76,18 @@ impl Default for MemoryBoundCheckMode {
}
/// Controls which experimental features will be enabled.
/// Features usually have a corresponding [WebAssembly proposal][wasm-props].
///
/// [wasm-props]: https://github.com/WebAssembly/proposals
#[derive(Debug, Default)]
pub struct Features {
/// Whether support for the [SIMD proposal][simd-prop] is enabled.
///
/// [simd-prop]: https://github.com/webassembly/simd
pub simd: bool,
/// Whether support for the [threads proposal][threads-prop] is enabled.
///
/// [threads-prop]: https://github.com/webassembly/threads
pub threads: bool,
}
@ -113,6 +122,32 @@ pub struct CompilerConfig {
pub backend_specific_config: Option<BackendCompilerConfig>,
}
/// An exception table for a `RunnableModule`.
#[derive(Clone, Debug, Default, Serialize, Deserialize)]
pub struct ExceptionTable {
/// Mappings from offsets in generated machine code to the corresponding exception code.
pub offset_to_code: HashMap<usize, ExceptionCode>,
}
impl ExceptionTable {
pub fn new() -> Self {
Self::default()
}
}
/// The code of an exception.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
pub enum ExceptionCode {
/// An `unreachable` opcode was executed.
Unreachable,
/// An arithmetic exception, e.g. divided by zero.
Arithmetic,
/// Memory access exception, e.g. misaligned/out-of-bound read/write.
Memory,
}
pub trait Compiler {
/// Compiles a `Module` from WebAssembly binary format.
/// The `CompileToken` parameter ensures that this can only
@ -144,6 +179,10 @@ pub trait RunnableModule: Send + Sync {
None
}
fn get_exception_table(&self) -> Option<&ExceptionTable> {
None
}
unsafe fn patch_local_function(&self, _idx: usize, _target_address: usize) -> bool {
false
}

View File

@ -3,7 +3,6 @@
//! and loaded to allow skipping compilation and fast startup.
use crate::{module::ModuleInfo, sys::Memory};
use blake2b_simd::blake2bp;
use std::{io, mem, slice};
/// Indicates the invalid type of invalid cache file
@ -46,10 +45,8 @@ impl From<io::Error> for Error {
///
/// [`Cache`]: trait.Cache.html
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
// WasmHash is made up of two 32 byte arrays instead of a 64 byte array
// because derive only works on fixed sized arrays size 32 or below
// TODO: fix this when this gets fixed by improved const generics
pub struct WasmHash([u8; 32], [u8; 32]);
// WasmHash is made up of a 32 byte array
pub struct WasmHash([u8; 32]);
impl WasmHash {
/// Hash a wasm module.
@ -58,18 +55,8 @@ impl WasmHash {
/// This does no verification that the supplied data
/// is, in fact, a wasm module.
pub fn generate(wasm: &[u8]) -> Self {
let mut first_part = [0u8; 32];
let mut second_part = [0u8; 32];
let mut state = blake2bp::State::new();
state.update(wasm);
let hasher = state.finalize();
let generic_array = hasher.as_bytes();
first_part.copy_from_slice(&generic_array[0..32]);
second_part.copy_from_slice(&generic_array[32..64]);
WasmHash(first_part, second_part)
let hash = blake3::hash(wasm);
WasmHash(hash.into())
}
/// Create the hexadecimal representation of the
@ -86,26 +73,20 @@ impl WasmHash {
e
))
})?;
if bytes.len() != 64 {
if bytes.len() != 32 {
return Err(Error::DeserializeError(
"Prehashed keys must deserialze into exactly 64 bytes".to_string(),
"Prehashed keys must deserialze into exactly 32 bytes".to_string(),
));
}
use std::convert::TryInto;
Ok(WasmHash(
bytes[0..32].try_into().map_err(|e| {
Error::DeserializeError(format!("Could not get first 32 bytes: {}", e))
})?,
bytes[32..64].try_into().map_err(|e| {
Error::DeserializeError(format!("Could not get last 32 bytes: {}", e))
})?,
))
Ok(WasmHash(bytes[0..32].try_into().map_err(|e| {
Error::DeserializeError(format!("Could not get first 32 bytes: {}", e))
})?))
}
pub(crate) fn into_array(self) -> [u8; 64] {
let mut total = [0u8; 64];
pub(crate) fn into_array(self) -> [u8; 32] {
let mut total = [0u8; 32];
total[0..32].copy_from_slice(&self.0);
total[32..64].copy_from_slice(&self.1);
total
}
}

View File

@ -1,5 +1,6 @@
//! The error module contains the data structures and helper functions used to implement errors that
//! are produced and returned from the wasmer runtime core.
use crate::backend::ExceptionCode;
use crate::types::{FuncSig, GlobalDescriptor, MemoryDescriptor, TableDescriptor, Type};
use core::borrow::Borrow;
use std::any::Any;
@ -208,6 +209,8 @@ impl std::fmt::Display for RuntimeError {
write!(f, "\"{}\"", s)
} else if let Some(s) = data.downcast_ref::<&str>() {
write!(f, "\"{}\"", s)
} else if let Some(exc_code) = data.downcast_ref::<ExceptionCode>() {
write!(f, "Caught exception of type \"{:?}\".", exc_code)
} else {
write!(f, "unknown error")
}

View File

@ -375,15 +375,23 @@ extern "C" fn signal_trap_handler(
_ => {}
}
// Now we have looked up all possible handler tables but failed to find a handler
// for this exception that allows a normal return.
//
// So here we check whether this exception is caused by a suspend signal, return the
// state image if so, or throw the exception out otherwise.
let ctx: &mut vm::Ctx = &mut **CURRENT_CTX.with(|x| x.get());
let es_image = fault
.read_stack(None)
.expect("fault.read_stack() failed. Broken invariants?");
if is_suspend_signal {
// If this is a suspend signal, we parse the runtime state and return the resulting image.
let image = build_instance_image(ctx, es_image);
unwind_result = Box::new(image);
} else {
// Otherwise, this is a real exception and we just throw it to the caller.
if es_image.frames.len() > 0 {
eprintln!(
"\n{}",
@ -391,7 +399,26 @@ extern "C" fn signal_trap_handler(
);
es_image.print_backtrace_if_needed();
}
// Just let the error propagate otherwise
// Look up the exception tables and try to find an exception code.
let exc_code = CURRENT_CODE_VERSIONS.with(|versions| {
let versions = versions.borrow();
for v in versions.iter() {
if let Some(table) = v.runnable_module.get_exception_table() {
let ip = fault.ip.get();
let end = v.base + v.msm.total_size;
if ip >= v.base && ip < end {
if let Some(exc_code) = table.offset_to_code.get(&(ip - v.base)) {
return Some(*exc_code);
}
}
}
}
None
});
if let Some(code) = exc_code {
unwind_result = Box::new(code);
}
}
true

View File

@ -173,7 +173,7 @@ pub fn validate_and_report_errors_with_features(
}
}
/// Creates a new module from the given cache `Artifact` for the specified compiler backend
/// Creates a new module from the given cache [`Artifact`] for the specified compiler backend
pub unsafe fn load_cache_with(
cache: Artifact,
compiler: &dyn backend::Compiler,

View File

@ -627,9 +627,11 @@ pub mod x64 {
use crate::vm::Ctx;
use std::any::Any;
#[allow(clippy::cast_ptr_alignment)]
unsafe fn compute_vmctx_deref(vmctx: *const Ctx, seq: &[usize]) -> u64 {
let mut ptr = &vmctx as *const *const Ctx as *const u8;
for x in seq {
debug_assert!(ptr.align_offset(std::mem::align_of::<*const u8>()) == 0);
ptr = (*(ptr as *const *const u8)).offset(*x as isize);
}
ptr as usize as u64

View File

@ -1,85 +0,0 @@
#[derive(Debug, Clone)]
enum MonoVecInner<T> {
None,
Inline(T),
Heap(Vec<T>),
}
/// A type that can hold zero items,
/// one item, or many items.
#[derive(Debug, Clone)]
pub struct MonoVec<T> {
inner: MonoVecInner<T>,
}
impl<T> MonoVec<T> {
pub fn new() -> Self {
Self {
inner: MonoVecInner::None,
}
}
pub fn new_inline(item: T) -> Self {
Self {
inner: MonoVecInner::Inline(item),
}
}
pub fn with_capacity(capacity: usize) -> Self {
match capacity {
0 | 1 => Self::new(),
_ => Self {
inner: MonoVecInner::Heap(Vec::with_capacity(capacity)),
},
}
}
pub fn push(&mut self, item: T) {
let uninit = MonoVecInner::None;
let prev = mem::replace(&mut self.inner, uninit);
let next = match prev {
MonoVecInner::None => MonoVecInner::Inline(item),
MonoVecInner::Inline(previous_item) => MonoVecInner::Heap(vec![previous_item, item]),
MonoVecInner::Heap(mut v) => {
v.push(item);
MonoVecInner::Heap(v)
}
};
let uninit = mem::replace(&mut self.inner, next);
mem::forget(uninit);
}
pub fn pop(&mut self) -> Option<T> {
match self.inner {
MonoVecInner::None => None,
MonoVecInner::Inline(ref mut item) => {
let uninit = unsafe { mem::zeroed() };
let item = mem::replace(item, uninit);
let uninit = mem::replace(&mut self.inner, MonoVecInner::None);
mem::forget(uninit);
Some(item)
}
MonoVecInner::Heap(ref mut v) => v.pop(),
}
}
pub fn as_slice(&self) -> &[T] {
match self.inner {
MonoVecInner::None => unsafe {
slice::from_raw_parts(mem::align_of::<T>() as *const T, 0)
},
MonoVecInner::Inline(ref item) => slice::from_ref(item),
MonoVecInner::Heap(ref v) => &v[..],
}
}
pub fn as_slice_mut(&mut self) -> &mut [T] {
match self.inner {
MonoVecInner::None => unsafe {
slice::from_raw_parts_mut(mem::align_of::<T>() as *mut T, 0)
},
MonoVecInner::Inline(ref mut item) => slice::from_mut(item),
MonoVecInner::Heap(ref mut v) => &mut v[..],
}
}
}

View File

@ -54,11 +54,14 @@ pub struct Ctx {
/// This is intended to be user-supplied, per-instance
/// contextual data. There are currently some issue with it,
/// notably that it cannot be set before running the `start`
/// function in a WebAssembly module.
/// function in a WebAssembly module. Additionally, the `data`
/// field may be taken by another ABI implementation that the user
/// wishes to use in addition to their own, such as WASI. This issue is
/// being discussed at [#1111](https://github.com/wasmerio/wasmer/pull/1111).
///
/// [#219](https://github.com/wasmerio/wasmer/pull/219) fixes that
/// issue, as well as allowing the user to have *per-function*
/// context, instead of just per-instance.
/// Alternatively, per-function data can be used if the function in the
/// [`ImportObject`] is a closure. This cannot duplicate data though,
/// so if data may be shared if the [`ImportObject`] is reused.
pub data: *mut c_void,
/// If there's a function set in this field, it gets called
@ -567,6 +570,7 @@ pub struct FuncCtx {
impl FuncCtx {
/// Offset to the `vmctx` field.
#[allow(clippy::erasing_op)]
pub const fn offset_vmctx() -> u8 {
0 * (mem::size_of::<usize>() as u8)
}

View File

@ -94,7 +94,7 @@
#[macro_use]
extern crate serde_derive;
pub use wasmer_runtime_core::backend::Features;
pub use wasmer_runtime_core::backend::{ExceptionCode, Features};
pub use wasmer_runtime_core::codegen::{MiddlewareChain, StreamingCompiler};
pub use wasmer_runtime_core::export::Export;
pub use wasmer_runtime_core::global::Global;
@ -111,6 +111,12 @@ pub use wasmer_runtime_core::Func;
pub use wasmer_runtime_core::{compile_with, validate};
pub use wasmer_runtime_core::{func, imports};
#[cfg(unix)]
pub use wasmer_runtime_core::{
fault::{pop_code_version, push_code_version},
state::CodeVersion,
};
pub mod memory {
//! The memory module contains the implementation data structures and helper functions used to
//! manipulate and access wasm memory.

File diff suppressed because it is too large Load Diff

View File

@ -312,7 +312,6 @@ singlepass:skip:simd_binaryen.wast:* # SIMD not implemented
singlepass:skip:atomic.wast:*:*:aarch64 # Threads not yet supported on singlepass
singlepass:fail:address.wast:192 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:address.wast:194 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:195 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:196 # AssertTrap - expected trap, got []
@ -323,7 +322,6 @@ singlepass:fail:address.wast:201 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:202 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:203 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:204 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:479 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:address.wast:481 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:482 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:483 # AssertTrap - expected trap, got []
@ -338,486 +336,140 @@ singlepass:fail:address.wast:492 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:493 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:494 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:495 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:539 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:address.wast:541 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:542 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:586 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:address.wast:588 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:589 # AssertTrap - expected trap, got []
singlepass:fail:align.wast:864 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:380 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:381 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:382 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:383 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:384 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:385 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:386 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:387 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:388 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:389 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:390 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:391 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:392 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:393 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:394 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:395 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:396 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:397 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:398 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:399 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:400 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:401 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:402 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:403 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:404 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:405 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:406 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:407 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:408 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:409 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:410 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:411 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:412 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:413 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:414 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:415 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:416 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:417 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:418 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:419 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:420 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:421 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:422 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:423 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:atomic.wast:424 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call.wast:289 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:469 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:470 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:471 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:472 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:473 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:479 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:480 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:486 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:487 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:493 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:494 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:500 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:501 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:84 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:85 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:86 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:87 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:88 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:105 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:106 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:107 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:108 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:109 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:110 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:111 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:112 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:128 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:129 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:130 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:131 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:132 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:133 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:134 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:135 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:151 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:152 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:153 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:154 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:155 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:156 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:157 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:158 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:159 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:160 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:161 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:179 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:180 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:181 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:182 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:183 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:184 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:186 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:200 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:201 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:202 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:203 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:204 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:205 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:206 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:224 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:226 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:227 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:228 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:229 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:231 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:250 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:252 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:253 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:254 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:255 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:elem.wast:353 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:func_ptrs.wast:78 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:func_ptrs.wast:79 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:func_ptrs.wast:80 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:func_ptrs.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:func_ptrs.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:func_ptrs.wast:91 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:globals.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:globals.wast:243 # AssertInvalid - Should be invalid
singlepass:fail:i32.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:82 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:99 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:82 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:99 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:100 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i64.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:if.wast:440 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:287 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:302 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:305 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:306 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:391 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:402 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:113 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:114 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:115 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:116 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:132 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:133 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:134 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:135 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:196 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:197 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:198 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:349 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:350 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:134 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:linking.wast:136 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:137 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:139 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:141 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:142 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:144 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:146 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:147 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:148 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:149 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:152 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:169 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:linking.wast:175 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:linking.wast:181 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:linking.wast:184 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:188 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:190 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:memory_grow.wast:15 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:16 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:17 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:18 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:24 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:25 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:23 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:24 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:25 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:26 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:27 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:28 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:29 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:30 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:31 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:32 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:111 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:112 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:113 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:114 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:115 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:116 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:117 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:118 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:119 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:120 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:121 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:122 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:123 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:124 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:125 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:126 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:127 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:128 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:129 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:130 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:131 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:132 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:133 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:134 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:135 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:136 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:137 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:138 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:139 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:140 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:141 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:142 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:143 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:144 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:145 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:146 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:147 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:148 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:149 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:150 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:151 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:152 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:153 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:154 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:155 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:156 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:157 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:158 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:159 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:160 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:161 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:162 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:163 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:164 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:165 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:166 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:167 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:168 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:169 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:170 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:171 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:172 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:173 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:174 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:175 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:176 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:177 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:178 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:179 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:180 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:181 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:182 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:183 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:184 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:185 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:186 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:188 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:189 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:190 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:191 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:192 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:193 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:194 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:195 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:196 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:197 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:198 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:200 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:201 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:202 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:203 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:204 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:205 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:206 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:207 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:208 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:209 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:210 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:211 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:212 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:213 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:214 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:215 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:216 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:217 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:218 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:219 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:220 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:222 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:223 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:224 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:226 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:227 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:228 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:229 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:231 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:232 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:233 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:234 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:235 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:237 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:238 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:239 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:240 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:243 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:244 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:246 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:247 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:250 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:252 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:253 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:254 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:255 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:256 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:257 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:258 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:259 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:260 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:261 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:262 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:264 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:265 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_trap.wast:266 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:208 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:209 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:210 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:211 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:16 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:17 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:18 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:19 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:20 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:21 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:34 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:35 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:36 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:37 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:50 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:51 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:52 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:53 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:54 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:55 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:56 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:57 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:78 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:79 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:80 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:81 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:82 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:83 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:84 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:85 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:86 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:87 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:88 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:91 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:218 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:219 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:220 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:223 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:224 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:226 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:228 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:229 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:231 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:234 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:235 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:239 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:243 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:246 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:247 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:253 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:254 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:256 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:259 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:260 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:261 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:262 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:265 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:266 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:267 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:269 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:270 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:271 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:272 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:274 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:275 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:276 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:278 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:279 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:281 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:282 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:284 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:288 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:289 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:291 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:293 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:294 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:296 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:298 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:212 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:230 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:239 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:257 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error
# These failures only happen on AArch64 and not on x86-64.
singlepass:fail:conversions.wast:83:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)]
singlepass:fail:conversions.wast:84:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)]
singlepass:fail:conversions.wast:85:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)]
singlepass:fail:conversions.wast:86:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)]
singlepass:fail:conversions.wast:87:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:88:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:89:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:90:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:105:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:106:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:107:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:108:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:109:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:110:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:111:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:112:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:128:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)]
singlepass:fail:conversions.wast:129:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)]
singlepass:fail:conversions.wast:130:*:aarch64 # AssertTrap - expected trap, got [I32(2147483647)]
singlepass:fail:conversions.wast:131:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)]
singlepass:fail:conversions.wast:132:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:133:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:134:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:135:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:151:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:152:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:153:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:154:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:155:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:156:*:aarch64 # AssertTrap - expected trap, got [I32(-1)]
singlepass:fail:conversions.wast:157:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:158:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:159:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:160:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:161:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:conversions.wast:179:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)]
singlepass:fail:conversions.wast:180:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)]
singlepass:fail:conversions.wast:181:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)]
singlepass:fail:conversions.wast:182:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)]
singlepass:fail:conversions.wast:183:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:184:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:185:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:186:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:199:*:aarch64 # AssertTrap - expected trap, got [I64(-1)]
singlepass:fail:conversions.wast:200:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:201:*:aarch64 # AssertTrap - expected trap, got [I64(-1)]
singlepass:fail:conversions.wast:202:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:203:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:204:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:205:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:206:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:224:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)]
singlepass:fail:conversions.wast:225:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)]
singlepass:fail:conversions.wast:226:*:aarch64 # AssertTrap - expected trap, got [I64(9223372036854775807)]
singlepass:fail:conversions.wast:227:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)]
singlepass:fail:conversions.wast:228:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:229:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:230:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:231:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:248:*:aarch64 # AssertTrap - expected trap, got [I64(-1)]
singlepass:fail:conversions.wast:249:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:250:*:aarch64 # AssertTrap - expected trap, got [I64(-1)]
singlepass:fail:conversions.wast:251:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:252:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:253:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:254:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:conversions.wast:255:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:i32.wast:62:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:i32.wast:63:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:i32.wast:64:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)]
singlepass:fail:i32.wast:82:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:i32.wast:83:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:i32.wast:99:*:aarch64 # AssertTrap - expected trap, got [I32(1)]
singlepass:fail:i32.wast:100:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:i32.wast:120:*:aarch64 # AssertTrap - expected trap, got [I32(1)]
singlepass:fail:i32.wast:121:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:i64.wast:62:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:i64.wast:63:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:i64.wast:64:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)]
singlepass:fail:i64.wast:82:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:i64.wast:83:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:i64.wast:99:*:aarch64 # AssertTrap - expected trap, got [I64(1)]
singlepass:fail:i64.wast:100:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:i64.wast:120:*:aarch64 # AssertTrap - expected trap, got [I64(1)]
singlepass:fail:i64.wast:121:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:113:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:int_exprs.wast:114:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:int_exprs.wast:115:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:116:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:132:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:int_exprs.wast:133:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:int_exprs.wast:134:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:135:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:196:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:int_exprs.wast:197:*:aarch64 # AssertTrap - expected trap, got [I32(0)]
singlepass:fail:int_exprs.wast:198:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:199:*:aarch64 # AssertTrap - expected trap, got [I64(0)]
singlepass:fail:int_exprs.wast:349:*:aarch64 # AssertTrap - expected trap, got [I32(-2147483648)]
singlepass:fail:int_exprs.wast:350:*:aarch64 # AssertTrap - expected trap, got [I64(-9223372036854775808)]
singlepass:fail:traps.wast:16:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:17:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:18:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:19:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:20:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:21:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:34:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:35:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:36:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:37:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:50:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:51:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:52:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:53:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:54:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:55:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:56:*:aarch64 # AssertTrap - expected trap, got []
singlepass:fail:traps.wast:57:*:aarch64 # AssertTrap - expected trap, got []

View File

@ -616,9 +616,47 @@ mod tests {
} => {
let maybe_call_result =
with_instance(instance.clone(), &named_modules, &module, |instance| {
#[cfg(unix)]
use wasmer_runtime::{
pop_code_version, push_code_version, CodeVersion,
};
// Manually push code version before calling WebAssembly function, as a hack.
//
// This should eventually be fixed by doing push/pop code version in the function invocation
// logic itself.
#[cfg(unix)]
let cv_pushed = if let Some(msm) =
instance.module.runnable_module.get_module_state_map()
{
push_code_version(CodeVersion {
baseline: true,
msm: msm,
base: instance
.module
.runnable_module
.get_code()
.unwrap()
.as_ptr()
as usize,
backend: backend.into(),
runnable_module: instance.module.runnable_module.clone(),
});
true
} else {
false
};
let params: Vec<wasmer_runtime::types::Value> =
args.iter().cloned().map(convert_value).collect();
instance.call(&field, &params[..])
let ret = instance.call(&field, &params[..]);
#[cfg(unix)]
{
if cv_pushed {
pop_code_version().unwrap();
}
}
ret
});
if maybe_call_result.is_none() {
test_report.add_failure(
@ -657,21 +695,28 @@ mod tests {
// TODO assert message?
test_report.count_passed()
}
RuntimeError::Error { .. } => {
test_report.add_failure(
SpecFailure {
file: filename.to_string(),
RuntimeError::Error { ref data } => {
use wasmer_runtime::ExceptionCode;
if let Some(_) =
data.downcast_ref::<ExceptionCode>()
{
test_report.count_passed();
} else {
test_report.add_failure(
SpecFailure {
file: filename.to_string(),
line,
kind: format!("{}", "AssertTrap"),
message: format!(
"expected trap, got Runtime:Error {:?}",
r
),
},
&test_key,
excludes,
line,
kind: format!("{}", "AssertTrap"),
message: format!(
"expected trap, got Runtime:Error {:?}",
r
),
},
&test_key,
excludes,
line,
);
);
}
}
}
}

View File

@ -1,4 +1,4 @@
#![allow(unused)]
#![allow(unused, clippy::too_many_arguments)]
pub mod types;
#[cfg(any(target_os = "linux", target_os = "macos"))]
pub mod unix;
@ -331,7 +331,7 @@ pub fn fd_allocate(
) -> __wasi_errno_t {
debug!("wasi::fd_allocate");
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_entry = wasi_try!(state.fs.get_fd(fd));
let inode = fd_entry.inode;
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_ALLOCATE) {
@ -374,7 +374,7 @@ pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
debug!("=> fd={}", fd);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_entry = wasi_try!(state.fs.get_fd(fd));
wasi_try!(state.fs.close_fd(fd));
@ -389,7 +389,7 @@ pub fn fd_close(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
pub fn fd_datasync(ctx: &mut Ctx, fd: __wasi_fd_t) -> __wasi_errno_t {
debug!("wasi::fd_datasync");
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_entry = wasi_try!(state.fs.get_fd(fd));
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_DATASYNC) {
return __WASI_EACCES;
}
@ -420,7 +420,7 @@ pub fn fd_fdstat_get(
buf_ptr.offset()
);
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_entry = wasi_try!(state.fs.get_fd(fd));
let stat = wasi_try!(state.fs.fdstat(fd));
let buf = wasi_try!(buf_ptr.deref(memory));
@ -528,7 +528,7 @@ pub fn fd_filestat_set_size(
) -> __wasi_errno_t {
debug!("wasi::fd_filestat_set_size");
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_entry = wasi_try!(state.fs.get_fd(fd));
let inode = fd_entry.inode;
if !has_rights(fd_entry.rights, __WASI_RIGHT_FD_FILESTAT_SET_SIZE) {
@ -1309,7 +1309,7 @@ pub fn path_create_directory(
debug!("wasi::path_create_directory");
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let working_dir = wasi_try!(state.fs.get_fd(fd)).clone();
let working_dir = wasi_try!(state.fs.get_fd(fd));
if let Kind::Root { .. } = &state.fs.inodes[working_dir.inode].kind {
return __WASI_EACCES;
}
@ -1468,7 +1468,7 @@ pub fn path_filestat_set_times(
) -> __wasi_errno_t {
debug!("wasi::path_filestat_set_times");
let (memory, state) = get_memory_and_wasi_state(ctx, 0);
let fd_entry = wasi_try!(state.fs.get_fd(fd)).clone();
let fd_entry = wasi_try!(state.fs.get_fd(fd));
let fd_inode = fd_entry.inode;
if !has_rights(fd_entry.rights, __WASI_RIGHT_PATH_FILESTAT_SET_TIMES) {
return __WASI_EACCES;

View File

@ -42,6 +42,11 @@ use wasmer_runtime_core::{
loader::{Instance as LoadedInstance, LocalLoader},
Module,
};
#[cfg(unix)]
use wasmer_runtime_core::{
fault::{pop_code_version, push_code_version},
state::CodeVersion,
};
#[cfg(feature = "wasi")]
use wasmer_wasi;
@ -478,12 +483,6 @@ fn execute_wasi(
#[cfg(not(feature = "managed"))]
{
use wasmer_runtime::error::RuntimeError;
#[cfg(unix)]
use wasmer_runtime_core::{
fault::{pop_code_version, push_code_version},
state::CodeVersion,
};
let result;
#[cfg(unix)]
@ -862,11 +861,33 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
};
let args = options.parse_args(&module, invoke_fn)?;
#[cfg(unix)]
let cv_pushed =
if let Some(msm) = instance.module.runnable_module.get_module_state_map() {
push_code_version(CodeVersion {
baseline: true,
msm: msm,
base: instance.module.runnable_module.get_code().unwrap().as_ptr() as usize,
backend: options.backend.to_string(),
runnable_module: instance.module.runnable_module.clone(),
});
true
} else {
false
};
let result = instance
.dyn_func(&invoke_fn)
.map_err(|e| format!("{:?}", e))?
.call(&args)
.map_err(|e| format!("{:?}", e))?;
#[cfg(unix)]
{
if cv_pushed {
pop_code_version().unwrap();
}
}
println!("{}({:?}) returned {:?}", invoke_fn, args, result);
}
}