Merge branch 'master' into feature/debug-prototype2

This commit is contained in:
Mark McCaskey 2020-02-26 14:39:02 -08:00
commit cb20cd9b2d
56 changed files with 1419 additions and 368 deletions

View File

@ -2,6 +2,12 @@
## **[Unreleased]**
## 0.14.1 - 2020-02-24
- [#1245](https://github.com/wasmerio/wasmer/pull/1245) Use Ubuntu 16.04 in CI so that we use an earlier version of GLIBC.
- [#1234](https://github.com/wasmerio/wasmer/pull/1234) Check for unused excluded spectest failures.
- [#1232](https://github.com/wasmerio/wasmer/pull/1232) `wasmer-interface-types` has a WAT decoder.
## 0.14.0 - 2020-02-20
- [#1233](https://github.com/wasmerio/wasmer/pull/1233) Improved Wasmer C API release artifacts.

143
Cargo.lock generated
View File

@ -227,45 +227,46 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
[[package]]
name = "cranelift-bforest"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56aa72ef104c5d634f2f9e84ef2c47e116c1d185fae13f196b97ca84b0a514f1"
checksum = "45a9c21f8042b9857bda93f6c1910b9f9f24100187a3d3d52f214a34e3dc5818"
dependencies = [
"cranelift-entity",
"cranelift-entity 0.59.0",
]
[[package]]
name = "cranelift-codegen"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460b9d20793543599308d22f5a1172c196e63a780c4e9aacb0b3f4f63d63ffe1"
checksum = "7853f77a6e4a33c67a69c40f5e1bb982bd2dc5c4a22e17e67b65bbccf9b33b2e"
dependencies = [
"byteorder",
"cranelift-bforest",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-entity",
"cranelift-entity 0.59.0",
"gimli",
"log",
"smallvec 1.2.0",
"target-lexicon",
"target-lexicon 0.10.0",
"thiserror",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cc70e4e8ccebd53a4f925147def857c9e9f7fe0fdbef4bb645a420473e012f50"
checksum = "084cd6d5fb0d1da28acd72c199471bfb09acc703ec8f3bf07b1699584272a3b9"
dependencies = [
"cranelift-codegen-shared",
"cranelift-entity",
"cranelift-entity 0.59.0",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3992000be4d18df0fe332b7c42c120de896e8ec54cd7b6cfa050910a8c9f6e2f"
checksum = "701b599783305a58c25027a4d73f2d6b599b2d8ef3f26677275f480b4d51e05d"
[[package]]
name = "cranelift-entity"
@ -274,14 +275,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "722957e05064d97a3157bf0976deed0f3e8ee4f8a4ce167a7c724ca63a4e8bd9"
[[package]]
name = "cranelift-native"
version = "0.52.0"
name = "cranelift-entity"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21398a0bc6ba389ea86964ac4a495426dd61080f2ddd306184777a8560fe9976"
checksum = "b88e792b28e1ebbc0187b72ba5ba880dad083abe9231a99d19604d10c9e73f38"
[[package]]
name = "cranelift-native"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32daf082da21c0c05d93394ff4842c2ab7c4991b1f3186a1d952f8ac660edd0b"
dependencies = [
"cranelift-codegen",
"raw-cpuid",
"target-lexicon",
"target-lexicon 0.10.0",
]
[[package]]
@ -491,7 +498,7 @@ dependencies = [
"log",
"scroll 0.10.1",
"string-interner",
"target-lexicon",
"target-lexicon 0.9.0",
"thiserror",
]
@ -633,9 +640,9 @@ dependencies = [
[[package]]
name = "hex"
version = "0.4.1"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76cdda6bf525062a0c9e8f14ee2b37935c86b8efb6c8b69b3c83dfb518a914af"
checksum = "644f9158b2f133fd50f5fb3242878846d9eb792e445c893805ff0e3824006e35"
[[package]]
name = "indexmap"
@ -718,6 +725,12 @@ version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "leb128"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3576a87f2ba00f6f106fdfcd16db1d698d648a26ad8e0573cad8537c3c362d2a"
[[package]]
name = "lexical-core"
version = "0.4.6"
@ -733,9 +746,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.66"
version = "0.2.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558"
checksum = "eb147597cdf94ed43ab7a9038716637d2d1bf2bc571da995d0028dec06bd3018"
[[package]]
name = "llvm-sys"
@ -1598,6 +1611,12 @@ version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6f4c118a7a38378f305a9e111fcb2f7f838c0be324bfb31a77ea04f7f6e684b4"
[[package]]
name = "target-lexicon"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab0e7238dcc7b40a7be719a25365910f6807bd864f4cce6b2e6b873658e2b19d"
[[package]]
name = "tempfile"
version = "3.1.0"
@ -1799,18 +1818,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86840eccceaf682e29be7810dcae5785b9c3b0349ce44d3eaecd9e50f893aee0"
dependencies = [
"anyhow",
"cranelift-entity",
"cranelift-entity 0.52.0",
"faerie",
"gimli",
"more-asserts",
"target-lexicon",
"target-lexicon 0.9.0",
"thiserror",
"wasmparser 0.39.3",
]
[[package]]
name = "wasmer"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"atty",
"byteorder",
@ -1841,11 +1860,11 @@ dependencies = [
[[package]]
name = "wasmer-clif-backend"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"byteorder",
"cranelift-codegen",
"cranelift-entity",
"cranelift-entity 0.59.0",
"cranelift-native",
"libc",
"nix",
@ -1854,52 +1873,52 @@ dependencies = [
"serde-bench",
"serde_bytes",
"serde_derive",
"target-lexicon",
"target-lexicon 0.10.0",
"wasm-debug",
"wasmer-clif-fork-frontend",
"wasmer-clif-fork-wasm",
"wasmer-runtime-core",
"wasmer-win-exception-handler",
"wasmparser 0.45.2",
"wasmparser 0.51.3",
"winapi",
]
[[package]]
name = "wasmer-clif-fork-frontend"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d2e13201ef9ef527ad30a6bf1b08e3e024a40cf2731f393d80375dc88506207"
checksum = "c23f2824f354a00a77e4b040eef6e1d4c595a8a3e9013bad65199cc8dade9a5a"
dependencies = [
"cranelift-codegen",
"log",
"smallvec 1.2.0",
"target-lexicon",
"target-lexicon 0.10.0",
]
[[package]]
name = "wasmer-clif-fork-wasm"
version = "0.52.0"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8b09302cc4fdc4efc03823cb3e1880b0fde578ba43f27ddd212811cb28c1530"
checksum = "a35e21d3aebc51cc6ebc0e830cf8458a9891c3482fb3c65ad18d408102929ae5"
dependencies = [
"cranelift-codegen",
"cranelift-entity",
"cranelift-entity 0.59.0",
"log",
"thiserror",
"wasmer-clif-fork-frontend",
"wasmparser 0.45.2",
"wasmparser 0.51.3",
]
[[package]]
name = "wasmer-dev-utils"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"libc",
]
[[package]]
name = "wasmer-emscripten"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"byteorder",
"getrandom",
@ -1912,7 +1931,7 @@ dependencies = [
[[package]]
name = "wasmer-emscripten-tests"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"glob 0.3.0",
"wabt",
@ -1926,9 +1945,10 @@ dependencies = [
[[package]]
name = "wasmer-interface-types"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"nom",
"wast",
]
[[package]]
@ -1941,7 +1961,7 @@ dependencies = [
[[package]]
name = "wasmer-llvm-backend"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"byteorder",
"cc",
@ -1956,7 +1976,7 @@ dependencies = [
"smallvec 0.6.13",
"wabt",
"wasmer-runtime-core",
"wasmparser 0.45.2",
"wasmparser 0.51.3",
"winapi",
]
@ -1972,14 +1992,14 @@ dependencies = [
[[package]]
name = "wasmer-middleware-common"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"wasmer-runtime-core",
]
[[package]]
name = "wasmer-middleware-common-tests"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"criterion",
"wabt",
@ -1992,7 +2012,7 @@ dependencies = [
[[package]]
name = "wasmer-runtime"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"criterion",
"lazy_static",
@ -2009,7 +2029,7 @@ dependencies = [
[[package]]
name = "wasmer-runtime-c-api"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"cbindgen",
"libc",
@ -2021,7 +2041,7 @@ dependencies = [
[[package]]
name = "wasmer-runtime-core"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"bincode",
"blake3",
@ -2041,15 +2061,15 @@ dependencies = [
"serde_bytes",
"serde_derive",
"smallvec 0.6.13",
"target-lexicon",
"target-lexicon 0.9.0",
"wasm-debug",
"wasmparser 0.45.2",
"wasmparser 0.51.3",
"winapi",
]
[[package]]
name = "wasmer-runtime-core-tests"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"wabt",
"wasmer-clif-backend",
@ -2060,7 +2080,7 @@ dependencies = [
[[package]]
name = "wasmer-singlepass-backend"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"bincode",
"byteorder",
@ -2077,7 +2097,7 @@ dependencies = [
[[package]]
name = "wasmer-spectests"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"glob 0.3.0",
"wabt",
@ -2089,7 +2109,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"bincode",
"byteorder",
@ -2106,7 +2126,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi-experimental-io-devices"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"log",
"minifb",
@ -2119,7 +2139,7 @@ dependencies = [
[[package]]
name = "wasmer-wasi-tests"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"glob 0.3.0",
"wasmer-clif-backend",
@ -2132,7 +2152,7 @@ dependencies = [
[[package]]
name = "wasmer-win-exception-handler"
version = "0.14.0"
version = "0.14.1"
dependencies = [
"cmake",
"libc",
@ -2148,9 +2168,18 @@ checksum = "c702914acda5feeeffbc29e4d953e5b9ce79d8b98da4dbf18a77086e116c5470"
[[package]]
name = "wasmparser"
version = "0.45.2"
version = "0.51.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b4eab1d9971d0803729cba3617b56eb04fcb4bd25361cb63880ed41a42f20d5"
checksum = "447465bb5cf5ecd5918919ef3a0002e0839c87fb2a9483d4816d9b2cc36221fa"
[[package]]
name = "wast"
version = "8.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9df3d716118a503b2f6bbb6ff46b21997ab0cc167b01de7a188e45e4b01e8d"
dependencies = [
"leb128",
]
[[package]]
name = "winapi"

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer"
version = "0.14.0"
version = "0.14.1"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
edition = "2018"
repository = "https://github.com/wasmerio/wasmer"

View File

@ -24,7 +24,7 @@ jobs:
- job: clippy_lint
pool:
vmImage: "ubuntu-18.04"
vmImage: "ubuntu-16.04"
steps:
- checkout: self
- template: .azure/install-rust.yml
@ -44,7 +44,7 @@ jobs:
strategy:
matrix:
linux:
imageName: "ubuntu-18.04"
imageName: "ubuntu-16.04"
rust_toolchain: nightly-2019-12-19
mac:
imageName: "macos-10.14"
@ -88,7 +88,7 @@ jobs:
- job: Check
pool:
vmImage: "ubuntu-18.04"
vmImage: "ubuntu-16.04"
variables:
rust_toolchain: nightly-2019-12-19
condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
@ -106,7 +106,7 @@ jobs:
strategy:
matrix:
linux:
imageName: "ubuntu-18.04"
imageName: "ubuntu-16.04"
rust_toolchain: nightly-2019-12-19
mac:
imageName: "macos-10.14"
@ -178,7 +178,7 @@ jobs:
strategy:
matrix:
linux:
imageName: "ubuntu-18.04"
imageName: "ubuntu-16.04"
rust_toolchain: nightly-2019-12-19
mac:
imageName: "macos-10.14"
@ -234,7 +234,7 @@ jobs:
- job: Build_Docs
pool:
vmImage: "ubuntu-18.04"
vmImage: "ubuntu-16.04"
variables:
rust_toolchain: nightly-2019-12-19
condition: in(variables['Build.SourceBranch'], 'refs/heads/master', 'refs/heads/staging', 'refs/heads/trying')
@ -309,7 +309,7 @@ jobs:
- Build_Docs
displayName: Deploy API Documentation to GitHub
pool:
vmImage: "ubuntu-18.04"
vmImage: "ubuntu-16.04"
condition: in(variables['Build.SourceBranch'], 'refs/heads/master')
steps:
- checkout: self

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-clif-backend"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime Cranelift compiler backend"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -11,14 +11,14 @@ edition = "2018"
readme = "README.md"
[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
cranelift-native = "0.52.0"
cranelift-codegen = "0.52.0"
cranelift-entity = "0.52.0"
cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.52.0" }
cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.52.0" }
target-lexicon = "0.9"
wasmparser = "0.45.0"
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
cranelift-native = "0.59.0"
cranelift-codegen = "0.59.0"
cranelift-entity = "0.59.0"
cranelift-frontend = { package = "wasmer-clif-fork-frontend", version = "0.59.0" }
cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.59.0" }
target-lexicon = "0.10"
wasmparser = "0.51.3"
byteorder = "1.3.2"
nix = "0.15.0"
libc = "0.2.60"
@ -38,7 +38,7 @@ version = "0.0.7"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3", features = ["errhandlingapi", "minwindef", "minwinbase", "winnt"] }
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.14.0" }
wasmer-win-exception-handler = { path = "../win-exception-handler", version = "0.14.1" }
[features]
generate-debug-information = ["wasm-debug"]

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -7,13 +7,14 @@ use crate::{
};
use cranelift_codegen::entity::EntityRef;
use cranelift_codegen::ir::{self, Ebb, Function, InstBuilder};
use cranelift_codegen::ir::{self, Block, Function, InstBuilder};
use cranelift_codegen::isa::CallConv;
use cranelift_codegen::{cursor::FuncCursor, isa};
use cranelift_frontend::{FunctionBuilder, Position, Variable};
use cranelift_wasm::{self, FuncTranslator, ModuleTranslationState};
use cranelift_wasm::{get_vmctx_value_label, translate_operator};
use cranelift_wasm::{FuncEnvironment, ReturnMode, TargetEnvironment, WasmError};
use std::mem;
use std::sync::{Arc, RwLock};
use wasmer_runtime_core::error::CompileError;
@ -110,7 +111,7 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
func_env.func.collect_debug_info();
}
debug_assert_eq!(func_env.func.dfg.num_ebbs(), 0, "Function must be empty");
debug_assert_eq!(func_env.func.dfg.num_blocks(), 0, "Function must be empty");
debug_assert_eq!(func_env.func.dfg.num_insts(), 0, "Function must be empty");
let mut builder = FunctionBuilder::new(
@ -121,20 +122,20 @@ impl ModuleCodeGenerator<CraneliftFunctionCodeGenerator, Caller, CodegenError>
builder.set_srcloc(ir::SourceLoc::new(loc.start()));
let entry_block = builder.create_ebb();
builder.append_ebb_params_for_function_params(entry_block);
let entry_block = builder.create_block();
builder.append_block_params_for_function_params(entry_block);
builder.switch_to_block(entry_block); // This also creates values for the arguments.
builder.seal_block(entry_block);
// Make sure the entry block is inserted in the layout before we make any callbacks to
// `environ`. The callback functions may need to insert things in the entry block.
builder.ensure_inserted_ebb();
builder.ensure_inserted_block();
declare_wasm_parameters(&mut builder, entry_block);
// Set up the translation state with a single pushed control block representing the whole
// function and its return values.
let exit_block = builder.create_ebb();
builder.append_ebb_params_for_function_returns(exit_block);
let exit_block = builder.create_block();
builder.append_block_params_for_function_returns(exit_block);
func_env
.func_translator
.state
@ -1021,7 +1022,7 @@ impl FuncEnvironment for FunctionEnvironment {
_src: ir::Value,
_len: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.copy yet implemented");
unimplemented!("table.copy not yet implemented");
}
fn translate_table_init(
@ -1034,7 +1035,7 @@ impl FuncEnvironment for FunctionEnvironment {
_src: ir::Value,
_len: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.init yet implemented");
unimplemented!("table.init not yet implemented");
}
fn translate_elem_drop(
@ -1042,7 +1043,72 @@ impl FuncEnvironment for FunctionEnvironment {
_pos: FuncCursor,
_seg_index: u32,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("elem.drop yet implemented");
unimplemented!("elem.drop not yet implemented");
}
fn translate_table_grow(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_delta: ir::Value,
_init_value: ir::Value,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("table.grow not yet implemented");
}
fn translate_table_get(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_index: ir::Value,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("table.get not yet implemented");
}
fn translate_table_set(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_value: ir::Value,
_index: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.set not yet implemented");
}
fn translate_table_fill(
&mut self,
_pos: FuncCursor,
_table_index: u32,
_dst: ir::Value,
_val: ir::Value,
_len: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("table.fill not yet implemented");
}
fn translate_ref_func(
&mut self,
_pos: FuncCursor,
_func_index: u32,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("ref.func not yet implemented");
}
fn translate_custom_global_get(
&mut self,
_pos: FuncCursor,
_global_index: cranelift_wasm::GlobalIndex,
) -> cranelift_wasm::WasmResult<ir::Value> {
unimplemented!("custom global.get not yet implemented");
}
fn translate_custom_global_set(
&mut self,
_pos: FuncCursor,
_global_index: cranelift_wasm::GlobalIndex,
_val: ir::Value,
) -> cranelift_wasm::WasmResult<()> {
unimplemented!("custom global.set not yet implemented");
}
}
@ -1242,7 +1308,7 @@ fn pointer_type(mcg: &CraneliftModuleCodeGenerator) -> ir::Type {
/// Declare local variables for the signature parameters that correspond to WebAssembly locals.
///
/// Return the number of local variables declared.
fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> usize {
fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Block) -> usize {
let sig_len = builder.func.signature.params.len();
let mut next_local = 0;
for i in 0..sig_len {
@ -1255,11 +1321,11 @@ fn declare_wasm_parameters(builder: &mut FunctionBuilder, entry_block: Ebb) -> u
builder.declare_var(local, param_type.value_type);
next_local += 1;
let param_value = builder.ebb_params(entry_block)[i];
let param_value = builder.block_params(entry_block)[i];
builder.def_var(local, param_value);
}
if param_type.purpose == ir::ArgumentPurpose::VMContext {
let param_value = builder.ebb_params(entry_block)[i];
let param_value = builder.block_params(entry_block)[i];
builder.set_val_label(param_value, get_vmctx_value_label());
}
}

View File

@ -40,7 +40,7 @@ fn get_isa() -> Box<dyn isa::TargetIsa> {
let flags = {
let mut builder = settings::builder();
builder.set("opt_level", "speed_and_size").unwrap();
builder.set("jump_tables_enabled", "false").unwrap();
builder.set("enable_jump_tables", "false").unwrap();
if cfg!(test) || cfg!(debug_assertions) {
builder.set("enable_verifier", "true").unwrap();

View File

@ -98,7 +98,7 @@ pub struct RelocSink {
}
impl binemit::RelocSink for RelocSink {
fn reloc_ebb(
fn reloc_block(
&mut self,
_offset: binemit::CodeOffset,
_reloc: binemit::Reloc,

View File

@ -159,12 +159,12 @@ impl FuncResolverBuilder {
let debug_entry = if generate_debug_info {
let func = &ctx.func;
let encinfo = isa.encoding_info();
let mut ebbs = func.layout.ebbs().collect::<Vec<_>>();
ebbs.sort_by_key(|ebb| func.offsets[*ebb]);
let instructions = ebbs
let mut blocks = func.layout.blocks().collect::<Vec<_>>();
blocks.sort_by_key(|block| func.offsets[*block]);
let instructions = blocks
.into_iter()
.flat_map(|ebb| {
func.inst_offsets(ebb, &encinfo)
.flat_map(|block| {
func.inst_offsets(block, &encinfo)
.map(|(offset, inst, length)| {
let srcloc = func.srclocs[inst];
let val = srcloc.bits();

View File

@ -16,7 +16,7 @@ use wasmer_runtime_core::{
struct NullRelocSink {}
impl RelocSink for NullRelocSink {
fn reloc_ebb(&mut self, _: u32, _: Reloc, _: u32) {}
fn reloc_block(&mut self, _: u32, _: Reloc, _: u32) {}
fn reloc_external(&mut self, _: u32, _: Reloc, _: &ir::ExternalName, _: i64) {}
fn reloc_constant(&mut self, _: u32, _: Reloc, _: u32) {
@ -158,12 +158,12 @@ fn generate_func(func_sig: &FuncSig) -> ir::Function {
let export_sig_ref = func.import_signature(generate_export_signature(func_sig));
let entry_ebb = func.dfg.make_ebb();
let vmctx_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
let func_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
let args_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
let returns_ptr = func.dfg.append_ebb_param(entry_ebb, ir::types::I64);
func.layout.append_ebb(entry_ebb);
let entry_ebb = func.dfg.make_block();
let vmctx_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
let func_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
let args_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
let returns_ptr = func.dfg.append_block_param(entry_ebb, ir::types::I64);
func.layout.append_block(entry_ebb);
let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(entry_ebb);

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-dev-utils"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime core library"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]

View File

@ -1,3 +1,3 @@
# Dev Utils
This is shared code between the modules for testing and development only. Code in this crate will not be shipped.
This is shared code between the modules for testing and development only. Code in this crate will not be shipped.

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-emscripten-tests"
version = "0.14.0"
version = "0.14.1"
description = "Tests for our Emscripten implementation"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -9,15 +9,15 @@ publish = false
build = "build/mod.rs"
[dependencies]
wasmer-emscripten = { path = "../emscripten", version = "0.14.0" }
wasmer-runtime = { path = "../runtime", version = "0.14.0", default-features = false }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true}
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", optional = true, features = ["test"] }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true }
wasmer-emscripten = { path = "../emscripten", version = "0.14.1" }
wasmer-runtime = { path = "../runtime", version = "0.14.1", default-features = false }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true}
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", optional = true, features = ["test"] }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true }
[dev-dependencies]
wabt = "0.9.1"
wasmer-dev-utils = { path = "../dev-utils", version = "0.14.0"}
wasmer-dev-utils = { path = "../dev-utils", version = "0.14.1"}
[build-dependencies]
glob = "0.3"

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-emscripten"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime emscripten implementation library"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -15,7 +15,7 @@ lazy_static = "1.4"
libc = "0.2.60"
log = "0.4"
time = "0.1"
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
[target.'cfg(windows)'.dependencies]
getrandom = "0.1"

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-interface-types"
version = "0.14.0"
version = "0.14.1"
description = "WebAssembly Interface Types library for Wasmer"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -9,3 +9,4 @@ edition = "2018"
[dependencies]
nom = "5.1"
wast = "8.0"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -5,7 +5,7 @@ use crate::interpreter::Instruction;
use std::str;
/// Represents the types supported by WIT.
#[derive(PartialEq, Clone, Debug)]
#[derive(PartialEq, Debug)]
pub enum InterfaceType {
/// An integer.
Int,
@ -190,7 +190,7 @@ pub struct Forward<'input> {
/// Represents a set of interfaces, i.e. it entirely describes a WIT
/// definition.
#[derive(PartialEq, Debug)]
#[derive(PartialEq, Default, Debug)]
pub struct Interfaces<'input> {
/// All the exported functions.
pub exports: Vec<Export<'input>>,

View File

@ -1,4 +1,4 @@
//! Parse the WIT binary representation into an AST.
//! Parse the WIT binary representation into an [AST](crate::ast).
use crate::{ast::*, interpreter::Instruction};
use nom::{
@ -432,7 +432,8 @@ fn interfaces<'input, E: ParseError<&'input [u8]>>(
}
/// Parse a sequence of bytes, expecting it to be a valid WIT binary
/// representation, into an `ast::Interfaces`.
/// representation, into an [`Interfaces`](crate::ast::Interfaces)
/// structure.
///
/// # Example
///

View File

@ -1,4 +1,6 @@
//! Reads the AST from a particular data representation; for instance,
//! `decoders::binary` reads the AST from a binary.
//! [`decoders::binary`](binary) reads the [AST](crate::ast)
//! from a binary.
pub mod binary;
pub mod wat;

View File

@ -0,0 +1,881 @@
//! Parse the WIT textual representation into an [AST](crate::ast).
use crate::{ast::*, interpreter::Instruction};
pub use wast::parser::ParseBuffer as Buffer;
use wast::{
parser::{self, Cursor, Parse, Parser, Peek, Result},
Id, LParen,
};
mod keyword {
pub use wast::{
custom_keyword,
kw::{anyref, export, f32, f64, func, i32, i64, import, param, result},
};
// New keywords.
custom_keyword!(adapt);
custom_keyword!(forward);
// New types.
custom_keyword!(int);
custom_keyword!(float);
custom_keyword!(any);
custom_keyword!(string);
custom_keyword!(seq);
// Instructions.
custom_keyword!(argument_get = "arg.get");
custom_keyword!(call);
custom_keyword!(call_export = "call-export");
custom_keyword!(read_utf8 = "read-utf8");
custom_keyword!(write_utf8 = "write-utf8");
custom_keyword!(as_wasm = "as-wasm");
custom_keyword!(as_interface = "as-interface");
custom_keyword!(table_ref_add = "table-ref-add");
custom_keyword!(table_ref_get = "table-ref-get");
custom_keyword!(call_method = "call-method");
custom_keyword!(make_record = "make-record");
custom_keyword!(get_field = "get-field");
custom_keyword!(r#const = "const");
custom_keyword!(fold_seq = "fold-seq");
custom_keyword!(add);
custom_keyword!(mem_to_seq = "mem-to-seq");
custom_keyword!(load);
custom_keyword!(seq_new = "seq.new");
custom_keyword!(list_push = "list.push");
custom_keyword!(repeat_until = "repeat-until");
}
/// Issue: Uppercased keyword aren't supported for the moment.
impl Parse<'_> for InterfaceType {
fn parse(parser: Parser<'_>) -> Result<Self> {
let mut lookahead = parser.lookahead1();
if lookahead.peek::<keyword::int>() {
parser.parse::<keyword::int>()?;
Ok(InterfaceType::Int)
} else if lookahead.peek::<keyword::float>() {
parser.parse::<keyword::float>()?;
Ok(InterfaceType::Float)
} else if lookahead.peek::<keyword::any>() {
parser.parse::<keyword::any>()?;
Ok(InterfaceType::Any)
} else if lookahead.peek::<keyword::string>() {
parser.parse::<keyword::string>()?;
Ok(InterfaceType::String)
} else if lookahead.peek::<keyword::seq>() {
parser.parse::<keyword::seq>()?;
Ok(InterfaceType::Seq)
} else if lookahead.peek::<keyword::i32>() {
parser.parse::<keyword::i32>()?;
Ok(InterfaceType::I32)
} else if lookahead.peek::<keyword::i64>() {
parser.parse::<keyword::i64>()?;
Ok(InterfaceType::I64)
} else if lookahead.peek::<keyword::f32>() {
parser.parse::<keyword::f32>()?;
Ok(InterfaceType::F32)
} else if lookahead.peek::<keyword::f64>() {
parser.parse::<keyword::f64>()?;
Ok(InterfaceType::F64)
} else if lookahead.peek::<keyword::anyref>() {
parser.parse::<keyword::anyref>()?;
Ok(InterfaceType::AnyRef)
} else {
Err(lookahead.error())
}
}
}
impl<'a> Parse<'a> for Instruction<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut lookahead = parser.lookahead1();
if lookahead.peek::<keyword::argument_get>() {
parser.parse::<keyword::argument_get>()?;
Ok(Instruction::ArgumentGet {
index: parser.parse()?,
})
} else if lookahead.peek::<keyword::call>() {
parser.parse::<keyword::call>()?;
Ok(Instruction::Call {
function_index: parser.parse::<u64>()? as usize,
})
} else if lookahead.peek::<keyword::call_export>() {
parser.parse::<keyword::call_export>()?;
Ok(Instruction::CallExport {
export_name: parser.parse()?,
})
} else if lookahead.peek::<keyword::read_utf8>() {
parser.parse::<keyword::read_utf8>()?;
Ok(Instruction::ReadUtf8)
} else if lookahead.peek::<keyword::write_utf8>() {
parser.parse::<keyword::write_utf8>()?;
Ok(Instruction::WriteUtf8 {
allocator_name: parser.parse()?,
})
} else if lookahead.peek::<keyword::as_wasm>() {
parser.parse::<keyword::as_wasm>()?;
Ok(Instruction::AsWasm(parser.parse()?))
} else if lookahead.peek::<keyword::as_interface>() {
parser.parse::<keyword::as_interface>()?;
Ok(Instruction::AsInterface(parser.parse()?))
} else if lookahead.peek::<keyword::table_ref_add>() {
parser.parse::<keyword::table_ref_add>()?;
Ok(Instruction::TableRefAdd)
} else if lookahead.peek::<keyword::table_ref_get>() {
parser.parse::<keyword::table_ref_get>()?;
Ok(Instruction::TableRefGet)
} else if lookahead.peek::<keyword::call_method>() {
parser.parse::<keyword::call_method>()?;
Ok(Instruction::CallMethod(parser.parse()?))
} else if lookahead.peek::<keyword::make_record>() {
parser.parse::<keyword::make_record>()?;
Ok(Instruction::MakeRecord(parser.parse()?))
} else if lookahead.peek::<keyword::get_field>() {
parser.parse::<keyword::get_field>()?;
Ok(Instruction::GetField(parser.parse()?, parser.parse()?))
} else if lookahead.peek::<keyword::r#const>() {
parser.parse::<keyword::r#const>()?;
Ok(Instruction::Const(parser.parse()?, parser.parse()?))
} else if lookahead.peek::<keyword::fold_seq>() {
parser.parse::<keyword::fold_seq>()?;
Ok(Instruction::FoldSeq(parser.parse()?))
} else if lookahead.peek::<keyword::add>() {
parser.parse::<keyword::add>()?;
Ok(Instruction::Add(parser.parse()?))
} else if lookahead.peek::<keyword::mem_to_seq>() {
parser.parse::<keyword::mem_to_seq>()?;
Ok(Instruction::MemToSeq(parser.parse()?, parser.parse()?))
} else if lookahead.peek::<keyword::load>() {
parser.parse::<keyword::load>()?;
Ok(Instruction::Load(parser.parse()?, parser.parse()?))
} else if lookahead.peek::<keyword::seq_new>() {
parser.parse::<keyword::seq_new>()?;
Ok(Instruction::SeqNew(parser.parse()?))
} else if lookahead.peek::<keyword::list_push>() {
parser.parse::<keyword::list_push>()?;
Ok(Instruction::ListPush)
} else if lookahead.peek::<keyword::repeat_until>() {
parser.parse::<keyword::repeat_until>()?;
Ok(Instruction::RepeatUntil(parser.parse()?, parser.parse()?))
} else {
Err(lookahead.error())
}
}
}
struct AtInterface;
impl Peek for AtInterface {
fn peek(cursor: Cursor<'_>) -> bool {
cursor.reserved().map(|(string, _)| string) == Some("@interface")
}
fn display() -> &'static str {
"`@interface`"
}
}
impl Parse<'_> for AtInterface {
fn parse(parser: Parser<'_>) -> Result<Self> {
parser.step(|cursor| {
if let Some(("@interface", rest)) = cursor.reserved() {
return Ok((AtInterface, rest));
}
Err(cursor.error("expected `@interface`"))
})
}
}
#[derive(PartialEq, Debug)]
enum FunctionType {
Input(Vec<InterfaceType>),
Output(Vec<InterfaceType>),
}
impl Parse<'_> for FunctionType {
fn parse(parser: Parser<'_>) -> Result<Self> {
parser.parens(|parser| {
let mut lookahead = parser.lookahead1();
if lookahead.peek::<keyword::param>() {
parser.parse::<keyword::param>()?;
let mut inputs = vec![];
while !parser.is_empty() {
inputs.push(parser.parse()?);
}
Ok(FunctionType::Input(inputs))
} else if lookahead.peek::<keyword::result>() {
parser.parse::<keyword::result>()?;
let mut outputs = vec![];
while !parser.is_empty() {
outputs.push(parser.parse()?);
}
Ok(FunctionType::Output(outputs))
} else {
Err(lookahead.error())
}
})
}
}
#[derive(PartialEq, Debug)]
enum Interface<'a> {
Export(Export<'a>),
#[allow(dead_code)]
Type(Type<'a>),
Import(Import<'a>),
Adapter(Adapter<'a>),
Forward(Forward<'a>),
}
impl<'a> Parse<'a> for Interface<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parens(|parser| {
let mut lookahead = parser.lookahead1();
if lookahead.peek::<AtInterface>() {
parser.parse::<AtInterface>()?;
let mut lookahead = parser.lookahead1();
if lookahead.peek::<keyword::export>() {
Ok(Interface::Export(parser.parse()?))
} else if lookahead.peek::<keyword::func>() {
Ok(Interface::Import(parser.parse()?))
} else if lookahead.peek::<keyword::adapt>() {
Ok(Interface::Adapter(parser.parse()?))
} else if lookahead.peek::<keyword::forward>() {
Ok(Interface::Forward(parser.parse()?))
} else {
Err(lookahead.error())
}
} else {
Err(lookahead.error())
}
})
}
}
impl<'a> Parse<'a> for Export<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<keyword::export>()?;
let name = parser.parse()?;
let mut input_types = vec![];
let mut output_types = vec![];
while !parser.is_empty() {
let function_type = parser.parse::<FunctionType>()?;
match function_type {
FunctionType::Input(mut inputs) => input_types.append(&mut inputs),
FunctionType::Output(mut outputs) => output_types.append(&mut outputs),
}
}
Ok(Export {
name,
input_types,
output_types,
})
}
}
impl<'a> Parse<'a> for Import<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<keyword::func>()?;
parser.parse::<Id>()?;
let (namespace, name) = parser.parens(|parser| {
parser.parse::<keyword::import>()?;
Ok((parser.parse()?, parser.parse()?))
})?;
let mut input_types = vec![];
let mut output_types = vec![];
while !parser.is_empty() {
let function_type = parser.parse::<FunctionType>()?;
match function_type {
FunctionType::Input(mut inputs) => input_types.append(&mut inputs),
FunctionType::Output(mut outputs) => output_types.append(&mut outputs),
}
}
Ok(Import {
namespace,
name,
input_types,
output_types,
})
}
}
impl<'a> Parse<'a> for Adapter<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<keyword::adapt>()?;
let (kind, namespace, name) = parser.parens(|parser| {
let mut lookahead = parser.lookahead1();
if lookahead.peek::<keyword::import>() {
parser.parse::<keyword::import>()?;
Ok((AdapterKind::Import, parser.parse()?, parser.parse()?))
} else if lookahead.peek::<keyword::export>() {
parser.parse::<keyword::export>()?;
Ok((AdapterKind::Export, "", parser.parse()?))
} else {
Err(lookahead.error())
}
})?;
let mut input_types = vec![];
let mut output_types = vec![];
let mut instructions = vec![];
while !parser.is_empty() {
if parser.peek::<LParen>() {
let function_type = parser.parse::<FunctionType>()?;
match function_type {
FunctionType::Input(mut inputs) => input_types.append(&mut inputs),
FunctionType::Output(mut outputs) => output_types.append(&mut outputs),
}
} else {
instructions.push(parser.parse()?);
}
}
Ok(match kind {
AdapterKind::Import => Adapter::Import {
namespace,
name,
input_types,
output_types,
instructions,
},
AdapterKind::Export => Adapter::Export {
name,
input_types,
output_types,
instructions,
},
_ => unimplemented!("Adapter of kind “helper” is not implemented yet."),
})
}
}
impl<'a> Parse<'a> for Forward<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
parser.parse::<keyword::forward>()?;
let name = parser.parens(|parser| {
parser.parse::<keyword::export>()?;
Ok(parser.parse()?)
})?;
Ok(Forward { name })
}
}
impl<'a> Parse<'a> for Interfaces<'a> {
fn parse(parser: Parser<'a>) -> Result<Self> {
let mut interfaces: Interfaces = Default::default();
while !parser.is_empty() {
let interface = parser.parse::<Interface>()?;
match interface {
Interface::Export(export) => interfaces.exports.push(export),
Interface::Type(ty) => interfaces.types.push(ty),
Interface::Import(import) => interfaces.imports.push(import),
Interface::Adapter(adapter) => interfaces.adapters.push(adapter),
Interface::Forward(forward) => interfaces.forwards.push(forward),
}
}
Ok(interfaces)
}
}
/// Parse a WIT definition in its textual format, and produces an
/// [AST](crate::ast) with the [`Interfaces`](crate::ast::Interfaces)
/// structure upon succesful.
///
/// # Examples
///
/// ```rust
/// use wasmer_interface_types::{
/// ast::*,
/// decoders::wat::{parse, Buffer},
/// interpreter::Instruction,
/// };
///
/// # fn main() {
/// let input = Buffer::new(
/// r#"(@interface export "foo"
/// (param i32))
///
/// (@interface export "bar")
///
/// (@interface func $ns_foo (import "ns" "foo")
/// (result i32))
///
/// (@interface func $ns_bar (import "ns" "bar"))
///
/// (@interface adapt (import "ns" "foo")
/// (param i32)
/// arg.get 42)
///
/// (@interface adapt (export "bar")
/// arg.get 42)
///
/// (@interface forward (export "main"))"#,
/// )
/// .unwrap();
/// let output = Interfaces {
/// exports: vec![
/// Export {
/// name: "foo",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![],
/// },
/// Export {
/// name: "bar",
/// input_types: vec![],
/// output_types: vec![],
/// },
/// ],
/// types: vec![],
/// imports: vec![
/// Import {
/// namespace: "ns",
/// name: "foo",
/// input_types: vec![],
/// output_types: vec![InterfaceType::I32],
/// },
/// Import {
/// namespace: "ns",
/// name: "bar",
/// input_types: vec![],
/// output_types: vec![],
/// },
/// ],
/// adapters: vec![
/// Adapter::Import {
/// namespace: "ns",
/// name: "foo",
/// input_types: vec![InterfaceType::I32],
/// output_types: vec![],
/// instructions: vec![Instruction::ArgumentGet { index: 42 }],
/// },
/// Adapter::Export {
/// name: "bar",
/// input_types: vec![],
/// output_types: vec![],
/// instructions: vec![Instruction::ArgumentGet { index: 42 }],
/// },
/// ],
/// forwards: vec![Forward { name: "main" }],
/// };
///
/// assert_eq!(parse(&input).unwrap(), output);
/// # }
/// ```
pub fn parse<'input>(input: &'input Buffer) -> Result<Interfaces<'input>> {
parser::parse::<Interfaces>(&input)
}
#[cfg(test)]
mod tests {
use super::*;
use wast::parser;
fn buffer(input: &str) -> Buffer {
Buffer::new(input).expect("Failed to build the parser buffer.")
}
#[test]
fn test_interface_type() {
let inputs = vec![
"int", "float", "any", "string", "seq", "i32", "i64", "f32", "f64", "anyref",
];
let outputs = vec![
InterfaceType::Int,
InterfaceType::Float,
InterfaceType::Any,
InterfaceType::String,
InterfaceType::Seq,
InterfaceType::I32,
InterfaceType::I64,
InterfaceType::F32,
InterfaceType::F64,
InterfaceType::AnyRef,
];
assert_eq!(inputs.len(), outputs.len());
for (input, output) in inputs.iter().zip(outputs.iter()) {
assert_eq!(
&parser::parse::<InterfaceType>(&buffer(input)).unwrap(),
output
);
}
}
#[test]
fn test_instructions() {
let inputs = vec![
"arg.get 7",
"call 7",
r#"call-export "foo""#,
"read-utf8",
r#"write-utf8 "foo""#,
"as-wasm int",
"as-interface anyref",
"table-ref-add",
"table-ref-get",
"call-method 7",
"make-record int",
"get-field int 7",
"const i32 7",
"fold-seq 7",
"add int",
r#"mem-to-seq int "foo""#,
r#"load int "foo""#,
"seq.new int",
"list.push",
"repeat-until 1 2",
];
let outputs = vec![
Instruction::ArgumentGet { index: 7 },
Instruction::Call { function_index: 7 },
Instruction::CallExport { export_name: "foo" },
Instruction::ReadUtf8,
Instruction::WriteUtf8 {
allocator_name: "foo",
},
Instruction::AsWasm(InterfaceType::Int),
Instruction::AsInterface(InterfaceType::AnyRef),
Instruction::TableRefAdd,
Instruction::TableRefGet,
Instruction::CallMethod(7),
Instruction::MakeRecord(InterfaceType::Int),
Instruction::GetField(InterfaceType::Int, 7),
Instruction::Const(InterfaceType::I32, 7),
Instruction::FoldSeq(7),
Instruction::Add(InterfaceType::Int),
Instruction::MemToSeq(InterfaceType::Int, "foo"),
Instruction::Load(InterfaceType::Int, "foo"),
Instruction::SeqNew(InterfaceType::Int),
Instruction::ListPush,
Instruction::RepeatUntil(1, 2),
];
assert_eq!(inputs.len(), outputs.len());
for (input, output) in inputs.iter().zip(outputs.iter()) {
assert_eq!(
&parser::parse::<Instruction>(&buffer(input)).unwrap(),
output
);
}
}
#[test]
fn test_param_empty() {
let input = buffer("(param)");
let output = FunctionType::Input(vec![]);
assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
}
#[test]
fn test_param() {
let input = buffer("(param i32 string)");
let output = FunctionType::Input(vec![InterfaceType::I32, InterfaceType::String]);
assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
}
#[test]
fn test_result_empty() {
let input = buffer("(result)");
let output = FunctionType::Output(vec![]);
assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
}
#[test]
fn test_result() {
let input = buffer("(result i32 string)");
let output = FunctionType::Output(vec![InterfaceType::I32, InterfaceType::String]);
assert_eq!(parser::parse::<FunctionType>(&input).unwrap(), output);
}
#[test]
fn test_export_with_no_param_no_result() {
let input = buffer(r#"(@interface export "foo")"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_with_some_param_no_result() {
let input = buffer(r#"(@interface export "foo" (param i32))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_with_no_param_some_result() {
let input = buffer(r#"(@interface export "foo" (result i32))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_with_some_param_some_result() {
let input = buffer(r#"(@interface export "foo" (param string) (result i32 i32))"#);
let output = Interface::Export(Export {
name: "foo",
input_types: vec![InterfaceType::String],
output_types: vec![InterfaceType::I32, InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_export_escaped_name() {
let input = buffer(r#"(@interface export "fo\"o")"#);
let output = Interface::Export(Export {
name: r#"fo"o"#,
input_types: vec![],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_no_param_no_result() {
let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo"))"#);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_some_param_no_result() {
let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo") (param i32))"#);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_no_param_some_result() {
let input = buffer(r#"(@interface func $ns_foo (import "ns" "foo") (result i32))"#);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_import_with_some_param_some_result() {
let input = buffer(
r#"(@interface func $ns_foo (import "ns" "foo") (param string) (result i32 i32))"#,
);
let output = Interface::Import(Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::String],
output_types: vec![InterfaceType::I32, InterfaceType::I32],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_adapter_import() {
let input =
buffer(r#"(@interface adapt (import "ns" "foo") (param i32 i32) (result i32))"#);
let output = Interface::Adapter(Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::I32],
output_types: vec![InterfaceType::I32],
instructions: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_adapter_export() {
let input = buffer(r#"(@interface adapt (export "foo") (param i32 i32) (result i32))"#);
let output = Interface::Adapter(Adapter::Export {
name: "foo",
input_types: vec![InterfaceType::I32, InterfaceType::I32],
output_types: vec![InterfaceType::I32],
instructions: vec![],
});
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_forward() {
let input = buffer(r#"(@interface forward (export "foo"))"#);
let output = Interface::Forward(Forward { name: "foo" });
assert_eq!(parser::parse::<Interface>(&input).unwrap(), output);
}
#[test]
fn test_interfaces() {
let input = buffer(
r#"(@interface export "foo"
(param i32))
(@interface export "bar")
(@interface func $ns_foo (import "ns" "foo")
(result i32))
(@interface func $ns_bar (import "ns" "bar"))
(@interface adapt (import "ns" "foo")
(param i32)
arg.get 42)
(@interface adapt (export "bar")
arg.get 42)
(@interface forward (export "main"))"#,
);
let output = Interfaces {
exports: vec![
Export {
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
},
Export {
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
types: vec![],
imports: vec![
Import {
namespace: "ns",
name: "foo",
input_types: vec![],
output_types: vec![InterfaceType::I32],
},
Import {
namespace: "ns",
name: "bar",
input_types: vec![],
output_types: vec![],
},
],
adapters: vec![
Adapter::Import {
namespace: "ns",
name: "foo",
input_types: vec![InterfaceType::I32],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }],
},
Adapter::Export {
name: "bar",
input_types: vec![],
output_types: vec![],
instructions: vec![Instruction::ArgumentGet { index: 42 }],
},
],
forwards: vec![Forward { name: "main" }],
};
assert_eq!(parser::parse::<Interfaces>(&input).unwrap(), output);
}
}

View File

@ -43,8 +43,8 @@ pub(crate) type ExecutableInstruction<Instance, Export, LocalImport, Memory, Mem
/// An interpreter is the central piece of this crate. It is a set of
/// executable instructions. Each instruction takes the runtime as
/// argument. The runtime holds the invocation inputs, the stack, and
/// the WebAssembly instance.
/// argument. The runtime holds the invocation inputs, [the
/// stack](stack), and [the WebAssembly instance](wasm).
///
/// When the interpreter executes the instructions, each of them can
/// query the WebAssembly instance, operates on the stack, or reads

View File

@ -1,21 +1,23 @@
//! This crate contains an implementation of [WebAssembly Interface
//! Types][wit] (abbreviated WIT). It is composed of 4 parts:
//!
//! 1. AST: To represent the WIT language as a tree (which is not
//! really abstract). This is the central representation of the
//! language.
//! 2. Decoders: To read the AST from a particular data representation;
//! for instance, `decoders::binary` reads the AST from a binary.
//! 3. Encoders: To write the AST into a particular format; for
//! instance, `encoders::wat` writes the AST into a string
//! representing WIT with its textual format.
//! 4. Interpreter: WIT defines a concept called Adapters. An adapter
//! contains a set of instructions. So, in more details, this
//! module contains:
//! * A very light and generic stack implementation, exposing only
//! the operations required by the interpreter,
//! * A stack-based interpreter, defined by:
//! 1. [AST]: To represent the WIT language as a tree
//! (which is not really abstract). This is the central
//! representation of the language.
//! 2. [Decoders](decoders): To read the [AST] from a particular data
//! representation; for instance, [`decoders::binary`] reads the
//! [AST] from a binary.
//! 3. [Encoders](encoders): To write the [AST](ast) into a particular
//! format; for instance, [`encoders::wat`] writes the [AST] into a
//! string representing WIT with its textual format.
//! 4. [Interpreter](interpreter): WIT defines a concept called
//! Adapters. An adapter contains a set of [instructions]. So, in
//! more details, this module contains:
//! * [A very light and generic stack
//! implementation](interpreter::stack), exposing only the
//! operations required by the interpreter,
//! * [A stack-based interpreter](interpreter::Interpreter),
//! defined by:
//! * A compiler that transforms a set of instructions into a
//! set of executable instructions,
//! * A stack,
@ -23,16 +25,19 @@
//! of the interpreter), the stack, and the WebAssembly
//! instance (which holds the exports, the imports, the
//! memories, the tables etc.),
//! * An hypothetic WebAssembly runtime, represented as a set of
//! enums, types, and traits —basically this is the part a
//! runtime should take a look to use the
//! * [An hypothetic WebAssembly runtime](interpreter::wasm),
//! represented as a set of enums, types, and traits —basically
//! this is the part a runtime should take a look to use the
//! `wasmer-interface-types` crate—.
//!
//!
//! [wit]: https://github.com/WebAssembly/interface-types
//! [AST]: ast
//! [instructions]: interpreter::Instruction
#![deny(
dead_code,
intra_doc_link_resolution_failure,
missing_docs,
nonstandard_style,
unreachable_patterns,

View File

@ -9,8 +9,8 @@ edition = "2018"
[dependencies]
wabt = "0.9.1"
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-runtime = { path = "../runtime", version = "0.14.0" }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"] }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
wasmer-runtime = { path = "../runtime", version = "0.14.1" }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"] }
[features]

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-llvm-backend"
version = "0.14.0"
version = "0.14.1"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
repository = "https://github.com/wasmerio/wasmer"
@ -10,8 +10,8 @@ edition = "2018"
readme = "README.md"
[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmparser = "0.45.0"
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
wasmparser = "0.51.3"
smallvec = "0.6"
goblin = "0.0.24"
libc = "0.2.60"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -37,7 +37,7 @@ use wasmer_runtime_core::{
codegen::*,
memory::MemoryType,
module::{ModuleInfo, ModuleInner},
parse::wp_type_to_type,
parse::{wp_type_to_type, LoadError},
structures::{Map, TypedIndex},
types::{
FuncIndex, FuncSig, GlobalIndex, LocalOrImport, MemoryIndex, SigIndex, TableIndex, Type,
@ -670,7 +670,7 @@ fn resolve_memory_ptr<'ctx>(
memarg: &MemoryImmediate,
ptr_ty: PointerType<'ctx>,
value_size: usize,
) -> Result<PointerValue<'ctx>, BinaryReaderError> {
) -> Result<PointerValue<'ctx>, CodegenError> {
// Look up the memory base (as pointer) and bounds (as unsigned integer).
let memory_cache = ctx.memory(MemoryIndex::new(0), intrinsics, module.clone());
let (mem_base, mem_bound, minimum, _maximum) = match memory_cache {
@ -958,7 +958,6 @@ pub struct LLVMModuleCodeGenerator<'ctx> {
intrinsics: Option<Intrinsics<'ctx>>,
functions: Vec<LLVMFunctionCodeGenerator<'ctx>>,
signatures: Map<SigIndex, FunctionType<'ctx>>,
signatures_raw: Map<SigIndex, FuncSig>,
function_signatures: Option<Arc<Map<FuncIndex, SigIndex>>>,
llvm_functions: Rc<RefCell<HashMap<FuncIndex, FunctionValue<'ctx>>>>,
func_import_count: usize,
@ -1206,9 +1205,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
* https://github.com/sunfishcode/wasm-reference-manual/blob/master/WebAssembly.md#control-flow-instructions
***************************/
Operator::Block { ty } => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
let end_block = context.append_basic_block(function, "end");
@ -1282,9 +1280,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
Operator::Br { relative_depth } => {
let frame = state.frame_at_depth(relative_depth)?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
let value_len = if frame.is_loop() {
@ -1314,9 +1311,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
let cond = state.pop1()?;
let frame = state.frame_at_depth(relative_depth)?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
let value_len = if frame.is_loop() {
@ -1346,9 +1342,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
builder.position_at_end(&else_block);
}
Operator::BrTable { ref table } => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
let (label_depths, default_depth) = table.read_table()?;
@ -1372,7 +1367,7 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
.iter()
.enumerate()
.map(|(case_index, &depth)| {
let frame_result: Result<&ControlFrame, BinaryReaderError> =
let frame_result: Result<&ControlFrame, CodegenError> =
state.frame_at_depth(depth);
let frame = match frame_result {
Ok(v) => v,
@ -1396,9 +1391,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
state.reachable = false;
}
Operator::If { ty } => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
let if_then_block = context.append_basic_block(function, "if_then");
let if_else_block = context.append_basic_block(function, "if_else");
@ -1437,9 +1431,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
Operator::Else => {
if state.reachable {
let frame = state.frame_at_depth(0)?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
for phi in frame.phis().to_vec().iter().rev() {
@ -1471,9 +1464,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
Operator::End => {
let frame = state.pop_frame()?;
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
if state.reachable {
@ -1530,9 +1522,8 @@ impl<'ctx> FunctionCodeGenerator<CodegenError> for LLVMFunctionCodeGenerator<'ct
}
}
Operator::Return => {
let current_block = builder.get_insert_block().ok_or(BinaryReaderError {
message: "not currently in a block",
offset: -1isize as usize,
let current_block = builder.get_insert_block().ok_or(CodegenError {
message: "not currently in a block".to_string(),
})?;
let frame = state.outermost_frame()?;
@ -8617,6 +8608,14 @@ impl From<BinaryReaderError> for CodegenError {
}
}
impl From<LoadError> for CodegenError {
fn from(other: LoadError) -> CodegenError {
CodegenError {
message: format!("{:?}", other),
}
}
}
impl Drop for LLVMModuleCodeGenerator<'_> {
fn drop(&mut self) {
// Ensure that all members of the context are dropped before we drop the context.
@ -8716,7 +8715,6 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
module: ManuallyDrop::new(Rc::new(RefCell::new(module))),
functions: vec![],
signatures: Map::new(),
signatures_raw: Map::new(),
function_signatures: None,
llvm_functions: Rc::new(RefCell::new(HashMap::new())),
func_import_count: 0,
@ -8738,7 +8736,7 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
fn next_function(
&mut self,
_module_info: Arc<RwLock<ModuleInfo>>,
module_info: Arc<RwLock<ModuleInfo>>,
_loc: WasmSpan,
) -> Result<&mut LLVMFunctionCodeGenerator<'ctx>, CodegenError> {
// Creates a new function and returns the function-scope code generator for it.
@ -8757,7 +8755,7 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
let func_index = FuncIndex::new(self.func_import_count + self.functions.len());
let sig_id = self.function_signatures.as_ref().unwrap()[func_index];
let func_sig = self.signatures_raw[sig_id].clone();
let func_sig = module_info.read().unwrap().signatures[sig_id].clone();
let function = &self.llvm_functions.borrow_mut()[&func_index];
function.set_personality_function(*self.personality_func);
@ -8965,7 +8963,6 @@ impl<'ctx> ModuleCodeGenerator<LLVMFunctionCodeGenerator<'ctx>, LLVMBackend, Cod
)
})
.collect();
self.signatures_raw = signatures.clone();
Ok(())
}

View File

@ -1,15 +1,16 @@
use crate::code::CodegenError;
use wasmer_runtime_core::parse::wp_type_to_type;
use wasmer_runtime_core::types::Type;
use wasmparser::{BinaryReaderError, TypeOrFuncType as WpTypeOrFuncType};
use wasmparser::TypeOrFuncType as WpTypeOrFuncType;
pub fn blocktype_to_type(ty: WpTypeOrFuncType) -> Result<Type, BinaryReaderError> {
pub fn blocktype_to_type(ty: WpTypeOrFuncType) -> Result<Type, CodegenError> {
match ty {
WpTypeOrFuncType::Type(inner_ty) => wp_type_to_type(inner_ty),
WpTypeOrFuncType::Type(inner_ty) => Ok(wp_type_to_type(inner_ty)?),
_ => {
return Err(BinaryReaderError {
return Err(CodegenError {
message:
"the wasmer llvm backend does not yet support the multi-value return extension",
offset: -1isize as usize,
"the wasmer llvm backend does not yet support the multi-value return extension"
.to_string(),
});
}
}

View File

@ -1,3 +1,4 @@
use crate::code::CodegenError;
use inkwell::{
basic_block::BasicBlock,
values::{BasicValue, BasicValueEnum, PhiValue},
@ -5,7 +6,6 @@ use inkwell::{
use smallvec::SmallVec;
use std::cell::Cell;
use std::ops::{BitAnd, BitOr, BitOrAssign};
use wasmparser::BinaryReaderError;
#[derive(Debug)]
pub enum ControlFrame<'ctx> {
@ -229,21 +229,19 @@ impl<'ctx> State<'ctx> {
self.stack.truncate(stack_size_snapshot);
}
pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, BinaryReaderError> {
self.control_stack.get(0).ok_or(BinaryReaderError {
message: "outermost_frame: invalid control stack depth",
offset: -1isize as usize,
pub fn outermost_frame(&self) -> Result<&ControlFrame<'ctx>, CodegenError> {
self.control_stack.get(0).ok_or(CodegenError {
message: "outermost_frame: invalid control stack depth".to_string(),
})
}
pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, BinaryReaderError> {
pub fn frame_at_depth(&self, depth: u32) -> Result<&ControlFrame<'ctx>, CodegenError> {
let index = self
.control_stack
.len()
.checked_sub(1 + (depth as usize))
.ok_or(BinaryReaderError {
message: "frame_at_depth: invalid control stack depth",
offset: -1isize as usize,
.ok_or(CodegenError {
message: "frame_at_depth: invalid control stack depth".to_string(),
})?;
Ok(&self.control_stack[index])
}
@ -251,22 +249,20 @@ impl<'ctx> State<'ctx> {
pub fn frame_at_depth_mut(
&mut self,
depth: u32,
) -> Result<&mut ControlFrame<'ctx>, BinaryReaderError> {
) -> Result<&mut ControlFrame<'ctx>, CodegenError> {
let index = self
.control_stack
.len()
.checked_sub(1 + (depth as usize))
.ok_or(BinaryReaderError {
message: "frame_at_depth_mut: invalid control stack depth",
offset: -1isize as usize,
.ok_or(CodegenError {
message: "frame_at_depth_mut: invalid control stack depth".to_string(),
})?;
Ok(&mut self.control_stack[index])
}
pub fn pop_frame(&mut self) -> Result<ControlFrame<'ctx>, BinaryReaderError> {
self.control_stack.pop().ok_or(BinaryReaderError {
message: "pop_frame: cannot pop from control stack",
offset: -1isize as usize,
pub fn pop_frame(&mut self) -> Result<ControlFrame<'ctx>, CodegenError> {
self.control_stack.pop().ok_or(CodegenError {
message: "pop_frame: cannot pop from control stack".to_string(),
})
}
@ -285,20 +281,17 @@ impl<'ctx> State<'ctx> {
self.stack.push((value.as_basic_value_enum(), info));
}
pub fn pop1(&mut self) -> Result<BasicValueEnum<'ctx>, BinaryReaderError> {
pub fn pop1(&mut self) -> Result<BasicValueEnum<'ctx>, CodegenError> {
Ok(self.pop1_extra()?.0)
}
pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> {
self.stack.pop().ok_or(BinaryReaderError {
message: "pop1_extra: invalid value stack",
offset: -1isize as usize,
pub fn pop1_extra(&mut self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), CodegenError> {
self.stack.pop().ok_or(CodegenError {
message: "pop1_extra: invalid value stack".to_string(),
})
}
pub fn pop2(
&mut self,
) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), BinaryReaderError> {
pub fn pop2(&mut self) -> Result<(BasicValueEnum<'ctx>, BasicValueEnum<'ctx>), CodegenError> {
let v2 = self.pop1()?;
let v1 = self.pop1()?;
Ok((v1, v2))
@ -311,7 +304,7 @@ impl<'ctx> State<'ctx> {
(BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
),
BinaryReaderError,
CodegenError,
> {
let v2 = self.pop1_extra()?;
let v1 = self.pop1_extra()?;
@ -326,7 +319,7 @@ impl<'ctx> State<'ctx> {
(BasicValueEnum<'ctx>, ExtraInfo),
(BasicValueEnum<'ctx>, ExtraInfo),
),
BinaryReaderError,
CodegenError,
> {
let v3 = self.pop1_extra()?;
let v2 = self.pop1_extra()?;
@ -334,25 +327,23 @@ impl<'ctx> State<'ctx> {
Ok((v1, v2, v3))
}
pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), BinaryReaderError> {
let index = self.stack.len().checked_sub(1).ok_or(BinaryReaderError {
message: "peek1_extra: invalid value stack",
offset: -1isize as usize,
pub fn peek1_extra(&self) -> Result<(BasicValueEnum<'ctx>, ExtraInfo), CodegenError> {
let index = self.stack.len().checked_sub(1).ok_or(CodegenError {
message: "peek1_extra: invalid value stack".to_string(),
})?;
Ok(self.stack[index])
}
pub fn peekn(&self, n: usize) -> Result<Vec<BasicValueEnum<'ctx>>, BinaryReaderError> {
pub fn peekn(&self, n: usize) -> Result<Vec<BasicValueEnum<'ctx>>, CodegenError> {
Ok(self.peekn_extra(n)?.iter().map(|x| x.0).collect())
}
pub fn peekn_extra(
&self,
n: usize,
) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], BinaryReaderError> {
let index = self.stack.len().checked_sub(n).ok_or(BinaryReaderError {
message: "peekn_extra: invalid value stack",
offset: -1isize as usize,
) -> Result<&[(BasicValueEnum<'ctx>, ExtraInfo)], CodegenError> {
let index = self.stack.len().checked_sub(n).ok_or(CodegenError {
message: "peekn_extra: invalid value stack".to_string(),
})?;
Ok(&self.stack[index..])
@ -361,16 +352,15 @@ impl<'ctx> State<'ctx> {
pub fn popn_save_extra(
&mut self,
n: usize,
) -> Result<Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, BinaryReaderError> {
) -> Result<Vec<(BasicValueEnum<'ctx>, ExtraInfo)>, CodegenError> {
let v = self.peekn_extra(n)?.to_vec();
self.popn(n)?;
Ok(v)
}
pub fn popn(&mut self, n: usize) -> Result<(), BinaryReaderError> {
let index = self.stack.len().checked_sub(n).ok_or(BinaryReaderError {
message: "popn: invalid value stack",
offset: -1isize as usize,
pub fn popn(&mut self, n: usize) -> Result<(), CodegenError> {
let index = self.stack.len().checked_sub(n).ok_or(CodegenError {
message: "popn: invalid value stack".to_string(),
})?;
self.stack.truncate(index);

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-middleware-common-tests"
version = "0.14.0"
version = "0.14.1"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
edition = "2018"
repository = "https://github.com/wasmerio/wasmer"
@ -8,11 +8,11 @@ license = "MIT"
publish = false
[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-middleware-common = { path = "../middleware-common", version = "0.14.0" }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
wasmer-middleware-common = { path = "../middleware-common", version = "0.14.1" }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true }
[features]
clif = ["wasmer-clif-backend"]

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-middleware-common"
version = "0.14.0"
version = "0.14.1"
repository = "https://github.com/wasmerio/wasmer"
description = "Wasmer runtime common middlewares"
license = "MIT"
@ -10,4 +10,4 @@ categories = ["wasm"]
edition = "2018"
[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-runtime-c-api"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer C API library"
documentation = "https://wasmerio.github.io/wasmer/c/runtime-c-api/"
license = "MIT"
@ -20,22 +20,22 @@ libc = "0.2.60"
[dependencies.wasmer-runtime]
default-features = false
path = "../runtime"
version = "0.14.0"
version = "0.14.1"
[dependencies.wasmer-runtime-core]
default-features = false
path = "../runtime-core"
version = "0.14.0"
version = "0.14.1"
[dependencies.wasmer-wasi]
default-features = false
path = "../wasi"
version = "0.14.0"
version = "0.14.1"
optional = true
[dependencies.wasmer-emscripten]
path = "../emscripten"
version = "0.14.0"
version = "0.14.1"
optional = true
[features]

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -7,7 +7,7 @@ DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = "wasmer-runtime-c-api"
PROJECT_NUMBER =
PROJECT_BRIEF =
PROJECT_LOGO = ../../logo.png
PROJECT_LOGO = ../../assets/logo.png
OUTPUT_DIRECTORY = doc/
CREATE_SUBDIRS = NO
ALLOW_UNICODE_NAMES = NO

View File

@ -127,7 +127,7 @@ pub unsafe extern "C" fn wasmer_emscripten_call_main(
/// `wasmer_emscripten_globals_t` from a `wasmer_module_t`.
///
/// WARNING:
///1
///
/// This `import_object_t` contains thin-wrappers around host system calls.
/// Do not use this to execute untrusted code without additional sandboxing.
#[no_mangle]

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-runtime-core-tests"
version = "0.14.0"
version = "0.14.1"
description = "Tests for the Wasmer runtime core crate"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -9,10 +9,10 @@ publish = false
[dependencies]
wabt = "0.9.1"
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true }
[features]
default = ["backend-cranelift"]

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-runtime-core"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime core library"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -12,7 +12,7 @@ edition = "2018"
[dependencies]
nix = "0.15"
page_size = "0.4"
wasmparser = "0.45.0"
wasmparser = "0.51.3"
parking_lot = "0.10.0"
lazy_static = "1.4"
errno = "0.2"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -275,8 +275,8 @@ fn validate_with_features(bytes: &[u8], features: &Features) -> CompileResult<()
let state = parser.read();
match *state {
wasmparser::ParserState::EndWasm => break Ok(()),
wasmparser::ParserState::Error(err) => Err(CompileError::ValidationError {
msg: err.message.to_string(),
wasmparser::ParserState::Error(ref err) => Err(CompileError::ValidationError {
msg: err.message().to_string(),
})?,
_ => {}
}

View File

@ -169,7 +169,7 @@ pub fn validate_and_report_errors_with_features(
let state = parser.read();
match *state {
wasmparser::ParserState::EndWasm => break Ok(()),
wasmparser::ParserState::Error(e) => break Err(format!("{}", e)),
wasmparser::ParserState::Error(ref e) => break Err(format!("{}", e)),
_ => {}
}
}

View File

@ -21,15 +21,15 @@ use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::{Arc, RwLock};
use wasmparser::{
BinaryReaderError, ExternalKind, FuncType, ImportSectionEntryType, Operator, Type as WpType,
WasmDecoder,
BinaryReaderError, ElemSectionEntryTable, ElementItem, ExternalKind, FuncType,
ImportSectionEntryType, Operator, Type as WpType, WasmDecoder,
};
/// Kind of load error.
#[derive(Debug)]
pub enum LoadError {
/// Parse error.
Parse(BinaryReaderError),
Parse(String),
/// Code generation error.
Codegen(String),
}
@ -44,7 +44,13 @@ impl From<LoadError> for CompileError {
impl From<BinaryReaderError> for LoadError {
fn from(other: BinaryReaderError) -> LoadError {
LoadError::Parse(other)
LoadError::Parse(format!("{:?}", other))
}
}
impl From<&BinaryReaderError> for LoadError {
fn from(other: &BinaryReaderError) -> LoadError {
LoadError::Parse(format!("{:?}", other))
}
}
@ -110,7 +116,7 @@ pub fn read_module<
use wasmparser::ParserState;
let state = parser.read();
match *state {
ParserState::Error(err) => Err(LoadError::Parse(err))?,
ParserState::Error(ref err) => return Err(err.clone().into()),
ParserState::TypeSectionEntry(ref ty) => {
info.write()
.unwrap()
@ -314,15 +320,18 @@ pub fn read_module<
.map_err(|x| LoadError::Codegen(format!("{:?}", x)))?;
func_count = func_count.wrapping_add(1);
}
ParserState::BeginActiveElementSectionEntry(table_index) => {
let table_index = TableIndex::new(table_index as usize);
ParserState::BeginElementSectionEntry {
table: ElemSectionEntryTable::Active(table_index_raw),
ty: WpType::AnyFunc,
} => {
let table_index = TableIndex::new(table_index_raw as usize);
let mut elements: Option<Vec<FuncIndex>> = None;
let mut base: Option<Initializer> = None;
loop {
let state = parser.read();
match *state {
ParserState::Error(err) => return Err(LoadError::Parse(err)),
ParserState::Error(ref err) => return Err(err.into()),
ParserState::InitExpressionOperator(ref op) => {
base = Some(eval_init_expr(op)?)
}
@ -330,9 +339,11 @@ pub fn read_module<
elements = Some(
_elements
.iter()
.cloned()
.map(|index| FuncIndex::new(index as usize))
.collect(),
.map(|elem_idx| match elem_idx {
ElementItem::Null => Err(LoadError::Parse(format!("Error at table {}: null entries in tables are not yet supported", table_index_raw))),
ElementItem::Func(idx) => Ok(FuncIndex::new(*idx as usize)),
})
.collect::<Result<Vec<FuncIndex>, LoadError>>()?,
);
}
ParserState::BeginInitExpressionBody
@ -350,6 +361,15 @@ pub fn read_module<
info.write().unwrap().elem_initializers.push(table_init);
}
ParserState::BeginElementSectionEntry {
table: ElemSectionEntryTable::Active(table_index),
ty,
} => {
return Err(LoadError::Parse(format!(
"Error at table {}: type \"{:?}\" is not supported in tables yet",
table_index, ty
)));
}
ParserState::BeginActiveDataSectionEntry(memory_index) => {
let memory_index = MemoryIndex::new(memory_index as usize);
let mut base: Option<Initializer> = None;
@ -358,7 +378,7 @@ pub fn read_module<
loop {
let state = parser.read();
match *state {
ParserState::Error(err) => return Err(LoadError::Parse(err)),
ParserState::Error(ref err) => return Err(err.into()),
ParserState::InitExpressionOperator(ref op) => {
base = Some(eval_init_expr(op)?)
}
@ -385,7 +405,7 @@ pub fn read_module<
let init = loop {
let state = parser.read();
match *state {
ParserState::Error(err) => return Err(LoadError::Parse(err)),
ParserState::Error(ref err) => return Err(err.into()),
ParserState::InitExpressionOperator(ref op) => {
break eval_init_expr(op)?;
}
@ -424,7 +444,7 @@ pub fn read_module<
}
/// Convert given `WpType` to `Type`.
pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> {
pub fn wp_type_to_type(ty: WpType) -> Result<Type, LoadError> {
match ty {
WpType::I32 => Ok(Type::I32),
WpType::I64 => Ok(Type::I64),
@ -432,10 +452,9 @@ pub fn wp_type_to_type(ty: WpType) -> Result<Type, BinaryReaderError> {
WpType::F64 => Ok(Type::F64),
WpType::V128 => Ok(Type::V128),
_ => {
return Err(BinaryReaderError {
message: "broken invariant, invalid type",
offset: -1isize as usize,
});
return Err(LoadError::Parse(
"broken invariant, invalid type".to_string(),
));
}
}
}
@ -451,7 +470,7 @@ pub fn type_to_wp_type(ty: Type) -> WpType {
}
}
fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, BinaryReaderError> {
fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, LoadError> {
assert_eq!(func_ty.form, WpType::Func);
Ok(FuncSig::new(
@ -470,7 +489,7 @@ fn func_type_to_func_sig(func_ty: &FuncType) -> Result<FuncSig, BinaryReaderErro
))
}
fn eval_init_expr(op: &Operator) -> Result<Initializer, BinaryReaderError> {
fn eval_init_expr(op: &Operator) -> Result<Initializer, LoadError> {
Ok(match *op {
Operator::GlobalGet { global_index } => {
Initializer::GetGlobal(ImportedGlobalIndex::new(global_index as usize))
@ -487,10 +506,9 @@ fn eval_init_expr(op: &Operator) -> Result<Initializer, BinaryReaderError> {
Initializer::Const(Value::V128(u128::from_le_bytes(*value.bytes())))
}
_ => {
return Err(BinaryReaderError {
message: "init expr evaluation failed: unsupported opcode",
offset: -1isize as usize,
});
return Err(LoadError::Parse(
"init expr evaluation failed: unsupported opcode".to_string(),
));
}
})
}

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-runtime"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime library"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -11,17 +11,17 @@ edition = "2018"
readme = "README.md"
[dependencies]
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true }
lazy_static = "1.4"
memmap = "0.7"
[dependencies.wasmer-runtime-core]
path = "../runtime-core"
version = "0.14.0"
version = "0.14.1"
[dependencies.wasmer-clif-backend]
path = "../clif-backend"
version = "0.14.0"
version = "0.14.1"
optional = true
# Dependencies for caching.

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-singlepass-backend"
version = "0.14.0"
version = "0.14.1"
repository = "https://github.com/wasmerio/wasmer"
description = "Wasmer runtime single pass compiler backend"
license = "MIT"
@ -11,7 +11,7 @@ edition = "2018"
readme = "README.md"
[dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
dynasm = "0.5"
dynasmrt = "0.5"
lazy_static = "1.4"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-spectests"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer spectests library"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -9,10 +9,10 @@ edition = "2018"
[dependencies]
glob = "0.3"
wasmer-runtime = { path = "../runtime", version = "0.14.0", default-features = false}
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true}
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true }
wasmer-runtime = { path = "../runtime", version = "0.14.1", default-features = false}
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true}
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true }
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true }
[build-dependencies]
wabt = "0.9.1"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -267,10 +267,6 @@ clif:fail:data.wast:186:windows # AssertUnlinkable - caught panic Any
clif:fail:data.wast:194:windows # AssertUnlinkable - caught panic Any
# LLVM
llvm:fail:f32.wast:1621 # AssertReturn - result F32(0) ("0x0") does not match expected F32(2147483648) ("0x80000000")
llvm:fail:f32.wast:2020 # AssertReturn - result F32(2147483648) ("0x80000000") does not match expected F32(0) ("0x0")
llvm:fail:f64.wast:1621 # AssertReturn - result F64(0) ("0x0") does not match expected F64(9223372036854775808) ("0x8000000000000000")
llvm:fail:f64.wast:2020 # AssertReturn - result F64(9223372036854775808) ("0x8000000000000000") does not match expected F64(0) ("0x0")
llvm:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: incorrect `call_indirect` signature
# LLVM AArch64
@ -312,48 +308,65 @@ singlepass:skip:simd_binaryen.wast:* # SIMD not implemented
singlepass:skip:atomic.wast:*:*:aarch64 # Threads not yet supported on singlepass
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 []
singlepass:fail:address.wast:197 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:198 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:200 # AssertTrap - expected trap, got []
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:481 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:482 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:483 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:484 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:485 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:486 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:487 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:489 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:490 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:491 # AssertTrap - expected trap, got []
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:541 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:542 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:588 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:589 # AssertTrap - expected trap, got []
singlepass:fail:globals.wast:243 # AssertInvalid - Should be invalid
singlepass:fail:linking.wast:134 # AssertReturn - Call failed RuntimeError: 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: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:147 # 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: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: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:388 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:address.wast:200:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:201:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:202:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:203:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:204:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:489:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:490:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:491:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:492:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:495:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:542:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:589:linux:x86_64 # AssertTrap - expected trap, got []
singlepass:fail:linking.wast:137:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:139:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:142:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:144:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:147:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:149:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:185:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:187:linux # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:388:linux # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:address.wast:194:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:195:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:196:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:197:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:198:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:200:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:201:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:202:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:203:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:204:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:481:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:482:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:483:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:484:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:485:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:486:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:487:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:489:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:490:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:491:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:492:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:493:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:494:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:495:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:541:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:542:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:588:macos # AssertTrap - expected trap, got []
singlepass:fail:address.wast:589:macos # AssertTrap - expected trap, got []
singlepass:fail:linking.wast:137:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:139:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:142:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:144:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:147:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:149:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:185:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:187:macos # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:388:macos # AssertReturn - Call failed RuntimeError: 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)]

View File

@ -48,12 +48,21 @@ mod tests {
&mut self,
failure: SpecFailure,
_testkey: &str,
excludes: &Vec<Exclude>,
excludes: &mut Vec<Option<Exclude>>,
line: u64,
) {
if excludes
.iter()
.any(|e| e.line_matches(line) && e.exclude_kind == ExcludeKind::Fail)
// Ensure that each exclude is only used once.
if let Some(_) = excludes
.iter_mut()
.find(|e| {
if let Some(ref e) = e {
e.line_matches(line) && e.exclude_kind == ExcludeKind::Fail
} else {
false
}
})
.take()
.and_then(|x| x.take())
{
self.allowed_failure += 1;
return;
@ -88,6 +97,21 @@ mod tests {
"windows"
}
#[cfg(target_os = "linux")]
fn get_target_os() -> &'static str {
"linux"
}
#[cfg(target_os = "macos")]
fn get_target_os() -> &'static str {
"macos"
}
#[cfg(target_os = "windows")]
fn get_target_os() -> &'static str {
"windows"
}
fn get_target_arch() -> &'static str {
if cfg!(target_arch = "x86_64") {
"x86_64"
@ -110,6 +134,7 @@ mod tests {
// clif:skip:data.wast:172:unix:x86
#[allow(dead_code)]
#[derive(Clone)]
struct Exclude {
backend: Option<String>,
exclude_kind: ExcludeKind,
@ -261,13 +286,11 @@ mod tests {
let mut named_modules: HashMap<String, Arc<Mutex<Instance>>> = HashMap::new();
let mut registered_modules: HashMap<String, Arc<Mutex<Instance>>> = HashMap::new();
//
let empty_excludes = vec![];
let excludes = if excludes.contains_key(filename) {
excludes.get(filename).unwrap()
} else {
&empty_excludes
};
let mut excludes: Vec<_> = excludes
.get(filename)
.map(|file| file.iter().map(|x| Some(x.clone())).collect())
.unwrap_or(vec![]);
let excludes = &mut excludes;
let backend = get_compiler_name();
@ -281,6 +304,7 @@ mod tests {
// Skip tests that match this line
if excludes
.iter()
.filter_map(|x| x.as_ref())
.any(|e| e.line_exact_match(line) && e.exclude_kind == ExcludeKind::Skip)
{
continue;
@ -1074,6 +1098,21 @@ mod tests {
},
}
}
// Check for unused excludes.
for excl in excludes {
if let Some(ref excl) = *excl {
if excl.exclude_kind == ExcludeKind::Fail {
test_report.failed += 1;
test_report.failures.push(SpecFailure {
file: filename.to_string(),
line: excl.line.unwrap_or(0),
kind: format!("{}", "Exclude"),
message: format!("Excluded failure did not occur"),
});
}
}
}
Ok(test_report)
}
@ -1235,6 +1274,7 @@ mod tests {
let mut result = HashMap::new();
let mut file_excludes = HashSet::new();
let current_backend = get_compiler_name();
let current_target_os = get_target_os();
let current_target_family = get_target_family();
let current_target_arch = get_target_arch();
@ -1283,7 +1323,8 @@ mod tests {
};
if exclude.matches_backend(current_backend)
&& exclude.matches_target_family(current_target_family)
&& (exclude.matches_target_family(current_target_os)
|| exclude.matches_target_family(current_target_family))
&& exclude.matches_target_arch(current_target_arch)
{
// Skip the whole file for line * and skip

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi-experimental-io-devices"
version = "0.14.0"
version = "0.14.1"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
edition = "2018"
repository = "https://github.com/wasmerio/wasmer"
@ -14,8 +14,8 @@ maintenance = { status = "experimental" }
[dependencies]
log = "0.4"
minifb = "0.13"
wasmer-wasi = { version = "0.14.0", path = "../wasi" }
wasmer-runtime-core = { version = "0.14.0", path = "../runtime-core" }
wasmer-wasi = { version = "0.14.1", path = "../wasi" }
wasmer-runtime-core = { version = "0.14.1", path = "../runtime-core" }
ref_thread_local = "0.0"
serde = "1"
typetag = "0.1"

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi-tests"
version = "0.14.0"
version = "0.14.1"
description = "Tests for our WASI implementation"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -10,18 +10,18 @@ build = "build/mod.rs"
[dependencies]
# We set default features to false to be able to use the singlepass backend properly
wasmer-runtime = { path = "../runtime", version = "0.14.0", default-features = false }
wasmer-wasi = { path = "../wasi", version = "0.14.0" }
wasmer-runtime = { path = "../runtime", version = "0.14.1", default-features = false }
wasmer-wasi = { path = "../wasi", version = "0.14.1" }
# hack to get tests to work
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.0", optional = true}
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.0", optional = true }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.0", features = ["test"], optional = true }
wasmer-clif-backend = { path = "../clif-backend", version = "0.14.1", optional = true}
wasmer-singlepass-backend = { path = "../singlepass-backend", version = "0.14.1", optional = true }
wasmer-llvm-backend = { path = "../llvm-backend", version = "0.14.1", features = ["test"], optional = true }
[build-dependencies]
glob = "0.3"
[dev-dependencies]
wasmer-dev-utils = { path = "../dev-utils", version = "0.14.0"}
wasmer-dev-utils = { path = "../dev-utils", version = "0.14.1"}
[features]
clif = ["wasmer-clif-backend", "wasmer-runtime/default-backend-cranelift"]

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-wasi"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime WASI implementation library"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -19,7 +19,7 @@ getrandom = "0.1"
time = "0.1"
typetag = "0.1"
serde = { version = "1", features = ["derive"] }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
[target.'cfg(windows)'.dependencies]
winapi = "0.3"

View File

@ -1,6 +1,6 @@
[package]
name = "wasmer-win-exception-handler"
version = "0.14.0"
version = "0.14.1"
description = "Wasmer runtime exception handling for Windows"
license = "MIT"
authors = ["The Wasmer Engineering Team <engineering@wasmer.io>"]
@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer"
edition = "2018"
[target.'cfg(windows)'.dependencies]
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.0" }
wasmer-runtime-core = { path = "../runtime-core", version = "0.14.1" }
winapi = { version = "0.3.8", features = ["winbase", "errhandlingapi", "minwindef", "minwinbase", "winnt"] }
libc = "0.2.60"

View File

@ -1,6 +1,6 @@
<p align="center">
<a href="https://wasmer.io" target="_blank" rel="noopener noreferrer">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/logo.png" alt="Wasmer logo">
<img width="300" src="https://raw.githubusercontent.com/wasmerio/wasmer/master/assets/logo.png" alt="Wasmer logo">
</a>
</p>

View File

@ -1,5 +1,5 @@
PREVIOUS_VERSION='0.13.1'
NEXT_VERSION='0.14.0'
PREVIOUS_VERSION='0.14.0'
NEXT_VERSION='0.14.1'
# quick hack
fd Cargo.toml --exec sed -i '' "s/version = \"$PREVIOUS_VERSION\"/version = \"$NEXT_VERSION\"/"

View File

@ -1,6 +1,6 @@
[Setup]
AppName=Wasmer
AppVersion=0.14.0
AppVersion=0.14.1
DefaultDirName={pf}\Wasmer
DefaultGroupName=Wasmer
Compression=lzma2