mirror of
https://github.com/mii443/wasmer.git
synced 2025-12-08 13:48:26 +00:00
Ported Emscripten to new Context API
This commit is contained in:
committed by
Manos Pitsidianakis
parent
d3d363bab2
commit
cf85615e55
@@ -1,5 +1,5 @@
|
||||
use super::env;
|
||||
use super::env::get_emscripten_data;
|
||||
use super::env::{get_emscripten_data, get_emscripten_funcs};
|
||||
use crate::storage::align_memory;
|
||||
use crate::EmEnv;
|
||||
use libc::stat;
|
||||
@@ -8,7 +8,7 @@ use std::mem::size_of;
|
||||
use std::os::raw::c_char;
|
||||
use std::path::PathBuf;
|
||||
use std::slice;
|
||||
use wasmer::{GlobalInit, Memory, Module, Pages, WasmPtr};
|
||||
use wasmer::{AsContextMut, ContextMut, GlobalInit, Memory, Module, Pages, WasmPtr};
|
||||
|
||||
/// We check if a provided module is an Emscripten generated one
|
||||
pub fn is_emscripten_module(module: &Module) -> bool {
|
||||
@@ -93,8 +93,13 @@ pub fn get_emscripten_metadata(module: &Module) -> Result<Option<(u32, u32)>, St
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn write_to_buf(ctx: &EmEnv, string: *const c_char, buf: u32, max: u32) -> u32 {
|
||||
let buf_addr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut c_char;
|
||||
pub unsafe fn write_to_buf(
|
||||
ctx: ContextMut<'_, EmEnv>,
|
||||
string: *const c_char,
|
||||
buf: u32,
|
||||
max: u32,
|
||||
) -> u32 {
|
||||
let buf_addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *mut c_char;
|
||||
|
||||
for i in 0..max {
|
||||
*buf_addr.add(i as _) = *string.add(i as _);
|
||||
@@ -104,11 +109,12 @@ pub unsafe fn write_to_buf(ctx: &EmEnv, string: *const c_char, buf: u32, max: u3
|
||||
}
|
||||
|
||||
/// This function expects nullbyte to be appended.
|
||||
pub unsafe fn copy_cstr_into_wasm(ctx: &EmEnv, cstr: *const c_char) -> u32 {
|
||||
pub unsafe fn copy_cstr_into_wasm(mut ctx: ContextMut<'_, EmEnv>, cstr: *const c_char) -> u32 {
|
||||
let s = CStr::from_ptr(cstr).to_str().unwrap();
|
||||
let cstr_len = s.len();
|
||||
let space_offset = env::call_malloc(ctx, (cstr_len as u32) + 1);
|
||||
let raw_memory = emscripten_memory_pointer!(ctx.memory(0), space_offset) as *mut c_char;
|
||||
let space_offset = env::call_malloc(ctx.as_context_mut(), (cstr_len as u32) + 1);
|
||||
let raw_memory =
|
||||
emscripten_memory_pointer!(ctx, ctx.data().memory(0), space_offset) as *mut c_char;
|
||||
let slice = slice::from_raw_parts_mut(raw_memory, cstr_len);
|
||||
|
||||
for (byte, loc) in s.bytes().zip(slice.iter_mut()) {
|
||||
@@ -124,14 +130,16 @@ pub unsafe fn copy_cstr_into_wasm(ctx: &EmEnv, cstr: *const c_char) -> u32 {
|
||||
|
||||
/// # Safety
|
||||
/// This method is unsafe because it operates directly with the slice of memory represented by the address
|
||||
pub unsafe fn allocate_on_stack<T: Copy>(ctx: &EmEnv, count: u32) -> (u32, &mut [T]) {
|
||||
let offset = get_emscripten_data(ctx)
|
||||
.stack_alloc_ref()
|
||||
.unwrap()
|
||||
.call(count * (size_of::<T>() as u32))
|
||||
pub unsafe fn allocate_on_stack<'a, T: Copy>(
|
||||
ctx: &mut ContextMut<'a, EmEnv>,
|
||||
count: u32,
|
||||
) -> (u32, &'a mut [T]) {
|
||||
let stack_alloc_ref = get_emscripten_funcs(ctx).stack_alloc_ref().unwrap().clone();
|
||||
let offset = stack_alloc_ref
|
||||
.call(&mut ctx.as_context_mut(), count * (size_of::<T>() as u32))
|
||||
.unwrap();
|
||||
|
||||
let addr = emscripten_memory_pointer!(ctx.memory(0), offset) as *mut T;
|
||||
let addr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), offset) as *mut T;
|
||||
let slice = slice::from_raw_parts_mut(addr, count as usize);
|
||||
|
||||
(offset, slice)
|
||||
@@ -139,7 +147,10 @@ pub unsafe fn allocate_on_stack<T: Copy>(ctx: &EmEnv, count: u32) -> (u32, &mut
|
||||
|
||||
/// # Safety
|
||||
/// This method is unsafe because it uses `allocate_on_stack` which is unsafe
|
||||
pub unsafe fn allocate_cstr_on_stack<'a>(ctx: &'a EmEnv, s: &str) -> (u32, &'a [u8]) {
|
||||
pub unsafe fn allocate_cstr_on_stack<'a>(
|
||||
ctx: &'a mut ContextMut<'a, EmEnv>,
|
||||
s: &str,
|
||||
) -> (u32, &'a [u8]) {
|
||||
let (offset, slice) = allocate_on_stack(ctx, (s.len() + 1) as u32);
|
||||
|
||||
use std::iter;
|
||||
@@ -151,7 +162,10 @@ pub unsafe fn allocate_cstr_on_stack<'a>(ctx: &'a EmEnv, s: &str) -> (u32, &'a [
|
||||
}
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub unsafe fn copy_terminated_array_of_cstrs(_ctx: &EmEnv, cstrs: *mut *mut c_char) -> u32 {
|
||||
pub unsafe fn copy_terminated_array_of_cstrs(
|
||||
mut _ctx: ContextMut<'_, EmEnv>,
|
||||
cstrs: *mut *mut c_char,
|
||||
) -> u32 {
|
||||
let _total_num = {
|
||||
let mut ptr = cstrs;
|
||||
let mut counter = 0;
|
||||
@@ -189,8 +203,8 @@ pub struct GuestStat {
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
pub unsafe fn copy_stat_into_wasm(ctx: &EmEnv, buf: u32, stat: &stat) {
|
||||
let stat_ptr = emscripten_memory_pointer!(ctx.memory(0), buf) as *mut GuestStat;
|
||||
pub unsafe fn copy_stat_into_wasm(ctx: ContextMut<'_, EmEnv>, buf: u32, stat: &stat) {
|
||||
let stat_ptr = emscripten_memory_pointer!(ctx, ctx.data().memory(0), buf) as *mut GuestStat;
|
||||
(*stat_ptr).st_dev = stat.st_dev as _;
|
||||
(*stat_ptr).__st_dev_padding = 0;
|
||||
(*stat_ptr).__st_ino_truncated = stat.st_ino as _;
|
||||
@@ -217,20 +231,20 @@ pub unsafe fn copy_stat_into_wasm(ctx: &EmEnv, buf: u32, stat: &stat) {
|
||||
}
|
||||
|
||||
#[allow(dead_code)] // it's used in `env/windows/mod.rs`.
|
||||
pub fn read_string_from_wasm(memory: &Memory, offset: u32) -> String {
|
||||
pub fn read_string_from_wasm(ctx: ContextMut<'_, EmEnv>, memory: &Memory, offset: u32) -> String {
|
||||
WasmPtr::<u8>::new(offset)
|
||||
.read_utf8_string_with_nul(memory)
|
||||
.read_utf8_string_with_nul(&ctx, memory)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
/// This function trys to find an entry in mapdir
|
||||
/// translating paths into their correct value
|
||||
pub fn get_cstr_path(ctx: &EmEnv, path: *const i8) -> Option<std::ffi::CString> {
|
||||
pub fn get_cstr_path(ctx: ContextMut<'_, EmEnv>, path: *const i8) -> Option<std::ffi::CString> {
|
||||
use std::collections::VecDeque;
|
||||
|
||||
let path_str =
|
||||
unsafe { std::ffi::CStr::from_ptr(path as *const _).to_str().unwrap() }.to_string();
|
||||
let data = get_emscripten_data(ctx);
|
||||
let data = get_emscripten_data(&ctx);
|
||||
let path = PathBuf::from(path_str);
|
||||
let mut prefix_added = false;
|
||||
let mut components = path.components().collect::<VecDeque<_>>();
|
||||
@@ -261,13 +275,13 @@ pub fn get_cstr_path(ctx: &EmEnv, path: *const i8) -> Option<std::ffi::CString>
|
||||
|
||||
/// gets the current directory
|
||||
/// handles mapdir logic
|
||||
pub fn get_current_directory(ctx: &EmEnv) -> Option<PathBuf> {
|
||||
if let Some(val) = get_emscripten_data(ctx).mapped_dirs.get(".") {
|
||||
pub fn get_current_directory(ctx: ContextMut<'_, EmEnv>) -> Option<PathBuf> {
|
||||
if let Some(val) = get_emscripten_data(&ctx).mapped_dirs.get(".") {
|
||||
return Some(val.clone());
|
||||
}
|
||||
std::env::current_dir()
|
||||
.map(|cwd| {
|
||||
if let Some(val) = get_emscripten_data(ctx)
|
||||
if let Some(val) = get_emscripten_data(&ctx)
|
||||
.mapped_dirs
|
||||
.get(&cwd.to_string_lossy().to_string())
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user