1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license.
import { assertEquals, assertRejects, assertThrows } from "./test_util.ts";
Deno.test({ permissions: { ffi: true } }, function dlopenInvalidArguments() {
const filename = "/usr/lib/libc.so.6";
assertThrows(() => {
// @ts-expect-error: ForeignFunction cannot be null
Deno.dlopen(filename, { malloc: null });
}, TypeError);
assertThrows(() => {
Deno.dlopen(filename, {
// @ts-expect-error: invalid NativeType
malloc: { parameters: ["a"], result: "b" },
});
}, TypeError);
assertThrows(() => {
// @ts-expect-error: DynamicLibrary symbols cannot be null
Deno.dlopen(filename, null);
}, TypeError);
assertThrows(() => {
// @ts-expect-error: require 2 arguments
Deno.dlopen(filename);
}, TypeError);
});
Deno.test({ permissions: { ffi: false } }, function ffiNotCapable() {
assertThrows(() => {
Deno.dlopen("/usr/lib/libc.so.6", {});
}, Deno.errors.NotCapable);
const fnptr = new Deno.UnsafeFnPointer(
// @ts-expect-error: Not NonNullable but null check is after permissions check.
null,
{
parameters: ["u32", "pointer"],
result: "void",
} as const,
);
assertThrows(() => {
fnptr.call(123, null);
}, Deno.errors.NotCapable);
assertThrows(() => {
Deno.UnsafePointer.of(new Uint8Array(0));
}, Deno.errors.NotCapable);
const ptrView = new Deno.UnsafePointerView(
// @ts-expect-error: Not NonNullable but null check is after permissions check.
null,
);
assertThrows(() => {
ptrView.copyInto(new Uint8Array(0));
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getCString();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getUint8();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getInt8();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getUint16();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getInt16();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getUint32();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getInt32();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getFloat32();
}, Deno.errors.NotCapable);
assertThrows(() => {
ptrView.getFloat64();
}, Deno.errors.NotCapable);
});
Deno.test({ permissions: { ffi: true } }, function pointerOf() {
const buffer = new ArrayBuffer(1024);
const baseAddress = Deno.UnsafePointer.value(Deno.UnsafePointer.of(buffer));
const uint8Address = Deno.UnsafePointer.value(
Deno.UnsafePointer.of(new Uint8Array(buffer)),
);
assertEquals(baseAddress, uint8Address);
const float64Address = Deno.UnsafePointer.value(
Deno.UnsafePointer.of(new Float64Array(buffer)),
);
assertEquals(baseAddress, float64Address);
const uint8AddressOffset = Deno.UnsafePointer.value(
Deno.UnsafePointer.of(new Uint8Array(buffer, 100)),
);
assertEquals(baseAddress + 100n, uint8AddressOffset);
const float64AddressOffset = Deno.UnsafePointer.value(
Deno.UnsafePointer.of(new Float64Array(buffer, 80)),
);
assertEquals(baseAddress + 80n, float64AddressOffset);
});
Deno.test({ permissions: { ffi: true } }, function callWithError() {
const throwCb = () => {
throw new Error("Error");
};
const cb = new Deno.UnsafeCallback({
parameters: [],
result: "void",
}, throwCb);
const fnPointer = new Deno.UnsafeFnPointer(cb.pointer, {
parameters: [],
result: "void",
});
assertThrows(() => fnPointer.call());
cb.close();
});
Deno.test(
{ permissions: { ffi: true }, ignore: true },
async function callNonBlockingWithError() {
const throwCb = () => {
throw new Error("Error");
};
const cb = new Deno.UnsafeCallback({
parameters: [],
result: "void",
}, throwCb);
const fnPointer = new Deno.UnsafeFnPointer(cb.pointer, {
parameters: [],
result: "void",
nonblocking: true,
});
// TODO(mmastrac): currently ignored as we do not thread callback exceptions through nonblocking pointers
await assertRejects(async () => await fnPointer.call());
cb.close();
},
);
|