summaryrefslogtreecommitdiff
path: root/ext/ffi/lib.rs
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-08-23 09:16:43 +0530
committerGitHub <noreply@github.com>2022-08-23 09:16:43 +0530
commite34260c5b05f2a93f695d807b7cb54a50605885e (patch)
tree3dac23f50bcc9bc86e85497e707a0a5c07b73df7 /ext/ffi/lib.rs
parentd0c54777311d2cc30b824f397b7541dca80875fa (diff)
BREAKING(ext/ffi): specialized `buffer` type (#15518)
Diffstat (limited to 'ext/ffi/lib.rs')
-rw-r--r--ext/ffi/lib.rs93
1 files changed, 64 insertions, 29 deletions
diff --git a/ext/ffi/lib.rs b/ext/ffi/lib.rs
index 1d400069e..70591411a 100644
--- a/ext/ffi/lib.rs
+++ b/ext/ffi/lib.rs
@@ -266,6 +266,7 @@ enum NativeType {
F32,
F64,
Pointer,
+ Buffer,
Function,
}
@@ -285,8 +286,9 @@ impl From<NativeType> for libffi::middle::Type {
NativeType::ISize => libffi::middle::Type::isize(),
NativeType::F32 => libffi::middle::Type::f32(),
NativeType::F64 => libffi::middle::Type::f64(),
- NativeType::Pointer => libffi::middle::Type::pointer(),
- NativeType::Function => libffi::middle::Type::pointer(),
+ NativeType::Pointer | NativeType::Buffer | NativeType::Function => {
+ libffi::middle::Type::pointer()
+ }
}
}
}
@@ -327,7 +329,9 @@ impl NativeValue {
NativeType::ISize => Arg::new(&self.isize_value),
NativeType::F32 => Arg::new(&self.f32_value),
NativeType::F64 => Arg::new(&self.f64_value),
- NativeType::Pointer | NativeType::Function => Arg::new(&self.pointer),
+ NativeType::Pointer | NativeType::Buffer | NativeType::Function => {
+ Arg::new(&self.pointer)
+ }
}
}
@@ -375,7 +379,7 @@ impl NativeValue {
}
NativeType::F32 => Value::from(self.f32_value),
NativeType::F64 => Value::from(self.f64_value),
- NativeType::Pointer | NativeType::Function => {
+ NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
let value = self.pointer as usize;
if value > MAX_SAFE_INTEGER as usize {
json!(U32x2::from(value as u64))
@@ -479,7 +483,7 @@ impl NativeValue {
v8::Number::new(scope, self.f64_value).into();
local_value.into()
}
- NativeType::Pointer | NativeType::Function => {
+ NativeType::Pointer | NativeType::Buffer | NativeType::Function => {
let value = self.pointer as u64;
let local_value: v8::Local<v8::Value> =
if value > MAX_SAFE_INTEGER as u64 {
@@ -751,8 +755,10 @@ impl From<&NativeType> for fast_api::Type {
NativeType::I64 => fast_api::Type::Int64,
NativeType::U64 => fast_api::Type::Uint64,
NativeType::ISize => fast_api::Type::Int64,
- NativeType::USize | NativeType::Function => fast_api::Type::Uint64,
- NativeType::Pointer => fast_api::Type::TypedArray(fast_api::CType::Uint8),
+ NativeType::USize | NativeType::Pointer | NativeType::Function => {
+ fast_api::Type::Uint64
+ }
+ NativeType::Buffer => fast_api::Type::TypedArray(fast_api::CType::Uint8),
}
}
}
@@ -762,6 +768,7 @@ fn needs_unwrap(rv: NativeType) -> bool {
rv,
NativeType::Function
| NativeType::Pointer
+ | NativeType::Buffer
| NativeType::I64
| NativeType::ISize
| NativeType::U64
@@ -1064,14 +1071,37 @@ fn ffi_parse_pointer_arg(
arg: v8::Local<v8::Value>,
) -> Result<NativeValue, AnyError> {
// Order of checking:
- // 1. ArrayBufferView: Common and not supported by Fast API, optimise this case.
- // 2. BigInt: Uncommon and not supported by Fast API, optimise this case as second.
- // 3. Number: Common and supported by Fast API, optimise the common case third.
- // 4. ArrayBuffer: Fairly common and not supported by Fast API.
+ // 1. BigInt: Uncommon and not supported by Fast API, optimise this case.
+ // 2. Number: Common and supported by Fast API.
+ // 3. Null: Very uncommon / can be represented by a 0.
+ let pointer = if let Ok(value) = v8::Local::<v8::BigInt>::try_from(arg) {
+ value.u64_value().0 as usize as *const u8
+ } else if let Ok(value) = v8::Local::<v8::Number>::try_from(arg) {
+ value.integer_value(scope).unwrap() as usize as *const u8
+ } else if arg.is_null() {
+ ptr::null()
+ } else {
+ return Err(type_error(
+ "Invalid FFI pointer type, expected null, integer or BigInt",
+ ));
+ };
+ Ok(NativeValue { pointer })
+}
+
+#[inline]
+fn ffi_parse_buffer_arg(
+ scope: &mut v8::HandleScope,
+ arg: v8::Local<v8::Value>,
+) -> Result<NativeValue, AnyError> {
+ // Order of checking:
+ // 1. ArrayBuffer: Fairly common and not supported by Fast API, optimise this case.
+ // 2. ArrayBufferView: Common and supported by Fast API
// 5. Null: Very uncommon / can be represented by a 0.
- let pointer = if let Ok(value) =
- v8::Local::<v8::ArrayBufferView>::try_from(arg)
- {
+
+ let pointer = if let Ok(value) = v8::Local::<v8::ArrayBuffer>::try_from(arg) {
+ let backing_store = value.get_backing_store();
+ &backing_store[..] as *const _ as *const u8
+ } else if let Ok(value) = v8::Local::<v8::ArrayBufferView>::try_from(arg) {
let byte_offset = value.byte_offset();
let backing_store = value
.buffer(scope)
@@ -1080,17 +1110,12 @@ fn ffi_parse_pointer_arg(
})?
.get_backing_store();
&backing_store[byte_offset..] as *const _ as *const u8
- } else if let Ok(value) = v8::Local::<v8::BigInt>::try_from(arg) {
- value.u64_value().0 as usize as *const u8
- } else if let Ok(value) = v8::Local::<v8::Number>::try_from(arg) {
- value.integer_value(scope).unwrap() as usize as *const u8
- } else if let Ok(value) = v8::Local::<v8::ArrayBuffer>::try_from(arg) {
- let backing_store = value.get_backing_store();
- &backing_store[..] as *const _ as *const u8
} else if arg.is_null() {
ptr::null()
} else {
- return Err(type_error("Invalid FFI pointer type, expected null, integer, BigInt, ArrayBuffer, or ArrayBufferView"));
+ return Err(type_error(
+ "Invalid FFI buffer type, expected null, ArrayBuffer, or ArrayBufferView",
+ ));
};
Ok(NativeValue { pointer })
}
@@ -1174,6 +1199,9 @@ where
NativeType::F64 => {
ffi_args.push(ffi_parse_f64_arg(value)?);
}
+ NativeType::Buffer => {
+ ffi_args.push(ffi_parse_buffer_arg(scope, value)?);
+ }
NativeType::Pointer => {
ffi_args.push(ffi_parse_pointer_arg(scope, value)?);
}
@@ -1247,6 +1275,9 @@ where
NativeType::F64 => {
ffi_args.push(ffi_parse_f64_arg(value)?);
}
+ NativeType::Buffer => {
+ ffi_args.push(ffi_parse_buffer_arg(scope, value)?);
+ }
NativeType::Pointer => {
ffi_args.push(ffi_parse_pointer_arg(scope, value)?);
}
@@ -1302,9 +1333,11 @@ where
NativeType::F64 => NativeValue {
f64_value: cif.call::<f64>(*fun_ptr, &call_args),
},
- NativeType::Pointer | NativeType::Function => NativeValue {
- pointer: cif.call::<*const u8>(*fun_ptr, &call_args),
- },
+ NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
+ NativeValue {
+ pointer: cif.call::<*const u8>(*fun_ptr, &call_args),
+ }
+ }
})
}
}
@@ -1368,9 +1401,11 @@ fn ffi_call(
NativeType::F64 => NativeValue {
f64_value: cif.call::<f64>(fun_ptr, &call_args),
},
- NativeType::Pointer | NativeType::Function => NativeValue {
- pointer: cif.call::<*const u8>(fun_ptr, &call_args),
- },
+ NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
+ NativeValue {
+ pointer: cif.call::<*const u8>(fun_ptr, &call_args),
+ }
+ }
})
}
}
@@ -2004,7 +2039,7 @@ fn op_ffi_get_static<'scope>(
let number: v8::Local<v8::Value> = v8::Number::new(scope, result).into();
number.into()
}
- NativeType::Pointer | NativeType::Function => {
+ NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
let result = data_ptr as u64;
let integer: v8::Local<v8::Value> = if result > MAX_SAFE_INTEGER as u64 {
v8::BigInt::new_from_u64(scope, result).into()