2024-01-01 14:58:21 -05:00
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
2022-12-12 09:14:20 -05:00
use crate ::FfiPermissions ;
2023-10-05 09:35:21 -04:00
use deno_core ::op2 ;
2022-12-12 09:14:20 -05:00
use deno_core ::v8 ;
2023-02-28 01:26:48 -05:00
use deno_core ::OpState ;
2022-12-12 09:14:20 -05:00
use std ::ffi ::c_char ;
use std ::ffi ::c_void ;
use std ::ffi ::CStr ;
use std ::ptr ;
2024-10-14 18:05:49 -04:00
#[ derive(Debug, thiserror::Error) ]
pub enum ReprError {
#[ error( " Invalid pointer to offset, pointer is null " ) ]
InvalidOffset ,
#[ error( " Invalid ArrayBuffer pointer, pointer is null " ) ]
InvalidArrayBuffer ,
#[ error( " Destination length is smaller than source length " ) ]
DestinationLengthTooShort ,
#[ error( " Invalid CString pointer, pointer is null " ) ]
InvalidCString ,
#[ error( " Invalid CString pointer, string exceeds max length " ) ]
CStringTooLong ,
#[ error( " Invalid bool pointer, pointer is null " ) ]
InvalidBool ,
#[ error( " Invalid u8 pointer, pointer is null " ) ]
InvalidU8 ,
#[ error( " Invalid i8 pointer, pointer is null " ) ]
InvalidI8 ,
#[ error( " Invalid u16 pointer, pointer is null " ) ]
InvalidU16 ,
#[ error( " Invalid i16 pointer, pointer is null " ) ]
InvalidI16 ,
#[ error( " Invalid u32 pointer, pointer is null " ) ]
InvalidU32 ,
#[ error( " Invalid i32 pointer, pointer is null " ) ]
InvalidI32 ,
#[ error( " Invalid u64 pointer, pointer is null " ) ]
InvalidU64 ,
#[ error( " Invalid i64 pointer, pointer is null " ) ]
InvalidI64 ,
#[ error( " Invalid f32 pointer, pointer is null " ) ]
InvalidF32 ,
#[ error( " Invalid f64 pointer, pointer is null " ) ]
InvalidF64 ,
#[ error( " Invalid pointer pointer, pointer is null " ) ]
InvalidPointer ,
#[ error(transparent) ]
2024-11-04 12:17:21 -05:00
Permission ( #[ from ] deno_permissions ::PermissionCheckError ) ,
2024-10-14 18:05:49 -04:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2023-10-05 09:35:21 -04:00
pub fn op_ffi_ptr_create < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-10-05 09:35:21 -04:00
#[ bigint ] ptr_number : usize ,
2024-10-14 18:05:49 -04:00
) -> Result < * mut c_void , ReprError >
2023-02-22 12:32:38 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2023-02-22 12:32:38 -05:00
Ok ( ptr_number as * mut c_void )
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2023-02-22 12:32:38 -05:00
pub fn op_ffi_ptr_equals < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
a : * const c_void ,
b : * const c_void ,
2024-10-14 18:05:49 -04:00
) -> Result < bool , ReprError >
2023-02-22 12:32:38 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2023-02-22 12:32:38 -05:00
Ok ( a = = b )
}
2024-11-20 16:24:04 -05:00
#[ op2(stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_ptr_of < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-10-08 01:02:07 -04:00
#[ anybuffer ] buf : * const u8 ,
2024-10-14 18:05:49 -04:00
) -> Result < * mut c_void , ReprError >
2023-02-22 12:32:38 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2023-02-22 12:32:38 -05:00
Ok ( buf as * mut c_void )
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2023-10-05 09:35:21 -04:00
pub fn op_ffi_ptr_of_exact < FP > (
state : & mut OpState ,
buf : v8 ::Local < v8 ::ArrayBufferView > ,
2024-10-14 18:05:49 -04:00
) -> Result < * mut c_void , ReprError >
2023-10-05 09:35:21 -04:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2023-10-05 09:35:21 -04:00
let Some ( buf ) = buf . get_backing_store ( ) else {
return Ok ( 0 as _ ) ;
} ;
let Some ( buf ) = buf . data ( ) else {
return Ok ( 0 as _ ) ;
} ;
Ok ( buf . as_ptr ( ) as _ )
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2023-10-05 09:35:21 -04:00
pub fn op_ffi_ptr_offset < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < * mut c_void , ReprError >
2023-02-22 12:32:38 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2023-02-22 12:32:38 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidOffset ) ;
2023-02-22 12:32:38 -05:00
}
2023-10-05 09:35:21 -04:00
// TODO(mmastrac): Create a RawPointer that can safely do pointer math.
// SAFETY: Using `ptr.offset` is *actually unsafe* and has generated UB, but our FFI code relies on this working so we're going to
// try and ask the compiler to be less undefined here by using `ptr.wrapping_offset`.
Ok ( ptr . wrapping_offset ( offset ) )
2023-02-22 12:32:38 -05:00
}
unsafe extern " C " fn noop_deleter_callback (
_data : * mut c_void ,
_byte_length : usize ,
_deleter_data : * mut c_void ,
) {
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2024-05-29 22:30:11 -04:00
#[ bigint ]
2023-10-05 09:35:21 -04:00
pub fn op_ffi_ptr_value < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2024-10-14 18:05:49 -04:00
) -> Result < usize , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
2024-05-29 22:30:11 -04:00
Ok ( ptr as usize )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_get_buf < FP , ' scope > (
scope : & mut v8 ::HandleScope < ' scope > ,
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
#[ number ] len : usize ,
2024-10-14 18:05:49 -04:00
) -> Result < v8 ::Local < ' scope , v8 ::ArrayBuffer > , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidArrayBuffer ) ;
2022-12-12 09:14:20 -05:00
}
2023-02-22 12:32:38 -05:00
// SAFETY: Trust the user to have provided a real pointer, offset, and a valid matching size to it. Since this is a foreign pointer, we should not do any deletion.
2022-12-12 09:14:20 -05:00
let backing_store = unsafe {
v8 ::ArrayBuffer ::new_backing_store_from_ptr (
2023-02-22 12:32:38 -05:00
ptr . offset ( offset ) ,
2022-12-12 09:14:20 -05:00
len ,
noop_deleter_callback ,
2024-10-14 18:05:49 -04:00
ptr ::null_mut ( ) ,
2022-12-12 09:14:20 -05:00
)
}
. make_shared ( ) ;
2023-10-05 09:35:21 -04:00
let array_buffer = v8 ::ArrayBuffer ::with_backing_store ( scope , & backing_store ) ;
Ok ( array_buffer )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_buf_copy_into < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
src : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2023-10-28 03:02:57 -04:00
#[ anybuffer ] dst : & mut [ u8 ] ,
2023-10-05 09:35:21 -04:00
#[ number ] len : usize ,
2024-10-14 18:05:49 -04:00
) -> Result < ( ) , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
2023-02-22 12:32:38 -05:00
if src . is_null ( ) {
2024-10-14 18:05:49 -04:00
Err ( ReprError ::InvalidArrayBuffer )
2023-02-22 12:32:38 -05:00
} else if dst . len ( ) < len {
2024-10-14 18:05:49 -04:00
Err ( ReprError ::DestinationLengthTooShort )
2022-12-12 09:14:20 -05:00
} else {
let src = src as * const c_void ;
2023-02-22 12:32:38 -05:00
// SAFETY: src and offset are user defined.
2022-12-12 09:14:20 -05:00
// dest is properly aligned and is valid for writes of len * size_of::<T>() bytes.
2023-02-22 12:32:38 -05:00
unsafe {
ptr ::copy ::< u8 > ( src . offset ( offset ) as * const u8 , dst . as_mut_ptr ( ) , len )
} ;
2022-12-12 09:14:20 -05:00
Ok ( ( ) )
}
}
2024-11-20 16:24:04 -05:00
#[ op2(stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_cstr_read < FP , ' scope > (
scope : & mut v8 ::HandleScope < ' scope > ,
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < v8 ::Local < ' scope , v8 ::String > , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidCString ) ;
2022-12-12 09:14:20 -05:00
}
2023-02-22 12:32:38 -05:00
let cstr =
// SAFETY: Pointer and offset are user provided.
unsafe { CStr ::from_ptr ( ptr . offset ( offset ) as * const c_char ) } . to_bytes ( ) ;
2023-10-05 09:35:21 -04:00
let value = v8 ::String ::new_from_utf8 ( scope , cstr , v8 ::NewStringType ::Normal )
2024-10-14 18:05:49 -04:00
. ok_or_else ( | | ReprError ::CStringTooLong ) ? ;
2023-10-05 09:35:21 -04:00
Ok ( value )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_bool < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < bool , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidBool ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe { ptr ::read_unaligned ::< bool > ( ptr . offset ( offset ) as * const bool ) } )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_u8 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < u32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidU8 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe {
ptr ::read_unaligned ::< u8 > ( ptr . offset ( offset ) as * const u8 ) as u32
} )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_i8 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < i32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidI8 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe {
ptr ::read_unaligned ::< i8 > ( ptr . offset ( offset ) as * const i8 ) as i32
} )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_u16 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < u32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidU16 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
Ok ( unsafe {
2023-02-22 12:32:38 -05:00
ptr ::read_unaligned ::< u16 > ( ptr . offset ( offset ) as * const u16 ) as u32
2022-12-12 09:14:20 -05:00
} )
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_i16 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < i32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidI16 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
Ok ( unsafe {
2023-02-22 12:32:38 -05:00
ptr ::read_unaligned ::< i16 > ( ptr . offset ( offset ) as * const i16 ) as i32
2022-12-12 09:14:20 -05:00
} )
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_u32 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < u32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidU32 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe { ptr ::read_unaligned ::< u32 > ( ptr . offset ( offset ) as * const u32 ) } )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_i32 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < i32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidI32 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe { ptr ::read_unaligned ::< i32 > ( ptr . offset ( offset ) as * const i32 ) } )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2024-05-29 22:30:11 -04:00
#[ bigint ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_u64 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2024-05-29 22:30:11 -04:00
// Note: The representation of 64-bit integers is function-wide. We cannot
// choose to take this parameter as a number while returning a bigint.
#[ bigint ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < u64 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidU64 ) ;
2022-12-12 09:14:20 -05:00
}
let value =
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
unsafe { ptr ::read_unaligned ::< u64 > ( ptr . offset ( offset ) as * const u64 ) } ;
2022-12-12 09:14:20 -05:00
2024-05-29 22:30:11 -04:00
Ok ( value )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2024-05-29 22:30:11 -04:00
#[ bigint ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_i64 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2024-05-29 22:30:11 -04:00
// Note: The representation of 64-bit integers is function-wide. We cannot
// choose to take this parameter as a number while returning a bigint.
#[ bigint ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < i64 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidI64 ) ;
2022-12-12 09:14:20 -05:00
}
let value =
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
unsafe { ptr ::read_unaligned ::< i64 > ( ptr . offset ( offset ) as * const i64 ) } ;
2022-12-12 09:14:20 -05:00
// SAFETY: Length and alignment of out slice were asserted to be correct.
2024-05-29 22:30:11 -04:00
Ok ( value )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_f32 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < f32 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidF32 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe { ptr ::read_unaligned ::< f32 > ( ptr . offset ( offset ) as * const f32 ) } )
2022-12-12 09:14:20 -05:00
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2022-12-12 09:14:20 -05:00
pub fn op_ffi_read_f64 < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < f64 , ReprError >
2022-12-12 09:14:20 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2022-12-12 09:14:20 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidF64 ) ;
2022-12-12 09:14:20 -05:00
}
// SAFETY: ptr and offset are user provided.
2023-02-22 12:32:38 -05:00
Ok ( unsafe { ptr ::read_unaligned ::< f64 > ( ptr . offset ( offset ) as * const f64 ) } )
}
2024-11-20 16:24:04 -05:00
#[ op2(fast, stack_trace) ]
2023-02-22 12:32:38 -05:00
pub fn op_ffi_read_ptr < FP > (
2023-02-28 01:26:48 -05:00
state : & mut OpState ,
2023-02-22 12:32:38 -05:00
ptr : * mut c_void ,
2023-10-05 09:35:21 -04:00
#[ number ] offset : isize ,
2024-10-14 18:05:49 -04:00
) -> Result < * mut c_void , ReprError >
2023-02-22 12:32:38 -05:00
where
FP : FfiPermissions + 'static ,
{
let permissions = state . borrow_mut ::< FP > ( ) ;
2024-11-04 12:17:21 -05:00
permissions . check_partial_no_path ( ) ? ;
2023-02-22 12:32:38 -05:00
if ptr . is_null ( ) {
2024-10-14 18:05:49 -04:00
return Err ( ReprError ::InvalidPointer ) ;
2023-02-22 12:32:38 -05:00
}
// SAFETY: ptr and offset are user provided.
Ok ( unsafe {
ptr ::read_unaligned ::< * mut c_void > ( ptr . offset ( offset ) as * const * mut c_void )
} )
2022-12-12 09:14:20 -05:00
}