diff --git a/javascript-container/src/main.rs b/javascript-container/src/main.rs index c5937a1..35f9010 100644 --- a/javascript-container/src/main.rs +++ b/javascript-container/src/main.rs @@ -15,8 +15,8 @@ fn main() -> Result<()> { let memory = instance.get_memory(&mut store, "memory").expect("SHOULD NOT HAPPEN"); let malloc = instance.get_typed_func::(&mut store, "malloc")?; - let free = instance.get_typed_func::<(i32, i32), ()>(&mut store, "free")?; - let eval = instance.get_typed_func::<(i32, i32), (i32, i32)>(&mut store, "eval")?; + let free = instance.get_typed_func::(&mut store, "free")?; + let eval = instance.get_typed_func::(&mut store, "eval")?; let js = "1+2"; let js_bytes = js.as_bytes(); @@ -24,10 +24,26 @@ fn main() -> Result<()> { let ptr = malloc.call(&mut store, js.as_bytes().len() as i32)?; let memory_data_mut = memory.data_mut(&mut store); for i in 0..js_bytes_len { - memory_data_mut[ptr as usize + i] = js_bytes[i]; + memory_data_mut[4 + ptr as usize + i] = js_bytes[i]; } - let eval_result = eval.call(&mut store, (ptr, js_bytes_len as i32))?; + let eval_result = eval.call(&mut store, ptr)?; println!("Eval result: {:?}", eval_result); + let memory = instance.get_memory(&mut store, "memory").expect("SHOULD NOT HAPPEN"); + let memory_data_mut = memory.data_mut(&mut store); + let mut a = [0_u8; 4]; + a[0] = memory_data_mut[eval_result as usize + 0]; + a[1] = memory_data_mut[eval_result as usize + 1]; + a[2] = memory_data_mut[eval_result as usize + 2]; + a[3] = memory_data_mut[eval_result as usize + 3]; + let aa = u32::from_be_bytes(a); + println!("Len: {}", aa); + let mut s = Vec::with_capacity(aa as usize); + for i in 0..aa { + s.push(memory_data_mut[eval_result as usize + 4 + i as usize]); + } + let ss = unsafe { String::from_utf8_unchecked(s) }; + println!("Result: {}", ss); + Ok(()) } diff --git a/javascript-engine/src/lib.rs b/javascript-engine/src/lib.rs index b6cc094..7fa7eeb 100644 --- a/javascript-engine/src/lib.rs +++ b/javascript-engine/src/lib.rs @@ -2,10 +2,10 @@ mod mem; mod engine; #[no_mangle] -pub unsafe fn eval(ptr: *mut u8, len: usize) -> (*mut u8, usize) { - let js = mem::read_string(ptr, len); +pub unsafe fn eval(ptr: *mut u8) -> *mut u8 { + let js = mem::read_string(ptr); let eval_result = engine::inner_eval(&js); let eval_result_json_string = serde_json::to_string(&eval_result).expect("SHOULD NOT HAPPEN"); - mem::malloc_and_write_string(&eval_result_json_string) + mem::malloc_and_write_string(&eval_result_json_string).0 } diff --git a/javascript-engine/src/mem.rs b/javascript-engine/src/mem.rs index 2e88bbe..2b6a970 100644 --- a/javascript-engine/src/mem.rs +++ b/javascript-engine/src/mem.rs @@ -3,23 +3,24 @@ use std::ptr; #[no_mangle] pub unsafe fn malloc(len: usize) -> *mut u8 { let align = std::mem::align_of::(); - let layout = std::alloc::Layout::from_size_align_unchecked(len, align); - std::alloc::alloc(layout) + let layout = std::alloc::Layout::from_size_align_unchecked(len + 4, align); + let addr = std::alloc::alloc(layout); + let len_in_bytes = (len as u32).to_be_bytes(); + write_bytes(addr, 0, 4, &len_in_bytes); + addr } #[no_mangle] -pub unsafe fn free(ptr: *mut u8, len: usize) { +pub unsafe fn free(ptr: *mut u8) { + let len = read_u32(ptr); let align = std::mem::align_of::(); - let layout = std::alloc::Layout::from_size_align_unchecked(len, align); + let layout = std::alloc::Layout::from_size_align_unchecked(4 + len as usize, align); std::alloc::dealloc(ptr, layout) } -pub(crate) fn read_string(ptr: *const u8, len: usize) -> String { - let mut buffer = Vec::with_capacity(len); - let len = len as isize; - for i in 0..len { - buffer.push(unsafe { ptr::read(ptr.offset(i)) }); - } +pub(crate) fn read_string(ptr: *const u8) -> String { + let len = read_u32(ptr); + let buffer = read_bytes(ptr, 4, len as usize); unsafe { String::from_utf8_unchecked(buffer) } } @@ -27,14 +28,32 @@ pub(crate) unsafe fn malloc_and_write_string(str: &str) -> (*mut u8, usize) { let bytes = str.as_bytes(); let bytes_len = bytes.len(); let ptr = malloc(bytes_len); - write_bytes(ptr, bytes_len, bytes); + write_bytes(ptr, 4, bytes_len, bytes); (ptr, bytes_len) } -pub(crate) fn write_bytes(ptr: *mut u8, len: usize, bytes: &[u8]) { +pub(crate) fn read_u32(ptr: *const u8) -> u32 { + let vec_u32 = read_bytes(ptr, 0, 4); + let mut bytes_u32 = [0_u8; 4]; + bytes_u32[0] = vec_u32[0]; + bytes_u32[1] = vec_u32[1]; + bytes_u32[2] = vec_u32[2]; + bytes_u32[3] = vec_u32[3]; + u32::from_be_bytes(bytes_u32) +} + +pub(crate) fn read_bytes(ptr: *const u8, offset: isize, len: usize) -> Vec { + let mut buffer = Vec::with_capacity(len); + for i in 0..len { + buffer.push(unsafe { ptr::read(ptr.offset(offset + i as isize)) }); + } + buffer +} + +pub(crate) fn write_bytes(ptr: *mut u8, offset: isize, len: usize, bytes: &[u8]) { let bytes_len = bytes.len(); assert!(bytes_len <= len); for i in 0..bytes_len { - unsafe { ptr::write(ptr.offset(i as isize), bytes[i]) }; + unsafe { ptr::write(ptr.offset(offset + i as isize), bytes[i]) }; } }