Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions core/src/main/java/io/roastedroot/quickjs4j/core/Engine.java
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -488,15 +488,15 @@ public byte[] readCompiled(int codePtr) {

public int writeCompiled(byte[] jsBytecode) {
var ptr =
exports.canonicalAbiRealloc(
exports.cabiRealloc(
0, // original_ptr
0, // original_size
ALIGNMENT, // alignment
8 // new size
);

var codePtr =
exports.canonicalAbiRealloc(
exports.cabiRealloc(
0, // original_ptr
0, // original_size
ALIGNMENT, // alignment
Expand Down
4 changes: 2 additions & 2 deletions javy-plugin/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

84 changes: 9 additions & 75 deletions javy-plugin/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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");

Expand All @@ -19,68 +18,13 @@ mod chicory_imports {
}
}

// Implement canonical ABI functions using Javy's allocator implementation
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks @saulecabrera you were right 👍

// 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();
Expand All @@ -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
};

Expand Down Expand Up @@ -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;
Expand All @@ -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,
Expand Down
Binary file modified javy_quickjs4j_plugin.wasm
Binary file not shown.