From 9dfd628da12c8916c048149927c36c8c294b5858 Mon Sep 17 00:00:00 2001 From: Stefan Richter-Huber Date: Wed, 18 Mar 2026 16:06:36 +0100 Subject: [PATCH] Cleanup of code --- .../quickjswasmjava/MessagePackRegistry.java | 3 +- src/main/rust/quickjslib/wasm_lib/Cargo.toml | 2 +- .../wasm_lib/src/completable_future.rs | 12 +++---- .../rust/quickjslib/wasm_lib/src/context.rs | 4 +-- .../quickjslib/wasm_lib/src/from_error.rs | 12 +++---- .../wasm_lib/src/into_wasm_result.rs | 35 ++++++++++++++++--- src/main/rust/quickjslib/wasm_lib/src/lib.rs | 19 +++++++--- .../quickjslib/wasm_lib/src/native_array.rs | 12 +++---- .../quickjslib/wasm_lib/src/native_object.rs | 12 +++---- .../wasm_lib/src/quickjs_function.rs | 8 ++--- .../rust/quickjslib/wasm_macros/Cargo.toml | 2 +- 11 files changed, 78 insertions(+), 43 deletions(-) diff --git a/src/main/java/io/github/stefanrichterhuber/quickjswasmjava/MessagePackRegistry.java b/src/main/java/io/github/stefanrichterhuber/quickjswasmjava/MessagePackRegistry.java index d79dd03..6e4717f 100644 --- a/src/main/java/io/github/stefanrichterhuber/quickjswasmjava/MessagePackRegistry.java +++ b/src/main/java/io/github/stefanrichterhuber/quickjswasmjava/MessagePackRegistry.java @@ -276,8 +276,7 @@ public Object unpack(MessageUnpacker u) throws IOException { * @return The object */ Object unpack(byte[] obj) { - MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(obj); - try { + try (MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(obj)) { return this.unpack(unpacker); } catch (IOException e) { throw new RuntimeException("Unable to unpack object", e); diff --git a/src/main/rust/quickjslib/wasm_lib/Cargo.toml b/src/main/rust/quickjslib/wasm_lib/Cargo.toml index f1d0f8e..b2c3f23 100644 --- a/src/main/rust/quickjslib/wasm_lib/Cargo.toml +++ b/src/main/rust/quickjslib/wasm_lib/Cargo.toml @@ -8,7 +8,7 @@ crate-type = ["cdylib"] [dependencies] wasm_macros = { path = "../wasm_macros" } -rmp-serde = "1.1" +rmp-serde = "1.3" log = { version = "0.4", features = ["std"] } serde = { version = "1.0", features = ["derive"] } rquickjs = { version = "0.11.0", features = [ diff --git a/src/main/rust/quickjslib/wasm_lib/src/completable_future.rs b/src/main/rust/quickjslib/wasm_lib/src/completable_future.rs index eb4a844..9c2ada9 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/completable_future.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/completable_future.rs @@ -116,7 +116,7 @@ pub fn promise_create( promise.set(JAVA_COMPLETABLE_FUTURE_PTR_FIELD, cf_ptr)?; let cf = Box::new(PromiseContainer::new( - &ctx, + ctx, promise, Some(resolve), Some(reject), @@ -275,12 +275,12 @@ pub(crate) fn convert_promise<'js>(promise: Promise<'js>) -> rquickjs::Result(promise: Promise<'js>) -> rquickjs::Result, script: String) -> rquickjs::Result, script: String) -> rquickjs::Result { debug!("Evaluating async script: {}", script); let promise = ctx.eval_promise(script)?; - let result = JSJavaProxy::from_js(&ctx, promise.into_value())?; + let result = JSJavaProxy::from_js(ctx, promise.into_value())?; Ok(result) } @@ -93,7 +93,7 @@ pub fn get_global(ctx: &Ctx<'_>, name: String) -> rquickjs::Result } thread_local! { - static CONTEXT_STACK: RefCell)>> = RefCell::new(Vec::new()); + static CONTEXT_STACK: RefCell)>> = const { RefCell::new(Vec::new()) }; } /// Helper function to get a Ctx from a Context, handling re-entrancy. diff --git a/src/main/rust/quickjslib/wasm_lib/src/from_error.rs b/src/main/rust/quickjslib/wasm_lib/src/from_error.rs index 8f38249..25f944c 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/from_error.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/from_error.rs @@ -40,12 +40,12 @@ impl<'js, T> FromError<'js> for Option> { error!("Failed to call js {}: {}", message, stacktrace); None } else { - error!("Failed to call js {}", err.to_string()); + error!("Failed to call js {}", err); None } } _ => { - error!("Failed to call js {}", err.to_string()); + error!("Failed to call js {}", err); None } } @@ -65,12 +65,12 @@ impl<'js> FromError<'js> for bool { error!("Failed to call js {}: {}", message, stacktrace); false } else { - error!("Failed to call js {}", err.to_string()); + error!("Failed to call js {}", err); false } } _ => { - error!("Failed to call js {}", err.to_string()); + error!("Failed to call js {}", err); false } } @@ -90,12 +90,12 @@ impl<'js> FromError<'js> for i32 { error!("Failed to call js {}: {}", message, stacktrace); -1 } else { - error!("Failed to call js {}", err.to_string()); + error!("Failed to call js {}", err); -1 } } _ => { - error!("Failed to call js {}", err.to_string()); + error!("Failed to call js {}", err); -1 } } diff --git a/src/main/rust/quickjslib/wasm_lib/src/into_wasm_result.rs b/src/main/rust/quickjslib/wasm_lib/src/into_wasm_result.rs index 11bd1ce..21f603d 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/into_wasm_result.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/into_wasm_result.rs @@ -18,6 +18,7 @@ impl IntoWasmResult for JSJavaProxy { /// Converts a Box into a u64 that can be returned to Java (by returning the pointer to the object) impl IntoWasmResult for Box { + #[inline] fn into_wasm(self) -> u64 { // return the pointer to the object let ptr = Box::into_raw(self); @@ -25,9 +26,13 @@ impl IntoWasmResult for Box { } } -/// Converts a Option> into a u64 that can be returned to Java (by returning the pointer to the object). -/// For None 0 is returned -impl IntoWasmResult for Option> { +/// Converts an Option into a u64 that can be returned to Java (by returning the pointer to the object). +/// For None 0 is returned +impl IntoWasmResult for Option +where + T: IntoWasmResult, +{ + #[inline] fn into_wasm(self) -> u64 { match self { Some(v) => v.into_wasm(), @@ -49,6 +54,7 @@ impl IntoWasmResult for String { /// Converts a bool into a u64 that can be returned to Java (by returning 1 for true and 0 for false) impl IntoWasmResult for bool { + #[inline] fn into_wasm(self) -> u64 { if self { 1 @@ -60,6 +66,7 @@ impl IntoWasmResult for bool { /// Converts an i32 into a u64 that can be returned to Java (by returning the value as is) impl IntoWasmResult for i32 { + #[inline] fn into_wasm(self) -> u64 { self as u64 } @@ -67,14 +74,15 @@ impl IntoWasmResult for i32 { /// Converts a u32 into a u64 that can be returned to Java (by returning the value as is) impl IntoWasmResult for u32 { + #[inline] fn into_wasm(self) -> u64 { self as u64 } } /// Converts an i64 into a u64 that can be returned to Java (by returning the value as is) -/// impl IntoWasmResult for i64 { + #[inline] fn into_wasm(self) -> u64 { self as u64 } @@ -82,7 +90,24 @@ impl IntoWasmResult for i64 { /// Converts a u64 into a u64 that can be returned to Java (by returning the value as is) impl IntoWasmResult for u64 { + #[inline] fn into_wasm(self) -> u64 { - self as u64 + self + } +} + +/// Converts a f32 into a u64 (by bit representation not by value) +impl IntoWasmResult for f32 { + #[inline] + fn into_wasm(self) -> u64 { + self.to_bits().into_wasm() + } +} + +/// Converts a f64 into a u64 (by bit representation not by value) +impl IntoWasmResult for f64 { + #[inline] + fn into_wasm(self) -> u64 { + self.to_bits().into_wasm() } } diff --git a/src/main/rust/quickjslib/wasm_lib/src/lib.rs b/src/main/rust/quickjslib/wasm_lib/src/lib.rs index acc16a0..0bfc7d9 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/lib.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/lib.rs @@ -10,17 +10,28 @@ mod native_object; mod quickjs_function; mod runtime; -/// Give the host a way to free memory to prevent leaks +/// Give the wasm host a way to free memory to prevent leaks +/// +/// # Safety +/// +/// * `ptr` must have been allocated by `alloc`. +/// * `size` must match the exact same size used during allocation. +/// * The memory must not be accessed or used after being deallocated. #[no_mangle] -pub extern "C" fn dealloc(ptr: *mut u8, size: usize) { +pub unsafe extern "C" fn dealloc(ptr: *mut u8, size: usize) { unsafe { let _ = Vec::from_raw_parts(ptr, 0, size); } } -/// Give the host a way to allocate memory inside the Wasm module +/// Give the wasm host a way to allocate memory inside the Wasm module +/// +/// # Safety +/// +/// * The caller must ensure that the returned pointer is properly deallocated using `dealloc` with the exact same size to prevent memory leaks. +/// * The allocated memory is uninitialized and must be initialized before being read. #[no_mangle] -pub extern "C" fn alloc(size: usize) -> *mut u8 { +pub unsafe extern "C" fn alloc(size: usize) -> *mut u8 { let mut buf = Vec::with_capacity(size); let ptr = buf.as_mut_ptr(); mem::forget(buf); // Prevent Rust from freeing the memory diff --git a/src/main/rust/quickjslib/wasm_lib/src/native_array.rs b/src/main/rust/quickjslib/wasm_lib/src/native_array.rs index 53f2e13..0f3555e 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/native_array.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/native_array.rs @@ -6,7 +6,7 @@ use crate::js_to_java_proxy::JSJavaProxy; #[wasm_export] pub fn array_create(ctx: &Ctx<'_>) -> rquickjs::Result>>>> { let js_array = rquickjs::Array::new(ctx.clone()).unwrap(); - let persistent = Persistent::save(&ctx, js_array); + let persistent = Persistent::save(ctx, js_array); let result = Box::new(persistent); Ok(Some(result)) } @@ -22,7 +22,7 @@ pub fn array_size( ctx: &Ctx<'_>, persistent_array: &Persistent>, ) -> rquickjs::Result { - let v = persistent_array.clone().restore(&ctx)?; + let v = persistent_array.clone().restore(ctx)?; Ok(v.len() as i32) } @@ -33,7 +33,7 @@ pub fn array_add( index: i32, value: JSJavaProxy, ) -> rquickjs::Result { - let array = persistent_array.clone().restore(&ctx)?; + let array = persistent_array.clone().restore(ctx)?; splice_array(array, index, 0, Some(value))?; Ok(true) } @@ -45,7 +45,7 @@ pub fn array_set( index: i32, value: JSJavaProxy, ) -> rquickjs::Result { - let array = persistent_array.clone().restore(&ctx)?; + let array = persistent_array.clone().restore(ctx)?; array.set(index as usize, value)?; Ok(true) @@ -57,7 +57,7 @@ pub fn array_get( persistent_array: &Persistent>, index: i32, ) -> rquickjs::Result { - let array = persistent_array.clone().restore(&ctx)?; + let array = persistent_array.clone().restore(ctx)?; array.get(index as usize)? } @@ -68,7 +68,7 @@ pub fn array_remove( persistent_array: &Persistent>, index: i32, ) -> rquickjs::Result { - let array = persistent_array.clone().restore(&ctx)?; + let array = persistent_array.clone().restore(ctx)?; splice_array(array, index, 1, None)?; diff --git a/src/main/rust/quickjslib/wasm_lib/src/native_object.rs b/src/main/rust/quickjslib/wasm_lib/src/native_object.rs index 7ade69c..34cbbb5 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/native_object.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/native_object.rs @@ -7,7 +7,7 @@ use crate::js_to_java_proxy::JSJavaProxy; #[wasm_export] pub fn object_create(ctx: &Ctx<'_>) -> rquickjs::Result>>>> { let js_object = rquickjs::Object::new(ctx.clone())?; - let persistent = Persistent::save(&ctx, js_object); + let persistent = Persistent::save(ctx, js_object); let result = Box::new(persistent); Ok(Some(result)) } @@ -23,7 +23,7 @@ pub fn object_size( ctx: &Ctx<'_>, persistent_object: &Persistent>, ) -> rquickjs::Result { - let v = persistent_object.clone().restore(&ctx)?; + let v = persistent_object.clone().restore(ctx)?; Ok(v.len() as i32) } @@ -33,7 +33,7 @@ pub fn object_contains_key( persistent_object: &Persistent>, key: JSJavaProxy, ) -> rquickjs::Result { - let v = persistent_object.clone().restore(&ctx)?; + let v = persistent_object.clone().restore(ctx)?; v.contains_key(key) } @@ -60,7 +60,7 @@ pub fn object_remove_value( persistent_object: &Persistent>, key: JSJavaProxy, ) -> rquickjs::Result { - let v = persistent_object.clone().restore(&ctx)?; + let v = persistent_object.clone().restore(ctx)?; v.remove(key)?; Ok(true) } @@ -72,7 +72,7 @@ pub fn object_set_value( key: JSJavaProxy, value: JSJavaProxy, ) -> rquickjs::Result { - let v = persistent_object.clone().restore(&ctx)?; + let v = persistent_object.clone().restore(ctx)?; v.set(key, value)?; Ok(true) } @@ -82,7 +82,7 @@ pub fn object_key_set( ctx: &Ctx<'_>, persistent_object: &Persistent>, ) -> rquickjs::Result { - let v = persistent_object.clone().restore(&ctx)?; + let v = persistent_object.clone().restore(ctx)?; let object_keys: ObjectKeysIter<'_, JSJavaProxy> = v.keys(); diff --git a/src/main/rust/quickjslib/wasm_lib/src/quickjs_function.rs b/src/main/rust/quickjslib/wasm_lib/src/quickjs_function.rs index 1c55960..cb3d5ed 100644 --- a/src/main/rust/quickjslib/wasm_lib/src/quickjs_function.rs +++ b/src/main/rust/quickjslib/wasm_lib/src/quickjs_function.rs @@ -11,12 +11,12 @@ use wasm_macros::wasm_export; use crate::js_to_java_proxy::JSJavaProxy; #[wasm_export] -pub fn call_function<'js>( +pub fn call_function( ctx: &Ctx<'_>, persistent_function: &Persistent>, args: JSJavaProxy, ) -> rquickjs::Result { - let function = persistent_function.clone().restore(&ctx)?; + let function = persistent_function.clone().restore(ctx)?; debug!("Calling function with args: {:?}", args); function.call(args)? } @@ -75,7 +75,7 @@ impl JavaFunction { JSJavaProxy::Undefined } }; - crate::dealloc(result_ptr as *mut u8, result_len); + unsafe { crate::dealloc(result_ptr as *mut u8, result_len) }; debug!( "Calling Java function: {} on context {} with arg: {:?} -> {:?}", @@ -113,7 +113,7 @@ impl<'js, P> IntoJsFunc<'js, P> for JavaFunction { // If the result is an exception, throw it if let JSJavaProxy::Exception(message, _stacktrace) = &result { - let exception = rquickjs::Exception::from_message(params.ctx().clone(), &message)?; + let exception = rquickjs::Exception::from_message(params.ctx().clone(), message)?; Err(params.ctx().throw(exception.into_value())) } else { result.into_js(params.ctx()) diff --git a/src/main/rust/quickjslib/wasm_macros/Cargo.toml b/src/main/rust/quickjslib/wasm_macros/Cargo.toml index 49e8d26..5ad2b66 100644 --- a/src/main/rust/quickjslib/wasm_macros/Cargo.toml +++ b/src/main/rust/quickjslib/wasm_macros/Cargo.toml @@ -10,4 +10,4 @@ proc-macro = true syn = { version = "2.0", features = ["full"] } quote = "1.0" proc-macro2 = "1.0" -regex = "1.12.3" \ No newline at end of file +regex = "1.12" \ No newline at end of file