diff --git a/README.md b/README.md
index e69fe2d1c..7e7f39cb1 100644
--- a/README.md
+++ b/README.md
@@ -44,6 +44,7 @@ Wasmer runtime can be used as a library embedded in different languages, so you
|  | [**PHP**](https://github.com/wasmerio/php-ext-wasm) | Wasmer | actively developed |  |  |
|  | [**Ruby**](https://github.com/wasmerio/ruby-ext-wasm) | Wasmer | actively developed |  |  |
|  | [**Postgres**](https://github.com/wasmerio/postgres-ext-wasm) | Wasmer | actively developed |  |  |
+|  | [**JavaScript**](https://github.com/wasmerio/wasmer-js) | Wasmer | actively developed |  |  |
|  | [**C#/.Net**](https://github.com/migueldeicaza/WasmerSharp) | [Miguel de Icaza](https://github.com/migueldeicaza) | actively developed |  |  |
|  | [**R**](https://github.com/dirkschumacher/wasmr) | [Dirk Schumacher](https://github.com/dirkschumacher) | actively developed | |  |
|  | [**Swift**](https://github.com/markmals/swift-ext-wasm) | [Mark Malström](https://github.com/markmals/) | passively maintained | |  |
diff --git a/docs/assets/languages/js.svg b/docs/assets/languages/js.svg
new file mode 100755
index 000000000..6a186f383
--- /dev/null
+++ b/docs/assets/languages/js.svg
@@ -0,0 +1,8 @@
+
+
diff --git a/lib/clif-backend/src/code.rs b/lib/clif-backend/src/code.rs
index b2ccc6652..f1d8489da 100644
--- a/lib/clif-backend/src/code.rs
+++ b/lib/clif-backend/src/code.rs
@@ -128,166 +128,6 @@ impl ModuleCodeGenerator
.state
.initialize(&builder.func.signature, exit_block);
- #[cfg(feature = "debug")]
- {
- use cranelift_codegen::cursor::{Cursor, FuncCursor};
- use cranelift_codegen::ir::InstBuilder;
- let entry_ebb = func.layout.entry_block().unwrap();
- let ebb = func.dfg.make_ebb();
- func.layout.insert_ebb(ebb, entry_ebb);
- let mut pos = FuncCursor::new(&mut func).at_first_insertion_point(ebb);
- let params = pos.func.dfg.ebb_params(entry_ebb).to_vec();
-
- let new_ebb_params: Vec<_> = params
- .iter()
- .map(|¶m| {
- pos.func
- .dfg
- .append_ebb_param(ebb, pos.func.dfg.value_type(param))
- })
- .collect();
-
- let start_debug = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::I32),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("strtdbug");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let end_debug = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![ir::AbiParam::special(
- ir::types::I64,
- ir::ArgumentPurpose::VMContext,
- )],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("enddbug");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let i32_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::I32),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("i32print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let i64_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::I64),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("i64print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let f32_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::F32),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("f32print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let f64_print = {
- let signature = pos.func.import_signature(ir::Signature {
- call_conv: self.target_config().default_call_conv,
- params: vec![
- ir::AbiParam::special(ir::types::I64, ir::ArgumentPurpose::VMContext),
- ir::AbiParam::new(ir::types::F64),
- ],
- returns: vec![],
- });
-
- let name = ir::ExternalName::testcase("f64print");
-
- pos.func.import_function(ir::ExtFuncData {
- name,
- signature,
- colocated: false,
- })
- };
-
- let vmctx = pos
- .func
- .special_param(ir::ArgumentPurpose::VMContext)
- .expect("missing vmctx parameter");
-
- let func_index = pos.ins().iconst(
- ir::types::I32,
- func_index.index() as i64 + self.module.info.imported_functions.len() as i64,
- );
-
- pos.ins().call(start_debug, &[vmctx, func_index]);
-
- for param in new_ebb_params.iter().cloned() {
- match pos.func.dfg.value_type(param) {
- ir::types::I32 => pos.ins().call(i32_print, &[vmctx, param]),
- ir::types::I64 => pos.ins().call(i64_print, &[vmctx, param]),
- ir::types::F32 => pos.ins().call(f32_print, &[vmctx, param]),
- ir::types::F64 => pos.ins().call(f64_print, &[vmctx, param]),
- _ => unimplemented!(),
- };
- }
-
- pos.ins().call(end_debug, &[vmctx]);
-
- pos.ins().jump(entry_ebb, new_ebb_params.as_slice());
- }
-
self.functions.push(func_env);
Ok(self.functions.last_mut().unwrap())
}
diff --git a/lib/clif-backend/src/resolver.rs b/lib/clif-backend/src/resolver.rs
index 7a868f35e..efc038d58 100644
--- a/lib/clif-backend/src/resolver.rs
+++ b/lib/clif-backend/src/resolver.rs
@@ -1,32 +1,31 @@
-use crate::{cache::BackendCache, trampoline::Trampolines};
use crate::{
+ cache::BackendCache,
libcalls,
relocation::{
ExternalRelocation, LibCall, LocalRelocation, LocalTrapSink, Reloc, RelocSink,
RelocationType, TrapSink, VmCall, VmCallKind,
},
signal::HandlerData,
+ trampoline::Trampolines,
};
-use rayon::prelude::*;
-
use byteorder::{ByteOrder, LittleEndian};
use cranelift_codegen::{
binemit::{Stackmap, StackmapSink},
ir, isa, Context,
};
+use rayon::prelude::*;
use std::{
mem,
ptr::{write_unaligned, NonNull},
sync::Arc,
};
-
-use wasmer_runtime_core::cache::Error as CacheError;
use wasmer_runtime_core::{
self,
backend::{
sys::{Memory, Protect},
SigRegistry,
},
+ cache::Error as CacheError,
error::{CompileError, CompileResult},
module::ModuleInfo,
structures::{Map, SliceMap, TypedIndex},
@@ -250,17 +249,9 @@ impl FuncResolverBuilder {
#[cfg(not(target_os = "windows"))]
LibCall::Probestack => __rust_probestack as isize,
},
- RelocationType::Intrinsic(ref name) => match name.as_str() {
- "i32print" => i32_print as isize,
- "i64print" => i64_print as isize,
- "f32print" => f32_print as isize,
- "f64print" => f64_print as isize,
- "strtdbug" => start_debug as isize,
- "enddbug" => end_debug as isize,
- _ => Err(CompileError::InternalError {
- msg: format!("unexpected intrinsic: {}", name),
- })?,
- },
+ RelocationType::Intrinsic(ref name) => Err(CompileError::InternalError {
+ msg: format!("unexpected intrinsic: {}", name),
+ })?,
RelocationType::VmCall(vmcall) => match vmcall {
VmCall::Local(kind) => match kind {
VmCallKind::StaticMemoryGrow | VmCallKind::SharedStaticMemoryGrow => {
@@ -371,28 +362,3 @@ impl FuncResolver {
fn round_up(n: usize, multiple: usize) -> usize {
(n + multiple - 1) & !(multiple - 1)
}
-
-extern "C" fn i32_print(_ctx: &mut vm::Ctx, n: i32) {
- eprint!(" i32: {},", n);
-}
-extern "C" fn i64_print(_ctx: &mut vm::Ctx, n: i64) {
- eprint!(" i64: {},", n);
-}
-extern "C" fn f32_print(_ctx: &mut vm::Ctx, n: f32) {
- eprint!(" f32: {},", n);
-}
-extern "C" fn f64_print(_ctx: &mut vm::Ctx, n: f64) {
- eprint!(" f64: {},", n);
-}
-extern "C" fn start_debug(ctx: &mut vm::Ctx, func_index: u32) {
- if let Some(symbol_map) = unsafe { ctx.borrow_symbol_map() } {
- if let Some(fn_name) = symbol_map.get(&func_index) {
- eprint!("func ({} ({})), args: [", fn_name, func_index);
- return;
- }
- }
- eprint!("func ({}), args: [", func_index);
-}
-extern "C" fn end_debug(_ctx: &mut vm::Ctx) {
- eprintln!(" ]");
-}
diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs
index fc4ac7184..ad2a2d7d3 100644
--- a/lib/llvm-backend/src/code.rs
+++ b/lib/llvm-backend/src/code.rs
@@ -2778,7 +2778,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::F32Min => {
// This implements the same logic as LLVM's @llvm.minimum
- // intrinsic would, but x86 lowering of that intrinsics
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
@@ -2832,7 +2832,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::F64Min => {
// This implements the same logic as LLVM's @llvm.minimum
- // intrinsic would, but x86 lowering of that intrinsics
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
@@ -2886,7 +2886,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::F32x4Min => {
// This implements the same logic as LLVM's @llvm.minimum
- // intrinsic would, but x86 lowering of that intrinsics
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let v1 = v128_into_f32x4(builder, intrinsics, v1, i1);
@@ -2952,7 +2952,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::F64x2Min => {
// This implements the same logic as LLVM's @llvm.minimum
- // intrinsic would, but x86 lowering of that intrinsics
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let v1 = v128_into_f64x2(builder, intrinsics, v1, i1);
@@ -3017,8 +3017,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::F32Max => {
- // This implements the same logic as LLVM's @llvm.minimum
- // intrinsic would, but x86 lowering of that intrinsics
+ // This implements the same logic as LLVM's @llvm.maximum
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
@@ -3070,8 +3070,8 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
state.push1(res);
}
Operator::F64Max => {
- // This implements the same logic as LLVM's @llvm.minimum
- // intrinsic would, but x86 lowering of that intrinsics
+ // This implements the same logic as LLVM's @llvm.maximum
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let (v1, v2) = state.pop2()?;
@@ -3124,7 +3124,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::F32x4Max => {
// This implements the same logic as LLVM's @llvm.maximum
- // intrinsic would, but x86 lowering of that intrinsics
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let v1 = v128_into_f32x4(builder, intrinsics, v1, i1);
@@ -3189,7 +3189,7 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator {
}
Operator::F64x2Max => {
// This implements the same logic as LLVM's @llvm.maximum
- // intrinsic would, but x86 lowering of that intrinsics
+ // intrinsic would, but x86 lowering of that intrinsic
// encounters a fatal error in LLVM 8 and LLVM 9.
let ((v1, i1), (v2, i2)) = state.pop2_extra()?;
let v1 = v128_into_f64x2(builder, intrinsics, v1, i1);
diff --git a/lib/runtime-core/src/module.rs b/lib/runtime-core/src/module.rs
index 6cc02343f..1bf914a46 100644
--- a/lib/runtime-core/src/module.rs
+++ b/lib/runtime-core/src/module.rs
@@ -29,7 +29,7 @@ pub struct ModuleInner {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ModuleInfo {
- // This are strictly local and the typsystem ensures that.
+ // This are strictly local and the typesystem ensures that.
pub memories: Map,
pub globals: Map,
pub tables: Map,
diff --git a/lib/runtime-core/src/vmcalls.rs b/lib/runtime-core/src/vmcalls.rs
index 5205a0d69..33d473aa0 100644
--- a/lib/runtime-core/src/vmcalls.rs
+++ b/lib/runtime-core/src/vmcalls.rs
@@ -10,7 +10,7 @@ use crate::{
// +*****************************+
// | LOCAL MEMORIES |
-// +****************************+
+// +*****************************+
pub unsafe extern "C" fn local_static_memory_grow(
ctx: &mut vm::Ctx,
@@ -72,7 +72,7 @@ pub unsafe extern "C" fn local_dynamic_memory_size(
// +*****************************+
// | IMPORTED MEMORIES |
-// +****************************+
+// +*****************************+
pub unsafe extern "C" fn imported_static_memory_grow(
ctx: &mut vm::Ctx,
@@ -140,7 +140,7 @@ pub unsafe extern "C" fn imported_dynamic_memory_size(
// +*****************************+
// | LOCAL TABLES |
-// +****************************+
+// +*****************************+
pub unsafe extern "C" fn local_table_grow(
ctx: &mut vm::Ctx,
diff --git a/lib/spectests/tests/excludes.txt b/lib/spectests/tests/excludes.txt
index 6cd94753b..a54b3df49 100644
--- a/lib/spectests/tests/excludes.txt
+++ b/lib/spectests/tests/excludes.txt
@@ -32,7 +32,6 @@ clif:fail:linking.wast:147 # AssertTrap - expected trap, got Runtime:Error "unkn
clif:fail:linking.wast:149 # AssertTrap - expected trap, got Runtime:Error "unknown trap at 0x106883037 - illegal instruction"
clif:fail:linking.wast:185 # AssertTrap - expected trap, got Runtime:Error "unknown trap at 0x106883062 - illegal instruction"
clif:fail:linking.wast:187 # AssertTrap - expected trap, got Runtime:Error "unknown trap at 0x106883062 - illegal instruction"
-clif:fail:linking.wast:387 # AssertReturn - result I32(0) ("0x0") does not match expected I32(104) ("0x68")
clif:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: `call_indirect` out-of-bounds
# clif:skip:skip-stack-guard-page.wast:2 # Slow test
@@ -83,6 +82,7 @@ clif:fail:data.wast:227:windows # AssertUnlinkable - caught panic Any
clif:fail:data.wast:258:windows # AssertUnlinkable - caught panic Any
clif:fail:data.wast:273:windows # AssertUnlinkable - caught panic Any
clif:fail:start.wast:92:windows # Module - caught panic Any
+clif:skip:start.wast:98:windows
clif:fail:align.wast:3:windows # Module - caught panic Any
clif:fail:align.wast:4:windows # Module - caught panic Any
@@ -269,7 +269,6 @@ llvm:fail:f32.wast:1621 # AssertReturn - result F32(0) ("0x0") does not match ex
llvm:fail:f32.wast:2020 # AssertReturn - result F32(2147483648) ("0x80000000") does not match expected F32(0) ("0x0")
llvm:fail:f64.wast:1621 # AssertReturn - result F64(0) ("0x0") does not match expected F64(9223372036854775808) ("0x8000000000000000")
llvm:fail:f64.wast:2020 # AssertReturn - result F64(9223372036854775808) ("0x8000000000000000") does not match expected F64(0) ("0x0")
-llvm:fail:linking.wast:387 # AssertReturn - result I32(0) ("0x0") does not match expected I32(104) ("0x68")
llvm:fail:linking.wast:388 # AssertReturn - Call failed RuntimeError: WebAssembly trap occurred during runtime: incorrect `call_indirect` signature
# LLVM Windows
@@ -957,7 +956,6 @@ singlepass:fail:linking.wast:190 # AssertTrap - expected trap, got Runtime:Error
singlepass:fail:linking.wast:225 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:236 # AssertTrap - expected trap, got Runtime:Error unknown error
singlepass:fail:linking.wast:248 # AssertTrap - expected trap, got Runtime:Error unknown error
-singlepass:fail:linking.wast: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: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
diff --git a/lib/spectests/tests/spectest.rs b/lib/spectests/tests/spectest.rs
index 62bfc7d53..19114ff67 100644
--- a/lib/spectests/tests/spectest.rs
+++ b/lib/spectests/tests/spectest.rs
@@ -445,8 +445,9 @@ mod tests {
"AssertReturnCanonicalNan"
),
message: format!(
- "value is not canonical nan {:?}",
- v
+ "value is not canonical nan {:?} ({:?})",
+ v,
+ value_to_hex(v.clone()),
),
},
&test_key,
@@ -512,8 +513,9 @@ mod tests {
"AssertReturnArithmeticNan"
),
message: format!(
- "value is not arithmetic nan {:?}",
- v
+ "value is not arithmetic nan {:?} ({:?})",
+ v,
+ value_to_hex(v.clone()),
),
},
&test_key,
@@ -718,10 +720,44 @@ mod tests {
}
}
}
- CommandKind::AssertUninstantiable {
- module: _,
- message: _,
- } => println!("AssertUninstantiable not yet implmented "),
+ CommandKind::AssertUninstantiable { module, message: _ } => {
+ let spectest_import_object = get_spectest_import_object(®istered_modules);
+ let config = CompilerConfig {
+ features: Features {
+ simd: true,
+ threads: true,
+ },
+ ..Default::default()
+ };
+ let module = wasmer_runtime_core::compile_with_config(
+ &module.into_vec(),
+ &get_compiler(),
+ config,
+ )
+ .expect("WASM can't be compiled");
+ let result = panic::catch_unwind(AssertUnwindSafe(|| {
+ module
+ .instantiate(&spectest_import_object)
+ .expect("WASM can't be instantiated");
+ }));
+ match result {
+ Err(_) => test_report.count_passed(),
+ Ok(_) => {
+ test_report.add_failure(
+ SpecFailure {
+ file: filename.to_string(),
+ line: line,
+ kind: format!("{}", "AssertUninstantiable"),
+ message: format!(
+ "instantiate successful, expected uninstantiable"
+ ),
+ },
+ &test_key,
+ excludes,
+ );
+ }
+ };
+ }
CommandKind::AssertExhaustion { action, message: _ } => {
match action {
Action::Invoke {
@@ -945,6 +981,16 @@ mod tests {
}
}
+ fn value_to_hex(val: wasmer_runtime_core::types::Value) -> String {
+ match val {
+ wasmer_runtime_core::types::Value::I32(x) => format!("{:#x}", x),
+ wasmer_runtime_core::types::Value::I64(x) => format!("{:#x}", x),
+ wasmer_runtime_core::types::Value::F32(x) => format!("{:#x}", x.to_bits()),
+ wasmer_runtime_core::types::Value::F64(x) => format!("{:#x}", x.to_bits()),
+ wasmer_runtime_core::types::Value::V128(x) => format!("{:#x}", x),
+ }
+ }
+
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum SpectestValue {
I32(i32),