diff --git a/CHANGELOG.md b/CHANGELOG.md index f8281c924..9b23fbe29 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ All PRs to the Wasmer repository must add to this file. Blocks of changes will separated by version increments. ## **[Unreleased]** +- [#515](https://github.com/wasmerio/wasmer/pull/515) Improved Emscripten dyncalls +- [#513](https://github.com/wasmerio/wasmer/pull/513) Fix emscripten lseek implementation. +- [#510](https://github.com/wasmerio/wasmer/pull/510) Simplify construction of floating point constants in LLVM backend. Fix LLVM assertion failure due to definition of %ctx. ## 0.5.1 - 2019-06-24 - [#508](https://github.com/wasmerio/wasmer/pull/508) Update wapm version, includes bug fixes diff --git a/lib/emscripten/src/emscripten_target.rs b/lib/emscripten/src/emscripten_target.rs index 7e0b81af2..3ec4b83af 100644 --- a/lib/emscripten/src/emscripten_target.rs +++ b/lib/emscripten/src/emscripten_target.rs @@ -634,6 +634,11 @@ pub fn invoke_iij(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { invoke!(ctx, dyn_call_iij, index, a1, a2, a3) } +pub fn invoke_iji(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32) -> i32 { + debug!("emscripten::invoke_iji"); + invoke!(ctx, dyn_call_iji, index, a1, a2, a3) +} + pub fn invoke_iiji(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32, a4: i32) -> i32 { debug!("emscripten::invoke_iiji"); invoke!(ctx, dyn_call_iiji, index, a1, a2, a3, a4) @@ -853,6 +858,10 @@ pub fn invoke_vijj(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: i32, a4: i32 panic!("dyn_call_vijj is set to None"); } } +pub fn invoke_vidd(ctx: &mut Ctx, index: i32, a1: i32, a2: f64, a3: f64) { + debug!("emscripten::invoke_viid"); + invoke_no_return!(ctx, dyn_call_vidd, index, a1, a2, a3); +} pub fn invoke_viid(ctx: &mut Ctx, index: i32, a1: i32, a2: i32, a3: f64) { debug!("emscripten::invoke_viid"); invoke_no_return!(ctx, dyn_call_viid, index, a1, a2, a3); diff --git a/lib/emscripten/src/lib.rs b/lib/emscripten/src/lib.rs index e7b51a26a..a61d02295 100644 --- a/lib/emscripten/src/lib.rs +++ b/lib/emscripten/src/lib.rs @@ -124,6 +124,7 @@ pub struct EmscriptenData<'a> { pub dyn_call_viiiiiiiiii: Option>, pub dyn_call_iij: Option>, + pub dyn_call_iji: Option>, pub dyn_call_iiji: Option>, pub dyn_call_iiijj: Option>, pub dyn_call_j: Option>, @@ -146,6 +147,7 @@ pub struct EmscriptenData<'a> { pub dyn_call_vijiii: Option>, pub dyn_call_vijj: Option>, pub dyn_call_viid: Option>, + pub dyn_call_vidd: Option>, pub dyn_call_viidii: Option>, pub dyn_call_viidddddddd: Option>, @@ -197,6 +199,7 @@ impl<'a> EmscriptenData<'a> { let dyn_call_viiiiiiiii = instance.func("dynCall_viiiiiiiii").ok(); let dyn_call_viiiiiiiiii = instance.func("dynCall_viiiiiiiiii").ok(); let dyn_call_iij = instance.func("dynCall_iij").ok(); + let dyn_call_iji = instance.func("dynCall_iji").ok(); let dyn_call_iiji = instance.func("dynCall_iiji").ok(); let dyn_call_iiijj = instance.func("dynCall_iiijj").ok(); let dyn_call_j = instance.func("dynCall_j").ok(); @@ -218,6 +221,7 @@ impl<'a> EmscriptenData<'a> { let dyn_call_vijiii = instance.func("dynCall_vijiii").ok(); let dyn_call_vijj = instance.func("dynCall_vijj").ok(); let dyn_call_viid = instance.func("dynCall_viid").ok(); + let dyn_call_vidd = instance.func("dynCall_vidd").ok(); let dyn_call_viidii = instance.func("dynCall_viidii").ok(); let dyn_call_viidddddddd = instance.func("dynCall_viidddddddd").ok(); @@ -263,6 +267,7 @@ impl<'a> EmscriptenData<'a> { dyn_call_viiiiiiiii, dyn_call_viiiiiiiiii, dyn_call_iij, + dyn_call_iji, dyn_call_iiji, dyn_call_iiijj, dyn_call_j, @@ -284,6 +289,7 @@ impl<'a> EmscriptenData<'a> { dyn_call_vijiii, dyn_call_vijj, dyn_call_viid, + dyn_call_vidd, dyn_call_viidii, dyn_call_viidddddddd, temp_ret_0: 0, @@ -912,6 +918,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "invoke_viiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiii), "invoke_viiiiiiiiii" => func!(crate::emscripten_target::invoke_viiiiiiiiii), "invoke_iij" => func!(crate::emscripten_target::invoke_iij), + "invoke_iji" => func!(crate::emscripten_target::invoke_iji), "invoke_iiji" => func!(crate::emscripten_target::invoke_iiji), "invoke_iiijj" => func!(crate::emscripten_target::invoke_iiijj), "invoke_j" => func!(crate::emscripten_target::invoke_j), @@ -930,6 +937,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject "invoke_viji" => func!(crate::emscripten_target::invoke_viji), "invoke_vijiii" => func!(crate::emscripten_target::invoke_vijiii), "invoke_vijj" => func!(crate::emscripten_target::invoke_vijj), + "invoke_vidd" => func!(crate::emscripten_target::invoke_vidd), "invoke_viid" => func!(crate::emscripten_target::invoke_viid), "invoke_viidii" => func!(crate::emscripten_target::invoke_viidii), "invoke_viidddddddd" => func!(crate::emscripten_target::invoke_viidddddddd), diff --git a/lib/emscripten/src/syscalls/mod.rs b/lib/emscripten/src/syscalls/mod.rs index 90c703d58..34ba90818 100644 --- a/lib/emscripten/src/syscalls/mod.rs +++ b/lib/emscripten/src/syscalls/mod.rs @@ -50,7 +50,6 @@ use super::env; use std::cell::Cell; #[allow(unused_imports)] use std::io::Error; -use std::mem; use std::slice; /// exit @@ -437,23 +436,21 @@ pub fn ___syscall140(ctx: &mut Ctx, _which: i32, mut varargs: VarArgs) -> i32 { // -> c_int debug!("emscripten::___syscall140 (lseek) {}", _which); let fd: i32 = varargs.get(ctx); - let _ = varargs.get::(ctx); // ignore high offset + let _offset_high: i32 = varargs.get(ctx); // We don't use the offset high as emscripten skips it let offset_low: i32 = varargs.get(ctx); - let result_ptr_value = varargs.get::(ctx); + let result_ptr_value: WasmPtr = varargs.get(ctx); let whence: i32 = varargs.get(ctx); let offset = offset_low as off_t; - let ret = unsafe { lseek(fd, offset, whence) as i32 }; - #[allow(clippy::cast_ptr_alignment)] - let result_ptr = emscripten_memory_pointer!(ctx.memory(0), result_ptr_value) as *mut i32; - assert_eq!(8, mem::align_of_val(&result_ptr)); - unsafe { - *result_ptr = ret; - } + let ret = unsafe { lseek(fd, offset, whence) as i64 }; + + let result_ptr = result_ptr_value.deref(ctx.memory(0)).unwrap(); + result_ptr.set(ret); + debug!( - "=> fd: {}, offset: {}, result_ptr: {}, whence: {} = {}\nlast os error: {}", + "=> fd: {}, offset: {}, result: {}, whence: {} = {}\nlast os error: {}", fd, offset, - result_ptr_value, + ret, whence, 0, Error::last_os_error(), diff --git a/lib/llvm-backend/src/code.rs b/lib/llvm-backend/src/code.rs index 7e76698a9..1a84a15c7 100644 --- a/lib/llvm-backend/src/code.rs +++ b/lib/llvm-backend/src/code.rs @@ -849,22 +849,12 @@ impl FunctionCodeGenerator for LLVMFunctionCodeGenerator { } Operator::F32Const { value } => { let bits = intrinsics.i32_ty.const_int(value.bits() as u64, false); - let space = - builder.build_alloca(intrinsics.f32_ty.as_basic_type_enum(), "const_space"); - let i32_space = - builder.build_pointer_cast(space, intrinsics.i32_ptr_ty, "i32_space"); - builder.build_store(i32_space, bits); - let f = builder.build_load(space, "f"); + let f = builder.build_bitcast(bits, intrinsics.f32_ty, "f"); state.push1(f); } Operator::F64Const { value } => { let bits = intrinsics.i64_ty.const_int(value.bits(), false); - let space = - builder.build_alloca(intrinsics.f64_ty.as_basic_type_enum(), "const_space"); - let i64_space = - builder.build_pointer_cast(space, intrinsics.i64_ptr_ty, "i32_space"); - builder.build_store(i64_space, bits); - let f = builder.build_load(space, "f"); + let f = builder.build_bitcast(bits, intrinsics.f64_ty, "f"); state.push1(f); } diff --git a/lib/llvm-backend/src/intrinsics.rs b/lib/llvm-backend/src/intrinsics.rs index 4dedfd5bc..c3a95f775 100644 --- a/lib/llvm-backend/src/intrinsics.rs +++ b/lib/llvm-backend/src/intrinsics.rs @@ -159,10 +159,10 @@ impl Intrinsics { let imported_func_ty = context.struct_type(&[i8_ptr_ty_basic, ctx_ptr_ty.as_basic_type_enum()], false); let sigindex_ty = i32_ty; - let rt_intrinsics_ty = void_ty; + let rt_intrinsics_ty = i8_ty; let stack_lower_bound_ty = i8_ty; let memory_base_ty = i8_ty; - let memory_bound_ty = void_ty; + let memory_bound_ty = i8_ty; let internals_ty = i64_ty; let interrupt_signal_mem_ty = i8_ty; let local_function_ty = i8_ptr_ty;