mirror of
https://github.com/denoland/deno.git
synced 2025-03-03 17:34:47 -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:
parent
fda24b54e9
commit
17271532d4
2 changed files with 9 additions and 116 deletions
|
@ -13,7 +13,6 @@
|
||||||
NumberIsSafeInteger,
|
NumberIsSafeInteger,
|
||||||
ArrayPrototypeJoin,
|
ArrayPrototypeJoin,
|
||||||
ObjectPrototypeIsPrototypeOf,
|
ObjectPrototypeIsPrototypeOf,
|
||||||
PromisePrototypeThen,
|
|
||||||
TypeError,
|
TypeError,
|
||||||
Int32Array,
|
Int32Array,
|
||||||
Uint32Array,
|
Uint32Array,
|
||||||
|
@ -21,23 +20,6 @@
|
||||||
Function,
|
Function,
|
||||||
} = window.__bootstrap.primordials;
|
} = 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 {
|
class UnsafePointerView {
|
||||||
pointer;
|
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 {
|
class UnsafeFnPointer {
|
||||||
pointer;
|
pointer;
|
||||||
definition;
|
definition;
|
||||||
|
@ -192,25 +155,13 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
call(...parameters) {
|
call(...parameters) {
|
||||||
const resultType = this.definition.result;
|
|
||||||
if (this.definition.nonblocking) {
|
if (this.definition.nonblocking) {
|
||||||
const promise = core.opAsync(
|
return core.opAsync(
|
||||||
"op_ffi_call_ptr_nonblocking",
|
"op_ffi_call_ptr_nonblocking",
|
||||||
this.pointer,
|
this.pointer,
|
||||||
this.definition,
|
this.definition,
|
||||||
parameters,
|
parameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (
|
|
||||||
isReturnedAsBigInt(resultType)
|
|
||||||
) {
|
|
||||||
return PromisePrototypeThen(
|
|
||||||
promise,
|
|
||||||
(result) => unpackNonblockingReturnValue(resultType, result),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
} else {
|
} else {
|
||||||
return ops.op_ffi_call_ptr(
|
return ops.op_ffi_call_ptr(
|
||||||
this.pointer,
|
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) {
|
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";
|
type === "usize" || type === "isize";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,22 +276,12 @@
|
||||||
configurable: false,
|
configurable: false,
|
||||||
enumerable: true,
|
enumerable: true,
|
||||||
value: (...parameters) => {
|
value: (...parameters) => {
|
||||||
const promise = core.opAsync(
|
return core.opAsync(
|
||||||
"op_ffi_call_nonblocking",
|
"op_ffi_call_nonblocking",
|
||||||
this.#rid,
|
this.#rid,
|
||||||
symbol,
|
symbol,
|
||||||
parameters,
|
parameters,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (needsUnpacking) {
|
|
||||||
return PromisePrototypeThen(
|
|
||||||
promise,
|
|
||||||
(result) =>
|
|
||||||
unpackNonblockingReturnValue(resultType, result),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return promise;
|
|
||||||
},
|
},
|
||||||
writable: false,
|
writable: false,
|
||||||
},
|
},
|
||||||
|
|
|
@ -10,7 +10,6 @@ use deno_core::futures::channel::mpsc;
|
||||||
use deno_core::futures::Future;
|
use deno_core::futures::Future;
|
||||||
use deno_core::include_js_files;
|
use deno_core::include_js_files;
|
||||||
use deno_core::op;
|
use deno_core::op;
|
||||||
use deno_core::serde_json::json;
|
|
||||||
use deno_core::serde_json::Value;
|
use deno_core::serde_json::Value;
|
||||||
use deno_core::serde_v8;
|
use deno_core::serde_v8;
|
||||||
use deno_core::v8;
|
use deno_core::v8;
|
||||||
|
@ -22,7 +21,6 @@ use dlopen::raw::Library;
|
||||||
use libffi::middle::Arg;
|
use libffi::middle::Arg;
|
||||||
use libffi::middle::Cif;
|
use libffi::middle::Cif;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use serde::Serialize;
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -341,47 +339,14 @@ impl NativeValue {
|
||||||
NativeType::I16 => Value::from(self.i16_value),
|
NativeType::I16 => Value::from(self.i16_value),
|
||||||
NativeType::U32 => Value::from(self.u32_value),
|
NativeType::U32 => Value::from(self.u32_value),
|
||||||
NativeType::I32 => Value::from(self.i32_value),
|
NativeType::I32 => Value::from(self.i32_value),
|
||||||
NativeType::U64 => {
|
NativeType::U64 => Value::from(self.u64_value),
|
||||||
let value = self.u64_value;
|
NativeType::I64 => Value::from(self.i64_value),
|
||||||
if value > MAX_SAFE_INTEGER as u64 {
|
NativeType::USize => Value::from(self.usize_value),
|
||||||
json!(U32x2::from(self.u64_value))
|
NativeType::ISize => Value::from(self.isize_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::F32 => Value::from(self.f32_value),
|
NativeType::F32 => Value::from(self.f32_value),
|
||||||
NativeType::F64 => Value::from(self.f64_value),
|
NativeType::F64 => Value::from(self.f64_value),
|
||||||
NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
|
NativeType::Pointer | NativeType::Function | NativeType::Buffer => {
|
||||||
let value = self.pointer as usize;
|
Value::from(self.pointer as usize)
|
||||||
if value > MAX_SAFE_INTEGER as usize {
|
|
||||||
json!(U32x2::from(value as u64))
|
|
||||||
} else {
|
|
||||||
Value::from(value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -501,15 +466,6 @@ impl NativeValue {
|
||||||
// SAFETY: unsafe trait must have unsafe implementation
|
// SAFETY: unsafe trait must have unsafe implementation
|
||||||
unsafe impl Send for NativeValue {}
|
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)]
|
#[derive(Deserialize, Debug)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
struct ForeignFunction {
|
struct ForeignFunction {
|
||||||
|
|
Loading…
Add table
Reference in a new issue