Skip to content

Commit

Permalink
Merge pull request #53 from wasmerio/feature/run-lua-wasm
Browse files Browse the repository at this point in the history
Running Lua
  • Loading branch information
syrusakbary authored Dec 19, 2018
2 parents 7dcb540 + a912c14 commit 04378d5
Show file tree
Hide file tree
Showing 17 changed files with 454 additions and 126 deletions.
Binary file added examples/lua.wasm
Binary file not shown.
28 changes: 15 additions & 13 deletions src/apis/emscripten/env.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,28 @@
use super::super::host;
/// NOTE: These syscalls only support wasm_32 for now because they take u32 offset
use libc::{c_int, c_long, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam, sysconf};
use libc::{c_int, c_long, getenv, getgrnam as libc_getgrnam, getpwnam as libc_getpwnam, sysconf};
use std::ffi::CStr;
use std::mem;
use std::os::raw::c_char;

use super::utils::{copy_cstr_into_wasm, copy_terminated_array_of_cstrs};
use crate::webassembly::Instance;

/// emscripten: _getenv
pub extern "C" fn _getenv(name_ptr: c_int, instance: &mut Instance) -> c_int {
debug!("emscripten::_getenv {}", name_ptr);
let name = unsafe {
let memory_name_ptr = instance.memory_offset_addr(0, name_ptr as usize) as *const c_char;
CStr::from_ptr(memory_name_ptr).to_str().unwrap()
};
match host::get_env(name, instance) {
Ok(_) => {
unimplemented!();
}
Err(_) => 0,
// #[no_mangle]
/// emscripten: _getenv // (name: *const char) -> *const c_char;
pub extern "C" fn _getenv(name: c_int, instance: &mut Instance) -> u32 {
debug!("emscripten::_getenv");

let name_addr = instance.memory_offset_addr(0, name as usize) as *const c_char;

debug!("=> name({:?})", unsafe { CStr::from_ptr(name_addr) });

let c_str = unsafe { getenv(name_addr) };
if c_str.is_null() {
return 0;
}

unsafe { copy_cstr_into_wasm(instance, c_str) }
}

pub extern "C" fn _getpwnam(name_ptr: c_int, instance: &mut Instance) -> c_int {
Expand Down
15 changes: 15 additions & 0 deletions src/apis/emscripten/exception.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
use super::process::_abort;
use crate::webassembly::Instance;

/// emscripten: ___cxa_allocate_exception
pub extern "C" fn ___cxa_allocate_exception(size: u32, instance: &mut Instance) -> u32 {
debug!("emscripten::___cxa_allocate_exception");
(instance.emscripten_data.as_ref().unwrap().malloc)(size as _, instance)
}

/// emscripten: ___cxa_throw
/// TODO: We don't have support for exceptions yet
pub extern "C" fn ___cxa_throw(ptr: u32, ty: u32, destructor: u32, instance: &mut Instance) {
debug!("emscripten::___cxa_throw");
_abort();
}
41 changes: 41 additions & 0 deletions src/apis/emscripten/jmp.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
use crate::webassembly::Instance;
use libc::{c_int, c_void};
use std::cell::UnsafeCell;

/// setjmp
pub extern "C" fn __setjmp(env_addr: u32, instance: &mut Instance) -> c_int {
debug!("emscripten::__setjmp (setjmp)");
unsafe {
// 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
// so the address of the jump it's outside the wasm memory itself.
let jump_index = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
// We create the jump buffer outside of the wasm memory
let jump_buf: UnsafeCell<[c_int; 27]> = UnsafeCell::new([0; 27]);
let mut jumps = &mut instance.emscripten_data.as_mut().unwrap().jumps;
let result = setjmp(jump_buf.get() as _);
// We set the jump index to be the last value of jumps
*jump_index = jumps.len() as _;
// We hold the reference of the jump buffer
jumps.push(jump_buf);
result
}
}

/// longjmp
pub extern "C" fn __longjmp(env_addr: u32, val: c_int, instance: &mut Instance) -> ! {
debug!("emscripten::__longjmp (longjmp) {}", val);
unsafe {
// We retrieve the jump index from the env address
let jump_index = instance.memory_offset_addr(0, env_addr as usize) as *mut i8;
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
let mut jump_buf = &jumps[*jump_index as usize];
longjmp(jump_buf.get() as _, val)
};
}

extern "C" {
fn setjmp(env: *mut c_void) -> c_int;
fn longjmp(env: *mut c_void, val: c_int) -> !;
}
27 changes: 27 additions & 0 deletions src/apis/emscripten/linking.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::webassembly::Instance;

// TODO: Need to implement.

/// emscripten: dlopen(filename: *const c_char, flag: c_int) -> *mut c_void
pub extern "C" fn _dlopen(filename: u32, flag: c_int) -> u32 {
debug!("emscripten::_dlopen");
-1
}

/// emscripten: dlclose(handle: *mut c_void) -> c_int
pub extern "C" fn _dlclose(filename: u32) -> u32 {
debug!("emscripten::_dlclose");
-1
}

/// emscripten: dlsym(handle: *mut c_void, symbol: *const c_char) -> *mut c_void
pub extern "C" fn _dlsym(filepath: u32, symbol: u32) -> u32 {
debug!("emscripten::_dlerror");
-1
}

/// emscripten: dlerror() -> *mut c_char
pub extern "C" fn _dlerror() -> u32 {
debug!("emscripten::_dlerror");
-1
}
5 changes: 5 additions & 0 deletions src/apis/emscripten/lock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ pub extern "C" fn ___lock(which: c_int, varargs: c_int, _instance: &mut Instance
pub extern "C" fn ___unlock(which: c_int, varargs: c_int, _instance: &mut Instance) {
debug!("emscripten::___unlock {}, {}", which, varargs);
}

// NOTE: Not implemented by Emscripten
pub extern "C" fn ___wait(_which: c_int, _varargs: c_int, _instance: &mut Instance) {
debug!("emscripten::___wait");
}
19 changes: 19 additions & 0 deletions src/apis/emscripten/math.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use crate::webassembly::Instance;

/// emscripten: _llvm_log10_f64
pub extern "C" fn _llvm_log10_f64(value: f64) -> f64 {
debug!("emscripten::_llvm_log10_f64");
value.log10()
}

/// emscripten: _llvm_log2_f64
pub extern "C" fn _llvm_log2_f64(value: f64) -> f64 {
debug!("emscripten::_llvm_log2_f64");
value.log2()
}

// emscripten: f64-rem
pub extern "C" fn f64_rem(x: f64, y: f64) -> f64 {
debug!("emscripten::f64-rem");
x % y
}
9 changes: 8 additions & 1 deletion src/apis/emscripten/memory.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use super::process::abort_with_message;
use crate::webassembly::Instance;
use libc::{c_void, memcpy, size_t};
use libc::{c_int, c_void, memcpy, size_t};

/// emscripten: _emscripten_memcpy_big
pub extern "C" fn _emscripten_memcpy_big(
Expand Down Expand Up @@ -39,3 +39,10 @@ pub extern "C" fn abort_on_cannot_grow_memory() {
debug!("emscripten::abort_on_cannot_grow_memory");
abort_with_message("Cannot enlarge memory arrays!");
}

/// emscripten: ___map_file
pub extern "C" fn ___map_file() -> c_int {
debug!("emscripten::___map_file");
// NOTE: TODO: Em returns -1 here as well. May need to implement properly
-1
}
Loading

0 comments on commit 04378d5

Please sign in to comment.