Merge branch 'master' into feature/add-default-run

This commit is contained in:
Ivan Enderlin 2019-08-22 13:47:37 +02:00 committed by GitHub
commit 7c6c983e3f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
48 changed files with 3174 additions and 935 deletions

33
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,33 @@
# How to Contribute to Wasmer
Thank you for your interest in contributing to Wasmer. This document outlines some recommendations on how to contribute.
## Issues & Feature Requests
Please use the issue template and provide a failing example if possible to help us recreate the issue.
## Pull Requests
For large changes, please try reaching the Wasmer using Github Issues or Spectrum Chat to ensure we can accept the change once it is ready.
We recommend trying the following commands before sending a pull request to ensure code quality:
- `cargo fmt --all` Ensures all code is correctly formatted.
- Run `cargo test` in the crates that you are modifying.
- Run `cargo build --all` (nightly) or `cargo build --all --exclude wasmer-singlepass-backend`
A comprehensive CI test suite will be run by a Wasmer team member after the PR has been created.
### Common Build Issues
**LLVM Dependency**
The LLVM backend requires LLVM to be installed to compile.
So, you may run into the following error:
```
Didn't find usable system-wide LLVM.
No suitable version of LLVM was found system-wide or pointed
```
**Singlepass Nightly Only**
The singlepass crate depends on nightly so you may need to add the `+nightly` cargo flag to compile this crate.
`error[E0554]: #![feature] may not be used on the stable release channel`

542
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -18,18 +18,18 @@ cranelift-wasm = { package = "wasmer-clif-fork-wasm", version = "0.33" }
target-lexicon = "0.4.0"
wasmparser = "0.35.1"
byteorder = "1.3.2"
nix = "0.14.1"
nix = "0.15.0"
libc = "0.2.60"
rayon = "1.1.0"
# Dependencies for caching.
[dependencies.serde]
version = "1.0.98"
version = "1.0.99"
features = ["rc"]
[dependencies.serde_derive]
version = "1.0.98"
[dependencies.serde_bytes]
version = "0.11.1"
version = "0.11.2"
[dependencies.serde-bench]
version = "0.0.7"

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -76,8 +76,7 @@ pub extern "C" fn nearbyintf64(x: f64) -> f64 {
}
}
/// A declaration for the stack probe function in Rust's standard library, for
/// catching callstack overflow.
extern "C" {
pub fn __rust_probestack();
}
// FIXME: Is there a replacement on AArch64?
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
#[no_mangle]
pub extern "C" fn __rust_probestack() {}

View File

@ -138,6 +138,14 @@ pub unsafe fn do_unwind(signum: i32, siginfo: *const c_void, ucontext: *const c_
longjmp(jmp_buf as *mut ::nix::libc::c_void, signum)
}
#[cfg(all(target_os = "linux", target_arch = "aarch64"))]
unsafe fn get_faulting_addr_and_ip(
_siginfo: *const c_void,
_ucontext: *const c_void,
) -> (*const c_void, *const c_void) {
(::std::ptr::null(), ::std::ptr::null())
}
#[cfg(all(target_os = "linux", target_arch = "x86_64"))]
unsafe fn get_faulting_addr_and_ip(
siginfo: *const c_void,
@ -230,5 +238,6 @@ unsafe fn get_faulting_addr_and_ip(
#[cfg(not(any(
all(target_os = "macos", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "x86_64"),
all(target_os = "linux", target_arch = "aarch64"),
)))]
compile_error!("This crate doesn't yet support compiling on operating systems other than linux and macos and architectures other than x86_64");

View File

