Merge branch 'master' into ventuzelo/fix-653-panic-memorydescriptor

This commit is contained in:
Patrick Ventuzelo
2019-09-24 09:10:45 +02:00
committed by GitHub
56 changed files with 850 additions and 517 deletions

View File

@ -12,14 +12,14 @@ pub use self::windows::*;
use libc::c_char;
use crate::{allocate_on_stack, EmscriptenData};
use crate::{
allocate_on_stack,
ptr::{Array, WasmPtr},
EmscriptenData,
};
use std::os::raw::c_int;
use wasmer_runtime_core::{
memory::ptr::{Array, WasmPtr},
types::ValueType,
vm::Ctx,
};
use wasmer_runtime_core::{types::ValueType, vm::Ctx};
pub fn call_malloc(ctx: &mut Ctx, size: u32) -> u32 {
get_emscripten_data(ctx)

View File

@ -9,11 +9,9 @@ use std::mem;
use std::os::raw::c_char;
use crate::env::{call_malloc, call_malloc_with_cast, EmAddrInfo, EmSockAddr};
use crate::ptr::{Array, WasmPtr};
use crate::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
use wasmer_runtime_core::{
memory::ptr::{Array, WasmPtr},
vm::Ctx,
};
use wasmer_runtime_core::vm::Ctx;
// #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char;

View File

@ -6,8 +6,9 @@ use std::mem;
use std::os::raw::c_char;
use crate::env::{call_malloc, EmAddrInfo};
use crate::ptr::WasmPtr;
use crate::utils::{copy_cstr_into_wasm, read_string_from_wasm};
use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
use wasmer_runtime_core::vm::Ctx;
extern "C" {
#[link_name = "_putenv"]

View File

@ -62,6 +62,7 @@ mod math;
mod memory;
mod process;
mod pthread;
mod ptr;
mod signal;
mod storage;
mod syscalls;
@ -730,8 +731,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"___syscall345" => func!(crate::syscalls::___syscall345),
// Process
"abort" => func!(crate::process::em_abort),
"abort" => func!(crate::process::_abort),
"_abort" => func!(crate::process::_abort),
"_prctl" => func!(crate::process::_prctl),
"abortStackOverflow" => func!(crate::process::abort_stack_overflow),
"_llvm_trap" => func!(crate::process::_llvm_trap),
"_fork" => func!(crate::process::_fork),
@ -824,6 +826,9 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"_gmtime" => func!(crate::time::_gmtime),
// Math
"sqrt" => func!(crate::math::sqrt),
"floor" => func!(crate::math::floor),
"fabs" => func!(crate::math::fabs),
"f64-rem" => func!(crate::math::f64_rem),
"_llvm_copysign_f32" => func!(crate::math::_llvm_copysign_f32),
"_llvm_copysign_f64" => func!(crate::math::_llvm_copysign_f64),

View File

@ -88,6 +88,21 @@ pub fn log(_ctx: &mut Ctx, value: f64) -> f64 {
value.ln()
}
// emscripten: global.Math sqrt
pub fn sqrt(_ctx: &mut Ctx, value: f64) -> f64 {
value.sqrt()
}
// emscripten: global.Math floor
pub fn floor(_ctx: &mut Ctx, value: f64) -> f64 {
value.floor()
}
// emscripten: global.Math fabs
pub fn fabs(_ctx: &mut Ctx, value: f64) -> f64 {
value.abs()
}
// emscripten: asm2wasm.f64-to-int
pub fn f64_to_int(_ctx: &mut Ctx, value: f64) -> i32 {
debug!("emscripten::f64_to_int {}", value);

View File

@ -1,11 +1,10 @@
use libc::{abort, c_char, c_int, exit, EAGAIN};
use libc::{abort, c_int, exit, EAGAIN};
#[cfg(not(target_os = "windows"))]
type PidT = libc::pid_t;
#[cfg(target_os = "windows")]
type PidT = c_int;
use std::ffi::CStr;
use wasmer_runtime_core::vm::Ctx;
pub fn abort_with_message(ctx: &mut Ctx, message: &str) {
@ -21,6 +20,12 @@ pub fn _abort(_ctx: &mut Ctx) {
}
}
pub fn _prctl(ctx: &mut Ctx, _a: i32, _b: i32) -> i32 {
debug!("emscripten::_prctl");
abort_with_message(ctx, "missing function: prctl");
-1
}
pub fn _fork(_ctx: &mut Ctx) -> PidT {
debug!("emscripten::_fork");
// unsafe {
@ -45,18 +50,6 @@ pub fn _exit(_ctx: &mut Ctx, status: c_int) {
unsafe { exit(status) }
}
pub fn em_abort(ctx: &mut Ctx, message: u32) {
debug!("emscripten::em_abort {}", message);
let message_addr = emscripten_memory_pointer!(ctx.memory(0), message) as *mut c_char;
unsafe {
let message = CStr::from_ptr(message_addr)
.to_str()
.unwrap_or("Unexpected abort");
abort_with_message(ctx, message);
}
}
pub fn _kill(_ctx: &mut Ctx, _one: i32, _two: i32) -> i32 {
debug!("emscripten::_kill");
-1

116
lib/emscripten/src/ptr.rs Normal file
View File

@ -0,0 +1,116 @@
//! This is a wrapper around the `WasmPtr` abstraction that does not allow deref of address 0
//! This is a common assumption in Emscripten code
// this is a wrapper with extra logic around the runtime-core `WasmPtr`, so we
// don't want to warn about unusued code here
#![allow(dead_code)]
use std::{cell::Cell, fmt};
pub use wasmer_runtime_core::memory::ptr::Array;
use wasmer_runtime_core::{
memory::{ptr, Memory},
types::{ValueType, WasmExternType},
};
#[repr(transparent)]
pub struct WasmPtr<T: Copy, Ty = ptr::Item>(ptr::WasmPtr<T, Ty>);
unsafe impl<T: Copy, Ty> ValueType for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> Copy for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> Clone for WasmPtr<T, Ty> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T: Copy, Ty> fmt::Debug for WasmPtr<T, Ty> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{:?}", self.0)
}
}
unsafe impl<T: Copy, Ty> WasmExternType for WasmPtr<T, Ty> {
type Native = <ptr::WasmPtr<T, Ty> as WasmExternType>::Native;
fn to_native(self) -> Self::Native {
self.0.to_native()
}
fn from_native(n: Self::Native) -> Self {
Self(ptr::WasmPtr::from_native(n))
}
}
impl<T: Copy, Ty> PartialEq for WasmPtr<T, Ty> {
fn eq(&self, other: &Self) -> bool {
self.0 == other.0
}
}
impl<T: Copy, Ty> Eq for WasmPtr<T, Ty> {}
impl<T: Copy, Ty> WasmPtr<T, Ty> {
#[inline(always)]
pub fn new(offset: u32) -> Self {
Self(ptr::WasmPtr::new(offset))
}
#[inline(always)]
pub fn offset(self) -> u32 {
self.0.offset()
}
}
impl<T: Copy + ValueType> WasmPtr<T, ptr::Item> {
#[inline(always)]
pub fn deref<'a>(self, memory: &'a Memory) -> Option<&'a Cell<T>> {
if self.0.offset() == 0 {
None
} else {
self.0.deref(memory)
}
}
#[inline(always)]
pub unsafe fn deref_mut<'a>(self, memory: &'a Memory) -> Option<&'a mut Cell<T>> {
if self.0.offset() == 0 {
None
} else {
self.0.deref_mut(memory)
}
}
}
impl<T: Copy + ValueType> WasmPtr<T, ptr::Array> {
#[inline(always)]
pub fn deref<'a>(self, memory: &'a Memory, index: u32, length: u32) -> Option<&'a [Cell<T>]> {
if self.0.offset() == 0 {
None
} else {
self.0.deref(memory, index, length)
}
}
#[inline]
pub unsafe fn deref_mut<'a>(
self,
memory: &'a Memory,
index: u32,
length: u32,
) -> Option<&'a mut [Cell<T>]> {
if self.0.offset() == 0 {
None
} else {
self.0.deref_mut(memory, index, length)
}
}
#[inline(always)]
pub fn get_utf8_string<'a>(self, memory: &'a Memory, str_len: u32) -> Option<&'a str> {
if self.0.offset() == 0 {
None
} else {
self.0.get_utf8_string(memory, str_len)
}
}
}

