mirror of
https://github.com/fluencelabs/wasmer
synced 2025-04-02 07:51:03 +00:00
Add EmscriptenData to instance and update usages
This commit is contained in:
parent
82e7ab6394
commit
99bc454c5b
@ -8,25 +8,15 @@ use std::mem;
|
|||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
|
|
||||||
use super::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
|
use super::utils::{allocate_on_stack, copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
|
||||||
|
use super::EmscriptenData;
|
||||||
use wasmer_runtime_core::{types::Value, vm::Ctx};
|
use wasmer_runtime_core::{types::Value, vm::Ctx};
|
||||||
//use super::EmscriptenData;
|
|
||||||
|
|
||||||
//impl Instance {
|
|
||||||
// pub fn memory_offset_addr(&self, index: usize, offset: usize) -> *const usize {
|
|
||||||
// unimplemented!("TODO replace this stub")
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// pub fn emscripten_data(&self) -> &'static mut Option<EmscriptenData> {
|
|
||||||
// unimplemented!("TODO replace this stub")
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
// #[no_mangle]
|
// #[no_mangle]
|
||||||
/// emscripten: _getenv // (name: *const char) -> *const c_char;
|
/// emscripten: _getenv // (name: *const char) -> *const c_char;
|
||||||
pub extern "C" fn _getenv(name: c_int, vmctx: &mut Ctx) -> u32 {
|
pub extern "C" fn _getenv(name: c_int, ctx: &mut Ctx) -> u32 {
|
||||||
debug!("emscripten::_getenv");
|
debug!("emscripten::_getenv");
|
||||||
|
|
||||||
let name_addr = vmctx.memory(0)[name as usize] as *const c_char;
|
let name_addr = ctx.memory(0)[name as usize] as *const c_char;
|
||||||
|
|
||||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||||
|
|
||||||
@ -35,15 +25,15 @@ pub extern "C" fn _getenv(name: c_int, vmctx: &mut Ctx) -> u32 {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe { copy_cstr_into_wasm(vmctx, c_str) }
|
unsafe { copy_cstr_into_wasm(ctx, c_str) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int);
|
/// emscripten: _setenv // (name: *const char, name: *const value, overwrite: int);
|
||||||
pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, vmctx: &mut Ctx) -> c_int {
|
pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, ctx: &mut Ctx) -> c_int {
|
||||||
debug!("emscripten::_setenv");
|
debug!("emscripten::_setenv");
|
||||||
|
|
||||||
let name_addr = vmctx.memory(0)[name as usize] as *const c_char;
|
let name_addr = ctx.memory(0)[name as usize] as *const c_char;
|
||||||
let value_addr = vmctx.memory(0)[value as usize] as *const c_char;
|
let value_addr = ctx.memory(0)[value as usize] as *const c_char;
|
||||||
|
|
||||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||||
debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) });
|
debug!("=> value({:?})", unsafe { CStr::from_ptr(value_addr) });
|
||||||
@ -52,10 +42,10 @@ pub extern "C" fn _setenv(name: c_int, value: c_int, overwrite: c_int, vmctx: &m
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// emscripten: _putenv // (name: *const char);
|
/// emscripten: _putenv // (name: *const char);
|
||||||
pub extern "C" fn _putenv(name: c_int, vmctx: &mut Ctx) -> c_int {
|
pub extern "C" fn _putenv(name: c_int, ctx: &mut Ctx) -> c_int {
|
||||||
debug!("emscripten::_putenv");
|
debug!("emscripten::_putenv");
|
||||||
|
|
||||||
let name_addr = vmctx.memory(0)[name as usize] as *const c_char;
|
let name_addr = ctx.memory(0)[name as usize] as *const c_char;
|
||||||
|
|
||||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||||
|
|
||||||
@ -63,10 +53,10 @@ pub extern "C" fn _putenv(name: c_int, vmctx: &mut Ctx) -> c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// emscripten: _unsetenv // (name: *const char);
|
/// emscripten: _unsetenv // (name: *const char);
|
||||||
pub extern "C" fn _unsetenv(name: c_int, vmctx: &mut Ctx) -> c_int {
|
pub extern "C" fn _unsetenv(name: c_int, ctx: &mut Ctx) -> c_int {
|
||||||
debug!("emscripten::_unsetenv");
|
debug!("emscripten::_unsetenv");
|
||||||
|
|
||||||
let name_addr = vmctx.memory(0)[name as usize] as *const c_char;
|
let name_addr = ctx.memory(0)[name as usize] as *const c_char;
|
||||||
|
|
||||||
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });
|
||||||
|
|
||||||
@ -74,7 +64,7 @@ pub extern "C" fn _unsetenv(name: c_int, vmctx: &mut Ctx) -> c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub extern "C" fn _getpwnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int {
|
pub extern "C" fn _getpwnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
|
||||||
debug!("emscripten::_getpwnam {}", name_ptr);
|
debug!("emscripten::_getpwnam {}", name_ptr);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -89,20 +79,20 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let name = unsafe {
|
let name = unsafe {
|
||||||
let memory_name_ptr = vmctx.memory(0)[name_ptr as usize] as *const c_char;
|
let memory_name_ptr = ctx.memory(0)[name_ptr as usize] as *const c_char;
|
||||||
CStr::from_ptr(memory_name_ptr)
|
CStr::from_ptr(memory_name_ptr)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let passwd = &*libc_getpwnam(name.as_ptr());
|
let passwd = &*libc_getpwnam(name.as_ptr());
|
||||||
let passwd_struct_offset = call_malloc(mem::size_of::<GuestPasswd>() as _, vmctx);
|
let passwd_struct_offset = call_malloc(mem::size_of::<GuestPasswd>() as _, ctx);
|
||||||
|
|
||||||
let passwd_struct_ptr = vmctx.memory(0)[passwd_struct_offset as usize] as *mut GuestPasswd;
|
let passwd_struct_ptr = ctx.memory(0)[passwd_struct_offset as usize] as *mut GuestPasswd;
|
||||||
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(vmctx, passwd.pw_name);
|
(*passwd_struct_ptr).pw_name = copy_cstr_into_wasm(ctx, passwd.pw_name);
|
||||||
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(vmctx, passwd.pw_passwd);
|
(*passwd_struct_ptr).pw_passwd = copy_cstr_into_wasm(ctx, passwd.pw_passwd);
|
||||||
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(vmctx, passwd.pw_gecos);
|
(*passwd_struct_ptr).pw_gecos = copy_cstr_into_wasm(ctx, passwd.pw_gecos);
|
||||||
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(vmctx, passwd.pw_dir);
|
(*passwd_struct_ptr).pw_dir = copy_cstr_into_wasm(ctx, passwd.pw_dir);
|
||||||
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(vmctx, passwd.pw_shell);
|
(*passwd_struct_ptr).pw_shell = copy_cstr_into_wasm(ctx, passwd.pw_shell);
|
||||||
(*passwd_struct_ptr).pw_uid = passwd.pw_uid;
|
(*passwd_struct_ptr).pw_uid = passwd.pw_uid;
|
||||||
(*passwd_struct_ptr).pw_gid = passwd.pw_gid;
|
(*passwd_struct_ptr).pw_gid = passwd.pw_gid;
|
||||||
|
|
||||||
@ -111,7 +101,7 @@ pub extern "C" fn _getpwnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub extern "C" fn _getgrnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int {
|
pub extern "C" fn _getgrnam(name_ptr: c_int, ctx: &mut Ctx) -> c_int {
|
||||||
debug!("emscripten::_getgrnam {}", name_ptr);
|
debug!("emscripten::_getgrnam {}", name_ptr);
|
||||||
|
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
@ -123,69 +113,38 @@ pub extern "C" fn _getgrnam(name_ptr: c_int, vmctx: &mut Ctx) -> c_int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let name = unsafe {
|
let name = unsafe {
|
||||||
let memory_name_ptr = vmctx.memory(0)[name_ptr as usize] as *const c_char;
|
let memory_name_ptr = ctx.memory(0)[name_ptr as usize] as *const c_char;
|
||||||
CStr::from_ptr(memory_name_ptr)
|
CStr::from_ptr(memory_name_ptr)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let group = &*libc_getgrnam(name.as_ptr());
|
let group = &*libc_getgrnam(name.as_ptr());
|
||||||
let group_struct_offset = call_malloc(mem::size_of::<GuestGroup>() as _, vmctx);
|
let group_struct_offset = call_malloc(mem::size_of::<GuestGroup>() as _, ctx);
|
||||||
|
|
||||||
let group_struct_ptr = vmctx.memory(0)[group_struct_offset as usize] as *mut GuestGroup;
|
let group_struct_ptr = ctx.memory(0)[group_struct_offset as usize] as *mut GuestGroup;
|
||||||
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(vmctx, group.gr_name);
|
(*group_struct_ptr).gr_name = copy_cstr_into_wasm(ctx, group.gr_name);
|
||||||
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(vmctx, group.gr_passwd);
|
(*group_struct_ptr).gr_passwd = copy_cstr_into_wasm(ctx, group.gr_passwd);
|
||||||
(*group_struct_ptr).gr_gid = group.gr_gid;
|
(*group_struct_ptr).gr_gid = group.gr_gid;
|
||||||
(*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(vmctx, group.gr_mem);
|
(*group_struct_ptr).gr_mem = copy_terminated_array_of_cstrs(ctx, group.gr_mem);
|
||||||
|
|
||||||
group_struct_offset as c_int
|
group_struct_offset as c_int
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_malloc(size: i32, vmctx: &mut Ctx) -> u32 {
|
pub fn call_malloc(size: i32, ctx: &mut Ctx) -> u32 {
|
||||||
unimplemented!()
|
(get_emscripten_data(ctx).malloc)(size, ctx)
|
||||||
// let ret = instance
|
|
||||||
// .call("_malloc", &[Value::I32(size)])
|
|
||||||
// .expect("_malloc call failed");
|
|
||||||
// if let [Value::I32(x)] = ret.as_slice() {
|
|
||||||
// *x as u32
|
|
||||||
// } else {
|
|
||||||
// panic!("unexpected value from _malloc: {:?}", ret);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_memalign(alignment: u32, size: u32, vmctx: &mut Ctx) -> u32 {
|
pub fn call_memalign(alignment: u32, size: u32, ctx: &mut Ctx) -> u32 {
|
||||||
unimplemented!()
|
(get_emscripten_data(ctx).memalign)(alignment, size, ctx)
|
||||||
// let ret =
|
|
||||||
// call(
|
|
||||||
// vmctx,
|
|
||||||
// "_memalign",
|
|
||||||
// &[Value::I32(alignment as i32), Value::I32(size as i32)],
|
|
||||||
// )
|
|
||||||
// .expect("_memalign call failed");
|
|
||||||
// if let [Value::I32(x)] = ret.as_slice() {
|
|
||||||
// *x as u32
|
|
||||||
// } else {
|
|
||||||
// panic!("unexpected value from _memalign {:?}", ret);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_memset(pointer: u32, value: i32, size: u32, vmctx: &mut Ctx) -> u32 {
|
pub fn call_memset(pointer: u32, value: i32, size: u32, ctx: &mut Ctx) -> u32 {
|
||||||
unimplemented!()
|
(get_emscripten_data(ctx).memset)(pointer, value, size, ctx)
|
||||||
// let ret = instance
|
}
|
||||||
// .call(
|
|
||||||
// "_memset",
|
pub(crate) fn get_emscripten_data(ctx: &mut Ctx) -> &mut EmscriptenData {
|
||||||
// &[
|
unsafe { &mut *(ctx.data as *mut EmscriptenData) }
|
||||||
// Value::I32(pointer as i32),
|
|
||||||
// Value::I32(value),
|
|
||||||
// Value::I32(size as i32),
|
|
||||||
// ],
|
|
||||||
// )
|
|
||||||
// .expect("_memset call failed");
|
|
||||||
// if let [Value::I32(x)] = ret.as_slice() {
|
|
||||||
// *x as u32
|
|
||||||
// } else {
|
|
||||||
// panic!("unexpected value from _memset {:?}", ret);
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn _getpagesize() -> u32 {
|
pub extern "C" fn _getpagesize() -> u32 {
|
||||||
@ -194,18 +153,18 @@ pub extern "C" fn _getpagesize() -> u32 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub extern "C" fn ___build_environment(environ: c_int, vmctx: &mut Ctx) {
|
pub extern "C" fn ___build_environment(environ: c_int, ctx: &mut Ctx) {
|
||||||
debug!("emscripten::___build_environment {}", environ);
|
debug!("emscripten::___build_environment {}", environ);
|
||||||
const MAX_ENV_VALUES: u32 = 64;
|
const MAX_ENV_VALUES: u32 = 64;
|
||||||
const TOTAL_ENV_SIZE: u32 = 1024;
|
const TOTAL_ENV_SIZE: u32 = 1024;
|
||||||
let mut environment = vmctx.memory(0)[environ as usize] as *mut c_int;
|
let mut environment = ctx.memory(0)[environ as usize] as *mut c_int;
|
||||||
unsafe {
|
unsafe {
|
||||||
let (pool_offset, _pool_slice): (u32, &mut [u8]) =
|
let (pool_offset, _pool_slice): (u32, &mut [u8]) =
|
||||||
allocate_on_stack(TOTAL_ENV_SIZE as u32, vmctx);
|
allocate_on_stack(TOTAL_ENV_SIZE as u32, ctx);
|
||||||
let (env_offset, _env_slice): (u32, &mut [u8]) =
|
let (env_offset, _env_slice): (u32, &mut [u8]) =
|
||||||
allocate_on_stack((MAX_ENV_VALUES * 4) as u32, vmctx);
|
allocate_on_stack((MAX_ENV_VALUES * 4) as u32, ctx);
|
||||||
let mut env_ptr = vmctx.memory(0)[env_offset as usize] as *mut c_int;
|
let mut env_ptr = ctx.memory(0)[env_offset as usize] as *mut c_int;
|
||||||
let mut _pool_ptr = vmctx.memory(0)[pool_offset as usize] as *mut c_int;
|
let mut _pool_ptr = ctx.memory(0)[pool_offset as usize] as *mut c_int;
|
||||||
*env_ptr = pool_offset as i32;
|
*env_ptr = pool_offset as i32;
|
||||||
*environment = env_offset as i32;
|
*environment = env_offset as i32;
|
||||||
|
|
||||||
@ -216,13 +175,13 @@ pub extern "C" fn ___build_environment(environ: c_int, vmctx: &mut Ctx) {
|
|||||||
// };
|
// };
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn _sysconf(name: c_int, _vmctx: &mut Ctx) -> c_long {
|
pub extern "C" fn _sysconf(name: c_int, _ctx: &mut Ctx) -> c_long {
|
||||||
debug!("emscripten::_sysconf {}", name);
|
debug!("emscripten::_sysconf {}", name);
|
||||||
// TODO: Implement like emscripten expects regarding memory/page size
|
// TODO: Implement like emscripten expects regarding memory/page size
|
||||||
unsafe { sysconf(name) }
|
unsafe { sysconf(name) }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub extern "C" fn ___assert_fail(a: c_int, b: c_int, c: c_int, d: c_int, _vmctx: &mut Ctx) {
|
pub extern "C" fn ___assert_fail(a: c_int, b: c_int, c: c_int, d: c_int, _ctx: &mut Ctx) {
|
||||||
debug!("emscripten::___assert_fail {} {} {} {}", a, b, c, d);
|
debug!("emscripten::___assert_fail {} {} {} {}", a, b, c, d);
|
||||||
// TODO: Implement like emscripten expects regarding memory/page size
|
// TODO: Implement like emscripten expects regarding memory/page size
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
@ -1,39 +1,39 @@
|
|||||||
|
use super::env::get_emscripten_data;
|
||||||
use libc::{c_int, c_void};
|
use libc::{c_int, c_void};
|
||||||
|
use std::cell::UnsafeCell;
|
||||||
use wasmer_runtime_core::vm::Ctx;
|
use wasmer_runtime_core::vm::Ctx;
|
||||||
|
|
||||||
/// setjmp
|
/// setjmp
|
||||||
pub extern "C" fn __setjmp(env_addr: u32, vmctx: &mut Ctx) -> c_int {
|
pub extern "C" fn __setjmp(env_addr: u32, ctx: &mut Ctx) -> c_int {
|
||||||
debug!("emscripten::__setjmp (setjmp)");
|
debug!("emscripten::__setjmp (setjmp)");
|
||||||
unimplemented!()
|
unsafe {
|
||||||
// unsafe {
|
// Rather than using the env as the holder of the jump buffer pointer,
|
||||||
// // Rather than using the env as the holder of the jump buffer pointer,
|
// we use the environment address to store the index relative to jumps
|
||||||
// // we use the environment address to store the index relative to jumps
|
// so the address of the jump it's outside the wasm memory itself.
|
||||||
// // so the address of the jump it's outside the wasm memory itself.
|
let jump_index = ctx.memory(0)[env_addr as usize] as *mut i8;
|
||||||
// let jump_index = vmctx.memory(0)[env_addr as usize] as *mut i8;
|
// We create the jump buffer outside of the wasm memory
|
||||||
// // We create the jump buffer outside of the wasm memory
|
let jump_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]);
|
||||||
// let jump_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]);
|
let mut jumps = &mut get_emscripten_data(ctx).jumps;
|
||||||
// let mut jumps = &mut instance.emscripten_data().as_mut().unwrap().jumps;
|
let result = setjmp(jump_buf.get() as _);
|
||||||
// let result = setjmp(jump_buf.get() as _);
|
// We set the jump index to be the last value of jumps
|
||||||
// // We set the jump index to be the last value of jumps
|
*jump_index = jumps.len() as _;
|
||||||
// *jump_index = jumps.len() as _;
|
// We hold the reference of the jump buffer
|
||||||
// // We hold the reference of the jump buffer
|
jumps.push(jump_buf);
|
||||||
// jumps.push(jump_buf);
|
result
|
||||||
// result
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// longjmp
|
/// longjmp
|
||||||
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, vmctx: &mut Ctx) -> ! {
|
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, ctx: &mut Ctx) -> ! {
|
||||||
debug!("emscripten::__longjmp (longjmp) {}", val);
|
debug!("emscripten::__longjmp (longmp)");
|
||||||
unimplemented!()
|
unsafe {
|
||||||
// unsafe {
|
// We retrieve the jump index from the env address
|
||||||
// // We retrieve the jump index from the env address
|
let jump_index = ctx.memory(0)[env_addr as usize] as *mut i8;
|
||||||
// let jump_index = vmctx.memory(0)[env_addr as usize] as *mut i8;
|
let mut jumps = &mut get_emscripten_data(ctx).jumps;
|
||||||
// let mut jumps = &mut instance.emscripten_data().as_mut().unwrap().jumps;
|
// We get the real jump buffer from the jumps vector, using the retrieved index
|
||||||
// // We get the real jump buffer from the jumps vector, using the retrieved index
|
let mut jump_buf = &jumps[*jump_index as usize];
|
||||||
// let mut jump_buf = &jumps[*jump_index as usize];
|
longjmp(jump_buf.get() as _, val)
|
||||||
// longjmp(jump_buf.get() as _, val)
|
};
|
||||||
// };
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -3,8 +3,9 @@ extern crate wasmer_runtime_core;
|
|||||||
|
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use hashbrown::HashMap;
|
use hashbrown::HashMap;
|
||||||
use std::mem;
|
use libc::c_int;
|
||||||
use std::ptr;
|
use std::cell::UnsafeCell;
|
||||||
|
use std::{ffi::c_void, mem, ptr};
|
||||||
use std::{mem::size_of, panic, slice};
|
use std::{mem::size_of, panic, slice};
|
||||||
use wasmer_runtime_core::{
|
use wasmer_runtime_core::{
|
||||||
error::{CallError, CallResult, ResolveError},
|
error::{CallError, CallResult, ResolveError},
|
||||||
@ -20,6 +21,7 @@ use wasmer_runtime_core::{
|
|||||||
Type::{self, *},
|
Type::{self, *},
|
||||||
Value,
|
Value,
|
||||||
},
|
},
|
||||||
|
vm::Ctx,
|
||||||
vm::LocalGlobal,
|
vm::LocalGlobal,
|
||||||
vm::LocalMemory,
|
vm::LocalMemory,
|
||||||
vm::LocalTable,
|
vm::LocalTable,
|
||||||
@ -82,14 +84,40 @@ fn dynamictop_ptr(static_bump: u32) -> u32 {
|
|||||||
static_bump + DYNAMICTOP_PTR_DIFF
|
static_bump + DYNAMICTOP_PTR_DIFF
|
||||||
}
|
}
|
||||||
|
|
||||||
//pub struct EmscriptenData {
|
pub struct EmscriptenData {
|
||||||
// pub malloc: extern "C" fn(i32, &Instance) -> u32,
|
pub malloc: extern "C" fn(i32, &mut Ctx) -> u32,
|
||||||
// pub free: extern "C" fn(i32, &mut Instance),
|
pub free: extern "C" fn(i32, &mut Ctx),
|
||||||
// pub memalign: extern "C" fn(u32, u32, &mut Instance) -> u32,
|
pub memalign: extern "C" fn(u32, u32, &mut Ctx) -> u32,
|
||||||
// pub memset: extern "C" fn(u32, i32, u32, &mut Instance) -> u32,
|
pub memset: extern "C" fn(u32, i32, u32, &mut Ctx) -> u32,
|
||||||
// pub stack_alloc: extern "C" fn(u32, &Instance) -> u32,
|
pub stack_alloc: extern "C" fn(u32, &mut Ctx) -> u32,
|
||||||
// pub jumps: Vec<UnsafeCell<[c_int; 27]>>,
|
pub jumps: Vec<UnsafeCell<[c_int; 27]>>,
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
impl EmscriptenData {
|
||||||
|
pub fn new(instance: &mut Instance) -> Self {
|
||||||
|
unsafe {
|
||||||
|
let malloc_func = instance.func("_malloc").unwrap();
|
||||||
|
let malloc_addr = malloc_func.raw() as *const u8;
|
||||||
|
let free_func = instance.func("_free").unwrap();
|
||||||
|
let free_addr = free_func.raw() as *const u8;
|
||||||
|
let memalign_func = instance.func("_memalign").unwrap();
|
||||||
|
let memalign_addr = memalign_func.raw() as *const u8;
|
||||||
|
let memset_func = instance.func("_memset").unwrap();
|
||||||
|
let memset_addr = memset_func.raw() as *const u8;
|
||||||
|
let stack_alloc_func = instance.func("stackAlloc").unwrap();
|
||||||
|
let stack_alloc_addr = stack_alloc_func.raw() as *const u8;
|
||||||
|
|
||||||
|
EmscriptenData {
|
||||||
|
malloc: mem::transmute(malloc_addr),
|
||||||
|
free: mem::transmute(free_addr),
|
||||||
|
memalign: mem::transmute(memalign_addr),
|
||||||
|
memset: mem::transmute(memset_addr),
|
||||||
|
stack_alloc: mem::transmute(stack_alloc_addr),
|
||||||
|
jumps: Vec::new(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn run_emscripten_instance(
|
pub fn run_emscripten_instance(
|
||||||
module: &Module,
|
module: &Module,
|
||||||
@ -97,7 +125,9 @@ pub fn run_emscripten_instance(
|
|||||||
_path: &str,
|
_path: &str,
|
||||||
args: Vec<&str>,
|
args: Vec<&str>,
|
||||||
) -> CallResult<()> {
|
) -> CallResult<()> {
|
||||||
// TODO atinit and atexit for emscripten
|
let mut data = EmscriptenData::new(instance);
|
||||||
|
let data_ptr = &mut data as *mut _ as *mut c_void;
|
||||||
|
instance.ctx().data = data_ptr;
|
||||||
|
|
||||||
// Get main arguments.
|
// Get main arguments.
|
||||||
let main_args = get_main_args("_main", args, instance).unwrap();
|
let main_args = get_main_args("_main", args, instance).unwrap();
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
use wasmer_runtime_core::{module::Module, vm::Ctx};
|
use wasmer_runtime_core::{module::Module, vm::Ctx};
|
||||||
//use wasmer_runtime_core::Instance;
|
//use wasmer_runtime_core::Instance;
|
||||||
use super::env;
|
use super::env;
|
||||||
|
use super::env::get_emscripten_data;
|
||||||
use libc::stat;
|
use libc::stat;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
|
use std::mem::size_of;
|
||||||
use std::os::raw::c_char;
|
use std::os::raw::c_char;
|
||||||
use std::slice;
|
use std::slice;
|
||||||
/// We check if a provided module is an Emscripten generated one
|
/// We check if a provided module is an Emscripten generated one
|
||||||
@ -15,8 +17,8 @@ pub fn is_emscripten_module(module: &Module) -> bool {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, vmctx: &mut Ctx) -> u32 {
|
pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, ctx: &mut Ctx) -> u32 {
|
||||||
let buf_addr = vmctx.memory(0)[buf as usize] as *mut c_char;
|
let buf_addr = ctx.memory(0)[buf as usize] as *mut c_char;
|
||||||
|
|
||||||
for i in 0..max {
|
for i in 0..max {
|
||||||
*buf_addr.add(i as _) = *string.add(i as _);
|
*buf_addr.add(i as _) = *string.add(i as _);
|
||||||
@ -26,11 +28,11 @@ pub unsafe fn write_to_buf(string: *const c_char, buf: u32, max: u32, vmctx: &mu
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// This function expects nullbyte to be appended.
|
/// This function expects nullbyte to be appended.
|
||||||
pub unsafe fn copy_cstr_into_wasm(vmctx: &mut Ctx, cstr: *const c_char) -> u32 {
|
pub unsafe fn copy_cstr_into_wasm(ctx: &mut Ctx, cstr: *const c_char) -> u32 {
|
||||||
let s = CStr::from_ptr(cstr).to_str().unwrap();
|
let s = CStr::from_ptr(cstr).to_str().unwrap();
|
||||||
let cstr_len = s.len();
|
let cstr_len = s.len();
|
||||||
let space_offset = env::call_malloc((cstr_len as i32) + 1, vmctx);
|
let space_offset = env::call_malloc((cstr_len as i32) + 1, ctx);
|
||||||
let raw_memory = vmctx.memory(0)[space_offset as usize] as *mut u8;
|
let raw_memory = ctx.memory(0)[space_offset as usize] as *mut u8;
|
||||||
let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
|
let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
|
||||||
|
|
||||||
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
||||||
@ -44,20 +46,16 @@ pub unsafe fn copy_cstr_into_wasm(vmctx: &mut Ctx, cstr: *const c_char) -> u32 {
|
|||||||
space_offset
|
space_offset
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, vmctx: &'a Ctx) -> (u32, &'a mut [T]) {
|
pub unsafe fn allocate_on_stack<'a, T: Copy>(count: u32, ctx: &'a mut Ctx) -> (u32, &'a mut [T]) {
|
||||||
unimplemented!("allocate_on_stack not implemented")
|
let offset = (get_emscripten_data(ctx).stack_alloc)(count * (size_of::<T>() as u32), ctx);
|
||||||
// let offset = (instance.emscripten_data().as_ref().unwrap().stack_alloc)(
|
let addr = ctx.memory(0)[offset as usize] as *mut T;
|
||||||
// count * (size_of::<T>() as u32),
|
let slice = slice::from_raw_parts_mut(addr, count as usize);
|
||||||
// vmctx,
|
|
||||||
// );
|
(offset, slice)
|
||||||
// let addr = vmctx.memory(0)[offset as usize] as *mut T;
|
|
||||||
// let slice = slice::from_raw_parts_mut(addr, count as usize);
|
|
||||||
//
|
|
||||||
// (offset, slice)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, vmctx: &'a Ctx) -> (u32, &'a [u8]) {
|
pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, ctx: &'a mut Ctx) -> (u32, &'a [u8]) {
|
||||||
let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, vmctx);
|
let (offset, slice) = allocate_on_stack((s.len() + 1) as u32, ctx);
|
||||||
|
|
||||||
use std::iter;
|
use std::iter;
|
||||||
for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) {
|
for (byte, loc) in s.bytes().chain(iter::once(0)).zip(slice.iter_mut()) {
|
||||||
@ -67,7 +65,7 @@ pub unsafe fn allocate_cstr_on_stack<'a>(s: &str, vmctx: &'a Ctx) -> (u32, &'a [
|
|||||||
(offset, slice)
|
(offset, slice)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub unsafe fn copy_terminated_array_of_cstrs(_vmctx: &mut Ctx, cstrs: *mut *mut c_char) -> u32 {
|
pub unsafe fn copy_terminated_array_of_cstrs(_ctx: &mut Ctx, 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;
|
||||||
@ -105,8 +103,8 @@ pub struct GuestStat {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cast_ptr_alignment)]
|
#[allow(clippy::cast_ptr_alignment)]
|
||||||
pub unsafe fn copy_stat_into_wasm(vmctx: &mut Ctx, buf: u32, stat: &stat) {
|
pub unsafe fn copy_stat_into_wasm(ctx: &mut Ctx, buf: u32, stat: &stat) {
|
||||||
let stat_ptr = vmctx.memory(0)[buf as usize] as *mut GuestStat;
|
let stat_ptr = ctx.memory(0)[buf as usize] as *mut GuestStat;
|
||||||
(*stat_ptr).st_dev = stat.st_dev as _;
|
(*stat_ptr).st_dev = stat.st_dev as _;
|
||||||
(*stat_ptr).__st_dev_padding = 0;
|
(*stat_ptr).__st_dev_padding = 0;
|
||||||
(*stat_ptr).__st_ino_truncated = stat.st_ino as _;
|
(*stat_ptr).__st_ino_truncated = stat.st_ino as _;
|
||||||
|
@ -227,7 +227,6 @@ impl Instance {
|
|||||||
|
|
||||||
Ok(returns)
|
Ok(returns)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl InstanceInner {
|
impl InstanceInner {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user