diff --git a/core/src/main/java/io/roastedroot/quickjs4j/core/Engine.java b/core/src/main/java/io/roastedroot/quickjs4j/core/Engine.java index 8c54876..13c9bec 100644 --- a/core/src/main/java/io/roastedroot/quickjs4j/core/Engine.java +++ b/core/src/main/java/io/roastedroot/quickjs4j/core/Engine.java @@ -278,7 +278,7 @@ private long[] invokeBuiltin(Instance instance, long[] args) { : mapper.writerFor(returnType).writeValueAsBytes(res); var returnPtr = - exports.canonicalAbiRealloc( + exports.cabiRealloc( 0, // original_ptr 0, // original_size ALIGNMENT, // alignment @@ -288,7 +288,7 @@ private long[] invokeBuiltin(Instance instance, long[] args) { var LEN = 8; var widePtr = - exports.canonicalAbiRealloc( + exports.cabiRealloc( 0, // original_ptr 0, // original_size ALIGNMENT, // alignment @@ -380,7 +380,7 @@ public int compileRaw(byte[] js) { byte[] jsCode = js; var ptr = - exports.canonicalAbiRealloc( + exports.cabiRealloc( 0, // original_ptr 0, // original_size ALIGNMENT, // alignment @@ -390,7 +390,7 @@ public int compileRaw(byte[] js) { exports.memory().write(ptr, jsCode); try { var aggregatedCodePtr = exports.compileSrc(ptr, jsCode.length); - exports.canonicalAbiFree( + exports.abiFree( ptr, // ptr jsCode.length, // length ALIGNMENT // alignement @@ -426,7 +426,7 @@ public void exec(int codePtr) { var codeLength = exports.memory().readInt(codePtr + 4); try { - exports.invoke( + exports.eval( ptr, // bytecode_ptr codeLength, // bytecode_len 0, // fn_name_ptr @@ -472,7 +472,7 @@ public void free(int codePtr) { var ptr = exports.memory().readInt(codePtr); var codeLength = exports.memory().readInt(codePtr + 4); - exports.canonicalAbiFree( + exports.abiFree( ptr, // ptr codeLength, // length ALIGNMENT // alignement @@ -488,7 +488,7 @@ public byte[] readCompiled(int codePtr) { public int writeCompiled(byte[] jsBytecode) { var ptr = - exports.canonicalAbiRealloc( + exports.cabiRealloc( 0, // original_ptr 0, // original_size ALIGNMENT, // alignment @@ -496,7 +496,7 @@ public int writeCompiled(byte[] jsBytecode) { ); var codePtr = - exports.canonicalAbiRealloc( + exports.cabiRealloc( 0, // original_ptr 0, // original_size ALIGNMENT, // alignment diff --git a/javy-plugin/Cargo.lock b/javy-plugin/Cargo.lock index 44b2935..8b11550 100644 --- a/javy-plugin/Cargo.lock +++ b/javy-plugin/Cargo.lock @@ -318,9 +318,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.8.5" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" dependencies = [ "rand_core", ] diff --git a/javy-plugin/src/lib.rs b/javy-plugin/src/lib.rs index d37b35c..4597047 100644 --- a/javy-plugin/src/lib.rs +++ b/javy-plugin/src/lib.rs @@ -1,7 +1,6 @@ extern crate javy_plugin_api; use javy_plugin_api::{import_namespace, javy::quickjs::prelude::Func, Config}; use std::alloc::{alloc, dealloc, Layout}; -use std::ptr::copy_nonoverlapping; import_namespace!("chicory_plugin"); @@ -19,68 +18,13 @@ mod chicory_imports { } } -// Implement canonical ABI functions using Javy's allocator implementation -// Based on: https://github.com/bytecodealliance/javy/blob/4142700f24f250b65478f165e27605d7a0571a3d/crates/javy/src/alloc.rs - -// Unlike C's realloc, zero-length allocations need not have -// unique addresses, so a zero-length allocation may be passed -// in and also requested, but it's ok to return anything that's -// non-zero to indicate success. -const ZERO_SIZE_ALLOCATION_PTR: *mut u8 = 1 as _; - -/// Allocates memory in instance. -/// -/// 1. Allocate memory of new_size with alignment. -/// 2. If original_ptr != 0. -/// a. copy min(new_size, original_size) bytes from original_ptr to new memory. -/// b. de-allocate original_ptr. -/// 3. Return new memory ptr. -/// -/// # Safety -/// -/// * `original_ptr` must be 0 or a valid pointer. -/// * If `original_ptr` is not 0, it must be valid for reads of `original_size` -/// bytes. -/// * If `original_ptr` is not 0, it must be properly aligned. -/// * If `original_size` is not 0, it must match the `new_size` value provided -/// in the original `canonical_abi_realloc` call that returned `original_ptr`. -#[no_mangle] -pub unsafe extern "C" fn canonical_abi_realloc( - original_ptr: *mut u8, - original_size: usize, - alignment: usize, - new_size: usize, -) -> *mut std::ffi::c_void { - assert!(new_size >= original_size); - - let new_mem = match new_size { - 0 => ZERO_SIZE_ALLOCATION_PTR, - // this call to `alloc` is safe since `new_size` must be > 0 - _ => alloc(Layout::from_size_align(new_size, alignment).unwrap()), - }; - - if !original_ptr.is_null() && original_size != 0 { - copy_nonoverlapping(original_ptr, new_mem, original_size); - canonical_abi_free(original_ptr, original_size, alignment); - } - new_mem as _ -} - -/// Frees allocated memory in instance. -/// -/// # Safety -/// -/// * `ptr` must denote a block of memory allocated by `canonical_abi_realloc`. -/// * `size` and `alignment` must match the values provided in the original -/// `canonical_abi_realloc` call that returned `ptr`. -#[no_mangle] -pub unsafe extern "C" fn canonical_abi_free(ptr: *mut u8, size: usize, alignment: usize) { +#[export_name = "abi_free"] +pub unsafe extern "C" fn abi_free(ptr: *mut u8, size: usize, alignment: usize) { if size > 0 { dealloc(ptr, Layout::from_size_align(size, alignment).unwrap()) - }; + } } - fn invoke_exec(module_str: String, name_str: String, args_str: String) -> String { let module_bytes: &[u8] = module_str.as_bytes(); let name_bytes: &[u8] = name_str.as_bytes(); @@ -100,8 +44,8 @@ fn invoke_exec(module_str: String, name_str: String, args_str: String) -> String }; let res = std::slice::from_raw_parts(*ptr as *const u8, *len as usize); let str_result = std::str::from_utf8(res).unwrap().to_string(); - canonical_abi_free(*wide_ptr as *mut u8, 8, 1); - canonical_abi_free(*ptr as *mut u8, *len as usize, 1); + dealloc(*wide_ptr as *mut u8, Layout::from_size_align(8, 1).unwrap()); + dealloc(*ptr as *mut u8, Layout::from_size_align(*len as usize, 1).unwrap()); str_result }; @@ -145,22 +89,12 @@ pub extern "C" fn compileSrc(js_src_ptr: *const u8, js_src_len: usize) -> *const let bytecode = javy_plugin_api::compile_src(source).unwrap(); let bytecode_len = bytecode.len(); - let bytecode_ptr = canonical_abi_realloc( - std::ptr::null_mut(), - 0, - 1, - bytecode_len, - ) as *mut u8; + let bytecode_ptr = alloc(Layout::from_size_align(bytecode_len, 1).unwrap()); std::ptr::copy_nonoverlapping(bytecode.as_ptr(), bytecode_ptr, bytecode_len); // Return a pointer to [ptr, len] as u32 array - let wide_ptr = canonical_abi_realloc( - std::ptr::null_mut(), - 0, - 1, - 8, // 2 * u32 = 8 bytes - ) as *mut u32; + let wide_ptr = alloc(Layout::from_size_align(8, 1).unwrap()) as *mut u32; let ptr_u32 = bytecode_ptr as u32; let len_u32 = bytecode_len as u32; @@ -172,8 +106,8 @@ pub extern "C" fn compileSrc(js_src_ptr: *const u8, js_src_len: usize) -> *const } } -#[no_mangle] -pub extern "C" fn invoke( +#[export_name = "eval"] +pub extern "C" fn eval( bytecode_ptr: *const u8, bytecode_len: usize, fn_name_ptr: *const u8, diff --git a/javy_quickjs4j_plugin.wasm b/javy_quickjs4j_plugin.wasm index a21f4a8..67b2997 100755 Binary files a/javy_quickjs4j_plugin.wasm and b/javy_quickjs4j_plugin.wasm differ