mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -05:00
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.
This commit is contained in:
parent
722ea20e86
commit
e2be70b035
4 changed files with 26 additions and 35 deletions
2
cli/tests/testdata/run/ffi/unstable_ffi_4.js
vendored
2
cli/tests/testdata/run/ffi/unstable_ffi_4.js
vendored
|
@ -1 +1 @@
|
||||||
Deno.core.ops.op_ffi_ptr_of(new Uint8Array(0));
|
Deno.core.ops.op_ffi_ptr_of(new Uint8Array(0), new Uint32Array(2));
|
||||||
|
|
|
@ -160,12 +160,19 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const OUT_BUFFER = new Uint32Array(2);
|
||||||
|
const OUT_BUFFER_64 = new BigInt64Array(OUT_BUFFER.buffer);
|
||||||
class UnsafePointer {
|
class UnsafePointer {
|
||||||
static of(value) {
|
static of(value) {
|
||||||
if (ObjectPrototypeIsPrototypeOf(UnsafeCallbackPrototype, value)) {
|
if (ObjectPrototypeIsPrototypeOf(UnsafeCallbackPrototype, value)) {
|
||||||
return value.pointer;
|
return value.pointer;
|
||||||
}
|
}
|
||||||
return ops.op_ffi_ptr_of(value);
|
ops.op_ffi_ptr_of(value, OUT_BUFFER);
|
||||||
|
const result = OUT_BUFFER[0] + 2 ** 32 * OUT_BUFFER[1];
|
||||||
|
if (NumberIsSafeInteger(result)) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return OUT_BUFFER_64[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2063,12 +2063,12 @@ fn op_ffi_call_nonblocking<'scope>(
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[op(v8)]
|
#[op(fast)]
|
||||||
fn op_ffi_ptr_of<FP, 'scope>(
|
fn op_ffi_ptr_of<FP>(
|
||||||
scope: &mut v8::HandleScope<'scope>,
|
|
||||||
state: &mut deno_core::OpState,
|
state: &mut deno_core::OpState,
|
||||||
buf: serde_v8::Value<'scope>,
|
buf: &[u8],
|
||||||
) -> Result<serde_v8::Value<'scope>, AnyError>
|
out: &mut [u32],
|
||||||
|
) -> Result<(), AnyError>
|
||||||
where
|
where
|
||||||
FP: FfiPermissions + 'static,
|
FP: FfiPermissions + 'static,
|
||||||
{
|
{
|
||||||
|
@ -2076,34 +2076,18 @@ where
|
||||||
let permissions = state.borrow_mut::<FP>();
|
let permissions = state.borrow_mut::<FP>();
|
||||||
permissions.check(None)?;
|
permissions.check(None)?;
|
||||||
|
|
||||||
let pointer = if let Ok(value) =
|
let outptr = out.as_ptr() as *mut usize;
|
||||||
v8::Local::<v8::ArrayBufferView>::try_from(buf.v8_value)
|
let length = out.len();
|
||||||
{
|
assert!(
|
||||||
let backing_store = value
|
length >= (std::mem::size_of::<usize>() / std::mem::size_of::<u32>())
|
||||||
.buffer(scope)
|
);
|
||||||
.ok_or_else(|| {
|
assert_eq!(outptr as usize % std::mem::size_of::<usize>(), 0);
|
||||||
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::<v8::ArrayBuffer>::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 integer: v8::Local<v8::Value> =
|
// SAFETY: Out buffer was asserted to be at least large enough to hold a usize, and properly aligned.
|
||||||
if pointer as usize > MAX_SAFE_INTEGER as usize {
|
let out = unsafe { &mut *outptr };
|
||||||
v8::BigInt::new_from_u64(scope, pointer as u64).into()
|
*out = buf.as_ptr() as usize;
|
||||||
} else {
|
|
||||||
v8::Number::new(scope, pointer as usize as f64).into()
|
Ok(())
|
||||||
};
|
|
||||||
Ok(integer.into())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" fn noop_deleter_callback(
|
unsafe extern "C" fn noop_deleter_callback(
|
||||||
|
|
|
@ -57,7 +57,7 @@ fn basic() {
|
||||||
false\n\
|
false\n\
|
||||||
true\n\
|
true\n\
|
||||||
false\n\
|
false\n\
|
||||||
false\n\
|
true\n\
|
||||||
false\n\
|
false\n\
|
||||||
579\n\
|
579\n\
|
||||||
true\n\
|
true\n\
|
||||||
|
|
Loading…
Add table
Reference in a new issue