From e2be70b035459cb534360b72ece4ff2abaa09cd7 Mon Sep 17 00:00:00 2001 From: Aapo Alasuutari Date: Thu, 20 Oct 2022 07:07:37 +0300 Subject: feat(ext/ffi): Make op_ffi_ptr_of fast (#16297) Makes `op_ffi_ptr_of` fast. One of the tests changed from printing `false` to `true` as the fast `&[u8]` slice path creates the slice with a null pointer. Thus the `op_ffi_ptr_of` will now return a null pointer value whereas previously it returned a dangling pointer value. --- ext/ffi/lib.rs | 48 ++++++++++++++++-------------------------------- 1 file changed, 16 insertions(+), 32 deletions(-) (limited to 'ext/ffi/lib.rs') diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs index ae51db34c..3ad75e245 100644 --- a/ext/ffi/lib.rs +++ b/ext/ffi/lib.rs @@ -2063,12 +2063,12 @@ fn op_ffi_call_nonblocking<'scope>( }) } -#[op(v8)] -fn op_ffi_ptr_of( - scope: &mut v8::HandleScope<'scope>, +#[op(fast)] +fn op_ffi_ptr_of( state: &mut deno_core::OpState, - buf: serde_v8::Value<'scope>, -) -> Result, AnyError> + buf: &[u8], + out: &mut [u32], +) -> Result<(), AnyError> where FP: FfiPermissions + 'static, { @@ -2076,34 +2076,18 @@ where let permissions = state.borrow_mut::(); permissions.check(None)?; - let pointer = if let Ok(value) = - v8::Local::::try_from(buf.v8_value) - { - let backing_store = value - .buffer(scope) - .ok_or_else(|| { - type_error("Invalid FFI ArrayBufferView, expected data in the buffer") - })? - .get_backing_store(); - let byte_offset = value.byte_offset(); - &backing_store[byte_offset..] as *const _ as *const u8 - } else if let Ok(value) = v8::Local::::try_from(buf.v8_value) - { - let backing_store = value.get_backing_store(); - &backing_store[..] as *const _ as *const u8 - } else { - return Err(type_error( - "Invalid FFI buffer, expected ArrayBuffer, or ArrayBufferView", - )); - }; + let outptr = out.as_ptr() as *mut usize; + let length = out.len(); + assert!( + length >= (std::mem::size_of::() / std::mem::size_of::()) + ); + assert_eq!(outptr as usize % std::mem::size_of::(), 0); - let integer: v8::Local = - if pointer as usize > MAX_SAFE_INTEGER as usize { - v8::BigInt::new_from_u64(scope, pointer as u64).into() - } else { - v8::Number::new(scope, pointer as usize as f64).into() - }; - Ok(integer.into()) + // SAFETY: Out buffer was asserted to be at least large enough to hold a usize, and properly aligned. + let out = unsafe { &mut *outptr }; + *out = buf.as_ptr() as usize; + + Ok(()) } unsafe extern "C" fn noop_deleter_callback( -- cgit v1.2.3