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