Added emscripten sbrk implementation

This commit is contained in:
Syrus
2019-07-06 22:05:45 -07:00
parent d3d84cbc22
commit d0b186b939
5 changed files with 64 additions and 3 deletions

View File

@ -85,6 +85,8 @@ const GLOBAL_BASE: u32 = 1024;
const STATIC_BASE: u32 = GLOBAL_BASE;
pub struct EmscriptenData<'a> {
pub globals: &'a EmscriptenGlobalsData,
pub malloc: Option<Func<'a, u32, u32>>,
pub free: Option<Func<'a, u32>>,
pub memalign: Option<Func<'a, (u32, u32), u32>>,
@ -163,6 +165,7 @@ pub struct EmscriptenData<'a> {
impl<'a> EmscriptenData<'a> {
pub fn new(
instance: &'a mut Instance,
globals: &'a EmscriptenGlobalsData,
mapped_dirs: HashMap<String, PathBuf>,
) -> EmscriptenData<'a> {
let malloc = instance.func("_malloc").or(instance.func("malloc")).ok();
@ -237,6 +240,8 @@ impl<'a> EmscriptenData<'a> {
.ok();
EmscriptenData {
globals,
malloc,
free,
memalign,
@ -312,12 +317,13 @@ impl<'a> EmscriptenData<'a> {
pub fn run_emscripten_instance(
_module: &Module,
instance: &mut Instance,
globals: &mut EmscriptenGlobals,
path: &str,
args: Vec<&str>,
entrypoint: Option<String>,
mapped_dirs: Vec<(String, PathBuf)>,
) -> CallResult<()> {
let mut data = EmscriptenData::new(instance, mapped_dirs.into_iter().collect());
let mut data = EmscriptenData::new(instance, &globals.data, mapped_dirs.into_iter().collect());
let data_ptr = &mut data as *mut _ as *mut c_void;
instance.context_mut().data = data_ptr;
@ -766,6 +772,7 @@ pub fn generate_emscripten_env(globals: &mut EmscriptenGlobals) -> ImportObject
"alignfault" => func!(crate::memory::alignfault),
"ftfault" => func!(crate::memory::ftfault),
"getTotalMemory" => func!(crate::memory::get_total_memory),
"_sbrk" => func!(crate::memory::sbrk),
"___map_file" => func!(crate::memory::___map_file),
// Exception

View File

@ -1,3 +1,4 @@
use super::env::get_emscripten_data;
use super::process::abort_with_message;
use libc::{c_int, c_void, memcpy, size_t};
use wasmer_runtime_core::{
@ -65,6 +66,57 @@ pub fn _emscripten_resize_heap(ctx: &mut Ctx, requested_size: u32) -> u32 {
}
}
// function _sbrk(increment) {
// increment = increment | 0;
// var oldDynamicTop = 0;
// var newDynamicTop = 0;
// var totalMemory = 0;
// totalMemory = _emscripten_get_heap_size() | 0;
// oldDynamicTop = HEAP32[DYNAMICTOP_PTR >> 2] | 0;
// newDynamicTop = oldDynamicTop + increment | 0;
// if ((increment | 0) > 0 & (newDynamicTop | 0) < (oldDynamicTop | 0) | (newDynamicTop | 0) < 0) {
// abortOnCannotGrowMemory(newDynamicTop | 0) | 0;
// ___setErrNo(12);
// return -1;
// }
// if ((newDynamicTop | 0) > (totalMemory | 0)) {
// if (_emscripten_resize_heap(newDynamicTop | 0) | 0) {} else {
// ___setErrNo(12);
// return -1;
// }
// }
// HEAP32[DYNAMICTOP_PTR >> 2] = newDynamicTop | 0;
// return oldDynamicTop | 0;
// }
/// emscripten: sbrk
pub fn sbrk(ctx: &mut Ctx, increment: i32) -> i32 {
debug!("emscripten::sbrk");
// let old_dynamic_top = 0;
// let new_dynamic_top = 0;
let mut globals = get_emscripten_data(ctx).globals;
let dynamictop_ptr = (globals.dynamictop_ptr) as usize;
let old_dynamic_top = ctx.memory(0).view::<u32>()[dynamictop_ptr].get() as i32;
let new_dynamic_top: i32 = old_dynamic_top + increment;
let total_memory = _emscripten_get_heap_size(ctx) as i32;
debug!(
" => PTR {}, old: {}, new: {}, increment: {}, total: {}",
dynamictop_ptr, old_dynamic_top, new_dynamic_top, increment, total_memory
);
if increment > 0 && new_dynamic_top < old_dynamic_top || new_dynamic_top < 0 {
abort_on_cannot_grow_memory_old(ctx);
return -1;
}
if new_dynamic_top > total_memory {
let resized = _emscripten_resize_heap(ctx, new_dynamic_top as u32);
if resized == 0 {
return -1;
}
}
ctx.memory(0).view::<u32>()[dynamictop_ptr].set(new_dynamic_top as u32);
return old_dynamic_top as _;
}
/// emscripten: getTotalMemory
pub fn get_total_memory(_ctx: &mut Ctx) -> u32 {
debug!("emscripten::get_total_memory");