diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2022-06-20 19:08:10 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-20 19:08:10 +0530 |
commit | 354fa6cd0013aeca9f0749822b3ef3050c764370 (patch) | |
tree | ef860e48149850afa2a785b4e9b95f04c668bd44 /ext/ffi/00_ffi.js | |
parent | 79b42808a474c0a049ae17a3b6b1f93ad83d217b (diff) |
BREAKING(ext/ffi): Remove `Deno.UnsafePointer` indirection (#14915)
Diffstat (limited to 'ext/ffi/00_ffi.js')
-rw-r--r-- | ext/ffi/00_ffi.js | 263 |
1 files changed, 27 insertions, 236 deletions
diff --git a/ext/ffi/00_ffi.js b/ext/ffi/00_ffi.js index d29e83fce..190873307 100644 --- a/ext/ffi/00_ffi.js +++ b/ext/ffi/00_ffi.js @@ -5,12 +5,7 @@ const core = window.Deno.core; const __bootstrap = window.__bootstrap; const { - ArrayBufferPrototype, - ArrayPrototypePush, - ArrayPrototypeSome, BigInt, - NumberIsFinite, - NumberIsInteger, ObjectDefineProperty, ObjectPrototypeIsPrototypeOf, PromisePrototypeThen, @@ -37,77 +32,77 @@ getUint8(offset = 0) { return core.opSync( "op_ffi_read_u8", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getInt8(offset = 0) { return core.opSync( "op_ffi_read_i8", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getUint16(offset = 0) { return core.opSync( "op_ffi_read_u16", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getInt16(offset = 0) { return core.opSync( "op_ffi_read_i16", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getUint32(offset = 0) { return core.opSync( "op_ffi_read_u32", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getInt32(offset = 0) { return core.opSync( "op_ffi_read_i32", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getBigUint64(offset = 0) { return core.opSync( "op_ffi_read_u64", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getBigInt64(offset = 0) { return core.opSync( "op_ffi_read_u64", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getFloat32(offset = 0) { return core.opSync( "op_ffi_read_f32", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getFloat64(offset = 0) { return core.opSync( "op_ffi_read_f64", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } getCString(offset = 0) { return core.opSync( "op_ffi_cstr_read", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), ); } @@ -120,7 +115,7 @@ copyInto(destination, offset = 0) { core.opSync( "op_ffi_buf_copy_into", - this.pointer.value + BigInt(offset), + this.pointer + BigInt(offset), destination, destination.byteLength, ); @@ -128,133 +123,20 @@ } class UnsafePointer { - value; - - constructor(value) { - if (typeof value === "number") { - value = BigInt(value); + static of(value) { + if (ObjectPrototypeIsPrototypeOf(UnsafeCallbackPrototype, value)) { + return value.pointer; } - this.value = value; - } - - static of(typedArray) { - return new UnsafePointer( - core.opSync("op_ffi_ptr_of", typedArray), - ); - } - - valueOf() { - return this.value; + return core.opSync("op_ffi_ptr_of", value); } } - const UnsafePointerPrototype = UnsafePointer.prototype; - - function prepareArgs(types, args) { - const parameters = []; - - if (types.length !== args.length) { - throw new TypeError("Invalid FFI call, parameter vs args count mismatch"); - } - - for (let i = 0; i < types.length; i++) { - const type = types[i]; - const arg = args[i]; - - if (type === "u8" || type === "u16" || type === "u32") { - if (!NumberIsInteger(arg) || arg < 0) { - throw new TypeError( - `Expected FFI argument to be an unsigned integer, but got '${arg}'`, - ); - } - ArrayPrototypePush(parameters, arg); - } else if (type === "i8" || type === "i16" || type === "i32") { - if (!NumberIsInteger(arg)) { - throw new TypeError( - `Expected FFI argument to be a signed integer, but got '${arg}'`, - ); - } - ArrayPrototypePush(parameters, arg); - } else if (type === "u64" || type === "usize") { - if ( - !(NumberIsInteger(arg) && arg >= 0 || - typeof arg === "bigint" && 0n <= arg && arg <= 0xffffffffffffffffn) - ) { - throw new TypeError( - `Expected FFI argument to be an unsigned integer, but got '${arg}'`, - ); - } - ArrayPrototypePush(parameters, arg); - } else if (type == "i64" || type === "isize") { - if ( - !(NumberIsInteger(arg) || - typeof arg === "bigint" && -1n * 2n ** 63n <= arg && - arg <= 2n ** 63n - 1n) - ) { - throw new TypeError( - `Expected FFI argument to be a signed integer, but got '${arg}'`, - ); - } - ArrayPrototypePush(parameters, arg); - } else if (type === "f32" || type === "f64") { - if (!NumberIsFinite(arg)) { - throw new TypeError( - `Expected FFI argument to be a number, but got '${arg}'`, - ); - } - ArrayPrototypePush(parameters, arg); - } else if (type === "pointer") { - if ( - ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, arg?.buffer) && - arg.byteLength !== undefined - ) { - ArrayPrototypePush(parameters, arg); - } else if (ObjectPrototypeIsPrototypeOf(UnsafePointerPrototype, arg)) { - ArrayPrototypePush(parameters, arg.value); - } else if (arg === null) { - ArrayPrototypePush(parameters, null); - } else { - throw new TypeError( - "Expected FFI argument to be TypedArray, UnsafePointer or null", - ); - } - } else if ( - typeof type === "object" && type !== null && "function" in type - ) { - if (ObjectPrototypeIsPrototypeOf(UnsafeCallbackPrototype, arg)) { - // Own registered callback, pass the pointer value - ArrayPrototypePush(parameters, arg.pointer.value); - } else if (arg === null) { - // nullptr - ArrayPrototypePush(parameters, null); - } else if ( - ObjectPrototypeIsPrototypeOf(UnsafeFnPointerPrototype, arg) - ) { - // Foreign function, pass the pointer value - ArrayPrototypePush(parameters, arg.pointer.value); - } else if ( - ObjectPrototypeIsPrototypeOf(UnsafePointerPrototype, arg) - ) { - // Foreign function, pass the pointer value - ArrayPrototypePush(parameters, arg.value); - } else { - throw new TypeError( - "Expected FFI argument to be UnsafeCallback, UnsafeFnPointer, UnsafePointer or null", - ); - } - } else { - throw new TypeError(`Invalid FFI argument type '${type}'`); - } - } - - return parameters; - } function unpackNonblockingReturnValue(type, result) { if ( typeof type === "object" && type !== null && "function" in type || type === "pointer" ) { - return new UnsafePointer(unpackU64(result)); + return unpackU64(result); } switch (type) { case "isize": @@ -277,16 +159,12 @@ this.definition = definition; } - call(...args) { - const parameters = prepareArgs( - this.definition.parameters, - args, - ); + call(...parameters) { const resultType = this.definition.result; if (this.definition.nonblocking) { const promise = core.opAsync( "op_ffi_call_ptr_nonblocking", - this.pointer.value, + this.pointer, this.definition, parameters, ); @@ -302,24 +180,16 @@ return promise; } else { - const result = core.opSync( + return core.opSync( "op_ffi_call_ptr", - this.pointer.value, + this.pointer, this.definition, parameters, ); - - if (isPointerType(resultType)) { - return new UnsafePointer(result); - } - - return result; } } } - const UnsafeFnPointerPrototype = UnsafeFnPointer.prototype; - function isPointerType(type) { return type === "pointer" || typeof type === "object" && type !== null && "function" in type; @@ -330,64 +200,8 @@ type === "usize" || type === "isize"; } - function prepareUnsafeCallbackParameters(types, args) { - const parameters = []; - if (types.length === 0) { - return parameters; - } - - for (let i = 0; i < types.length; i++) { - const type = types[i]; - const arg = args[i]; - ArrayPrototypePush( - parameters, - isPointerType(type) ? new UnsafePointer(arg) : arg, - ); - } - - return parameters; - } - - function unwrapUnsafeCallbackReturnValue(result) { - if ( - ObjectPrototypeIsPrototypeOf(UnsafePointerPrototype, result) - ) { - // Foreign function, return the pointer value - ArrayPrototypePush(parameters, result.value); - } else if ( - ObjectPrototypeIsPrototypeOf(UnsafeFnPointerPrototype, result) - ) { - // Foreign function, return the pointer value - ArrayPrototypePush(parameters, result.pointer.value); - } else if ( - ObjectPrototypeIsPrototypeOf(UnsafeCallbackPrototype, result) - ) { - // Own registered callback, return the pointer value. - // Note that returning the ResourceId here would not work as - // the Rust side code cannot access OpState to get the resource. - ArrayPrototypePush(parameters, result.pointer.value); - } - return result; - } - - function createInternalCallback(definition, callback) { - const mustUnwrap = isPointerType(definition.result); - return (...args) => { - const convertedArgs = prepareUnsafeCallbackParameters( - definition.parameters, - args, - ); - const result = callback(...convertedArgs); - if (mustUnwrap) { - return unwrapUnsafeCallbackReturnValue(result); - } - return result; - }; - } - class UnsafeCallback { #rid; - #internal; definition; callback; pointer; @@ -398,20 +212,13 @@ "Invalid UnsafeCallback, cannot be nonblocking", ); } - const needsWrapping = isPointerType(definition.result) || - ArrayPrototypeSome(definition.parameters, isPointerType); - const internalCallback = needsWrapping - ? createInternalCallback(definition, callback) - : callback; - const [rid, pointer] = core.opSync( "op_ffi_unsafe_callback_create", definition, - internalCallback, + callback, ); this.#rid = rid; - this.pointer = new UnsafePointer(pointer); - this.#internal = internalCallback; + this.pointer = pointer; this.definition = definition; this.callback = callback; } @@ -440,15 +247,12 @@ } const name = symbols[symbol].name || symbol; - let value = core.opSync( + const value = core.opSync( "op_ffi_get_static", this.#rid, name, type, ); - if (type === "pointer") { - value = new UnsafePointer(value); - } ObjectDefineProperty( this.symbols, symbol, @@ -463,15 +267,12 @@ } const isNonBlocking = symbols[symbol].nonblocking; - const types = symbols[symbol].parameters; const resultType = symbols[symbol].result; let fn; if (isNonBlocking) { const needsUnpacking = isReturnedAsBigInt(resultType); - fn = (...args) => { - const parameters = prepareArgs(types, args); - + fn = (...parameters) => { const promise = core.opAsync( "op_ffi_call_nonblocking", this.#rid, @@ -489,23 +290,13 @@ return promise; }; } else { - const mustWrap = isPointerType(resultType); - fn = (...args) => { - const parameters = prepareArgs(types, args); - - const result = core.opSync( + fn = (...parameters) => + core.opSync( "op_ffi_call", this.#rid, symbol, parameters, ); - - if (mustWrap) { - return new UnsafePointer(result); - } - - return result; - }; } ObjectDefineProperty( |