mirror of
https://github.com/fluencelabs/wasmer
synced 2024-12-13 06:15:33 +00:00
Improved formatting
This commit is contained in:
parent
50f6ea3bd4
commit
c2ede37a72
@ -1,15 +1,12 @@
|
||||
use super::super::host;
|
||||
/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset
|
||||
use libc::{
|
||||
c_int, getpwnam as libc_getpwnam,
|
||||
getgrnam as libc_getgrnam,
|
||||
};
|
||||
use libc::{c_int, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam};
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::c_char;
|
||||
use std::mem;
|
||||
use std::os::raw::c_char;
|
||||
|
||||
use crate::webassembly::Instance;
|
||||
use super::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
|
||||
use crate::webassembly::Instance;
|
||||
|
||||
/// emscripten: _getenv
|
||||
pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
@ -47,9 +44,11 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
|
||||
unsafe {
|
||||
let passwd = &*libc_getpwnam(name.as_ptr());
|
||||
let passwd_struct_offset = (instance.emscripten_data.malloc)(mem::size_of::<GuestPasswd>() as _, instance);
|
||||
let passwd_struct_offset =
|
||||
(instance.emscripten_data.malloc)(mem::size_of::<GuestPasswd>() as _, instance);
|
||||
|
||||
let passwd_struct_ptr = instance.memory_offset_addr(0, passwd_struct_offset as _) as *mut GuestPasswd;
|
||||
let passwd_struct_ptr =
|
||||
instance.memory_offset_addr(0, passwd_struct_offset as _) as *mut GuestPasswd;
|
||||
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(instance, passwd.pw_name);
|
||||
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(instance, passwd.pw_passwd);
|
||||
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(instance, passwd.pw_gecos);
|
||||
@ -80,9 +79,11 @@ pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
|
||||
unsafe {
|
||||
let group = &*libc_getgrnam(name.as_ptr());
|
||||
let group_struct_offset = (instance.emscripten_data.malloc)(mem::size_of::<GuestGroup>() as _, instance);
|
||||
let group_struct_offset =
|
||||
(instance.emscripten_data.malloc)(mem::size_of::<GuestGroup>() as _, instance);
|
||||
|
||||
let group_struct_ptr = instance.memory_offset_addr(0, group_struct_offset as _) as *mut GuestGroup;
|
||||
let group_struct_ptr =
|
||||
instance.memory_offset_addr(0, group_struct_offset as _) as *mut GuestGroup;
|
||||
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(instance, group.gr_name);
|
||||
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(instance, group.gr_passwd);
|
||||
(*group_struct_ptr).gr_gid = group.gr_gid;
|
||||
@ -92,12 +93,12 @@ pub extern "C" fn _getgrnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
|
||||
}
|
||||
}
|
||||
|
||||
pub extern fn _localtime_r() -> u32 {
|
||||
pub extern "C" fn _localtime_r() -> u32 {
|
||||
debug!("emscripten::_localtime_r");
|
||||
0
|
||||
}
|
||||
|
||||
pub extern fn _getpagesize() -> u32 {
|
||||
pub extern "C" fn _getpagesize() -> u32 {
|
||||
debug!("emscripten::_getpagesize");
|
||||
16384
|
||||
}
|
||||
}
|
||||
|
@ -263,4 +263,3 @@ pub extern "C" fn ___seterrno(value: i32) -> i32 {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
use libc::c_int;
|
||||
use crate::webassembly::Instance;
|
||||
use libc::c_int;
|
||||
|
||||
// NOTE: Not implemented by Emscripten
|
||||
pub extern "C" fn ___lock(_which: c_int, _varargs: c_int, _instance: &mut Instance) {}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use libc::{c_void, memcpy, size_t};
|
||||
use crate::webassembly::Instance;
|
||||
use super::process::abort_with_message;
|
||||
use crate::webassembly::Instance;
|
||||
use libc::{c_void, memcpy, size_t};
|
||||
|
||||
/// emscripten: _emscripten_memcpy_big
|
||||
pub extern "C" fn _emscripten_memcpy_big(
|
||||
|
@ -1,24 +1,24 @@
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
/// NOTE: TODO: These emscripten api implementation only support wasm32 for now because they assume offsets are u32
|
||||
use crate::webassembly::{ImportObject, ImportValue, LinearMemory};
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use std::mem;
|
||||
|
||||
// EMSCRIPTEN APIS
|
||||
mod env;
|
||||
mod errno;
|
||||
mod io;
|
||||
mod memory;
|
||||
mod process;
|
||||
mod syscalls;
|
||||
mod lock;
|
||||
mod memory;
|
||||
mod nullfunc;
|
||||
mod process;
|
||||
mod storage;
|
||||
mod syscalls;
|
||||
mod time;
|
||||
mod utils;
|
||||
mod varargs;
|
||||
mod errno;
|
||||
mod storage;
|
||||
mod nullfunc;
|
||||
mod time;
|
||||
|
||||
pub use self::utils::is_emscripten_module;
|
||||
pub use self::storage::{align_memory, static_alloc};
|
||||
pub use self::utils::is_emscripten_module;
|
||||
|
||||
// TODO: Magic number - how is this calculated?
|
||||
const TOTAL_STACK: u32 = 5242880;
|
||||
@ -51,21 +51,17 @@ fn dynamictop_ptr(static_bump: u32) -> u32 {
|
||||
|
||||
pub fn emscripten_set_up_memory(memory: &mut LinearMemory) {
|
||||
let dynamictop_ptr = dynamictop_ptr(STATIC_BUMP) as usize;
|
||||
let mem = &mut memory[dynamictop_ptr..dynamictop_ptr+mem::size_of::<u32>()];
|
||||
let mem = &mut memory[dynamictop_ptr..dynamictop_ptr + mem::size_of::<u32>()];
|
||||
LittleEndian::write_u32(mem, dynamic_base(STATIC_BUMP));
|
||||
}
|
||||
|
||||
macro_rules! mock_external {
|
||||
($import:ident, $name:ident) => {{
|
||||
extern fn _mocked_fn() -> i32 {
|
||||
extern "C" fn _mocked_fn() -> i32 {
|
||||
debug!("emscripten::{} <mock>", stringify!($name));
|
||||
-1
|
||||
}
|
||||
$import.set(
|
||||
"env",
|
||||
stringify!($name),
|
||||
ImportValue::Func(_mocked_fn as _),
|
||||
);
|
||||
$import.set("env", stringify!($name), ImportValue::Func(_mocked_fn as _));
|
||||
}};
|
||||
}
|
||||
|
||||
@ -103,11 +99,7 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"DYNAMICTOP_PTR",
|
||||
ImportValue::Global(dynamictop_ptr(STATIC_BUMP) as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"tableBase",
|
||||
ImportValue::Global(0),
|
||||
);
|
||||
import_object.set("env", "tableBase", ImportValue::Global(0));
|
||||
|
||||
// Print functions
|
||||
import_object.set("env", "printf", ImportValue::Func(io::printf as *const u8));
|
||||
@ -133,16 +125,8 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"_getenv",
|
||||
ImportValue::Func(env::_getenv as *const u8),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_getpwnam",
|
||||
ImportValue::Func(env::_getpwnam as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_getgrnam",
|
||||
ImportValue::Func(env::_getgrnam as _),
|
||||
);
|
||||
import_object.set("env", "_getpwnam", ImportValue::Func(env::_getpwnam as _));
|
||||
import_object.set("env", "_getgrnam", ImportValue::Func(env::_getgrnam as _));
|
||||
// Errno
|
||||
import_object.set(
|
||||
"env",
|
||||
@ -370,16 +354,8 @@ pub fn generate_emscripten_env<'a, 'b>() -> ImportObject<&'a str, &'b str> {
|
||||
"_localtime",
|
||||
ImportValue::Func(time::_localtime as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_time",
|
||||
ImportValue::Func(time::_time as _),
|
||||
);
|
||||
import_object.set(
|
||||
"env",
|
||||
"_strftime",
|
||||
ImportValue::Func(time::_strftime as _),
|
||||
);
|
||||
import_object.set("env", "_time", ImportValue::Func(time::_time as _));
|
||||
import_object.set("env", "_strftime", ImportValue::Func(time::_strftime as _));
|
||||
import_object.set(
|
||||
"env",
|
||||
"_localtime_r",
|
||||
|
@ -36,4 +36,3 @@ pub extern "C" fn nullfunc_viii(_x: u32, _instance: &Instance) {
|
||||
pub extern "C" fn nullfunc_viiii(_x: u32, _instance: &Instance) {
|
||||
abort_with_message("Invalid function pointer called with signature 'viiii'. Perhaps this is an invalid value (e.g. caused by calling a virtual method on a NULL pointer)? Or calling a function with an incorrect type, which will fail? (it is worth building your source files with -Werror (warnings are errors), as warnings can indicate undefined behavior which can cause this)");
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
|
||||
use crate::webassembly::LinearMemory;
|
||||
|
||||
pub fn align_memory(ptr: u32) -> u32 {
|
||||
@ -18,6 +17,9 @@ pub fn static_alloc(size: u32, static_top: &mut u32, memory: &LinearMemory) -> u
|
||||
let total_memory = memory.maximum_size() * LinearMemory::PAGE_SIZE;
|
||||
// NOTE: The `4294967280` is a u32 conversion of -16 as gotten from emscripten.
|
||||
*static_top = (*static_top + size + 15) & 4294967280;
|
||||
assert!(*static_top < total_memory, "not enough memory for static allocation - increase total_memory!");
|
||||
assert!(
|
||||
*static_top < total_memory,
|
||||
"not enough memory for static allocation - increase total_memory!"
|
||||
);
|
||||
old_static_top
|
||||
}
|
||||
|
@ -1,34 +1,66 @@
|
||||
use super::utils::copy_stat_into_wasm;
|
||||
use super::varargs::VarArgs;
|
||||
use crate::webassembly::Instance;
|
||||
/// NOTE: TODO: These syscalls only support wasm_32 for now because they assume offsets are u32
|
||||
/// Syscall list: https://www.cs.utexas.edu/~bismith/test/syscalls/syscalls32.html
|
||||
use libc::{
|
||||
c_int, c_void, utsname, off_t,
|
||||
ssize_t, write, exit, read,
|
||||
open, close,
|
||||
uname, lseek, readv,
|
||||
iovec, writev, socklen_t,
|
||||
sockaddr, socket, bind,
|
||||
connect, listen, accept,
|
||||
getsockname, getpeername,
|
||||
sendto, recvfrom,
|
||||
getsockopt, sendmsg, recvmsg,
|
||||
msghdr, getpid, pid_t,
|
||||
gid_t, getgid, fstat, stat,
|
||||
pread, mkdir, chown,
|
||||
accept,
|
||||
bind,
|
||||
c_int,
|
||||
c_void,
|
||||
chown,
|
||||
// fcntl, ioctl, setsockopt, getppid
|
||||
close,
|
||||
connect,
|
||||
exit,
|
||||
fstat,
|
||||
getgid,
|
||||
getpeername,
|
||||
getpid,
|
||||
getsockname,
|
||||
getsockopt,
|
||||
gid_t,
|
||||
iovec,
|
||||
listen,
|
||||
lseek,
|
||||
mkdir,
|
||||
msghdr,
|
||||
off_t,
|
||||
open,
|
||||
pid_t,
|
||||
pread,
|
||||
read,
|
||||
readv,
|
||||
recvfrom,
|
||||
recvmsg,
|
||||
sendmsg,
|
||||
sendto,
|
||||
sockaddr,
|
||||
socket,
|
||||
socklen_t,
|
||||
ssize_t,
|
||||
stat,
|
||||
uname,
|
||||
utsname,
|
||||
write,
|
||||
writev,
|
||||
};
|
||||
use crate::webassembly::Instance;
|
||||
use super::varargs::VarArgs;
|
||||
use super::utils::copy_stat_into_wasm;
|
||||
|
||||
/// sys_exit
|
||||
pub extern "C" fn ___syscall1(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) {
|
||||
debug!("emscripten::___syscall1");
|
||||
let status: i32 = varargs.get(instance);
|
||||
unsafe { exit(status); }
|
||||
unsafe {
|
||||
exit(status);
|
||||
}
|
||||
}
|
||||
|
||||
/// sys_read
|
||||
pub extern "C" fn ___syscall3(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> ssize_t {
|
||||
pub extern "C" fn ___syscall3(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> ssize_t {
|
||||
debug!("emscripten::___syscall3");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let buf: u32 = varargs.get(instance);
|
||||
@ -39,7 +71,11 @@ pub extern "C" fn ___syscall3(_which: c_int, mut varargs: VarArgs, instance: &mu
|
||||
}
|
||||
|
||||
/// sys_write
|
||||
pub extern "C" fn ___syscall4(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall4(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall4");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let buf: u32 = varargs.get(instance);
|
||||
@ -50,7 +86,11 @@ pub extern "C" fn ___syscall4(_which: c_int, mut varargs: VarArgs, instance: &mu
|
||||
}
|
||||
|
||||
/// sys_open
|
||||
pub extern "C" fn ___syscall5(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall5(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall5");
|
||||
let pathname: u32 = varargs.get(instance);
|
||||
let flags: i32 = varargs.get(instance);
|
||||
@ -67,7 +107,11 @@ pub extern "C" fn ___syscall5(_which: c_int, mut varargs: VarArgs, instance: &mu
|
||||
}
|
||||
|
||||
/// sys_close
|
||||
pub extern "C" fn ___syscall6(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall6(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall6");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
debug!("fd: {}", fd);
|
||||
@ -75,7 +119,11 @@ pub extern "C" fn ___syscall6(_which: c_int, mut varargs: VarArgs, instance: &mu
|
||||
}
|
||||
|
||||
/// sys_ioctl
|
||||
pub extern "C" fn ___syscall54(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall54(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall54");
|
||||
let _fd: i32 = varargs.get(instance);
|
||||
let _request: u32 = varargs.get(instance);
|
||||
@ -86,7 +134,11 @@ pub extern "C" fn ___syscall54(_which: c_int, mut varargs: VarArgs, instance: &m
|
||||
|
||||
/// sys_uname
|
||||
// NOTE: Wondering if we should return custom utsname, like Emscripten.
|
||||
pub extern "C" fn ___syscall122(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall122(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall122");
|
||||
let buf: u32 = varargs.get(instance);
|
||||
debug!("buf: {}", buf);
|
||||
@ -95,7 +147,11 @@ pub extern "C" fn ___syscall122(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
}
|
||||
|
||||
/// sys_lseek
|
||||
pub extern "C" fn ___syscall140(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> off_t {
|
||||
pub extern "C" fn ___syscall140(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> off_t {
|
||||
debug!("emscripten::___syscall145");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let offset: i64 = varargs.get(instance);
|
||||
@ -105,7 +161,11 @@ pub extern "C" fn ___syscall140(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
}
|
||||
|
||||
/// sys_readv
|
||||
pub extern "C" fn ___syscall145(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> ssize_t {
|
||||
pub extern "C" fn ___syscall145(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> ssize_t {
|
||||
debug!("emscripten::___syscall145");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let iov: u32 = varargs.get(instance);
|
||||
@ -116,7 +176,11 @@ pub extern "C" fn ___syscall145(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
}
|
||||
|
||||
// sys_writev
|
||||
pub extern "C" fn ___syscall146(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> ssize_t {
|
||||
pub extern "C" fn ___syscall146(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> ssize_t {
|
||||
debug!("emscripten::___syscall145");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let iov: u32 = varargs.get(instance);
|
||||
@ -136,65 +200,80 @@ pub extern "C" fn ___syscall146(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
// }
|
||||
|
||||
// sys_socketcall
|
||||
pub extern "C" fn ___syscall102(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall102(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall102");
|
||||
let call: u32 = varargs.get(instance);
|
||||
let mut socket_varargs: VarArgs = varargs.get(instance);
|
||||
match call {
|
||||
1 => { // socket (domain: c_int, ty: c_int, protocol: c_int) -> c_int
|
||||
1 => {
|
||||
// socket (domain: c_int, ty: c_int, protocol: c_int) -> c_int
|
||||
let domain: i32 = socket_varargs.get(instance);
|
||||
let ty: i32 = socket_varargs.get(instance);
|
||||
let protocol: i32 = socket_varargs.get(instance);
|
||||
let socket = unsafe { socket(domain, ty, protocol) };
|
||||
debug!("socket: {}", socket);
|
||||
socket
|
||||
},
|
||||
2 => { // bind (socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int
|
||||
}
|
||||
2 => {
|
||||
// bind (socket: c_int, address: *const sockaddr, address_len: socklen_t) -> c_int
|
||||
// TODO: Emscripten has a different signature.
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let address: u32 = socket_varargs.get(instance);
|
||||
let address_len: u32 = socket_varargs.get(instance);
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
unsafe { bind(socket, address, address_len) }
|
||||
},
|
||||
3 => { // connect (socket: c_int, address: *const sockaddr, len: socklen_t) -> c_int
|
||||
}
|
||||
3 => {
|
||||
// connect (socket: c_int, address: *const sockaddr, len: socklen_t) -> c_int
|
||||
// TODO: Emscripten has a different signature.
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let address: u32 = socket_varargs.get(instance);
|
||||
let address_len: u32 = socket_varargs.get(instance);
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
unsafe { connect(socket, address, address_len) }
|
||||
},
|
||||
4 => { // listen (socket: c_int, backlog: c_int) -> c_int
|
||||
}
|
||||
4 => {
|
||||
// listen (socket: c_int, backlog: c_int) -> c_int
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let backlog: i32 = socket_varargs.get(instance);
|
||||
unsafe { listen(socket, backlog) }
|
||||
},
|
||||
5 => { // accept (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
|
||||
}
|
||||
5 => {
|
||||
// accept (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let address: u32 = socket_varargs.get(instance);
|
||||
let address_len: u32 = socket_varargs.get(instance);
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
let address_len_addr = instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
let address_len_addr =
|
||||
instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
unsafe { accept(socket, address, address_len_addr) }
|
||||
},
|
||||
6 => { // getsockname (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
|
||||
}
|
||||
6 => {
|
||||
// getsockname (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let address: u32 = socket_varargs.get(instance);
|
||||
let address_len: u32 = socket_varargs.get(instance);
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
let address_len_addr = instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
let address_len_addr =
|
||||
instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
unsafe { getsockname(socket, address, address_len_addr) }
|
||||
},
|
||||
7 => { // getpeername (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
|
||||
}
|
||||
7 => {
|
||||
// getpeername (socket: c_int, address: *mut sockaddr, address_len: *mut socklen_t) -> c_int
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let address: u32 = socket_varargs.get(instance);
|
||||
let address_len: u32 = socket_varargs.get(instance);
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
let address_len_addr = instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
let address_len_addr =
|
||||
instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
unsafe { getpeername(socket, address, address_len_addr) }
|
||||
},
|
||||
11 => { // sendto (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t
|
||||
}
|
||||
11 => {
|
||||
// sendto (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let buf: u32 = socket_varargs.get(instance);
|
||||
let flags: usize = socket_varargs.get(instance);
|
||||
@ -204,8 +283,9 @@ pub extern "C" fn ___syscall102(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut c_void;
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
unsafe { sendto(socket, buf_addr, flags, len, address, address_len) as i32 }
|
||||
},
|
||||
12 => { // recvfrom (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t
|
||||
}
|
||||
12 => {
|
||||
// recvfrom (socket: c_int, buf: *const c_void, len: size_t, flags: c_int, addr: *const sockaddr, addrlen: socklen_t) -> ssize_t
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let buf: u32 = socket_varargs.get(instance);
|
||||
let flags: usize = socket_varargs.get(instance);
|
||||
@ -214,10 +294,12 @@ pub extern "C" fn ___syscall102(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
let address_len: u32 = socket_varargs.get(instance);
|
||||
let buf_addr = instance.memory_offset_addr(0, buf as usize) as *mut c_void;
|
||||
let address = instance.memory_offset_addr(0, address as usize) as *mut sockaddr;
|
||||
let address_len_addr = instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
let address_len_addr =
|
||||
instance.memory_offset_addr(0, address_len as usize) as *mut socklen_t;
|
||||
unsafe { recvfrom(socket, buf_addr, flags, len, address, address_len_addr) as i32 }
|
||||
},
|
||||
14 => { // setsockopt (socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
|
||||
}
|
||||
14 => {
|
||||
// setsockopt (socket: c_int, level: c_int, name: c_int, value: *const c_void, option_len: socklen_t) -> c_int
|
||||
// let socket: i32 = socket_varargs.get(instance);
|
||||
// debug!("socket: {}", socket);
|
||||
// let level: i32 = socket_varargs.get(instance);
|
||||
@ -229,7 +311,7 @@ pub extern "C" fn ___syscall102(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
// let option_len: u32 = socket_varargs.get(instance);
|
||||
// debug!("option_len: {}", option_len);
|
||||
// let value_addr = instance.memory_offset_addr(0, value as usize) as *const c_void;
|
||||
|
||||
|
||||
// let ret = unsafe { setsockopt(socket, level, name, value_addr, option_len) };
|
||||
// debug!("ret: {}", ret);
|
||||
// if ret != 0 {
|
||||
@ -237,54 +319,54 @@ pub extern "C" fn ___syscall102(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
// }
|
||||
// ret
|
||||
0
|
||||
},
|
||||
15 => { // getsockopt (sockfd: c_int, level: c_int, optname: c_int, optval: *mut c_void, optlen: *mut socklen_t) -> c_int
|
||||
}
|
||||
15 => {
|
||||
// getsockopt (sockfd: c_int, level: c_int, optname: c_int, optval: *mut c_void, optlen: *mut socklen_t) -> c_int
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let level: i32 = socket_varargs.get(instance);
|
||||
let name: i32 = socket_varargs.get(instance);
|
||||
let value: u32 = socket_varargs.get(instance);
|
||||
let option_len: u32 = socket_varargs.get(instance);
|
||||
let value_addr = instance.memory_offset_addr(0, value as usize) as *mut c_void;
|
||||
let option_len_addr = instance.memory_offset_addr(0, option_len as usize) as *mut socklen_t;
|
||||
let option_len_addr =
|
||||
instance.memory_offset_addr(0, option_len as usize) as *mut socklen_t;
|
||||
unsafe { getsockopt(socket, level, name, value_addr, option_len_addr) }
|
||||
},
|
||||
16 => { // sendmsg (fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t
|
||||
}
|
||||
16 => {
|
||||
// sendmsg (fd: c_int, msg: *const msghdr, flags: c_int) -> ssize_t
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let msg: u32 = socket_varargs.get(instance);
|
||||
let flags: i32 = socket_varargs.get(instance);
|
||||
let msg_addr = instance.memory_offset_addr(0, msg as usize) as *const msghdr;
|
||||
unsafe { sendmsg(socket, msg_addr, flags) as i32 }
|
||||
},
|
||||
17 => { // recvmsg (fd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t
|
||||
}
|
||||
17 => {
|
||||
// recvmsg (fd: c_int, msg: *mut msghdr, flags: c_int) -> ssize_t
|
||||
let socket: i32 = socket_varargs.get(instance);
|
||||
let msg: u32 = socket_varargs.get(instance);
|
||||
let flags: i32 = socket_varargs.get(instance);
|
||||
let msg_addr = instance.memory_offset_addr(0, msg as usize) as *mut msghdr;
|
||||
unsafe { recvmsg(socket, msg_addr, flags) as i32 }
|
||||
},
|
||||
_ => { // others
|
||||
}
|
||||
_ => {
|
||||
// others
|
||||
-1
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sys_getpid
|
||||
pub extern "C" fn ___syscall20() -> pid_t {
|
||||
debug!("emscripten::___syscall20");
|
||||
unsafe {
|
||||
getpid()
|
||||
}
|
||||
unsafe { getpid() }
|
||||
}
|
||||
|
||||
// sys_getppid
|
||||
pub extern "C" fn ___syscall64() -> pid_t {
|
||||
debug!("emscripten::___syscall64");
|
||||
unsafe {
|
||||
getpid()
|
||||
}
|
||||
unsafe { getpid() }
|
||||
}
|
||||
|
||||
|
||||
// sys_getgid
|
||||
pub extern "C" fn ___syscall201() -> gid_t {
|
||||
debug!("emscripten::___syscall201");
|
||||
@ -304,15 +386,22 @@ pub extern "C" fn ___syscall202() -> gid_t {
|
||||
}
|
||||
|
||||
// sys_prlimit64
|
||||
pub extern "C" fn ___syscall340(_which: c_int, mut _varargs: VarArgs, _instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall340(
|
||||
_which: c_int,
|
||||
mut _varargs: VarArgs,
|
||||
_instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall340");
|
||||
// NOTE: Doesn't really matter. Wasm modules cannot exceed WASM_PAGE_SIZE anyway.
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
// sys_fstat64
|
||||
pub extern "C" fn ___syscall197(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall197(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall197");
|
||||
let fd: c_int = varargs.get(instance);
|
||||
let buf: u32 = varargs.get(instance);
|
||||
@ -331,7 +420,11 @@ pub extern "C" fn ___syscall197(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
}
|
||||
|
||||
// sys_pread
|
||||
pub extern "C" fn ___syscall180(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall180(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall180");
|
||||
let fd: i32 = varargs.get(instance);
|
||||
let buf: u32 = varargs.get(instance);
|
||||
@ -344,25 +437,29 @@ pub extern "C" fn ___syscall180(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
|
||||
let buf_ptr = instance.memory_offset_addr(0, buf as _) as _;
|
||||
|
||||
unsafe {
|
||||
pread(fd, buf_ptr, count as _, offset) as _
|
||||
}
|
||||
unsafe { pread(fd, buf_ptr, count as _, offset) as _ }
|
||||
}
|
||||
|
||||
// sys_mkdir
|
||||
pub extern "C" fn ___syscall39(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall39(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall39");
|
||||
let pathname: u32 = varargs.get(instance);
|
||||
let mode: u32 = varargs.get(instance);
|
||||
let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8;
|
||||
|
||||
unsafe {
|
||||
mkdir(pathname_addr, mode as _)
|
||||
}
|
||||
|
||||
unsafe { mkdir(pathname_addr, mode as _) }
|
||||
}
|
||||
|
||||
// sys_stat64
|
||||
pub extern "C" fn ___syscall195(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall195(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall195");
|
||||
let pathname: u32 = varargs.get(instance);
|
||||
let buf: u32 = varargs.get(instance);
|
||||
@ -382,7 +479,11 @@ pub extern "C" fn ___syscall195(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
}
|
||||
|
||||
// sys_chown
|
||||
pub extern "C" fn ___syscall212(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall212(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
debug!("emscripten::___syscall212");
|
||||
|
||||
let pathname: u32 = varargs.get(instance);
|
||||
@ -391,17 +492,19 @@ pub extern "C" fn ___syscall212(_which: c_int, mut varargs: VarArgs, instance: &
|
||||
|
||||
let pathname_addr = instance.memory_offset_addr(0, pathname as usize) as *const i8;
|
||||
|
||||
unsafe {
|
||||
chown(pathname_addr, owner, group)
|
||||
}
|
||||
unsafe { chown(pathname_addr, owner, group) }
|
||||
}
|
||||
|
||||
// sys_fcntl64
|
||||
pub extern "C" fn ___syscall221(_which: c_int, mut varargs: VarArgs, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn ___syscall221(
|
||||
_which: c_int,
|
||||
mut varargs: VarArgs,
|
||||
instance: &mut Instance,
|
||||
) -> c_int {
|
||||
let _fd: i32 = varargs.get(instance);
|
||||
let cmd: u32 = varargs.get(instance);
|
||||
match cmd {
|
||||
2 => 0,
|
||||
_ => -1,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,31 @@
|
||||
use super::utils::copy_cstr_into_wasm;
|
||||
use libc::{
|
||||
c_int,
|
||||
c_long,
|
||||
clock_gettime as libc_clock_gettime,
|
||||
timespec,
|
||||
// tm,
|
||||
localtime,
|
||||
time,
|
||||
time_t,
|
||||
time
|
||||
timespec,
|
||||
};
|
||||
use std::{mem};
|
||||
use std::mem;
|
||||
use std::time::SystemTime;
|
||||
use super::utils::{copy_cstr_into_wasm};
|
||||
|
||||
|
||||
use crate::webassembly::Instance;
|
||||
|
||||
/// emscripten: _gettimeofday
|
||||
pub extern fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_int {
|
||||
#[repr(C)]
|
||||
struct GuestTimeVal {
|
||||
tv_sec: i32,
|
||||
tv_usec: i32,
|
||||
}
|
||||
|
||||
assert!(tz == 0, "the timezone argument of `_gettimeofday` must be null");
|
||||
assert!(
|
||||
tz == 0,
|
||||
"the timezone argument of `_gettimeofday` must be null"
|
||||
);
|
||||
unsafe {
|
||||
let now = SystemTime::now();
|
||||
let since_epoch = now.duration_since(SystemTime::UNIX_EPOCH).unwrap();
|
||||
@ -35,9 +37,8 @@ pub extern fn _gettimeofday(tp: c_int, tz: c_int, instance: &mut Instance) -> c_
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
/// emscripten: _clock_gettime
|
||||
pub extern fn _clock_gettime(clk_id: c_int, tp: c_int, instance: &mut Instance) -> c_int {
|
||||
pub extern "C" fn _clock_gettime(clk_id: c_int, tp: c_int, instance: &mut Instance) -> c_int {
|
||||
#[repr(C)]
|
||||
struct GuestTimeSpec {
|
||||
tv_sec: i32,
|
||||
@ -85,7 +86,8 @@ pub extern "C" fn _localtime(time_p: u32, instance: &mut Instance) -> c_int {
|
||||
let tm_struct = &*localtime(time_p_addr);
|
||||
|
||||
// Webassembly allocation
|
||||
let tm_struct_offset = (instance.emscripten_data.malloc)(mem::size_of::<GuestTm>() as _, instance);
|
||||
let tm_struct_offset =
|
||||
(instance.emscripten_data.malloc)(mem::size_of::<GuestTm>() as _, instance);
|
||||
let tm_struct_ptr = instance.memory_offset_addr(0, tm_struct_offset as _) as *mut GuestTm;
|
||||
|
||||
// Initializing
|
||||
@ -116,7 +118,16 @@ pub extern "C" fn _time(time_p: u32, instance: &mut Instance) -> time_t {
|
||||
}
|
||||
|
||||
/// emscripten: _strftime
|
||||
pub extern "C" fn _strftime(s_ptr: c_int, maxsize: u32, format_ptr: c_int, tm_ptr: c_int, _instance: &mut Instance) -> time_t {
|
||||
debug!("emscripten::_strftime {} {} {} {}", s_ptr, maxsize, format_ptr, tm_ptr);
|
||||
pub extern "C" fn _strftime(
|
||||
s_ptr: c_int,
|
||||
maxsize: u32,
|
||||
format_ptr: c_int,
|
||||
tm_ptr: c_int,
|
||||
_instance: &mut Instance,
|
||||
) -> time_t {
|
||||
debug!(
|
||||
"emscripten::_strftime {} {} {} {}",
|
||||
s_ptr, maxsize, format_ptr, tm_ptr
|
||||
);
|
||||
0
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
use crate::webassembly::module::Module;
|
||||
use crate::webassembly::Instance;
|
||||
use libc::stat;
|
||||
use std::ffi::CStr;
|
||||
use std::os::raw::c_char;
|
||||
use std::slice;
|
||||
use libc::stat;
|
||||
use byteorder::{ByteOrder, LittleEndian};
|
||||
|
||||
/// We check if a provided module is an Emscripten generated one
|
||||
pub fn is_emscripten_module(module: &Module) -> bool {
|
||||
@ -28,7 +28,10 @@ pub unsafe fn copy_cstr_into_wasm(instance: &mut Instance, cstr: *const c_char)
|
||||
space_offset
|
||||
}
|
||||
|
||||
pub unsafe fn copy_terminated_array_of_cstrs(_instance: &mut Instance, cstrs: *mut *mut c_char) -> u32 {
|
||||
pub unsafe fn copy_terminated_array_of_cstrs(
|
||||
_instance: &mut Instance,
|
||||
cstrs: *mut *mut c_char,
|
||||
) -> u32 {
|
||||
let total_num = {
|
||||
let mut ptr = cstrs;
|
||||
let mut counter = 0;
|
||||
@ -38,14 +41,17 @@ pub unsafe fn copy_terminated_array_of_cstrs(_instance: &mut Instance, cstrs: *m
|
||||
}
|
||||
counter
|
||||
};
|
||||
debug!("emscripten::copy_terminated_array_of_cstrs::total_num: {}", total_num);
|
||||
debug!(
|
||||
"emscripten::copy_terminated_array_of_cstrs::total_num: {}",
|
||||
total_num
|
||||
);
|
||||
0
|
||||
}
|
||||
|
||||
pub unsafe fn copy_stat_into_wasm(instance: &mut Instance, buf: u32, stat: &stat) {
|
||||
let buf_ptr = instance.memory_offset_addr(0, buf as _) as *mut u8;
|
||||
let buf = slice::from_raw_parts_mut(buf_ptr, 76);
|
||||
|
||||
|
||||
LittleEndian::write_u32(&mut buf[..], stat.st_dev as _);
|
||||
LittleEndian::write_u32(&mut buf[4..], 0);
|
||||
LittleEndian::write_u32(&mut buf[8..], stat.st_ino as _);
|
||||
|
@ -12,4 +12,4 @@ impl VarArgs {
|
||||
self.pointer += mem::size_of::<T>() as u32;
|
||||
unsafe { (ptr as *const T).read() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
pub mod emscripten;
|
||||
pub mod host;
|
||||
|
||||
pub use self::emscripten::{generate_emscripten_env, is_emscripten_module, align_memory};
|
||||
pub use self::emscripten::{align_memory, generate_emscripten_env, is_emscripten_module};
|
||||
|
@ -12,9 +12,9 @@ extern crate wabt;
|
||||
extern crate wasmparser;
|
||||
#[macro_use]
|
||||
extern crate target_lexicon;
|
||||
extern crate byteorder;
|
||||
extern crate nix;
|
||||
extern crate rayon;
|
||||
extern crate byteorder;
|
||||
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
@ -26,39 +26,40 @@ thread_local! {
|
||||
/// the behavior of call_protected is undefined.
|
||||
#[macro_export]
|
||||
macro_rules! call_protected {
|
||||
($x:expr) => {unsafe {
|
||||
use crate::webassembly::ErrorKind;
|
||||
use crate::recovery::{SETJMP_BUFFER, setjmp};
|
||||
use crate::sighandler::install_sighandler;
|
||||
($x:expr) => {
|
||||
unsafe {
|
||||
use crate::recovery::{setjmp, SETJMP_BUFFER};
|
||||
use crate::sighandler::install_sighandler;
|
||||
use crate::webassembly::ErrorKind;
|
||||
|
||||
use nix::sys::signal::{Signal, SIGFPE, SIGILL, SIGSEGV, SIGBUS};
|
||||
use nix::sys::signal::{Signal, SIGBUS, SIGFPE, SIGILL, SIGSEGV};
|
||||
|
||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||
let prev_jmp_buf = *jmp_buf;
|
||||
let jmp_buf = SETJMP_BUFFER.with(|buf| buf.get());
|
||||
let prev_jmp_buf = *jmp_buf;
|
||||
|
||||
install_sighandler();
|
||||
install_sighandler();
|
||||
|
||||
let signum = setjmp(jmp_buf as *mut ::nix::libc::c_void);
|
||||
if signum != 0 {
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
let signal = match Signal::from_c_int(signum) {
|
||||
Ok(SIGFPE) => "floating-point exception",
|
||||
Ok(SIGILL) => "illegal instruction",
|
||||
Ok(SIGSEGV) => "segmentation violation",
|
||||
Ok(SIGBUS) => "bus error",
|
||||
Err(_) => "error while getting the Signal",
|
||||
_ => "unkown trapped signal",
|
||||
};
|
||||
Err(ErrorKind::RuntimeError(format!("trap - {}", signal)))
|
||||
} else {
|
||||
let ret = $x; // TODO: Switch stack?
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
Ok(ret)
|
||||
let signum = setjmp(jmp_buf as *mut ::nix::libc::c_void);
|
||||
if signum != 0 {
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
let signal = match Signal::from_c_int(signum) {
|
||||
Ok(SIGFPE) => "floating-point exception",
|
||||
Ok(SIGILL) => "illegal instruction",
|
||||
Ok(SIGSEGV) => "segmentation violation",
|
||||
Ok(SIGBUS) => "bus error",
|
||||
Err(_) => "error while getting the Signal",
|
||||
_ => "unkown trapped signal",
|
||||
};
|
||||
Err(ErrorKind::RuntimeError(format!("trap - {}", signal)))
|
||||
} else {
|
||||
let ret = $x; // TODO: Switch stack?
|
||||
*jmp_buf = prev_jmp_buf;
|
||||
Ok(ret)
|
||||
}
|
||||
}
|
||||
}}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// Unwinds to last protected_call.
|
||||
pub unsafe fn do_unwind(signum: i32) -> ! {
|
||||
// Since do_unwind is only expected to get called from WebAssembly code which doesn't hold any host resources (locks etc.)
|
||||
|
@ -18,8 +18,8 @@ use std::iter::FromIterator;
|
||||
use std::iter::Iterator;
|
||||
use std::mem::size_of;
|
||||
use std::ptr::write_unaligned;
|
||||
use std::{fmt, slice, mem};
|
||||
use std::sync::Arc;
|
||||
use std::{fmt, mem, slice};
|
||||
|
||||
use super::super::common::slice::{BoundedSlice, UncheckedSlice};
|
||||
use super::errors::ErrorKind;
|
||||
@ -68,8 +68,8 @@ fn get_function_addr(
|
||||
}
|
||||
|
||||
pub struct EmscriptenData {
|
||||
pub malloc: extern fn(i32, &mut Instance) -> u32,
|
||||
pub free: extern fn(i32, &mut Instance),
|
||||
pub malloc: extern "C" fn(i32, &mut Instance) -> u32,
|
||||
pub free: extern "C" fn(i32, &mut Instance),
|
||||
}
|
||||
|
||||
impl fmt::Debug for EmscriptenData {
|
||||
@ -243,8 +243,7 @@ impl Instance {
|
||||
// let r = *Arc::from_raw(isa_ptr);
|
||||
compile_function(&*options.isa, function_body).unwrap()
|
||||
// unimplemented!()
|
||||
})
|
||||
.collect();
|
||||
}).collect();
|
||||
|
||||
for compiled_func in compiled_funcs.into_iter() {
|
||||
let CompiledFunction {
|
||||
@ -495,12 +494,7 @@ impl Instance {
|
||||
tables.iter().map(|table| table[..].into()).collect();
|
||||
let memories_pointer: Vec<BoundedSlice<u8>> = memories
|
||||
.iter()
|
||||
.map(|mem| {
|
||||
BoundedSlice::new(
|
||||
&mem[..],
|
||||
mem.current_size(),
|
||||
)
|
||||
})
|
||||
.map(|mem| BoundedSlice::new(&mem[..], mem.current_size()))
|
||||
.collect();
|
||||
let globals_pointer: GlobalsSlice = globals[..].into();
|
||||
|
||||
@ -511,14 +505,16 @@ impl Instance {
|
||||
};
|
||||
|
||||
let emscripten_data = unsafe {
|
||||
let malloc_index = if let Some(Export::Function(index)) = module.info.exports.get("_malloc") {
|
||||
index
|
||||
} else {
|
||||
panic!("Unable to find _malloc export")
|
||||
};
|
||||
let malloc_index =
|
||||
if let Some(Export::Function(index)) = module.info.exports.get("_malloc") {
|
||||
index
|
||||
} else {
|
||||
panic!("Unable to find _malloc export")
|
||||
};
|
||||
let malloc_addr = get_function_addr(&malloc_index, &import_functions, &functions);
|
||||
|
||||
let free_index = if let Some(Export::Function(index)) = module.info.exports.get("_free") {
|
||||
let free_index = if let Some(Export::Function(index)) = module.info.exports.get("_free")
|
||||
{
|
||||
index
|
||||
} else {
|
||||
panic!("Unable to find _free export")
|
||||
@ -564,8 +560,7 @@ impl Instance {
|
||||
if let Some(func_index) = self.start_func {
|
||||
let func: fn(&Instance) = get_instance_function!(&self, func_index);
|
||||
call_protected!(func(self))
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,17 @@
|
||||
//! webassembly::Instance.
|
||||
//! A memory created by Rust or in WebAssembly code will be accessible and
|
||||
//! mutable from both Rust and WebAssembly.
|
||||
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
|
||||
use nix::libc::{c_void, mprotect, PROT_READ, PROT_WRITE};
|
||||
use std::slice;
|
||||
use nix::sys::mman::{mmap, MapFlags, ProtFlags};
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::slice;
|
||||
|
||||
/// A linear memory instance.
|
||||
//
|
||||
#[derive(Debug)]
|
||||
pub struct LinearMemory {
|
||||
base: *mut c_void, // The size will always be `LinearMemory::DEFAULT_SIZE`
|
||||
current: u32, // current number of wasm pages
|
||||
current: u32, // current number of wasm pages
|
||||
// The maximum size the WebAssembly Memory is allowed to grow
|
||||
// to, in units of WebAssembly pages. When present, the maximum
|
||||
// parameter acts as a hint to the engine to reserve memory up
|
||||
@ -36,8 +36,8 @@ impl LinearMemory {
|
||||
///
|
||||
/// `maximum` cannot be set to more than `65536` pages.
|
||||
pub fn new(initial: u32, maximum: Option<u32>) -> Self {
|
||||
assert!(initial <= Self::MAX_PAGES);
|
||||
assert!(maximum.is_none() || maximum.unwrap() <= Self::MAX_PAGES);
|
||||
assert!(initial <= Self::MAX_PAGES);
|
||||
assert!(maximum.is_none() || maximum.unwrap() <= Self::MAX_PAGES);
|
||||
debug!(
|
||||
"Instantiate LinearMemory(initial={:?}, maximum={:?})",
|
||||
initial, maximum
|
||||
@ -56,13 +56,16 @@ impl LinearMemory {
|
||||
};
|
||||
|
||||
if initial > 0 {
|
||||
assert_eq!(unsafe {
|
||||
mprotect(
|
||||
base,
|
||||
(initial * Self::PAGE_SIZE) as _,
|
||||
PROT_READ | PROT_WRITE,
|
||||
)
|
||||
}, 0);
|
||||
assert_eq!(
|
||||
unsafe {
|
||||
mprotect(
|
||||
base,
|
||||
(initial * Self::PAGE_SIZE) as _,
|
||||
PROT_READ | PROT_WRITE,
|
||||
)
|
||||
},
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
debug!("LinearMemory instantiated");
|
||||
@ -124,11 +127,14 @@ impl LinearMemory {
|
||||
let new_bytes = (new_pages * Self::PAGE_SIZE) as usize;
|
||||
|
||||
unsafe {
|
||||
assert_eq!(mprotect(
|
||||
self.base.add(prev_bytes),
|
||||
new_bytes - prev_bytes,
|
||||
PROT_READ | PROT_WRITE,
|
||||
), 0);
|
||||
assert_eq!(
|
||||
mprotect(
|
||||
self.base.add(prev_bytes),
|
||||
new_bytes - prev_bytes,
|
||||
PROT_READ | PROT_WRITE,
|
||||
),
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
self.current = new_pages;
|
||||
@ -156,20 +162,15 @@ impl PartialEq for LinearMemory {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl Deref for LinearMemory {
|
||||
type Target = [u8];
|
||||
fn deref(&self) -> &[u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts(self.base as _, (self.current * Self::PAGE_SIZE) as _)
|
||||
}
|
||||
unsafe { slice::from_raw_parts(self.base as _, (self.current * Self::PAGE_SIZE) as _) }
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for LinearMemory {
|
||||
fn deref_mut(&mut self) -> &mut [u8] {
|
||||
unsafe {
|
||||
slice::from_raw_parts_mut(self.base as _, (self.current * Self::PAGE_SIZE) as _)
|
||||
}
|
||||
unsafe { slice::from_raw_parts_mut(self.base as _, (self.current * Self::PAGE_SIZE) as _) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,10 @@ pub mod module;
|
||||
pub mod relocation;
|
||||
pub mod utils;
|
||||
|
||||
use cranelift_codegen::{isa, settings::{self, Configurable}};
|
||||
use cranelift_codegen::{
|
||||
isa,
|
||||
settings::{self, Configurable},
|
||||
};
|
||||
use std::panic;
|
||||
use std::str::FromStr;
|
||||
use target_lexicon;
|
||||
@ -47,11 +50,9 @@ pub fn instantiate(
|
||||
buffer_source: Vec<u8>,
|
||||
import_object: ImportObject<&str, &str>,
|
||||
) -> Result<ResultObject, ErrorKind> {
|
||||
|
||||
let flags = {
|
||||
let mut builder = settings::builder();
|
||||
builder.set("opt_level", "best")
|
||||
.unwrap();
|
||||
builder.set("opt_level", "best").unwrap();
|
||||
|
||||
let flags = settings::Flags::new(builder);
|
||||
debug_assert_eq!(flags.opt_level(), settings::OptLevel::Best);
|
||||
|
Loading…
Reference in New Issue
Block a user