1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-23 07:44:48 -05:00

fix(ext/ffi): Invalid 'function' return type check logic, remove U32x2 as unnecessary (#16259)

The return type checking for `"function"` type FFI values was incorrect
and presumed that functions were still being registered as objects
containing a "function" key.

While here, I also removed the whole return type checking logic as it
was needed for optionally creating BigInts on return when needed, but
serde_v8 does this automatically now (I think).
This commit is contained in:
Aapo Alasuutari 2022-10-13 15:06:52 +03:00 committed by GitHub
parent fda24b54e9
commit 17271532d4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 116 deletions

View file

@ -13,7 +13,6 @@
NumberIsSafeInteger,
ArrayPrototypeJoin,
ObjectPrototypeIsPrototypeOf,
PromisePrototypeThen,
TypeError,
Int32Array,
Uint32Array,
@ -21,23 +20,6 @@
Function,
} = window.__bootstrap.primordials;
function unpackU64(returnValue) {
if (typeof returnValue === "number") {
return returnValue;
}
const [hi, lo] = returnValue;
return BigInt(hi) << 32n | BigInt(lo);
}
function unpackI64(returnValue) {
if (typeof returnValue === "number") {
return returnValue;
}
const [hi, lo] = returnValue;
const u64 = unpackU64([hi, lo]);
return u64 >> 63n ? u64 - 0x10000000000000000n : u64;
}
class UnsafePointerView {
pointer;
@ -163,25 +145,6 @@
}
}
function unpackNonblockingReturnValue(type, result) {
if (
typeof type === "object" && type !== null && "function" in type ||
type === "pointer"
) {
return unpackU64(result);
}
switch (type) {
case "isize":
case "i64":
return unpackI64(result);
case "usize":
case "u64":
return unpackU64(result);
default:
return result;
}
}
class UnsafeFnPointer {
pointer;
definition;
@ -192,25 +155,13 @@
}
call(...parameters) {
const resultType = this.definition.result;
if (this.definition.nonblocking) {
const promise = core.opAsync(
return core.opAsync(
"op_ffi_call_ptr_nonblocking",
this.pointer,
this.definition,
parameters,
);
if (
isReturnedAsBigInt(resultType)
) {
return PromisePrototypeThen(
promise,
(result) => unpackNonblockingReturnValue(resultType, result),
);
}
return promise;
} else {
return ops.op_ffi_call_ptr(
this.pointer,
@ -221,13 +172,9 @@
}
}
function isPointerType(type) {
return type === "buffer" || type === "pointer" ||
typeof type === "object" && type !== null && "function" in type;
}
function isReturnedAsBigInt(type) {
return isPointerType(type) || type === "u64" || type === "i64" ||
return type === "buffer" || type === "pointer" || type === "function" ||
type === "u64" || type === "i64" ||
type === "usize" || type === "isize";
}
@ -329,22 +276,12 @@
configurable: false,
enumerable: true,
value: (...parameters) => {
const promise = core.opAsync(
return core.opAsync(
"op_ffi_call_nonblocking",
this.#rid,
symbol,
parameters,
);
if (needsUnpacking) {
return PromisePrototypeThen(
promise,
(result) =>
unpackNonblockingReturnValue(resultType, result),
);
}
return promise;
},
writable: false,
},

View file

@ -10,7 +10,6 @@ use deno_core::futures::channel::mpsc;
use deno_core::futures::Future;
use deno_core::include_js_files;
use deno_core::op;
use deno_core::serde_json::json;
use deno_core::serde_json::Value;
use deno_core::serde_v8;
use deno_core::v8;
@ -22,7 +21,6 @@ use dlopen::raw::Library;
use libffi::middle::Arg;
use libffi::middle::Cif;
use serde::Deserialize;
use serde::Serialize;
use std::borrow::Cow;
use std::cell::RefCell;
use std::collections::HashMap;
@ -341,47 +339,14 @@ impl NativeValue {
NativeType::I16 => Value::from(self.i16_value),
NativeType::U32 => Value::from(self.u32_value),
NativeType::I32 => Value::from(self.i32_value),
NativeType::U64 => {
let value = self.u64_value;
if value > MAX_SAFE_INTEGER as u64 {
json!(U32x2::from(self.u64_value))
} else {
Value::from(value)
}
}
NativeType::I64 => {
let value = self.i64_value;
if value > MAX_SAFE_INTEGER as i64 || value < MIN_SAFE_INTEGER as i64 {
json!(U32x2::from(self.i64_value as u64))
} else {
Value::from(value)
}
}
NativeType::USize => {
let value = self.usize_value;
if value > MAX_SAFE_INTEGER as usize {
json!(U32x2::from(self.usize_value as u64))
} else {
Value::from(value)
}
}
NativeType::ISize => {
let value = self.isize_value;
if !(MIN_SAFE_INTEGER..=MAX_SAFE_INTEGER).contains(&value) {
json!(U32x2::from(self.isize_value as u64))
} else {
Value::from(value)
}
}
NativeType::U64 => Value::from(self.u64_value),
NativeType::I64 => Value::from(self.i64_value),
NativeType::USize => Value::from(self.usize_value),
NativeType::ISize => Value::from(self.isize_value),
NativeType::F32 => Value::from(self.f32_value),
NativeType::F64 => Value::from(self.f64_value),
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))
} else {
Value::from(value)
}
Value::from(self.pointer as usize)
}
}
}
@ -501,15 +466,6 @@ impl NativeValue {
// SAFETY: unsafe trait must have unsafe implementation
unsafe impl Send for NativeValue {}
#[derive(Serialize, Debug, Clone, Copy)]
struct U32x2(u32, u32);
impl From<u64> for U32x2 {
fn from(value: u64) -> Self {
Self((value >> 32) as u32, value as u32)
}
}
#[derive(Deserialize, Debug)]
#[serde(rename_all = "camelCase")]
struct ForeignFunction {