@ -42,7 +42,7 @@ macro_rules! assert_emscripten_output {
// let module = compile(&wasm_bytes[..])
// .map_err(|err| format!("Can't create the WebAssembly module: {}", err)).unwrap(); // NOTE: Need to figure what the unwrap is for ??
let mut emscripten_globals = EmscriptenGlobals::new(&module);
let mut emscripten_globals = EmscriptenGlobals::new(&module).expect("globals are valid");
let import_object = generate_emscripten_env(&mut emscripten_globals);
let mut instance = module.instantiate(&import_object)

View File

@ -159,7 +159,7 @@ pub fn _gai_strerror(ctx: &mut Ctx, ecode: i32) -> i32 {
.unwrap()
};
for (i, byte) in bytes.iter().enumerate() {
writer[i].set(*byte as i8);
writer[i].set(*byte as _);
}
string_on_guest.offset() as _
@ -283,7 +283,7 @@ pub fn _getaddrinfo(
.deref(ctx.memory(0), 0, str_size as _)
.unwrap();
for (i, b) in canonname_bytes.into_iter().enumerate() {
guest_canonname_writer[i].set(*b as i8)
guest_canonname_writer[i].set(*b as _)
}
guest_canonname

View File

@ -37,7 +37,7 @@ pub fn execvp(ctx: &mut Ctx, command_name_offset: u32, argv_offset: u32) -> i32
// construct raw pointers and hand them to `execvp`
let command_pointer = command_name_string.as_ptr() as *const i8;
let args_pointer = argv.as_ptr();
unsafe { libc_execvp(command_pointer, args_pointer) }
unsafe { libc_execvp(command_pointer as *const _, args_pointer as *const *const _) }
}
/// execl

View File

@ -23,7 +23,7 @@ pub fn printf(ctx: &mut Ctx, memory_offset: i32, extra: i32) -> i32 {
pub fn chroot(ctx: &mut Ctx, name_ptr: i32) -> i32 {
debug!("emscripten::chroot");
let name = emscripten_memory_pointer!(ctx.memory(0), name_ptr) as *const i8;
unsafe { _chroot(name) }
unsafe { _chroot(name as *const _) }
}
/// getpwuid

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -14,7 +16,7 @@ use std::collections::HashMap;
use std::path::PathBuf;
use std::{f64, ffi::c_void};
use wasmer_runtime_core::{
error::CallResult,
error::{CallError, CallResult, ResolveError},
export::Export,
func,
global::Global,
@ -371,10 +373,11 @@ pub fn run_emscripten_instance(
0 => {
instance.call(func_name, &[])?;
}
_ => panic!(
"The emscripten main function has received an incorrect number of params {}",
num_params
),
_ => {
return Err(CallError::Resolve(ResolveError::ExportWrongType {
name: "main".to_string(),
}))
}
};
}
@ -402,11 +405,18 @@ fn store_module_arguments(ctx: &mut Ctx, args: Vec<&str>) -> (u32, u32) {
(argc as u32 - 1, argv_offset)
}
pub fn emscripten_set_up_memory(memory: &Memory, globals: &EmscriptenGlobalsData) {
pub fn emscripten_set_up_memory(
memory: &Memory,
globals: &EmscriptenGlobalsData,
) -> Result<(), String> {
let dynamictop_ptr = globals.dynamictop_ptr;
let dynamic_base = globals.dynamic_base;
if (dynamictop_ptr / 4) as usize >= memory.view::<u32>().len() {
return Err("dynamictop_ptr beyond memory len".to_string());
}
memory.view::<u32>()[(dynamictop_ptr / 4) as usize].set(dynamic_base);
Ok(())
}
pub struct EmscriptenGlobalsData {
@ -434,7 +444,7 @@ pub struct EmscriptenGlobals {
}
impl EmscriptenGlobals {
pub fn new(module: &Module /*, static_bump: u32 */) -> Self {
pub fn new(module: &Module /*, static_bump: u32 */) -> Result<Self, String> {
let mut use_old_abort_on_cannot_grow_memory = false;
for (
index,
@ -456,8 +466,8 @@ impl EmscriptenGlobals {
}
}
let (table_min, table_max) = get_emscripten_table_size(&module);
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module);
let (table_min, table_max) = get_emscripten_table_size(&module)?;
let (memory_min, memory_max, shared) = get_emscripten_memory_size(&module)?;
// Memory initialization
let memory_type = MemoryDescriptor {
@ -486,7 +496,7 @@ impl EmscriptenGlobals {
static_top += 16;
let (dynamic_base, dynamictop_ptr) =
get_emscripten_metadata(&module).unwrap_or_else(|| {
get_emscripten_metadata(&module)?.unwrap_or_else(|| {
let dynamictop_ptr = static_alloc(&mut static_top, 4);
(
align_memory(align_memory(static_top) + TOTAL_STACK),
@ -510,7 +520,7 @@ impl EmscriptenGlobals {
}
};
emscripten_set_up_memory(&memory, &data);
emscripten_set_up_memory(&memory, &data)?;
let mut null_func_names = vec![];
for (
@ -528,14 +538,14 @@ impl EmscriptenGlobals {
}
}
Self {
Ok(Self {
data,
memory,
table,
memory_min,
memory_max,
null_func_names,
}
})
}
}

View File

@ -54,7 +54,7 @@ pub fn killpg(_ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
pub fn pathconf(ctx: &mut Ctx, path_ptr: i32, name: i32) -> i32 {
debug!("emscripten::pathconf");
let path = emscripten_memory_pointer!(ctx.memory(0), path_ptr) as *const i8;
unsafe { libc::pathconf(path, name).try_into().unwrap() }
unsafe { libc::pathconf(path as *const _, name).try_into().unwrap() }
}
#[cfg(not(unix))]

View File

@ -97,7 +97,7 @@ pub fn ___syscall6(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
pub fn ___syscall12(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall12 (chdir) {}", _which);
let path_ptr = varargs.get_str(ctx);
let real_path_owned = get_cstr_path(ctx, path_ptr);
let real_path_owned = get_cstr_path(ctx, path_ptr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -168,13 +168,13 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall38 (rename)");
let old_path = varargs.get_str(ctx);
let new_path = varargs.get_str(ctx);
let real_old_path_owned = get_cstr_path(ctx, old_path);
let real_old_path_owned = get_cstr_path(ctx, old_path as *const _);
let real_old_path = if let Some(ref rp) = real_old_path_owned {
rp.as_c_str().as_ptr()
} else {
old_path
};
let real_new_path_owned = get_cstr_path(ctx, new_path);
let real_new_path_owned = get_cstr_path(ctx, new_path as *const _);
let real_new_path = if let Some(ref rp) = real_new_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -194,7 +194,7 @@ pub fn ___syscall38(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
pub fn ___syscall40(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall40 (rmdir)");
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -359,7 +359,7 @@ pub fn ___syscall183(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32
let buf_writer = buf_offset.deref(ctx.memory(0), 0, len as u32 + 1).unwrap();
for (i, byte) in path_string.bytes().enumerate() {
buf_writer[i].set(byte as i8);
buf_writer[i].set(byte as _);
}
buf_writer[len].set(0);
buf_offset.offset() as i32
@ -535,7 +535,7 @@ pub fn ___syscall195(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
let pathname_addr = varargs.get_str(ctx);
let buf: u32 = varargs.get(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {

View File

@ -146,7 +146,7 @@ pub fn ___syscall5(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
let pathname_addr = varargs.get_str(ctx);
let flags: i32 = varargs.get(ctx);
let mode: u32 = varargs.get(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -198,13 +198,13 @@ pub fn ___syscall83(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
let path1 = varargs.get_str(ctx);
let path2 = varargs.get_str(ctx);
let real_path1_owned = utils::get_cstr_path(ctx, path1);
let real_path1_owned = utils::get_cstr_path(ctx, path1 as *const _);
let real_path1 = if let Some(ref rp) = real_path1_owned {
rp.as_c_str().as_ptr()
} else {
path1
};
let real_path2_owned = utils::get_cstr_path(ctx, path2);
let real_path2_owned = utils::get_cstr_path(ctx, path2 as *const _);
let real_path2 = if let Some(ref rp) = real_path2_owned {
rp.as_c_str().as_ptr()
} else {
@ -227,7 +227,7 @@ pub fn ___syscall85(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> i32 {
let buf = varargs.get_str(ctx);
// let buf_addr: i32 = varargs.get(ctx);
let buf_size: i32 = varargs.get(ctx);
let real_path_owned = get_cstr_path(ctx, pathname_addr);
let real_path_owned = get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -266,7 +266,7 @@ pub fn ___syscall194(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall198(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall198 (lchown) {}", _which);
let path_ptr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path_ptr);
let real_path_owned = utils::get_cstr_path(ctx, path_ptr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -307,7 +307,7 @@ pub fn ___syscall212(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
debug!("emscripten::___syscall212 (chown) {}", _which);
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -336,7 +336,7 @@ pub fn ___syscall219(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall33(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall33 (access) {}", _which);
let path = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -364,7 +364,7 @@ pub fn ___syscall34(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int
pub fn ___syscall39(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_int {
debug!("emscripten::___syscall39 (mkdir) {}", _which);
let pathname_addr = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr);
let real_path_owned = utils::get_cstr_path(ctx, pathname_addr as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -986,7 +986,7 @@ pub fn ___syscall122(ctx: &mut Ctx, _which: c_int, mut varargs: VarArgs) -> c_in
pub fn ___syscall196(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
debug!("emscripten::___syscall196 (lstat64) {}", _which);
let path = varargs.get_str(ctx);
let real_path_owned = utils::get_cstr_path(ctx, path);
let real_path_owned = utils::get_cstr_path(ctx, path as *const _);
let real_path = if let Some(ref rp) = real_path_owned {
rp.as_c_str().as_ptr()
} else {
@ -1063,7 +1063,7 @@ pub fn ___syscall220(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 {
let upper_bound = std::cmp::min((*dirent).d_reclen, 255) as usize;
let mut i = 0;
while i < upper_bound {
*(dirp.add(pos + 11 + i) as *mut i8) = (*dirent).d_name[i];
*(dirp.add(pos + 11 + i) as *mut i8) = (*dirent).d_name[i] as _;
i += 1;
}
// We set the termination string char

View File

@ -33,37 +33,43 @@ pub fn is_emscripten_module(module: &Module) -> bool {
false
}
pub fn get_emscripten_table_size(module: &Module) -> (u32, Option<u32>) {
assert!(
module.info().imported_tables.len() > 0,
"Emscripten requires at least one imported table"
);
pub fn get_emscripten_table_size(module: &Module) -> Result<(u32, Option<u32>), String> {
if module.info().imported_tables.len() == 0 {
return Err("Emscripten requires at least one imported table".to_string());
}
let (_, table) = &module.info().imported_tables[ImportedTableIndex::new(0)];
(table.minimum, table.maximum)
Ok((table.minimum, table.maximum))
}
pub fn get_emscripten_memory_size(module: &Module) -> (Pages, Option<Pages>, bool) {
assert!(
module.info().imported_tables.len() > 0,
"Emscripten requires at least one imported memory"
);
pub fn get_emscripten_memory_size(module: &Module) -> Result<(Pages, Option<Pages>, bool), String> {
if module.info().imported_memories.len() == 0 {
return Err("Emscripten requires at least one imported memory".to_string());
}
let (_, memory) = &module.info().imported_memories[ImportedMemoryIndex::new(0)];
(memory.minimum, memory.maximum, memory.shared)
Ok((memory.minimum, memory.maximum, memory.shared))
}
/// Reads values written by `-s EMIT_EMSCRIPTEN_METADATA=1`
/// Assumes values start from the end in this order:
/// Last export: Dynamic Base
/// Second-to-Last export: Dynamic top pointer
pub fn get_emscripten_metadata(module: &Module) -> Option<(u32, u32)> {
let max_idx = &module.info().globals.iter().map(|(k, _)| k).max()?;
let snd_max_idx = &module
pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, String> {
let max_idx = match module.info().globals.iter().map(|(k, _)| k).max() {
Some(x) => x,
None => return Ok(None),
};
let snd_max_idx = match module
.info()
.globals
.iter()
.map(|(k, _)| k)
.filter(|k| k != max_idx)
.max()?;
.filter(|k| *k != max_idx)
.max()
{
Some(x) => x,
None => return Ok(None),
};
use wasmer_runtime_core::types::{GlobalInit, Initializer::Const, Value::I32};
if let (
@ -76,15 +82,23 @@ pub fn get_emscripten_metadata(module: &Module) -> Option<(u32, u32)> {
..
},
) = (
&module.info().globals[*max_idx],
&module.info().globals[*snd_max_idx],
&module.info().globals[max_idx],
&module.info().globals[snd_max_idx],
) {
Some((
align_memory(*dynamic_base as u32 - 32),
align_memory(*dynamictop_ptr as u32 - 32),
))
let dynamic_base = (*dynamic_base as u32).checked_sub(32).ok_or(format!(
"emscripten unexpected dynamic_base {}",
*dynamic_base as u32
))?;
let dynamictop_ptr = (*dynamictop_ptr as u32).checked_sub(32).ok_or(format!(
"emscripten unexpected dynamictop_ptr {}",
*dynamictop_ptr as u32
))?;
Ok(Some((
align_memory(dynamic_base),
align_memory(dynamictop_ptr),
)))
} else {
None
Ok(None)
}
}
@ -222,7 +236,8 @@ pub fn read_string_from_wasm(memory: &Memory, offset: u32) -> String {
pub fn get_cstr_path(ctx: &mut Ctx, path: *const i8) -> Option<std::ffi::CString> {
use std::collections::VecDeque;
let path_str = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() }.to_string();
let path_str =
unsafe { std::ffi::CStr::from_ptr(path as *const _).to_str().unwrap() }.to_string();
let data = get_emscripten_data(ctx);
let path = PathBuf::from(path_str);
let mut prefix_added = false;

View File

@ -20,7 +20,7 @@ default-features = false
features = ["llvm8-0", "target-x86"]
[target.'cfg(unix)'.dependencies]
nix = "0.14.1"
nix = "0.15.0"
[target.'cfg(windows)'.dependencies]
winapi = { version = "0.3.7", features = ["memoryapi"] }

File diff suppressed because it is too large Load Diff

View File

@ -131,6 +131,7 @@ pub struct Intrinsics {
pub trap_call_indirect_oob: BasicValueEnum,
pub trap_memory_oob: BasicValueEnum,
pub trap_illegal_arithmetic: BasicValueEnum,
pub trap_misaligned_atomic: BasicValueEnum,
// VM intrinsics.
pub memory_grow_dynamic_local: FunctionValue,
@ -458,6 +459,7 @@ impl Intrinsics {
trap_call_indirect_oob: i32_ty.const_int(3, false).as_basic_value_enum(),
trap_memory_oob: i32_ty.const_int(2, false).as_basic_value_enum(),
trap_illegal_arithmetic: i32_ty.const_int(4, false).as_basic_value_enum(),
trap_misaligned_atomic: i32_ty.const_int(5, false).as_basic_value_enum(),
// VM intrinsics.
memory_grow_dynamic_local: module.add_function(

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -16,26 +16,63 @@ use std::{ptr, slice};
use wasmer_runtime::{Instance, Memory, Module, Value};
use wasmer_runtime_core::{export::Export, module::ExportIndex};
/// Intermediate representation of an `Export` instance that is
/// exposed to C.
pub(crate) struct NamedExport {
/// The export name.
pub(crate) name: String,
/// The export instance.
pub(crate) export: Export,
/// The instance that holds the export.
pub(crate) instance: *mut Instance,
}
/// Opaque pointer to `NamedExport`.
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_export_t;
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_exports_t;
/// Opaque pointer to `wasmer_export_t`.
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_export_func_t;
/// Intermediate representation of a vector of `NamedExport` that is
/// exposed to C.
pub(crate) struct NamedExports(pub Vec<NamedExport>);
/// Opaque pointer to `NamedExports`.
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_exports_t;
/// Intermediate representation of an export descriptor that is
/// exposed to C.
pub(crate) struct NamedExportDescriptor {
/// The export name.
name: String,
/// The export kind.
kind: wasmer_import_export_kind,
}
/// Opaque pointer to `NamedExportDescriptor`.
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_export_descriptor_t;
/// Intermediate representation of a vector of `NamedExportDescriptor`
/// that is exposed to C.
pub struct NamedExportDescriptors(Vec<NamedExportDescriptor>);
/// Opaque pointer to `NamedExportDescriptors`.
#[repr(C)]
#[derive(Clone)]
pub struct wasmer_export_descriptors_t;
/// Union of import/export value.
#[repr(C)]
#[derive(Clone, Copy)]
pub union wasmer_import_export_value {
@ -45,6 +82,7 @@ pub union wasmer_import_export_value {
pub global: *const wasmer_global_t,
}
/// List of export/import kinds.
#[allow(non_camel_case_types)]
#[repr(u32)]
#[derive(Clone)]
@ -73,8 +111,6 @@ pub unsafe extern "C" fn wasmer_export_descriptors(
Box::into_raw(named_export_descriptors) as *mut wasmer_export_descriptors_t;
}
pub struct NamedExportDescriptors(Vec<NamedExportDescriptor>);
/// Frees the memory for the given export descriptors
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
@ -136,8 +172,6 @@ pub unsafe extern "C" fn wasmer_export_descriptor_kind(
named_export_descriptor.kind.clone()
}
pub(crate) struct NamedExports(pub Vec<NamedExport>);
/// Frees the memory for the given exports
#[allow(clippy::cast_ptr_alignment)]
#[no_mangle]
@ -429,14 +463,3 @@ impl From<(&std::string::String, &ExportIndex)> for NamedExportDescriptor {
}
}
}
pub(crate) struct NamedExport {
pub(crate) name: String,
pub(crate) export: Export,
pub(crate) instance: *mut Instance,
}
pub(crate) struct NamedExportDescriptor {
name: String,
kind: wasmer_import_export_kind,
}

View File

@ -8,7 +8,7 @@ repository = "https://github.com/wasmerio/wasmer"
edition = "2018"
[dependencies]
nix = "0.14.1"
nix = "0.15.0"
page_size = "0.4.1"
wasmparser = "0.35.1"
parking_lot = "0.9.0"
@ -26,13 +26,13 @@ features = ["serde-1"]
# Dependencies for caching.
[dependencies.serde]
version = "1.0.98"
version = "1.0.99"
# This feature is required for serde to support serializing/deserializing reference counted pointers (e.g. Rc and Arc).
features = ["rc"]
[dependencies.serde_derive]
version = "1.0.98"
[dependencies.serde_bytes]
version = "0.11.1"
version = "0.11.2"
[dependencies.serde-bench]
version = "0.0.7"
[dependencies.blake2b_simd]

View File

@ -114,6 +114,7 @@ impl Default for MemoryBoundCheckMode {
#[derive(Debug, Default)]
pub struct Features {
pub simd: bool,
pub threads: bool,
}
/// Configuration data for the compiler

View File

@ -140,7 +140,7 @@ impl<
pub fn validating_parser_config(features: &Features) -> wasmparser::ValidatingParserConfig {
wasmparser::ValidatingParserConfig {
operator_config: wasmparser::OperatorValidatorConfig {
enable_threads: false,
enable_threads: features.threads,
enable_reference_types: false,
enable_simd: features.simd,
enable_bulk_memory: false,

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -138,7 +140,7 @@ pub fn validate_and_report_errors_with_features(
enable_bulk_memory: false,
enable_multi_value: false,
enable_reference_types: false,
enable_threads: false,
enable_threads: features.threads,
},
mutable_global_imports: true,
};

View File

@ -1,263 +0,0 @@
//! This is mostly copied from https://docs.rs/integer-atomics/1.0.2/src/integer_atomics/atomic.rs.html
//! Many thanks to "main()" for writing this.
use std::cell::UnsafeCell;
use std::mem;
use std::num::Wrapping;
use std::ops::{Add, BitAnd, BitOr, BitXor, Sub};
use std::panic::RefUnwindSafe;
use std::sync::atomic::{AtomicUsize, Ordering};
pub trait IntCast:
Copy
+ Eq
+ Add<Output = Self>
+ BitAnd<Output = Self>
+ BitOr<Output = Self>
+ BitXor<Output = Self>
+ Sub<Output = Self>
{
type Public: PartialEq + Copy;
fn from(u: usize) -> Self;
fn to(self) -> usize;
fn new(p: Self::Public) -> Self;
fn unwrap(self) -> Self::Public;
}
macro_rules! intcast {
($($type:ident)+) => {
$(
impl IntCast for $type {
type Public = $type;
fn from(u: usize) -> Self {
u as $type
}
fn to(self) -> usize {
self as usize
}
fn new(p: $type) -> Self {
p
}
fn unwrap(self) -> $type {
self
}
}
)+
}
}
intcast! { u8 i8 u16 i16 u32 i32 u64 i64 }
#[repr(transparent)]
pub struct Atomic<T> {
v: UnsafeCell<Wrapping<T>>,
}
impl<T: Default + IntCast> Default for Atomic<T> {
fn default() -> Self {
Self::new(T::default().unwrap())
}
}
// TODO: impl Debug
unsafe impl<T> Sync for Atomic<T> {}
impl<T> RefUnwindSafe for Atomic<T> {}
fn inject<T>(a: usize, b: usize, offset: usize) -> usize {
let mask = ((1 << (mem::size_of::<T>() * 8)) - 1) << offset;
(a & !mask) | (b << offset)
}
// straight from libcore's atomic.rs
#[inline]
fn strongest_failure_ordering(order: Ordering) -> Ordering {
use self::Ordering::*;
match order {
Release => Relaxed,
Relaxed => Relaxed,
SeqCst => SeqCst,
Acquire => Acquire,
AcqRel => Acquire,
_ => unreachable!(),
}
}
impl<T: IntCast> Atomic<T> {
#[inline]
fn proxy(&self) -> (&AtomicUsize, usize) {
let ptr = self.v.get() as usize;
let aligned = ptr & !(mem::size_of::<usize>() - 1);
(
unsafe { &*(aligned as *const AtomicUsize) },
(ptr - aligned) * 8,
)
}
#[inline]
pub(super) fn new(v: T::Public) -> Self {
Atomic {
v: UnsafeCell::new(Wrapping(T::new(v))),
}
}
#[inline]
pub fn get_mut(&mut self) -> &mut T::Public {
unsafe { &mut *(self.v.get() as *mut T::Public) }
}
#[inline]
pub fn into_inner(self) -> T::Public {
self.v.into_inner().0.unwrap()
}
#[inline]
pub fn load(&self, order: Ordering) -> T::Public {
let (p, o) = self.proxy();
T::from(p.load(order) >> o).unwrap()
}
#[inline]
fn op<F: Fn(T) -> Option<T>>(&self, f: F, order: Ordering) -> T::Public {
self.op_new(f, order, strongest_failure_ordering(order))
}
#[inline]
fn op_new<F: Fn(T) -> Option<T>>(
&self,
f: F,
success: Ordering,
failure: Ordering,
) -> T::Public {
let (p, o) = self.proxy();
let mut old = p.load(Ordering::Relaxed);
loop {
let old_t = T::from(old >> o);
let new_t = match f(old_t) {
Some(x) => x,
None => return old_t.unwrap(),
};
match Self::op_weak(p, o, old, new_t, success, failure) {
Ok(()) => return T::from(old >> o).unwrap(),
Err(prev) => old = prev,
};
}
}
#[inline]
fn op_weak(
p: &AtomicUsize,
o: usize,
old: usize,
new_t: T,
success: Ordering,
failure: Ordering,
) -> Result<(), usize> {
let new = inject::<T>(old, new_t.to(), o);
p.compare_exchange_weak(old, new, success, failure)
.map(|_| ())
}
#[inline]
pub fn store(&self, val: T::Public, order: Ordering) {
self.op(|_| Some(T::new(val)), order);
}
#[inline]
pub fn swap(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|_| Some(T::new(val)), order)
}
#[inline]
pub fn compare_and_swap(
&self,
current: T::Public,
new: T::Public,
order: Ordering,
) -> T::Public {
self.op(
|x| {
if x == T::new(current) {
Some(T::new(new))
} else {
None
}
},
order,
)
}
#[inline]
pub fn compare_exchange(
&self,
current: T::Public,
new: T::Public,
success: Ordering,
failure: Ordering,
) -> Result<T::Public, T::Public> {
match self.op_new(
|x| {
if x == T::new(current) {
Some(T::new(new))
} else {
None
}
},
success,
failure,
) {
x if x == current => Ok(x),
x => Err(x),
}
}
#[inline]
pub fn compare_exchange_weak(
&self,
current: T::Public,
new: T::Public,
success: Ordering,
failure: Ordering,
) -> Result<T::Public, T::Public> {
let (p, o) = self.proxy();
let old = p.load(Ordering::Relaxed);
let old_t = T::from(old >> o).unwrap();
if old_t != current {
return Err(old_t);
}
Self::op_weak(p, o, old, T::new(new), success, failure)
.map(|()| current)
.map_err(|x| T::from(x >> o).unwrap())
}
#[inline]
pub fn fetch_add(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x + T::new(val)), order)
}
#[inline]
pub fn fetch_sub(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x - T::new(val)), order)
}
#[inline]
pub fn fetch_and(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x & T::new(val)), order)
}
#[inline]
pub fn fetch_or(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x | T::new(val)), order)
}
#[inline]
pub fn fetch_xor(&self, val: T::Public, order: Ordering) -> T::Public {
self.op(|x| Some(x ^ T::new(val)), order)
}
}

View File

@ -12,14 +12,15 @@ use std::{
cell::{Cell, RefCell},
fmt, mem,
rc::Rc,
sync::Arc,
};
pub use self::atomic::Atomic;
pub use self::dynamic::DynamicMemory;
pub use self::static_::{SharedStaticMemory, StaticMemory};
pub use self::static_::StaticMemory;
pub use self::view::{Atomically, MemoryView};
mod atomic;
use parking_lot::Mutex;
mod dynamic;
pub mod ptr;
mod static_;
@ -153,20 +154,10 @@ impl Memory {
unsafe { MemoryView::new(base as _, length as u32) }
}
/// Convert this memory to a shared memory if the shared flag
/// is present in the description used to create it.
pub fn shared(self) -> Option<SharedMemory> {
if self.desc.shared {
Some(SharedMemory { desc: self.desc })
} else {
None
}
}
pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory {
match &self.variant {
MemoryVariant::Unshared(unshared_mem) => unshared_mem.vm_local_memory(),
MemoryVariant::Shared(_) => unimplemented!(),
MemoryVariant::Shared(shared_mem) => shared_mem.vm_local_memory(),
}
}
}
@ -243,7 +234,7 @@ impl UnsharedMemory {
MemoryType::SharedStatic => panic!("attempting to create shared unshared memory"),
};
Ok(UnsharedMemory {
Ok(Self {
internal: Rc::new(UnsharedMemoryInternal {
storage: RefCell::new(storage),
local: Cell::new(local),
@ -291,27 +282,56 @@ impl Clone for UnsharedMemory {
}
pub struct SharedMemory {
#[allow(dead_code)]
desc: MemoryDescriptor,
internal: Arc<SharedMemoryInternal>,
}
pub struct SharedMemoryInternal {
memory: RefCell<Box<StaticMemory>>,
local: Cell<vm::LocalMemory>,
lock: Mutex<()>,
}
impl SharedMemory {
fn new(desc: MemoryDescriptor) -> Result<Self, CreationError> {
Ok(Self { desc })
let mut local = vm::LocalMemory {
base: std::ptr::null_mut(),
bound: 0,
memory: std::ptr::null_mut(),
};
let memory = StaticMemory::new(desc, &mut local)?;
Ok(Self {
internal: Arc::new(SharedMemoryInternal {
memory: RefCell::new(memory),
local: Cell::new(local),
lock: Mutex::new(()),
}),
})
}
pub fn grow(&self, _delta: Pages) -> Result<Pages, GrowError> {
unimplemented!()
pub fn grow(&self, delta: Pages) -> Result<Pages, GrowError> {
let _guard = self.internal.lock.lock();
let mut local = self.internal.local.get();
let pages = self.internal.memory.borrow_mut().grow(delta, &mut local);
pages
}
pub fn size(&self) -> Pages {
unimplemented!()
let _guard = self.internal.lock.lock();
self.internal.memory.borrow_mut().size()
}
pub(crate) fn vm_local_memory(&self) -> *mut vm::LocalMemory {
self.internal.local.as_ptr()
}
}
impl Clone for SharedMemory {
fn clone(&self) -> Self {
unimplemented!()
SharedMemory {
internal: Arc::clone(&self.internal),
}
}
}

View File

@ -1,12 +1,10 @@
use crate::error::GrowError;
use crate::{
error::CreationError,
memory::static_::{SAFE_STATIC_GUARD_SIZE, SAFE_STATIC_HEAP_SIZE},
sys,
types::MemoryDescriptor,
units::Pages,
vm,
};
use crate::{error::CreationError, sys, types::MemoryDescriptor, units::Pages, vm};
#[doc(hidden)]
pub const SAFE_STATIC_HEAP_SIZE: usize = 1 << 32; // 4 GiB
#[doc(hidden)]
pub const SAFE_STATIC_GUARD_SIZE: usize = 1 << 31; // 2 GiB
/// This is an internal-only api.
///

View File

@ -1,10 +0,0 @@
#[doc(hidden)]
pub const SAFE_STATIC_HEAP_SIZE: usize = 1 << 32; // 4 GiB
#[doc(hidden)]
pub const SAFE_STATIC_GUARD_SIZE: usize = 1 << 31; // 2 GiB
mod shared;
mod unshared;
pub use self::shared::SharedStaticMemory;
pub use self::unshared::StaticMemory;

View File

@ -1,11 +0,0 @@
use crate::sys;
use parking_lot::Mutex;
use std::sync::atomic::AtomicUsize;
// Remove this attribute once this is used.
#[allow(dead_code)]
pub struct SharedStaticMemory {
memory: sys::Memory,
current: AtomicUsize,
lock: Mutex<()>,
}

View File

@ -1,8 +1,44 @@
use super::atomic::{Atomic, IntCast};
use crate::types::ValueType;
use std::sync::atomic::{
AtomicI16, AtomicI32, AtomicI64, AtomicI8, AtomicU16, AtomicU32, AtomicU64, AtomicU8,
};
use std::{cell::Cell, marker::PhantomData, ops::Deref, slice};
pub trait Atomic {
type Output;
}
impl Atomic for i8 {
type Output = AtomicI8;
}
impl Atomic for i16 {
type Output = AtomicI16;
}
impl Atomic for i32 {
type Output = AtomicI32;
}
impl Atomic for i64 {
type Output = AtomicI64;
}
impl Atomic for u8 {
type Output = AtomicU8;
}
impl Atomic for u16 {
type Output = AtomicU16;
}
impl Atomic for u32 {
type Output = AtomicU32;
}
impl Atomic for u64 {
type Output = AtomicU64;
}
impl Atomic for f32 {
type Output = AtomicU32;
}
impl Atomic for f64 {
type Output = AtomicU64;
}
pub trait Atomicity {}
pub struct Atomically;
impl Atomicity for Atomically {}
@ -28,10 +64,10 @@ where
}
}
impl<'a, T: IntCast> MemoryView<'a, T, NonAtomically> {
pub fn atomically(&self) -> MemoryView<'a, T, Atomically> {
impl<'a, T: Atomic> MemoryView<'a, T> {
pub fn atomically(&self) -> MemoryView<'a, T::Output, Atomically> {
MemoryView {
ptr: self.ptr,
ptr: self.ptr as *mut T::Output,
length: self.length,
_phantom: PhantomData,
}
@ -45,9 +81,9 @@ impl<'a, T> Deref for MemoryView<'a, T, NonAtomically> {
}
}
impl<'a, T: IntCast> Deref for MemoryView<'a, T, Atomically> {
type Target = [Atomic<T>];
fn deref(&self) -> &[Atomic<T>] {
unsafe { slice::from_raw_parts(self.ptr as *const Atomic<T>, self.length) }
impl<'a, T> Deref for MemoryView<'a, T, Atomically> {
type Target = [T];
fn deref(&self) -> &[T] {
unsafe { slice::from_raw_parts(self.ptr as *const T, self.length) }
}
}

View File

@ -23,6 +23,7 @@ pub enum WasmTrapInfo {
MemoryOutOfBounds = 2,
CallIndirectOOB = 3,
IllegalArithmetic = 4,
MisalignedAtomicAccess = 5,
Unknown,
}
@ -39,6 +40,7 @@ impl fmt::Display for WasmTrapInfo {
WasmTrapInfo::MemoryOutOfBounds => "memory out-of-bounds access",
WasmTrapInfo::CallIndirectOOB => "`call_indirect` out-of-bounds",
WasmTrapInfo::IllegalArithmetic => "illegal arithmetic operation",
WasmTrapInfo::MisalignedAtomicAccess => "misaligned atomic access",
WasmTrapInfo::Unknown => "unknown",
}
)

View File

@ -208,7 +208,7 @@ fn get_intrinsics_for_module(m: &ModuleInfo) -> *const Intrinsics {
match mem_desc.memory_type() {
MemoryType::Dynamic => &INTRINSICS_LOCAL_DYNAMIC_MEMORY,
MemoryType::Static => &INTRINSICS_LOCAL_STATIC_MEMORY,
MemoryType::SharedStatic => unimplemented!(),
MemoryType::SharedStatic => &INTRINSICS_LOCAL_STATIC_MEMORY,
}
}
LocalOrImport::Import(import_mem_index) => {
@ -216,7 +216,7 @@ fn get_intrinsics_for_module(m: &ModuleInfo) -> *const Intrinsics {
match mem_desc.memory_type() {
MemoryType::Dynamic => &INTRINSICS_IMPORTED_DYNAMIC_MEMORY,
MemoryType::Static => &INTRINSICS_IMPORTED_STATIC_MEMORY,
MemoryType::SharedStatic => unimplemented!(),
MemoryType::SharedStatic => &INTRINSICS_IMPORTED_STATIC_MEMORY,
}
}
}

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -98,7 +100,7 @@ pub use wasmer_runtime_core::{compile_with, validate};
pub use wasmer_runtime_core::{func, imports};
pub mod memory {
pub use wasmer_runtime_core::memory::{Atomic, Atomically, Memory, MemoryView};
pub use wasmer_runtime_core::memory::{Atomically, Memory, MemoryView};
}
pub mod wasm {

View File

@ -15,7 +15,7 @@ dynasm = "0.3.2"
dynasmrt = "0.3.1"
lazy_static = "1.3.0"
byteorder = "1.3.2"
nix = "0.14.1"
nix = "0.15.0"
libc = "0.2.60"
smallvec = "0.6.10"
colored = "1.8"

View File

@ -404,22 +404,22 @@ impl ModuleCodeGenerator<X64FunctionCode, X64ExecutionContext, CodegenError>
mut self,
_: &ModuleInfo,
) -> Result<(X64ExecutionContext, Box<dyn CacheGen>), CodegenError> {
let (assembler, breakpoints) = match self.functions.last_mut() {
Some(x) => (x.assembler.take().unwrap(), x.breakpoints.take().unwrap()),
None => {
return Err(CodegenError {
message: "no function",
});
}
let (assembler, function_labels, breakpoints) = match self.functions.last_mut() {
Some(x) => (
x.assembler.take().unwrap(),
x.function_labels.take().unwrap(),
x.breakpoints.take().unwrap(),
),
None => (
self.assembler.take().unwrap(),
self.function_labels.take().unwrap(),
HashMap::new(),
),
};
let total_size = assembler.get_offset().0;
let output = assembler.finalize().unwrap();
let function_labels = if let Some(x) = self.functions.last() {
x.function_labels.as_ref().unwrap()
} else {
self.function_labels.as_ref().unwrap()
};
let mut out_labels: Vec<FuncPtr> = vec![];
let mut out_offsets: Vec<AssemblyOffset> = vec![];

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

473
lib/spectests/spectests/atomic.wast vendored Normal file
View File

@ -0,0 +1,473 @@
;; atomic.wast from WebAssembly test suite.
;; https://github.com/WebAssembly/testsuite/blob/master/LICENSE
;;
;; Modified by Wasmer to parse with the wabt spec test parser, replacing
;; '_u.add' with '.add_u' and similarly for 'sub', 'and', 'or', 'xor', 'xchg'
;; and 'cmpxchg'.
;; atomic operations
(module
(memory 1 1 shared)
(func (export "init") (param $value i64) (i64.store (i32.const 0) (local.get $value)))
(func (export "i32.atomic.load") (param $addr i32) (result i32) (i32.atomic.load (local.get $addr)))
(func (export "i64.atomic.load") (param $addr i32) (result i64) (i64.atomic.load (local.get $addr)))
(func (export "i32.atomic.load8_u") (param $addr i32) (result i32) (i32.atomic.load8_u (local.get $addr)))
(func (export "i32.atomic.load16_u") (param $addr i32) (result i32) (i32.atomic.load16_u (local.get $addr)))
(func (export "i64.atomic.load8_u") (param $addr i32) (result i64) (i64.atomic.load8_u (local.get $addr)))
(func (export "i64.atomic.load16_u") (param $addr i32) (result i64) (i64.atomic.load16_u (local.get $addr)))
(func (export "i64.atomic.load32_u") (param $addr i32) (result i64) (i64.atomic.load32_u (local.get $addr)))
(func (export "i32.atomic.store") (param $addr i32) (param $value i32) (i32.atomic.store (local.get $addr) (local.get $value)))
(func (export "i64.atomic.store") (param $addr i32) (param $value i64) (i64.atomic.store (local.get $addr) (local.get $value)))
(func (export "i32.atomic.store8") (param $addr i32) (param $value i32) (i32.atomic.store8 (local.get $addr) (local.get $value)))
(func (export "i32.atomic.store16") (param $addr i32) (param $value i32) (i32.atomic.store16 (local.get $addr) (local.get $value)))
(func (export "i64.atomic.store8") (param $addr i32) (param $value i64) (i64.atomic.store8 (local.get $addr) (local.get $value)))
(func (export "i64.atomic.store16") (param $addr i32) (param $value i64) (i64.atomic.store16 (local.get $addr) (local.get $value)))
(func (export "i64.atomic.store32") (param $addr i32) (param $value i64) (i64.atomic.store32 (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.add") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.add (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw.add") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.add (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw8.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.add_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw16.add_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.add_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw8.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.add_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw16.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.add_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw32.add_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.add_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.sub") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.sub (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw.sub") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.sub (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw8.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.sub_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw16.sub_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.sub_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw8.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.sub_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw16.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.sub_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw32.sub_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.sub_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.and") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.and (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw.and") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.and (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw8.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.and_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw16.and_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.and_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw8.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.and_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw16.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.and_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw32.and_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.and_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.or") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.or (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw.or") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.or (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw8.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.or_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw16.or_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.or_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw8.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.or_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw16.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.or_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw32.or_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.or_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.xor") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xor (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw.xor") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xor (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw8.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.xor_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw16.xor_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xor_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw8.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.xor_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw16.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xor_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw32.xor_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xor_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.xchg") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw.xchg (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw.xchg") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw.xchg (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw8.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw8.xchg_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw16.xchg_u") (param $addr i32) (param $value i32) (result i32) (i32.atomic.rmw16.xchg_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw8.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw8.xchg_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw16.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw16.xchg_u (local.get $addr) (local.get $value)))
(func (export "i64.atomic.rmw32.xchg_u") (param $addr i32) (param $value i64) (result i64) (i64.atomic.rmw32.xchg_u (local.get $addr) (local.get $value)))
(func (export "i32.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw.cmpxchg (local.get $addr) (local.get $expected) (local.get $value)))
(func (export "i64.atomic.rmw.cmpxchg") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw.cmpxchg (local.get $addr) (local.get $expected) (local.get $value)))
(func (export "i32.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw8.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value)))
(func (export "i32.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i32) (param $value i32) (result i32) (i32.atomic.rmw16.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value)))
(func (export "i64.atomic.rmw8.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw8.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value)))
(func (export "i64.atomic.rmw16.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw16.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value)))
(func (export "i64.atomic.rmw32.cmpxchg_u") (param $addr i32) (param $expected i64) (param $value i64) (result i64) (i64.atomic.rmw32.cmpxchg_u (local.get $addr) (local.get $expected) (local.get $value)))
)
;; *.atomic.load*
(invoke "init" (i64.const 0x0706050403020100))
(assert_return (invoke "i32.atomic.load" (i32.const 0)) (i32.const 0x03020100))
(assert_return (invoke "i32.atomic.load" (i32.const 4)) (i32.const 0x07060504))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0706050403020100))
(assert_return (invoke "i32.atomic.load8_u" (i32.const 0)) (i32.const 0x00))
(assert_return (invoke "i32.atomic.load8_u" (i32.const 5)) (i32.const 0x05))
(assert_return (invoke "i32.atomic.load16_u" (i32.const 0)) (i32.const 0x0100))
(assert_return (invoke "i32.atomic.load16_u" (i32.const 6)) (i32.const 0x0706))
(assert_return (invoke "i64.atomic.load8_u" (i32.const 0)) (i64.const 0x00))
(assert_return (invoke "i64.atomic.load8_u" (i32.const 5)) (i64.const 0x05))
(assert_return (invoke "i64.atomic.load16_u" (i32.const 0)) (i64.const 0x0100))
(assert_return (invoke "i64.atomic.load16_u" (i32.const 6)) (i64.const 0x0706))
(assert_return (invoke "i64.atomic.load32_u" (i32.const 0)) (i64.const 0x03020100))
(assert_return (invoke "i64.atomic.load32_u" (i32.const 4)) (i64.const 0x07060504))
;; *.atomic.store*
(invoke "init" (i64.const 0x0000000000000000))
(assert_return (invoke "i32.atomic.store" (i32.const 0) (i32.const 0xffeeddcc)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x00000000ffeeddcc))
(assert_return (invoke "i64.atomic.store" (i32.const 0) (i64.const 0x0123456789abcdef)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0123456789abcdef))
(assert_return (invoke "i32.atomic.store8" (i32.const 1) (i32.const 0x42)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0123456789ab42ef))
(assert_return (invoke "i32.atomic.store16" (i32.const 4) (i32.const 0x8844)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0123884489ab42ef))
(assert_return (invoke "i64.atomic.store8" (i32.const 1) (i64.const 0x99)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0123884489ab99ef))
(assert_return (invoke "i64.atomic.store16" (i32.const 4) (i64.const 0xcafe)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0123cafe89ab99ef))
(assert_return (invoke "i64.atomic.store32" (i32.const 4) (i64.const 0xdeadbeef)))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0xdeadbeef89ab99ef))
;; *.atomic.rmw*.add
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.add" (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111123456789))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.add" (i32.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1212121213131313))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.add_u" (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111111111de))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.add_u" (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111dc0f))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.add_u" (i32.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111153))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.add_u" (i32.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111d000))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.add_u" (i32.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111dbccb7f6))
;; *.atomic.rmw*.sub
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.sub" (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111fedcba99))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.sub" (i32.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x101010100f0f0f0f))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.sub_u" (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111144))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.sub_u" (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111114613))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.sub_u" (i32.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111111111cf))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.sub_u" (i32.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111115222))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.sub_u" (i32.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111146556a2c))
;; *.atomic.rmw*.and
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.and" (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111110101010))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.and" (i32.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0101010100000000))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.and_u" (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111101))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.and_u" (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111110010))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.and_u" (i32.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111100))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.and_u" (i32.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111001))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.and_u" (i32.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111100110001))
;; *.atomic.rmw*.or
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.or" (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111113355779))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.or" (i32.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111113131313))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.or_u" (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111111111dd))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.or_u" (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111dbff))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.or_u" (i32.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111153))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.or_u" (i32.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111bfff))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.or_u" (i32.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111dbbbb7f5))
;; *.atomic.rmw*.xor
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.xor" (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111103254769))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.xor" (i32.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1010101013131313))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.xor_u" (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111111111dc))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.xor_u" (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111dbef))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.xor_u" (i32.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111153))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.xor_u" (i32.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111affe))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.xor_u" (i32.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111dbaab7f4))
;; *.atomic.rmw*.xchg
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.xchg" (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111112345678))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.xchg" (i32.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0101010102020202))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.xchg_u" (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111111111cd))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.xchg_u" (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111cafe))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.xchg_u" (i32.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111142))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.xchg_u" (i32.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111beef))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.xchg_u" (i32.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111cabba6e5))
;; *.atomic.rmw*.cmpxchg (compare false)
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.cmpxchg" (i32.const 0) (i32.const 0) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.cmpxchg" (i32.const 0) (i64.const 0) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.cmpxchg_u" (i32.const 0) (i32.const 0) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.cmpxchg_u" (i32.const 0) (i32.const 0) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 0) (i64.const 0) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111111))
;; *.atomic.rmw*.cmpxchg (compare true)
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw.cmpxchg" (i32.const 0) (i32.const 0x11111111) (i32.const 0x12345678)) (i32.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111112345678))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw.cmpxchg" (i32.const 0) (i64.const 0x1111111111111111) (i64.const 0x0101010102020202)) (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x0101010102020202))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw8.cmpxchg_u" (i32.const 0) (i32.const 0x11) (i32.const 0xcdcdcdcd)) (i32.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111111111cd))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i32.atomic.rmw16.cmpxchg_u" (i32.const 0) (i32.const 0x1111) (i32.const 0xcafecafe)) (i32.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111cafe))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw8.cmpxchg_u" (i32.const 0) (i64.const 0x11) (i64.const 0x4242424242424242)) (i64.const 0x11))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x1111111111111142))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 0) (i64.const 0x1111) (i64.const 0xbeefbeefbeefbeef)) (i64.const 0x1111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x111111111111beef))
(invoke "init" (i64.const 0x1111111111111111))
(assert_return (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 0) (i64.const 0x11111111) (i64.const 0xcabba6e5cabba6e5)) (i64.const 0x11111111))
(assert_return (invoke "i64.atomic.load" (i32.const 0)) (i64.const 0x11111111cabba6e5))
;; unaligned accesses
(assert_trap (invoke "i32.atomic.load" (i32.const 1)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.load" (i32.const 1)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.load16_u" (i32.const 1)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.load16_u" (i32.const 1)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.load32_u" (i32.const 1)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.store" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.store" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.store16" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.store16" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.store32" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.add" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.add" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.add_u" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.add_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.add_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.sub" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.sub" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.sub_u" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.sub_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.sub_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.and" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.and" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.and_u" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.and_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.and_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.or" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.or" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.or_u" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.or_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.or_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.xor" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.xor" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.xor_u" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.xor_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.xor_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.xchg" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.xchg" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.xchg_u" (i32.const 1) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.xchg_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.xchg_u" (i32.const 1) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw.cmpxchg" (i32.const 1) (i32.const 0) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw.cmpxchg" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i32.atomic.rmw16.cmpxchg_u" (i32.const 1) (i32.const 0) (i32.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw16.cmpxchg_u" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic")
(assert_trap (invoke "i64.atomic.rmw32.cmpxchg_u" (i32.const 1) (i64.const 0) (i64.const 0)) "unaligned atomic")
;; unshared memory
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.load (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.load (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.load16_u (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.load16_u (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.load32_u (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (i32.atomic.store (i32.const 0) (i32.const 0)))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (i64.atomic.store (i32.const 0) (i64.const 0)))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (i32.atomic.store16 (i32.const 0) (i32.const 0)))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (i64.atomic.store16 (i32.const 0) (i64.const 0)))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (i64.atomic.store32 (i32.const 0) (i64.const 0)))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.add (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.add (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.add_u (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.add_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.add_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.sub (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.sub (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.sub_u (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.sub_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.sub_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.and (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.and (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.and_u (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.and_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.and_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.or (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.or (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.or_u (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.or_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.or_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.xor (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.xor (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.xor_u (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.xor_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.xor_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.xchg (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.xchg (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.xchg_u (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.xchg_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.xchg_u (i32.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw.cmpxchg (i32.const 0) (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw.cmpxchg (i32.const 0) (i64.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i32.atomic.rmw16.cmpxchg_u (i32.const 0) (i32.const 0) (i32.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw16.cmpxchg_u (i32.const 0) (i64.const 0) (i64.const 0))))) "atomic accesses require shared memory")
(assert_invalid (module (memory 1 1) (func (drop (i64.atomic.rmw32.cmpxchg_u (i32.const 0) (i64.const 0) (i64.const 0))))) "atomic accesses require shared memory")

View File

@ -589,9 +589,7 @@
;; Test that LLVM undef isn't introduced by SIMD shifts greater than the scalar width.
(module
;; wabt says "memories may not be shared"
;; (memory 1 1 shared)
(memory 1 1)
(memory 1 1 shared)
(func (export "test-simd-shift-mask") (param $v v128) (result i32)
(block $0
(block $1

View File

@ -17,6 +17,7 @@
#
# Cranelift
clif:skip:atomic.wast:* # Threads not implemented
clif:skip:simd.wast:* # SIMD not implemented
clif:skip:simd_binaryen.wast:* # SIMD not implemented
@ -860,6 +861,7 @@ llvm:skip:unreachable.wast:*:windows
llvm:skip:unwind.wast:*:windows
# Singlepass
singlepass:skip:atomic.wast:* # Threads not implemented
singlepass:skip:simd.wast:* # SIMD not implemented
singlepass:skip:simd_binaryen.wast:* # SIMD not implemented
@ -896,39 +898,6 @@ singlepass:fail:address.wast:586 # AssertTrap - expected trap, got Runtime:Error
singlepass:fail:address.wast:588 # AssertTrap - expected trap, got []
singlepass:fail:address.wast:589 # AssertTrap - expected trap, got []
singlepass:fail:align.wast:864 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:binary-leb128.wast:2 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:7 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:12 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:18 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:24 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:32 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:40 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:48 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:56 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:65 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:74 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:86 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:98 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:157 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:164 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:171 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:178 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:186 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:193 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:200 # Module - caught panic Any
singlepass:fail:binary-leb128.wast:207 # Module - caught panic Any
singlepass:fail:binary.wast:1 # Module - caught panic Any
singlepass:fail:binary.wast:2 # Module - caught panic Any
singlepass:fail:binary.wast:3 # Module - caught panic Any
singlepass:fail:binary.wast:4 # Module - caught panic Any
singlepass:fail:binary.wast:406 # Module - caught panic Any
singlepass:fail:binary.wast:412 # Module - caught panic Any
singlepass:fail:binary.wast:418 # Module - caught panic Any
singlepass:fail:binary.wast:446 # Module - caught panic Any
singlepass:fail:binary.wast:498 # Module - caught panic Any
singlepass:fail:binary.wast:514 # Module - caught panic Any
singlepass:fail:binary.wast:530 # Module - caught panic Any
singlepass:fail:binary.wast:661 # Module - caught panic Any
singlepass:fail:call.wast:289 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:469 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:470 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -943,10 +912,6 @@ singlepass:fail:call_indirect.wast:493 # AssertTrap - expected trap, got Runtime
singlepass:fail:call_indirect.wast:494 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:500 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:call_indirect.wast:501 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:comments.wast:10 # Module - caught panic Any
singlepass:fail:comments.wast:52 # Module - caught panic Any
singlepass:fail:comments.wast:62 # Module - caught panic Any
singlepass:fail:comments.wast:71 # Module - caught panic Any
singlepass:fail:conversions.wast:70 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:71 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:72 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -1014,98 +979,7 @@ singlepass:fail:conversions.wast:239 # AssertTrap - expected trap, got Runtime:E
singlepass:fail:conversions.wast:240 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:241 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:conversions.wast:242 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:custom.wast:1 # Module - caught panic Any
singlepass:fail:custom.wast:14 # Module - caught panic Any
singlepass:fail:data.wast:5 # Module - caught panic Any
singlepass:fail:data.wast:23 # Module - caught panic Any
singlepass:fail:data.wast:27 # Module - caught panic Any
singlepass:fail:data.wast:32 # Module - caught panic Any
singlepass:fail:data.wast:40 # Module - caught panic Any
singlepass:fail:data.wast:50 # Module - caught panic Any
singlepass:fail:data.wast:55 # Module - caught panic Any
singlepass:fail:data.wast:61 # Module - caught panic Any
singlepass:fail:data.wast:66 # Module - caught panic Any
singlepass:fail:data.wast:78 # Module - caught panic Any
singlepass:fail:data.wast:83 # Module - caught panic Any
singlepass:fail:data.wast:89 # Module - caught panic Any
singlepass:fail:data.wast:94 # Module - caught panic Any
singlepass:fail:data.wast:98 # Module - caught panic Any
singlepass:fail:data.wast:103 # Module - caught panic Any
singlepass:fail:data.wast:108 # Module - caught panic Any
singlepass:fail:data.wast:113 # Module - caught panic Any
singlepass:fail:data.wast:117 # Module - caught panic Any
singlepass:fail:data.wast:122 # Module - caught panic Any
singlepass:fail:data.wast:127 # Module - caught panic Any
singlepass:fail:data.wast:132 # Module - caught panic Any
singlepass:fail:data.wast:137 # Module - caught panic Any
singlepass:fail:data.wast:143 # Module - caught panic Any
singlepass:fail:data.wast:149 # Module - caught panic Any
singlepass:fail:data.wast:154 # Module - caught panic Any
singlepass:fail:data.wast:162 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:170 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:178 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:186 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:194 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:211 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:220 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:227 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:235 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:243 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:251 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:258 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:266 # AssertUnlinkable - caught panic Any
singlepass:fail:data.wast:273 # AssertUnlinkable - caught panic Any
singlepass:fail:elem.wast:97 # Module - caught panic Any
singlepass:fail:elem.wast:101 # Module - caught panic Any
singlepass:fail:elem.wast:106 # Module - caught panic Any
singlepass:fail:elem.wast:111 # Module - caught panic Any
singlepass:fail:elem.wast:170 # AssertUnlinkable - caught panic Any
singlepass:fail:elem.wast:353 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:exports.wast:24 # Module - caught panic Any
singlepass:fail:exports.wast:25 # Module - caught panic Any
singlepass:fail:exports.wast:56 # Module - caught panic Any
singlepass:fail:exports.wast:57 # Module - caught panic Any
singlepass:fail:exports.wast:58 # Module - caught panic Any
singlepass:fail:exports.wast:60 # Module - caught panic Any
singlepass:fail:exports.wast:61 # Module - caught panic Any
singlepass:fail:exports.wast:62 # Module - caught panic Any
singlepass:fail:exports.wast:63 # Module - caught panic Any
singlepass:fail:exports.wast:64 # Module - caught panic Any
singlepass:fail:exports.wast:65 # Module - caught panic Any
singlepass:fail:exports.wast:67 # Module - caught panic Any
singlepass:fail:exports.wast:71 # AssertReturn Get - No instance available None
singlepass:fail:exports.wast:72 # AssertReturn Get - No instance available Some("$Global")
singlepass:fail:exports.wast:73 # Module - caught panic Any
singlepass:fail:exports.wast:74 # Module - caught panic Any
singlepass:fail:exports.wast:75 # AssertReturn Get - No instance available Some("$Global")
singlepass:fail:exports.wast:105 # Module - caught panic Any
singlepass:fail:exports.wast:106 # Module - caught panic Any
singlepass:fail:exports.wast:110 # Module - caught panic Any
singlepass:fail:exports.wast:111 # Module - caught panic Any
singlepass:fail:exports.wast:112 # Module - caught panic Any
singlepass:fail:exports.wast:113 # Module - caught panic Any
singlepass:fail:exports.wast:114 # Module - caught panic Any
singlepass:fail:exports.wast:115 # Module - caught panic Any
singlepass:fail:exports.wast:116 # Module - caught panic Any
singlepass:fail:exports.wast:117 # Module - caught panic Any
singlepass:fail:exports.wast:118 # Module - caught panic Any
singlepass:fail:exports.wast:119 # Module - caught panic Any
singlepass:fail:exports.wast:120 # Module - caught panic Any
singlepass:fail:exports.wast:121 # Module - caught panic Any
singlepass:fail:exports.wast:154 # Module - caught panic Any
singlepass:fail:exports.wast:155 # Module - caught panic Any
singlepass:fail:exports.wast:159 # Module - caught panic Any
singlepass:fail:exports.wast:160 # Module - caught panic Any
singlepass:fail:exports.wast:161 # Module - caught panic Any
singlepass:fail:exports.wast:162 # Module - caught panic Any
singlepass:fail:exports.wast:163 # Module - caught panic Any
singlepass:fail:exports.wast:164 # Module - caught panic Any
singlepass:fail:exports.wast:165 # Module - caught panic Any
singlepass:fail:exports.wast:166 # Module - caught panic Any
singlepass:fail:exports.wast:167 # Module - caught panic Any
singlepass:fail:exports.wast:168 # Module - caught panic Any
singlepass:fail:exports.wast:169 # Module - caught panic Any
singlepass:fail:exports.wast:170 # Module - caught panic Any
singlepass:fail:f32.wast:1620 # AssertReturn - result F32(0) ("0x0") does not match expected F32(2147483648) ("0x80000000")
singlepass:fail:f32.wast:1652 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
singlepass:fail:f32.wast:1654 # "AssertReturnArithmeticNan" - value is not arithmetic nan F32(NaN)
@ -1534,10 +1408,6 @@ singlepass:fail:func_ptrs.wast:90 # AssertTrap - expected trap, got Runtime:Erro
singlepass:fail:func_ptrs.wast:91 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:globals.wast:221 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:globals.wast:243 # AssertInvalid - Should be invalid
singlepass:fail:globals.wast:248 # Module - caught panic Any
singlepass:fail:globals.wast:249 # Module - caught panic Any
singlepass:fail:globals.wast:301 # Module - caught panic Any
singlepass:fail:globals.wast:331 # Module - caught panic Any
singlepass:fail:i32.wast:62 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:63 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:i32.wast:64 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -1575,102 +1445,14 @@ singlepass:fail:i64.wast:248 # AssertReturn - result I64(1) ("0x1") does not mat
singlepass:fail:i64.wast:249 # AssertReturn - result I64(62) ("0x3e") does not match expected I64(1) ("0x1")
singlepass:fail:i64.wast:252 # AssertReturn - result I64(0) ("0x0") does not match expected I64(64) ("0x40")
singlepass:fail:if.wast:440 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:98 # Module - caught panic Any
singlepass:fail:imports.wast:99 # Module - caught panic Any
singlepass:fail:imports.wast:100 # Module - caught panic Any
singlepass:fail:imports.wast:101 # Module - caught panic Any
singlepass:fail:imports.wast:102 # Module - caught panic Any
singlepass:fail:imports.wast:103 # Module - caught panic Any
singlepass:fail:imports.wast:104 # Module - caught panic Any
singlepass:fail:imports.wast:107 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:111 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:116 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:120 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:124 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:128 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:132 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:136 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:140 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:144 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:148 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:152 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:156 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:160 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:164 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:168 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:172 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:176 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:181 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:185 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:189 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:193 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:197 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:201 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:231 # Module - caught panic Any
singlepass:fail:imports.wast:232 # Module - caught panic Any
singlepass:fail:imports.wast:235 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:239 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:244 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:248 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:252 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:256 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:260 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:264 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:283 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:286 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:287 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:302 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:305 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:306 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:322 # Module - caught panic Any
singlepass:fail:imports.wast:323 # Module - caught panic Any
singlepass:fail:imports.wast:324 # Module - caught panic Any
singlepass:fail:imports.wast:325 # Module - caught panic Any
singlepass:fail:imports.wast:326 # Module - caught panic Any
singlepass:fail:imports.wast:327 # Module - caught panic Any
singlepass:fail:imports.wast:328 # Module - caught panic Any
singlepass:fail:imports.wast:329 # Module - caught panic Any
singlepass:fail:imports.wast:330 # Module - caught panic Any
singlepass:fail:imports.wast:331 # Module - caught panic Any
singlepass:fail:imports.wast:332 # Module - caught panic Any
singlepass:fail:imports.wast:335 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:339 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:344 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:348 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:352 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:356 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:361 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:365 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:369 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:373 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:391 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:402 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:imports.wast:417 # Module - caught panic Any
singlepass:fail:imports.wast:418 # Module - caught panic Any
singlepass:fail:imports.wast:419 # Module - caught panic Any
singlepass:fail:imports.wast:420 # Module - caught panic Any
singlepass:fail:imports.wast:421 # Module - caught panic Any
singlepass:fail:imports.wast:422 # Module - caught panic Any
singlepass:fail:imports.wast:423 # Module - caught panic Any
singlepass:fail:imports.wast:424 # Module - caught panic Any
singlepass:fail:imports.wast:425 # Module - caught panic Any
singlepass:fail:imports.wast:428 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:432 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:437 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:441 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:445 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:449 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:454 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:458 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:462 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:466 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:470 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:474 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:479 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:483 # AssertUnlinkable - caught panic Any
singlepass:fail:imports.wast:571 # Module - caught panic Any
singlepass:fail:imports.wast:572 # Register - No instance available
singlepass:fail:imports.wast:574 # AssertUnlinkable - caught panic Any
singlepass:fail:int_exprs.wast:113 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:114 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:115 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -1685,12 +1467,6 @@ singlepass:fail:int_exprs.wast:198 # AssertTrap - expected trap, got Runtime:Err
singlepass:fail:int_exprs.wast:199 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:349 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:int_exprs.wast:350 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:22 # Module - caught panic Any
singlepass:fail:linking.wast:26 # Register - No instance available
singlepass:fail:linking.wast:28 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:32 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:87 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:91 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:134 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:linking.wast:136 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:137 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -1711,24 +1487,12 @@ singlepass:fail:linking.wast:185 # AssertTrap - expected trap, got Runtime:Error
singlepass:fail:linking.wast:187 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:188 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:190 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:198 # Module - caught panic Any
singlepass:fail:linking.wast:199 # Register - No instance available
singlepass:fail:linking.wast:200 # Module - caught panic Any
singlepass:fail:linking.wast:204 # AssertReturn Get - No instance available Some("$G2")
singlepass:fail:linking.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:293 # Module - caught panic Any
singlepass:fail:linking.wast:299 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:324 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:335 # AssertUnlinkable - caught panic Any
singlepass:fail:linking.wast:387 # AssertReturn - result I32(0) ("0x0") does not match expected I32(104) ("0x68")
singlepass:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: unknown error
singlepass:fail:load.wast:201 # AssertReturn - result I32(0) ("0x0") does not match expected I32(32) ("0x20")
singlepass:fail:memory.wast:3 # Module - caught panic Any
singlepass:fail:memory.wast:4 # Module - caught panic Any
singlepass:fail:memory.wast:5 # Module - caught panic Any
singlepass:fail:memory.wast:6 # Module - caught panic Any
singlepass:fail:memory_grow.wast:15 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:16 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:memory_grow.wast:17 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -1909,7 +1673,6 @@ singlepass:fail:select.wast:210 # AssertTrap - expected trap, got Runtime:Error
singlepass:fail:select.wast:211 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:select.wast:249 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:start.wast:92 # Module - caught panic Any
singlepass:fail:traps.wast:16 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:17 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:18 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -1942,7 +1705,6 @@ singlepass:fail:traps.wast:88 # AssertTrap - expected trap, got Runtime:Error un
singlepass:fail:traps.wast:89 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:90 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:traps.wast:91 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:type.wast:3 # Module - caught panic Any
singlepass:fail:unreachable.wast:218 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:219 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unreachable.wast:220 # AssertTrap - expected trap, got Runtime:Error unknown error
@ -2007,4 +1769,4 @@ singlepass:fail:unwind.wast:239 # AssertTrap - expected trap, got Runtime:Error
singlepass:fail:unwind.wast:245 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:251 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:257 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:unwind.wast:263 # AssertTrap - expected trap, got Runtime:Error unknown error

View File

@ -167,6 +167,7 @@ mod tests {
let mut features = wabt::Features::new();
features.enable_simd();
features.enable_threads();
let mut parser: ScriptParser =
ScriptParser::from_source_and_name_with_features(&source, filename, features)
.expect(&format!("Failed to parse script {}", &filename));
@ -203,7 +204,10 @@ mod tests {
let spectest_import_object =
get_spectest_import_object(&registered_modules);
let config = CompilerConfig {
features: Features { simd: true },
features: Features {
simd: true,
threads: true,
},
..Default::default()
};
let module = wasmer_runtime_core::compile_with_config(
@ -630,7 +634,10 @@ mod tests {
// println!("AssertInvalid");
let result = panic::catch_unwind(|| {
let config = CompilerConfig {
features: Features { simd: true },
features: Features {
simd: true,
threads: true,
},
..Default::default()
};
wasmer_runtime_core::compile_with_config(
@ -681,7 +688,10 @@ mod tests {
let result = panic::catch_unwind(|| {
let config = CompilerConfig {
features: Features { simd: true },
features: Features {
simd: true,
threads: true,
},
..Default::default()
};
wasmer_runtime_core::compile_with_config(
@ -798,7 +808,10 @@ mod tests {
let spectest_import_object =
get_spectest_import_object(&registered_modules);
let config = CompilerConfig {
features: Features { simd: true },
features: Features {
simd: true,
threads: true,
},
..Default::default()
};
let module = wasmer_runtime_core::compile_with_config(

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

BIN
logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 KiB

After

Width:  |  Height:  |  Size: 27 KiB

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns
@ -83,6 +85,10 @@ struct PrestandardFeatures {
#[structopt(long = "enable-simd")]
simd: bool,
/// Enable support for the threads proposal.
#[structopt(long = "enable-threads")]
threads: bool,
/// Enable support for all pre-standard proposals.
#[structopt(long = "enable-all")]
all: bool,
@ -373,6 +379,9 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
if options.features.simd || options.features.all {
features.enable_simd();
}
if options.features.threads || options.features.all {
features.enable_threads();
}
wasm_binary = wabt::wat2wasm_with_features(wasm_binary, features)
.map_err(|e| format!("Can't convert from wast to wasm: {:?}", e))?;
}
@ -425,6 +434,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
track_state,
features: Features {
simd: options.features.simd || options.features.all,
threads: options.features.threads || options.features.all,
},
},
&*compiler,
@ -438,6 +448,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
track_state,
features: Features {
simd: options.features.simd || options.features.all,
threads: options.features.threads || options.features.all,
},
..Default::default()
},
@ -485,6 +496,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
track_state,
features: Features {
simd: options.features.simd || options.features.all,
threads: options.features.threads || options.features.all,
},
..Default::default()
},
@ -542,7 +554,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
// TODO: refactor this
if wasmer_emscripten::is_emscripten_module(&module) {
let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module);
let mut emscripten_globals = wasmer_emscripten::EmscriptenGlobals::new(&module)?;
let import_object = wasmer_emscripten::generate_emscripten_env(&mut emscripten_globals);
let mut instance = module
.instantiate(&import_object)
@ -817,6 +829,7 @@ fn validate_wasm(validate: Validate) -> Result<(), String> {
&wasm_binary,
Features {
simd: validate.features.simd || validate.features.all,
threads: validate.features.threads || validate.features.all,
},
)
.map_err(|err| format!("Validation failed: {}", err))?;

View File

@ -1,6 +1,8 @@
#![deny(
dead_code,
nonstandard_style,
unused_imports,
unused_mut,
unused_variables,
unused_unsafe,
unreachable_patterns