0
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2025-03-03 17:34:47 -05:00

BREAKING(ext/ffi): Remove Deno.UnsafePointer indirection (#14915)

This commit is contained in:
Divy Srivastava 2022-06-20 19:08:10 +05:30 committed by GitHub
parent 79b42808a4
commit 354fa6cd00
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 60 additions and 294 deletions

View file

@ -390,17 +390,14 @@ declare namespace Deno {
? void ? void
: T extends StaticNativeBigIntType ? bigint : T extends StaticNativeBigIntType ? bigint
: T extends StaticNativeNumberType ? number : T extends StaticNativeNumberType ? number
: T extends "pointer" ? UnsafePointer : T extends "pointer" ? bigint
: never; : never;
type StaticForeignFunctionParameter<T> = T extends "void" ? void type StaticForeignFunctionParameter<T> = T extends "void" ? void
: T extends StaticNativeNumberType | StaticNativeBigIntType : T extends StaticNativeNumberType | StaticNativeBigIntType
? number | bigint ? number | bigint
: T extends "pointer" ? UnsafePointer | TypedArray | null : T extends "pointer" ? bigint | TypedArray | null
: T extends NativeCallbackType< : T extends NativeCallbackType ? bigint | null
infer U extends readonly NativeType[],
infer V extends NativeParameterType
> ? UnsafeCallback<U, V> | UnsafePointer | null
: unknown; : unknown;
/** Infers a foreign function parameter list. */ /** Infers a foreign function parameter list. */
@ -449,19 +446,10 @@ declare namespace Deno {
* An unsafe pointer to a memory location for passing and returning pointers to and from the ffi * An unsafe pointer to a memory location for passing and returning pointers to and from the ffi
*/ */
export class UnsafePointer { export class UnsafePointer {
constructor(value: bigint);
value: bigint;
/** /**
* Return the direct memory pointer to the typed array in memory * Return the direct memory pointer to the typed array in memory
*/ */
static of(typedArray: TypedArray): UnsafePointer; static of(value: Deno.UnsafeCallback | TypedArray): bigint;
/**
* Returns the value of the pointer which is useful in certain scenarios.
*/
valueOf(): bigint;
} }
/** **UNSTABLE**: Unsafe and new API, beware! /** **UNSTABLE**: Unsafe and new API, beware!
@ -472,9 +460,9 @@ declare namespace Deno {
* (numbers, strings and raw bytes). * (numbers, strings and raw bytes).
*/ */
export class UnsafePointerView { export class UnsafePointerView {
constructor(pointer: UnsafePointer); constructor(pointer: bigint);
pointer: UnsafePointer; pointer: bigint;
/** Gets an unsigned 8-bit integer at the specified byte offset from the pointer. */ /** Gets an unsigned 8-bit integer at the specified byte offset from the pointer. */
getUint8(offset?: number): number; getUint8(offset?: number): number;
@ -511,10 +499,10 @@ declare namespace Deno {
* present as symbols. * present as symbols.
*/ */
export class UnsafeFnPointer<Fn extends ForeignFunction> { export class UnsafeFnPointer<Fn extends ForeignFunction> {
pointer: UnsafePointer; pointer: bigint;
definition: Fn; definition: Fn;
constructor(pointer: UnsafePointer, definition: Fn); constructor(pointer: bigint, definition: Fn);
call( call(
...args: StaticForeignFunctionParameters<Fn["parameters"]> ...args: StaticForeignFunctionParameters<Fn["parameters"]>
@ -552,18 +540,15 @@ declare namespace Deno {
type UnsafeCallbackParameter<T extends NativeType> = T extends type UnsafeCallbackParameter<T extends NativeType> = T extends
StaticNativeBigIntType ? bigint StaticNativeBigIntType ? bigint
: T extends StaticNativeNumberType ? number : T extends StaticNativeNumberType ? number
: T extends "pointer" ? UnsafePointer : T extends "pointer" ? bigint
: never; : never;
type UnsafeCallbackResult<T extends NativeParameterType> = T extends "void" type UnsafeCallbackResult<T extends NativeParameterType> = T extends "void"
? void ? void
: T extends StaticNativeBigIntType ? number | bigint : T extends StaticNativeBigIntType ? number | bigint
: T extends StaticNativeNumberType ? number : T extends StaticNativeNumberType ? number
: T extends "pointer" ? UnsafePointer | TypedArray | null : T extends "pointer" ? bigint | TypedArray | null
: T extends NativeCallbackType< : T extends NativeCallbackType ? bigint | null
infer U extends readonly NativeType[],
infer V extends NativeParameterType
> ? UnsafeCallback<U, V> | UnsafePointer | null
: never; : never;
type UnsafeCallbackFunction< type UnsafeCallbackFunction<
@ -594,7 +579,7 @@ declare namespace Deno {
callback: UnsafeCallbackFunction<Parameters, Result>, callback: UnsafeCallbackFunction<Parameters, Result>,
); );
pointer: UnsafePointer; pointer: bigint;
definition: UnsafeCallbackDefinition<Parameters, Result>; definition: UnsafeCallbackDefinition<Parameters, Result>;
callback: UnsafeCallbackFunction<Parameters, Result>; callback: UnsafeCallbackFunction<Parameters, Result>;

View file

@ -28,9 +28,8 @@ Deno.test({ permissions: { ffi: false } }, function ffiPermissionDenied() {
assertThrows(() => { assertThrows(() => {
Deno.dlopen("/usr/lib/libc.so.6", {}); Deno.dlopen("/usr/lib/libc.so.6", {});
}, Deno.errors.PermissionDenied); }, Deno.errors.PermissionDenied);
const ptr = new Deno.UnsafePointer(0n);
const fnptr = new Deno.UnsafeFnPointer( const fnptr = new Deno.UnsafeFnPointer(
ptr, 0n,
{ {
parameters: ["u32", "pointer"], parameters: ["u32", "pointer"],
result: "void", result: "void",
@ -42,7 +41,7 @@ Deno.test({ permissions: { ffi: false } }, function ffiPermissionDenied() {
assertThrows(() => { assertThrows(() => {
Deno.UnsafePointer.of(new Uint8Array(0)); Deno.UnsafePointer.of(new Uint8Array(0));
}, Deno.errors.PermissionDenied); }, Deno.errors.PermissionDenied);
const ptrView = new Deno.UnsafePointerView(ptr); const ptrView = new Deno.UnsafePointerView(0n);
assertThrows(() => { assertThrows(() => {
ptrView.copyInto(new Uint8Array(0)); ptrView.copyInto(new Uint8Array(0));
}, Deno.errors.PermissionDenied); }, Deno.errors.PermissionDenied);

View file

@ -5,12 +5,7 @@
const core = window.Deno.core; const core = window.Deno.core;
const __bootstrap = window.__bootstrap; const __bootstrap = window.__bootstrap;
const { const {
ArrayBufferPrototype,
ArrayPrototypePush,
ArrayPrototypeSome,
BigInt, BigInt,
NumberIsFinite,
NumberIsInteger,
ObjectDefineProperty, ObjectDefineProperty,
ObjectPrototypeIsPrototypeOf, ObjectPrototypeIsPrototypeOf,
PromisePrototypeThen, PromisePrototypeThen,
@ -37,77 +32,77 @@
getUint8(offset = 0) { getUint8(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_u8", "op_ffi_read_u8",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getInt8(offset = 0) { getInt8(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_i8", "op_ffi_read_i8",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getUint16(offset = 0) { getUint16(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_u16", "op_ffi_read_u16",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getInt16(offset = 0) { getInt16(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_i16", "op_ffi_read_i16",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getUint32(offset = 0) { getUint32(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_u32", "op_ffi_read_u32",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getInt32(offset = 0) { getInt32(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_i32", "op_ffi_read_i32",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getBigUint64(offset = 0) { getBigUint64(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_u64", "op_ffi_read_u64",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getBigInt64(offset = 0) { getBigInt64(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_u64", "op_ffi_read_u64",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getFloat32(offset = 0) { getFloat32(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_f32", "op_ffi_read_f32",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getFloat64(offset = 0) { getFloat64(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_read_f64", "op_ffi_read_f64",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
getCString(offset = 0) { getCString(offset = 0) {
return core.opSync( return core.opSync(
"op_ffi_cstr_read", "op_ffi_cstr_read",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
); );
} }
@ -120,7 +115,7 @@
copyInto(destination, offset = 0) { copyInto(destination, offset = 0) {
core.opSync( core.opSync(
"op_ffi_buf_copy_into", "op_ffi_buf_copy_into",
this.pointer.value + BigInt(offset), this.pointer + BigInt(offset),
destination, destination,
destination.byteLength, destination.byteLength,
); );
@ -128,125 +123,12 @@
} }
class UnsafePointer { class UnsafePointer {
value; static of(value) {
if (ObjectPrototypeIsPrototypeOf(UnsafeCallbackPrototype, value)) {
constructor(value) { return value.pointer;
if (typeof value === "number") {
value = BigInt(value);
} }
this.value = value; return core.opSync("op_ffi_ptr_of", value);
} }
static of(typedArray) {
return new UnsafePointer(
core.opSync("op_ffi_ptr_of", typedArray),
);
}
valueOf() {
return this.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) { function unpackNonblockingReturnValue(type, result) {
@ -254,7 +136,7 @@
typeof type === "object" && type !== null && "function" in type || typeof type === "object" && type !== null && "function" in type ||
type === "pointer" type === "pointer"
) { ) {
return new UnsafePointer(unpackU64(result)); return unpackU64(result);
} }
switch (type) { switch (type) {
case "isize": case "isize":
@ -277,16 +159,12 @@
this.definition = definition; this.definition = definition;
} }
call(...args) { call(...parameters) {
const parameters = prepareArgs(
this.definition.parameters,
args,
);
const resultType = this.definition.result; const resultType = this.definition.result;
if (this.definition.nonblocking) { if (this.definition.nonblocking) {
const promise = core.opAsync( const promise = core.opAsync(
"op_ffi_call_ptr_nonblocking", "op_ffi_call_ptr_nonblocking",
this.pointer.value, this.pointer,
this.definition, this.definition,
parameters, parameters,
); );
@ -302,24 +180,16 @@
return promise; return promise;
} else { } else {
const result = core.opSync( return core.opSync(
"op_ffi_call_ptr", "op_ffi_call_ptr",
this.pointer.value, this.pointer,
this.definition, this.definition,
parameters, parameters,
); );
if (isPointerType(resultType)) {
return new UnsafePointer(result);
}
return result;
} }
} }
} }
const UnsafeFnPointerPrototype = UnsafeFnPointer.prototype;
function isPointerType(type) { function isPointerType(type) {
return type === "pointer" || return type === "pointer" ||
typeof type === "object" && type !== null && "function" in type; typeof type === "object" && type !== null && "function" in type;
@ -330,64 +200,8 @@
type === "usize" || type === "isize"; 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 { class UnsafeCallback {
#rid; #rid;
#internal;
definition; definition;
callback; callback;
pointer; pointer;
@ -398,20 +212,13 @@
"Invalid UnsafeCallback, cannot be nonblocking", "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( const [rid, pointer] = core.opSync(
"op_ffi_unsafe_callback_create", "op_ffi_unsafe_callback_create",
definition, definition,
internalCallback, callback,
); );
this.#rid = rid; this.#rid = rid;
this.pointer = new UnsafePointer(pointer); this.pointer = pointer;
this.#internal = internalCallback;
this.definition = definition; this.definition = definition;
this.callback = callback; this.callback = callback;
} }
@ -440,15 +247,12 @@
} }
const name = symbols[symbol].name || symbol; const name = symbols[symbol].name || symbol;
let value = core.opSync( const value = core.opSync(
"op_ffi_get_static", "op_ffi_get_static",
this.#rid, this.#rid,
name, name,
type, type,
); );
if (type === "pointer") {
value = new UnsafePointer(value);
}
ObjectDefineProperty( ObjectDefineProperty(
this.symbols, this.symbols,
symbol, symbol,
@ -463,15 +267,12 @@
} }
const isNonBlocking = symbols[symbol].nonblocking; const isNonBlocking = symbols[symbol].nonblocking;
const types = symbols[symbol].parameters;
const resultType = symbols[symbol].result; const resultType = symbols[symbol].result;
let fn; let fn;
if (isNonBlocking) { if (isNonBlocking) {
const needsUnpacking = isReturnedAsBigInt(resultType); const needsUnpacking = isReturnedAsBigInt(resultType);
fn = (...args) => { fn = (...parameters) => {
const parameters = prepareArgs(types, args);
const promise = core.opAsync( const promise = core.opAsync(
"op_ffi_call_nonblocking", "op_ffi_call_nonblocking",
this.#rid, this.#rid,
@ -489,23 +290,13 @@
return promise; return promise;
}; };
} else { } else {
const mustWrap = isPointerType(resultType); fn = (...parameters) =>
fn = (...args) => { core.opSync(
const parameters = prepareArgs(types, args);
const result = core.opSync(
"op_ffi_call", "op_ffi_call",
this.#rid, this.#rid,
symbol, symbol,
parameters, parameters,
); );
if (mustWrap) {
return new UnsafePointer(result);
}
return result;
};
} }
ObjectDefineProperty( ObjectDefineProperty(

View file

@ -13,6 +13,10 @@ const libPath = `${targetDir}/${libPrefix}test_ffi.${libSuffix}`;
const resourcesPre = Deno.resources(); const resourcesPre = Deno.resources();
function ptr(v) {
return Deno.UnsafePointer.of(v);
}
// dlopen shouldn't panic // dlopen shouldn't panic
assertThrows(() => { assertThrows(() => {
Deno.dlopen("cli/src/main.rs", {}); Deno.dlopen("cli/src/main.rs", {});
@ -188,9 +192,9 @@ const buffer = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8]);
const buffer2 = new Uint8Array([9, 10]); const buffer2 = new Uint8Array([9, 10]);
dylib.symbols.print_buffer(buffer, buffer.length); dylib.symbols.print_buffer(buffer, buffer.length);
dylib.symbols.print_buffer2(buffer, buffer.length, buffer2, buffer2.length); dylib.symbols.print_buffer2(buffer, buffer.length, buffer2, buffer2.length);
const ptr = dylib.symbols.return_buffer(); const ptr0 = dylib.symbols.return_buffer();
dylib.symbols.print_buffer(ptr, 8); dylib.symbols.print_buffer(ptr0, 8);
const ptrView = new Deno.UnsafePointerView(ptr); const ptrView = new Deno.UnsafePointerView(ptr0);
const into = new Uint8Array(6); const into = new Uint8Array(6);
const into2 = new Uint8Array(3); const into2 = new Uint8Array(3);
const into2ptr = Deno.UnsafePointer.of(into2); const into2ptr = Deno.UnsafePointer.of(into2);
@ -210,7 +214,7 @@ const stringPtr = Deno.UnsafePointer.of(string);
const stringPtrview = new Deno.UnsafePointerView(stringPtr); const stringPtrview = new Deno.UnsafePointerView(stringPtr);
console.log(stringPtrview.getCString()); console.log(stringPtrview.getCString());
console.log(stringPtrview.getCString(11)); console.log(stringPtrview.getCString(11));
console.log(Boolean(dylib.symbols.is_null_ptr(ptr))); console.log(Boolean(dylib.symbols.is_null_ptr(ptr0)));
console.log(Boolean(dylib.symbols.is_null_ptr(null))); console.log(Boolean(dylib.symbols.is_null_ptr(null)));
console.log(Boolean(dylib.symbols.is_null_ptr(Deno.UnsafePointer.of(into)))); console.log(Boolean(dylib.symbols.is_null_ptr(Deno.UnsafePointer.of(into))));
@ -232,20 +236,7 @@ await sleepNonBlocking.call(100);
console.log(performance.now() - before >= 100); console.log(performance.now() - before >= 100);
console.log(dylib.symbols.add_u32(123, 456)); console.log(dylib.symbols.add_u32(123, 456));
assertThrows(
() => {
dylib.symbols.add_u32(-1, 100);
},
TypeError,
"Expected FFI argument to be an unsigned integer, but got '-1'",
);
assertThrows(
() => {
dylib.symbols.add_u32(null, 100);
},
TypeError,
"Expected FFI argument to be an unsigned integer, but got 'null'",
);
console.log(dylib.symbols.add_i32(123, 456)); console.log(dylib.symbols.add_i32(123, 456));
console.log(dylib.symbols.add_u64(0xffffffffn, 0xffffffffn)); console.log(dylib.symbols.add_u64(0xffffffffn, 0xffffffffn));
console.log(dylib.symbols.add_i64(-0xffffffffn, -0xffffffffn)); console.log(dylib.symbols.add_i64(-0xffffffffn, -0xffffffffn));
@ -345,7 +336,7 @@ const logManyParametersCallback = new Deno.UnsafeCallback({
], ],
result: "void", result: "void",
}, (u8, i8, u16, i16, u32, i32, u64, i64, f32, f64, pointer) => { }, (u8, i8, u16, i16, u32, i32, u64, i64, f32, f64, pointer) => {
const view = new Deno.UnsafePointerView(new Deno.UnsafePointer(pointer)); const view = new Deno.UnsafePointerView(pointer);
const copy_buffer = new Uint8Array(8); const copy_buffer = new Uint8Array(8);
view.copyInto(copy_buffer); view.copyInto(copy_buffer);
console.log(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64, ...copy_buffer); console.log(u8, i8, u16, i16, u32, i32, u64, i64, f32, f64, ...copy_buffer);
@ -373,19 +364,19 @@ const throwCallback = new Deno.UnsafeCallback({
assertThrows( assertThrows(
() => { () => {
dylib.symbols.call_fn_ptr(throwCallback); dylib.symbols.call_fn_ptr(ptr(throwCallback));
}, },
TypeError, TypeError,
"hi", "hi",
); );
dylib.symbols.call_fn_ptr(logCallback); dylib.symbols.call_fn_ptr(ptr(logCallback));
dylib.symbols.call_fn_ptr_many_parameters(logManyParametersCallback); dylib.symbols.call_fn_ptr_many_parameters(ptr(logManyParametersCallback));
dylib.symbols.call_fn_ptr_return_u8(returnU8Callback); dylib.symbols.call_fn_ptr_return_u8(ptr(returnU8Callback));
dylib.symbols.call_fn_ptr_return_buffer(returnBufferCallback); dylib.symbols.call_fn_ptr_return_buffer(ptr(returnBufferCallback));
dylib.symbols.store_function(logCallback); dylib.symbols.store_function(ptr(logCallback));
dylib.symbols.call_stored_function(); dylib.symbols.call_stored_function();
dylib.symbols.store_function_2(add10Callback); dylib.symbols.store_function_2(ptr(add10Callback));
dylib.symbols.call_stored_function_2(20); dylib.symbols.call_stored_function_2(20);
const nestedCallback = new Deno.UnsafeCallback( const nestedCallback = new Deno.UnsafeCallback(
@ -394,7 +385,7 @@ const nestedCallback = new Deno.UnsafeCallback(
dylib.symbols.call_stored_function_2(10); dylib.symbols.call_stored_function_2(10);
}, },
); );
dylib.symbols.store_function(nestedCallback); dylib.symbols.store_function(ptr(nestedCallback));
dylib.symbols.store_function(null); dylib.symbols.store_function(null);
dylib.symbols.store_function_2(null); dylib.symbols.store_function_2(null);
@ -404,7 +395,7 @@ console.log("Static u32:", dylib.symbols.static_u32);
console.log("Static i64:", dylib.symbols.static_i64); console.log("Static i64:", dylib.symbols.static_i64);
console.log( console.log(
"Static ptr:", "Static ptr:",
dylib.symbols.static_ptr instanceof Deno.UnsafePointer, typeof dylib.symbols.static_ptr === "bigint",
); );
const view = new Deno.UnsafePointerView(dylib.symbols.static_ptr); const view = new Deno.UnsafePointerView(dylib.symbols.static_ptr);
console.log("Static ptr value:", view.getUint32()); console.log("Static ptr value:", view.getUint32());