View File

@ -10,7 +10,10 @@ pub use self::unix::*;
#[cfg(windows)]
pub use self::windows::*;
use crate::utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory};
use crate::{
ptr::{Array, WasmPtr},
utils::{copy_stat_into_wasm, get_cstr_path, get_current_directory},
};
use super::varargs::VarArgs;
use byteorder::{ByteOrder, LittleEndian};
@ -40,10 +43,7 @@ use libc::{
write,
// ENOTTY,
};
use wasmer_runtime_core::{
memory::ptr::{Array, WasmPtr},
vm::Ctx,
};
use wasmer_runtime_core::vm::Ctx;
use super::env;
use std::cell::Cell;

View File

@ -1,4 +1,4 @@
use crate::varargs::VarArgs;
use crate::{ptr::WasmPtr, varargs::VarArgs};
#[cfg(target_os = "macos")]
use libc::size_t;
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
@ -111,7 +111,7 @@ fn translate_ioctl(wasm_ioctl: u32) -> c_ulong {
#[allow(unused_imports)]
use std::ffi::CStr;
use wasmer_runtime_core::{memory::ptr::WasmPtr, vm::Ctx};
use wasmer_runtime_core::vm::Ctx;
use crate::env::EmSockAddr;
use crate::utils::{self, get_cstr_path};

View File

@ -24,7 +24,9 @@ pub fn is_emscripten_module(module: &Module) -> bool {
.namespace_table
.get(import_name.namespace_index);
let field = module.info().name_table.get(import_name.name_index);
if (field == "_emscripten_memcpy_big" || field == "emscripten_memcpy_big")
if (field == "_emscripten_memcpy_big"
|| field == "emscripten_memcpy_big"
|| field == "__map_file")
&& namespace == "env"
{
return true;