Fix memory issue with Emscripten

This commit is contained in:
Mark McCaskey
2020-08-04 17:09:00 -07:00
parent 354c331bcb
commit 7e9d9cab08
7 changed files with 53 additions and 13 deletions

26
Cargo.lock generated
View File

@@ -276,6 +276,17 @@ dependencies = [
"bitflags", "bitflags",
] ]
[[package]]
name = "colored"
version = "1.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ffc801dacf156c5854b9df4f425a626539c3a6ef7893cc0c5084a23f0b6c59"
dependencies = [
"atty",
"lazy_static",
"winapi",
]
[[package]] [[package]]
name = "colored" name = "colored"
version = "2.0.0" version = "2.0.0"
@@ -643,6 +654,16 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "fern"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c9a4820f0ccc8a7afd67c39a0f1a0f4b07ca1725164271a64939d7aeb9af065"
dependencies = [
"colored 1.9.3",
"log",
]
[[package]] [[package]]
name = "fnv" name = "fnv"
version = "1.0.7" version = "1.0.7"
@@ -1925,6 +1946,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e2a2de6b0d5cbb13fc21193a2296888eaab62b6044479aafb3c54c01c29fcd" checksum = "c2e2a2de6b0d5cbb13fc21193a2296888eaab62b6044479aafb3c54c01c29fcd"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"log",
"tracing-attributes", "tracing-attributes",
"tracing-core", "tracing-core",
] ]
@@ -2169,8 +2191,10 @@ dependencies = [
"atty", "atty",
"bytesize", "bytesize",
"cfg-if", "cfg-if",
"colored", "colored 2.0.0",
"distance", "distance",
"fern",
"log",
"structopt", "structopt",
"wasm-common", "wasm-common",
"wasmer", "wasmer",

View File

@@ -57,6 +57,9 @@ bench:
build-wasmer: build-wasmer:
cargo build --release --manifest-path lib/cli/Cargo.toml $(compiler_features) cargo build --release --manifest-path lib/cli/Cargo.toml $(compiler_features)
build-wasmer-debug:
cargo build --manifest-path lib/cli/Cargo.toml $(compiler_features)
WAPM_VERSION = v0.5.0 WAPM_VERSION = v0.5.0
build-wapm: build-wapm:
git clone --branch $(WAPM_VERSION) https://github.com/wasmerio/wapm-cli.git git clone --branch $(WAPM_VERSION) https://github.com/wasmerio/wapm-cli.git

View File

@@ -21,7 +21,7 @@ use wasmer_vm::{Export, ExportMemory, Memory as RuntimeMemory, MemoryError};
/// mutable from both host and WebAssembly. /// mutable from both host and WebAssembly.
/// ///
/// Spec: https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances /// Spec: https://webassembly.github.io/spec/core/exec/runtime.html#memory-instances
#[derive(Clone)] #[derive(Debug, Clone)]
pub struct Memory { pub struct Memory {
store: Store, store: Store,
memory: Arc<dyn RuntimeMemory>, memory: Arc<dyn RuntimeMemory>,

View File

@@ -62,6 +62,11 @@ impl WasmerCLIOptions {
} }
fn main() { fn main() {
let builder = std::thread::Builder::new().stack_size(1_024_000_000);
builder.spawn(real_main).unwrap().join().unwrap();
}
fn real_main() {
// We allow windows to print properly colors // We allow windows to print properly colors
#[cfg(windows)] #[cfg(windows)]
colored::control::set_virtual_terminal(true).unwrap(); colored::control::set_virtual_terminal(true).unwrap();

View File

@@ -55,7 +55,7 @@ pub fn call_memset(ctx: &mut EmEnv, pointer: u32, value: u32, size: u32) -> u32
} }
pub(crate) fn get_emscripten_data<'a>(ctx: &'a mut EmEnv) -> &'a mut EmscriptenData<'static> { pub(crate) fn get_emscripten_data<'a>(ctx: &'a mut EmEnv) -> &'a mut EmscriptenData<'static> {
unsafe { &mut *ctx.data } unsafe { &mut **ctx.data }
} }
pub fn _getpagesize(_ctx: &mut EmEnv) -> u32 { pub fn _getpagesize(_ctx: &mut EmEnv) -> u32 {

View File

@@ -72,29 +72,33 @@ pub use self::utils::{
#[derive(Clone)] #[derive(Clone)]
/// The environment provided to the Emscripten imports. /// The environment provided to the Emscripten imports.
pub struct EmEnv { pub struct EmEnv {
memory: Option<Arc<Memory>>, memory: Arc<Option<Memory>>,
data: *mut EmscriptenData<'static>, data: *mut *mut EmscriptenData<'static>,
} }
impl EmEnv { impl EmEnv {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
memory: None, memory: Arc::new(None),
data: std::ptr::null_mut(), // TODO: clean this up
data: Box::into_raw(Box::new(std::ptr::null_mut())),
} }
} }
pub fn set_memory(&mut self, memory: Arc<Memory>) { pub fn set_memory(&mut self, memory: Memory) {
self.memory = Some(memory) let ptr = Arc::as_ptr(&self.memory) as *mut _;
unsafe {
*ptr = Some(memory);
}
} }
pub fn set_data(&mut self, data: *mut c_void) { pub fn set_data(&mut self, data: *mut c_void) {
self.data = data as _; unsafe { *self.data = data as _ };
} }
/// Get a reference to the memory /// Get a reference to the memory
pub fn memory(&self, _mem_idx: u32) -> &Memory { pub fn memory(&self, _mem_idx: u32) -> &Memory {
self.memory.as_ref().unwrap() (*self.memory).as_ref().unwrap()
} }
} }
@@ -475,7 +479,7 @@ pub fn run_emscripten_instance(
mapped_dirs: Vec<(String, PathBuf)>, mapped_dirs: Vec<(String, PathBuf)>,
) -> Result<(), RuntimeError> { ) -> Result<(), RuntimeError> {
let mut data = EmscriptenData::new(instance, &globals.data, mapped_dirs.into_iter().collect()); let mut data = EmscriptenData::new(instance, &globals.data, mapped_dirs.into_iter().collect());
env.set_memory(Arc::new(globals.memory.clone())); env.set_memory(globals.memory.clone());
env.set_data(&mut data as *mut _ as *mut c_void); env.set_data(&mut data as *mut _ as *mut c_void);
set_up_emscripten(instance)?; set_up_emscripten(instance)?;
@@ -626,7 +630,10 @@ impl EmscriptenGlobals {
let mut null_function_names = vec![]; let mut null_function_names = vec![];
for import in module.imports().functions() { for import in module.imports().functions() {
if import.module() == "env" && import.name().starts_with("nullFunction_") { if import.module() == "env"
&& (import.name().starts_with("nullFunction_")
|| import.name().starts_with("nullFunc_"))
{
null_function_names.push(import.name().to_string()) null_function_names.push(import.name().to_string())
} }
} }

View File

@@ -129,6 +129,7 @@ pub unsafe fn allocate_on_stack<'a, T: Copy>(ctx: &'a mut EmEnv, count: u32) ->
.unwrap() .unwrap()
.call(count * (size_of::<T>() as u32)) .call(count * (size_of::<T>() as u32))
.unwrap(); .unwrap();
let addr = emscripten_memory_pointer!(ctx.memory(0), offset) as *mut T; let addr = emscripten_memory_pointer!(ctx.memory(0), offset) as *mut T;
let slice = slice::from_raw_parts_mut(addr, count as usize); let slice = slice::from_raw_parts_mut(addr, count as usize);