quickjs-emscripten-sync 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -7
- package/dist/index.d.ts +12 -7
- package/dist/quickjs-emscripten-sync.mjs +842 -0
- package/dist/quickjs-emscripten-sync.umd.js +15 -15
- package/package.json +9 -18
- package/src/default.ts +2 -2
- package/src/index.test.ts +21 -13
- package/src/index.ts +30 -43
- package/src/marshal/custom.test.ts +50 -0
- package/src/marshal/custom.ts +36 -0
- package/src/marshal/function.test.ts +17 -37
- package/src/marshal/function.ts +8 -12
- package/src/marshal/index.test.ts +35 -39
- package/src/marshal/index.ts +6 -9
- package/src/marshal/json.test.ts +9 -15
- package/src/marshal/json.ts +1 -4
- package/src/marshal/object.test.ts +19 -51
- package/src/marshal/object.ts +3 -11
- package/src/marshal/primitive.test.ts +4 -13
- package/src/marshal/primitive.ts +1 -1
- package/src/marshal/promise.test.ts +9 -10
- package/src/marshal/promise.ts +4 -11
- package/src/marshal/properties.test.ts +7 -14
- package/src/marshal/properties.ts +6 -9
- package/src/unmarshal/custom.test.ts +50 -0
- package/src/unmarshal/custom.ts +31 -0
- package/src/unmarshal/function.test.ts +20 -44
- package/src/unmarshal/function.ts +7 -17
- package/src/unmarshal/index.test.ts +30 -23
- package/src/unmarshal/index.ts +4 -6
- package/src/unmarshal/object.test.ts +9 -17
- package/src/unmarshal/object.ts +7 -12
- package/src/unmarshal/primitive.test.ts +1 -4
- package/src/unmarshal/primitive.ts +3 -10
- package/src/unmarshal/promise.test.ts +3 -3
- package/src/unmarshal/promise.ts +3 -10
- package/src/unmarshal/properties.test.ts +2 -2
- package/src/unmarshal/properties.ts +4 -8
- package/src/util.test.ts +1 -7
- package/src/util.ts +3 -8
- package/src/vmmap.ts +13 -31
- package/src/vmutil.test.ts +15 -29
- package/src/vmutil.ts +12 -39
- package/src/wrapper.test.ts +27 -90
- package/src/wrapper.ts +43 -50
- package/dist/quickjs-emscripten-sync.es.js +0 -962
- package/src/marshal/symbol.test.ts +0 -24
- package/src/marshal/symbol.ts +0 -21
- package/src/unmarshal/symbol.test.ts +0 -25
- package/src/unmarshal/symbol.ts +0 -12
package/src/unmarshal/object.ts
CHANGED
|
@@ -1,30 +1,25 @@
|
|
|
1
1
|
import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
|
|
2
2
|
|
|
3
|
-
import unmarshalProperties from "./properties";
|
|
4
3
|
import { call } from "../vmutil";
|
|
5
4
|
|
|
5
|
+
import unmarshalProperties from "./properties";
|
|
6
|
+
|
|
6
7
|
export default function unmarshalObject(
|
|
7
8
|
ctx: QuickJSContext,
|
|
8
9
|
handle: QuickJSHandle,
|
|
9
10
|
unmarshal: (handle: QuickJSHandle) => [unknown, boolean],
|
|
10
|
-
preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined
|
|
11
|
+
preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined,
|
|
11
12
|
): object | undefined {
|
|
12
13
|
if (
|
|
13
14
|
ctx.typeof(handle) !== "object" ||
|
|
14
15
|
// null check
|
|
15
16
|
ctx
|
|
16
17
|
.unwrapResult(ctx.evalCode("o => o === null"))
|
|
17
|
-
.consume((n)
|
|
18
|
-
ctx.dump(ctx.unwrapResult(ctx.callFunction(n, ctx.undefined, handle)))
|
|
19
|
-
)
|
|
18
|
+
.consume(n => ctx.dump(ctx.unwrapResult(ctx.callFunction(n, ctx.undefined, handle))))
|
|
20
19
|
)
|
|
21
20
|
return;
|
|
22
21
|
|
|
23
|
-
const raw = call(ctx, "Array.isArray", undefined, handle).consume((r)
|
|
24
|
-
ctx.dump(r)
|
|
25
|
-
)
|
|
26
|
-
? []
|
|
27
|
-
: {};
|
|
22
|
+
const raw = call(ctx, "Array.isArray", undefined, handle).consume(r => ctx.dump(r)) ? [] : {};
|
|
28
23
|
const obj = preUnmarshal(raw, handle) ?? raw;
|
|
29
24
|
|
|
30
25
|
const prototype = call(
|
|
@@ -34,8 +29,8 @@ export default function unmarshalObject(
|
|
|
34
29
|
return !p || p === Object.prototype || p === Array.prototype ? undefined : p;
|
|
35
30
|
}`,
|
|
36
31
|
undefined,
|
|
37
|
-
handle
|
|
38
|
-
).consume(
|
|
32
|
+
handle,
|
|
33
|
+
).consume(prototype => {
|
|
39
34
|
if (ctx.typeof(prototype) === "undefined") return;
|
|
40
35
|
const [proto] = unmarshal(prototype);
|
|
41
36
|
return proto;
|
|
@@ -10,10 +10,7 @@ test("works", async () => {
|
|
|
10
10
|
expect(unmarshalPrimitive(ctx, ctx.true)).toEqual([true, true]);
|
|
11
11
|
expect(unmarshalPrimitive(ctx, ctx.false)).toEqual([false, true]);
|
|
12
12
|
expect(unmarshalPrimitive(ctx, ctx.null)).toEqual([null, true]);
|
|
13
|
-
expect(unmarshalPrimitive(ctx, ctx.newString("hoge"))).toEqual([
|
|
14
|
-
"hoge",
|
|
15
|
-
true,
|
|
16
|
-
]);
|
|
13
|
+
expect(unmarshalPrimitive(ctx, ctx.newString("hoge"))).toEqual(["hoge", true]);
|
|
17
14
|
expect(unmarshalPrimitive(ctx, ctx.newNumber(-10))).toEqual([-10, true]);
|
|
18
15
|
// expect(
|
|
19
16
|
// unmarshalPrimitive(ctx, ctx.unwrapResult(vm.evalCode(`BigInt(1)`)))
|
|
@@ -2,22 +2,15 @@ import type { QuickJSContext, QuickJSHandle } from "quickjs-emscripten";
|
|
|
2
2
|
|
|
3
3
|
export default function unmarshalPrimitive(
|
|
4
4
|
ctx: QuickJSContext,
|
|
5
|
-
handle: QuickJSHandle
|
|
5
|
+
handle: QuickJSHandle,
|
|
6
6
|
): [any, boolean] {
|
|
7
7
|
const ty = ctx.typeof(handle);
|
|
8
|
-
if (
|
|
9
|
-
ty === "undefined" ||
|
|
10
|
-
ty === "number" ||
|
|
11
|
-
ty === "string" ||
|
|
12
|
-
ty === "boolean"
|
|
13
|
-
) {
|
|
8
|
+
if (ty === "undefined" || ty === "number" || ty === "string" || ty === "boolean") {
|
|
14
9
|
return [ctx.dump(handle), true];
|
|
15
10
|
} else if (ty === "object") {
|
|
16
11
|
const isNull = ctx
|
|
17
12
|
.unwrapResult(ctx.evalCode("a => a === null"))
|
|
18
|
-
.consume((n)
|
|
19
|
-
ctx.dump(ctx.unwrapResult(ctx.callFunction(n, ctx.undefined, handle)))
|
|
20
|
-
);
|
|
13
|
+
.consume(n => ctx.dump(ctx.unwrapResult(ctx.callFunction(n, ctx.undefined, handle))));
|
|
21
14
|
if (isNull) {
|
|
22
15
|
return [null, true];
|
|
23
16
|
}
|
|
@@ -7,13 +7,13 @@ const testPromise = (reject: boolean) => async () => {
|
|
|
7
7
|
const ctx = (await getQuickJS()).newContext();
|
|
8
8
|
const disposables: Disposable[] = [];
|
|
9
9
|
const marshal = vi.fn((v): [QuickJSHandle, boolean] => {
|
|
10
|
-
const f = ctx.newFunction(v.name,
|
|
10
|
+
const f = ctx.newFunction(v.name, h => {
|
|
11
11
|
v(ctx.dump(h));
|
|
12
12
|
});
|
|
13
13
|
disposables.push(f);
|
|
14
14
|
return [f, false];
|
|
15
15
|
});
|
|
16
|
-
const preUnmarshal = vi.fn(
|
|
16
|
+
const preUnmarshal = vi.fn(a => a);
|
|
17
17
|
|
|
18
18
|
const deferred = ctx.newPromise();
|
|
19
19
|
disposables.push(deferred);
|
|
@@ -36,7 +36,7 @@ const testPromise = (reject: boolean) => async () => {
|
|
|
36
36
|
expect(promise).resolves.toBe("hoge");
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
disposables.forEach(
|
|
39
|
+
disposables.forEach(d => d.dispose());
|
|
40
40
|
ctx.dispose();
|
|
41
41
|
};
|
|
42
42
|
|
package/src/unmarshal/promise.ts
CHANGED
|
@@ -8,21 +8,14 @@ export default function unmarshalPromise<T = unknown>(
|
|
|
8
8
|
handle: QuickJSHandle,
|
|
9
9
|
/** marshal returns handle and boolean indicates that the handle should be disposed after use */
|
|
10
10
|
marshal: (value: unknown) => [QuickJSHandle, boolean],
|
|
11
|
-
preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined
|
|
11
|
+
preUnmarshal: <T>(target: T, handle: QuickJSHandle) => T | undefined,
|
|
12
12
|
): Promise<T> | undefined {
|
|
13
13
|
if (!isPromiseHandle(ctx, handle)) return;
|
|
14
14
|
|
|
15
15
|
const deferred = newDeferred<T>();
|
|
16
16
|
const [resHandle, resShouldBeDisposed] = marshal(deferred.resolve);
|
|
17
17
|
const [rejHandle, rejShouldBeDisposed] = marshal(deferred.reject);
|
|
18
|
-
call(
|
|
19
|
-
ctx,
|
|
20
|
-
"(p, res, rej) => { p.then(res, rej); }",
|
|
21
|
-
undefined,
|
|
22
|
-
handle,
|
|
23
|
-
resHandle,
|
|
24
|
-
rejHandle
|
|
25
|
-
);
|
|
18
|
+
call(ctx, "(p, res, rej) => { p.then(res, rej); }", undefined, handle, resHandle, rejHandle);
|
|
26
19
|
if (resShouldBeDisposed) resHandle.dispose();
|
|
27
20
|
if (rejShouldBeDisposed) rejHandle.dispose();
|
|
28
21
|
|
|
@@ -31,7 +24,7 @@ export default function unmarshalPromise<T = unknown>(
|
|
|
31
24
|
|
|
32
25
|
function isPromiseHandle(ctx: QuickJSContext, handle: QuickJSHandle): boolean {
|
|
33
26
|
if (!handle.owner) return false;
|
|
34
|
-
return ctx.unwrapResult(ctx.evalCode("Promise")).consume(
|
|
27
|
+
return ctx.unwrapResult(ctx.evalCode("Promise")).consume(promise => {
|
|
35
28
|
if (!handle.owner) return false;
|
|
36
29
|
return instanceOf(ctx, handle, promise);
|
|
37
30
|
});
|
|
@@ -21,7 +21,7 @@ test("works", async () => {
|
|
|
21
21
|
c: { get: () => {}, set: () => {} },
|
|
22
22
|
});
|
|
23
23
|
obj
|
|
24
|
-
}`)
|
|
24
|
+
}`),
|
|
25
25
|
);
|
|
26
26
|
|
|
27
27
|
unmarshalProperties(ctx, handle, obj, unmarshal);
|
|
@@ -47,7 +47,7 @@ test("works", async () => {
|
|
|
47
47
|
expect(unmarshal).toReturnWith(["c", false]);
|
|
48
48
|
expect(unmarshal).toReturnWith([expect.any(Function), false]); // get, set
|
|
49
49
|
|
|
50
|
-
disposables.forEach(
|
|
50
|
+
disposables.forEach(d => d.dispose());
|
|
51
51
|
handle.dispose();
|
|
52
52
|
ctx.dispose();
|
|
53
53
|
});
|
|
@@ -6,16 +6,12 @@ export default function unmarshalProperties(
|
|
|
6
6
|
ctx: QuickJSContext,
|
|
7
7
|
handle: QuickJSHandle,
|
|
8
8
|
target: object | Function,
|
|
9
|
-
unmarshal: (handle: QuickJSHandle) => [unknown, boolean]
|
|
9
|
+
unmarshal: (handle: QuickJSHandle) => [unknown, boolean],
|
|
10
10
|
) {
|
|
11
11
|
ctx
|
|
12
12
|
.newFunction("", (key, value) => {
|
|
13
13
|
const [keyName] = unmarshal(key);
|
|
14
|
-
if (
|
|
15
|
-
typeof keyName !== "string" &&
|
|
16
|
-
typeof keyName !== "number" &&
|
|
17
|
-
typeof keyName !== "symbol"
|
|
18
|
-
)
|
|
14
|
+
if (typeof keyName !== "string" && typeof keyName !== "number" && typeof keyName !== "symbol")
|
|
19
15
|
return;
|
|
20
16
|
|
|
21
17
|
const desc = (
|
|
@@ -48,7 +44,7 @@ export default function unmarshalProperties(
|
|
|
48
44
|
|
|
49
45
|
Object.defineProperty(target, keyName, desc);
|
|
50
46
|
})
|
|
51
|
-
.consume(
|
|
47
|
+
.consume(fn => {
|
|
52
48
|
call(
|
|
53
49
|
ctx,
|
|
54
50
|
`(o, fn) => {
|
|
@@ -58,7 +54,7 @@ export default function unmarshalProperties(
|
|
|
58
54
|
}`,
|
|
59
55
|
undefined,
|
|
60
56
|
handle,
|
|
61
|
-
fn
|
|
57
|
+
fn,
|
|
62
58
|
).dispose();
|
|
63
59
|
});
|
|
64
60
|
}
|
package/src/util.test.ts
CHANGED
|
@@ -1,12 +1,6 @@
|
|
|
1
1
|
import { expect, test, vi } from "vitest";
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
isES2015Class,
|
|
5
|
-
isObject,
|
|
6
|
-
walkObject,
|
|
7
|
-
complexity,
|
|
8
|
-
newDeferred,
|
|
9
|
-
} from "./util";
|
|
3
|
+
import { isES2015Class, isObject, walkObject, complexity, newDeferred } from "./util";
|
|
10
4
|
|
|
11
5
|
test("isES2015Class", () => {
|
|
12
6
|
expect(isES2015Class(class {})).toBe(true);
|
package/src/util.ts
CHANGED
|
@@ -1,19 +1,14 @@
|
|
|
1
1
|
export function isES2015Class(cls: any): cls is new (...args: any[]) => any {
|
|
2
|
-
return (
|
|
3
|
-
typeof cls === "function" &&
|
|
4
|
-
/^class\s/.test(Function.prototype.toString.call(cls))
|
|
5
|
-
);
|
|
2
|
+
return typeof cls === "function" && /^class\s/.test(Function.prototype.toString.call(cls));
|
|
6
3
|
}
|
|
7
4
|
|
|
8
5
|
export function isObject(value: any): value is object | Function {
|
|
9
|
-
return (
|
|
10
|
-
typeof value === "function" || (typeof value === "object" && value !== null)
|
|
11
|
-
);
|
|
6
|
+
return typeof value === "function" || (typeof value === "object" && value !== null);
|
|
12
7
|
}
|
|
13
8
|
|
|
14
9
|
export function walkObject(
|
|
15
10
|
value: any,
|
|
16
|
-
callback?: (target: any, set: Set<any>) => boolean | void
|
|
11
|
+
callback?: (target: any, set: Set<any>) => boolean | void,
|
|
17
12
|
): Set<any> {
|
|
18
13
|
const set = new Set<any>();
|
|
19
14
|
const walk = (v: any) => {
|
package/src/vmmap.ts
CHANGED
|
@@ -42,9 +42,9 @@ export default class VMMap {
|
|
|
42
42
|
map2 = new WeakMap();
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
}`)
|
|
45
|
+
}`),
|
|
46
46
|
)
|
|
47
|
-
.consume(
|
|
47
|
+
.consume(fn => this._call(fn, undefined));
|
|
48
48
|
|
|
49
49
|
this._mapGet = ctx.getProp(result, "get");
|
|
50
50
|
this._mapSet = ctx.getProp(result, "set");
|
|
@@ -59,12 +59,7 @@ export default class VMMap {
|
|
|
59
59
|
this._disposables.add(this._mapClear);
|
|
60
60
|
}
|
|
61
61
|
|
|
62
|
-
set(
|
|
63
|
-
key: any,
|
|
64
|
-
handle: QuickJSHandle,
|
|
65
|
-
key2?: any,
|
|
66
|
-
handle2?: QuickJSHandle
|
|
67
|
-
): boolean {
|
|
62
|
+
set(key: any, handle: QuickJSHandle, key2?: any, handle2?: QuickJSHandle): boolean {
|
|
68
63
|
if (!handle.alive || (handle2 && !handle2.alive)) return false;
|
|
69
64
|
|
|
70
65
|
const v = this.get(key) ?? this.get(key2);
|
|
@@ -84,14 +79,8 @@ export default class VMMap {
|
|
|
84
79
|
}
|
|
85
80
|
}
|
|
86
81
|
|
|
87
|
-
this.ctx.newNumber(counter).consume(
|
|
88
|
-
this._call(
|
|
89
|
-
this._mapSet,
|
|
90
|
-
undefined,
|
|
91
|
-
handle,
|
|
92
|
-
c,
|
|
93
|
-
handle2 ?? this.ctx.undefined
|
|
94
|
-
);
|
|
82
|
+
this.ctx.newNumber(counter).consume(c => {
|
|
83
|
+
this._call(this._mapSet, undefined, handle, c, handle2 ?? this.ctx.undefined);
|
|
95
84
|
});
|
|
96
85
|
|
|
97
86
|
return true;
|
|
@@ -103,7 +92,7 @@ export default class VMMap {
|
|
|
103
92
|
| [any, QuickJSHandle | undefined]
|
|
104
93
|
| [any, QuickJSHandle | undefined, any, QuickJSHandle | undefined]
|
|
105
94
|
>
|
|
106
|
-
| undefined
|
|
95
|
+
| undefined,
|
|
107
96
|
) {
|
|
108
97
|
if (!iteratable) return;
|
|
109
98
|
for (const iter of iteratable) {
|
|
@@ -131,9 +120,7 @@ export default class VMMap {
|
|
|
131
120
|
if (!handle.alive) {
|
|
132
121
|
return;
|
|
133
122
|
}
|
|
134
|
-
return this._counterMap.get(
|
|
135
|
-
this.ctx.getNumber(this._call(this._mapGet, undefined, handle))
|
|
136
|
-
);
|
|
123
|
+
return this._counterMap.get(this.ctx.getNumber(this._call(this._mapGet, undefined, handle)));
|
|
137
124
|
}
|
|
138
125
|
|
|
139
126
|
has(key: any) {
|
|
@@ -157,7 +144,7 @@ export default class VMMap {
|
|
|
157
144
|
this._call(
|
|
158
145
|
this._mapDelete,
|
|
159
146
|
undefined,
|
|
160
|
-
...[handle, handle2].filter((h): h is QuickJSHandle => !!h?.alive)
|
|
147
|
+
...[handle, handle2].filter((h): h is QuickJSHandle => !!h?.alive),
|
|
161
148
|
);
|
|
162
149
|
|
|
163
150
|
this._map1.delete(key);
|
|
@@ -235,12 +222,11 @@ export default class VMMap {
|
|
|
235
222
|
return this._map1.size;
|
|
236
223
|
}
|
|
237
224
|
|
|
238
|
-
[Symbol.iterator](): Iterator<
|
|
239
|
-
[any, QuickJSHandle, any, QuickJSHandle | undefined]
|
|
240
|
-
> {
|
|
225
|
+
[Symbol.iterator](): Iterator<[any, QuickJSHandle, any, QuickJSHandle | undefined]> {
|
|
241
226
|
const keys = this._map1.keys();
|
|
242
227
|
return {
|
|
243
228
|
next: () => {
|
|
229
|
+
// eslint-disable-next-line no-constant-condition
|
|
244
230
|
while (true) {
|
|
245
231
|
const k1 = keys.next();
|
|
246
232
|
if (k1.done) return { value: undefined, done: true };
|
|
@@ -262,17 +248,13 @@ export default class VMMap {
|
|
|
262
248
|
}
|
|
263
249
|
}
|
|
264
250
|
|
|
265
|
-
_call(
|
|
266
|
-
fn: QuickJSHandle,
|
|
267
|
-
thisArg: QuickJSHandle | undefined,
|
|
268
|
-
...args: QuickJSHandle[]
|
|
269
|
-
) {
|
|
251
|
+
_call(fn: QuickJSHandle, thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]) {
|
|
270
252
|
return this.ctx.unwrapResult(
|
|
271
253
|
this.ctx.callFunction(
|
|
272
254
|
fn,
|
|
273
255
|
typeof thisArg === "undefined" ? this.ctx.undefined : thisArg,
|
|
274
|
-
...args
|
|
275
|
-
)
|
|
256
|
+
...args,
|
|
257
|
+
),
|
|
276
258
|
);
|
|
277
259
|
}
|
|
278
260
|
}
|
package/src/vmutil.test.ts
CHANGED
|
@@ -18,9 +18,7 @@ test("fn", async () => {
|
|
|
18
18
|
const ctx = (await getQuickJS()).newContext();
|
|
19
19
|
|
|
20
20
|
const f = fn(ctx, "(a, b) => a + b");
|
|
21
|
-
expect(ctx.getNumber(f(undefined, ctx.newNumber(1), ctx.newNumber(2)))).toBe(
|
|
22
|
-
3
|
|
23
|
-
);
|
|
21
|
+
expect(ctx.getNumber(f(undefined, ctx.newNumber(1), ctx.newNumber(2)))).toBe(3);
|
|
24
22
|
|
|
25
23
|
const obj = ctx.newObject();
|
|
26
24
|
ctx.setProp(obj, "a", ctx.newNumber(2));
|
|
@@ -41,22 +39,12 @@ test("call", async () => {
|
|
|
41
39
|
const ctx = (await getQuickJS()).newContext();
|
|
42
40
|
|
|
43
41
|
expect(
|
|
44
|
-
ctx.getNumber(
|
|
45
|
-
call(
|
|
46
|
-
ctx,
|
|
47
|
-
"(a, b) => a + b",
|
|
48
|
-
undefined,
|
|
49
|
-
ctx.newNumber(1),
|
|
50
|
-
ctx.newNumber(2)
|
|
51
|
-
)
|
|
52
|
-
)
|
|
42
|
+
ctx.getNumber(call(ctx, "(a, b) => a + b", undefined, ctx.newNumber(1), ctx.newNumber(2))),
|
|
53
43
|
).toBe(3);
|
|
54
44
|
|
|
55
45
|
const obj = ctx.newObject();
|
|
56
46
|
ctx.setProp(obj, "a", ctx.newNumber(2));
|
|
57
|
-
expect(
|
|
58
|
-
ctx.getNumber(call(ctx, "(function() { return this.a + 1; })", obj))
|
|
59
|
-
).toBe(3);
|
|
47
|
+
expect(ctx.getNumber(call(ctx, "(function() { return this.a + 1; })", obj))).toBe(3);
|
|
60
48
|
|
|
61
49
|
obj.dispose();
|
|
62
50
|
ctx.dispose();
|
|
@@ -117,9 +105,7 @@ test("json", async () => {
|
|
|
117
105
|
const handle = json(ctx, {
|
|
118
106
|
hoge: { foo: ["bar"] },
|
|
119
107
|
});
|
|
120
|
-
expect(
|
|
121
|
-
ctx.dump(call(ctx, `a => a.hoge.foo[0] === "bar"`, undefined, handle))
|
|
122
|
-
).toBe(true);
|
|
108
|
+
expect(ctx.dump(call(ctx, `a => a.hoge.foo[0] === "bar"`, undefined, handle))).toBe(true);
|
|
123
109
|
expect(ctx.typeof(json(ctx, undefined))).toBe("undefined");
|
|
124
110
|
|
|
125
111
|
handle.dispose();
|
|
@@ -135,18 +121,18 @@ test("consumeAll", async () => {
|
|
|
135
121
|
expect(
|
|
136
122
|
consumeAll(
|
|
137
123
|
handles,
|
|
138
|
-
vi.fn(() => o)
|
|
139
|
-
)
|
|
124
|
+
vi.fn(() => o),
|
|
125
|
+
),
|
|
140
126
|
).toBe(o);
|
|
141
|
-
expect(handles.every(
|
|
127
|
+
expect(handles.every(h => !h.alive)).toBe(true);
|
|
142
128
|
|
|
143
129
|
const handles2 = [ctx.newObject(), ctx.newObject()];
|
|
144
130
|
expect(() =>
|
|
145
131
|
consumeAll(handles2, () => {
|
|
146
132
|
throw new Error("qes error");
|
|
147
|
-
})
|
|
133
|
+
}),
|
|
148
134
|
).toThrow("qes error");
|
|
149
|
-
expect(handles2.every(
|
|
135
|
+
expect(handles2.every(h => !h.alive)).toBe(true);
|
|
150
136
|
|
|
151
137
|
ctx.dispose();
|
|
152
138
|
});
|
|
@@ -160,8 +146,8 @@ test("mayConsume", async () => {
|
|
|
160
146
|
expect(
|
|
161
147
|
mayConsume(
|
|
162
148
|
[handle, false],
|
|
163
|
-
vi.fn(() => o)
|
|
164
|
-
)
|
|
149
|
+
vi.fn(() => o),
|
|
150
|
+
),
|
|
165
151
|
).toBe(o);
|
|
166
152
|
expect(handle.alive).toBe(true);
|
|
167
153
|
|
|
@@ -172,7 +158,7 @@ test("mayConsume", async () => {
|
|
|
172
158
|
expect(() =>
|
|
173
159
|
mayConsume([handle2, true], () => {
|
|
174
160
|
throw new Error("qes error");
|
|
175
|
-
})
|
|
161
|
+
}),
|
|
176
162
|
).toThrow("qes error");
|
|
177
163
|
expect(handle.alive).toBe(false);
|
|
178
164
|
|
|
@@ -191,8 +177,8 @@ test("mayConsumeAll", async () => {
|
|
|
191
177
|
expect(
|
|
192
178
|
mayConsumeAll(
|
|
193
179
|
handles,
|
|
194
|
-
vi.fn((..._: any[]) => o)
|
|
195
|
-
)
|
|
180
|
+
vi.fn((..._: any[]) => o),
|
|
181
|
+
),
|
|
196
182
|
).toBe(o);
|
|
197
183
|
expect(handles[0][0].alive).toBe(true);
|
|
198
184
|
expect(handles[1][0].alive).toBe(false);
|
|
@@ -204,7 +190,7 @@ test("mayConsumeAll", async () => {
|
|
|
204
190
|
expect(() =>
|
|
205
191
|
mayConsumeAll(handles2, (..._args) => {
|
|
206
192
|
throw new Error("qes error");
|
|
207
|
-
})
|
|
193
|
+
}),
|
|
208
194
|
).toThrow("qes error");
|
|
209
195
|
expect(handles2[0][0].alive).toBe(true);
|
|
210
196
|
expect(handles2[1][0].alive).toBe(false);
|
package/src/vmutil.ts
CHANGED
|
@@ -7,20 +7,11 @@ import type {
|
|
|
7
7
|
|
|
8
8
|
export function fn(
|
|
9
9
|
ctx: QuickJSContext,
|
|
10
|
-
code: string
|
|
11
|
-
): ((
|
|
12
|
-
thisArg: QuickJSHandle | undefined,
|
|
13
|
-
...args: QuickJSHandle[]
|
|
14
|
-
) => QuickJSHandle) &
|
|
15
|
-
Disposable {
|
|
10
|
+
code: string,
|
|
11
|
+
): ((thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]) => QuickJSHandle) & Disposable {
|
|
16
12
|
const handle = ctx.unwrapResult(ctx.evalCode(code));
|
|
17
|
-
const f = (
|
|
18
|
-
thisArg
|
|
19
|
-
...args: QuickJSHandle[]
|
|
20
|
-
): any => {
|
|
21
|
-
return ctx.unwrapResult(
|
|
22
|
-
ctx.callFunction(handle, thisArg ?? ctx.undefined, ...args)
|
|
23
|
-
);
|
|
13
|
+
const f = (thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]): any => {
|
|
14
|
+
return ctx.unwrapResult(ctx.callFunction(handle, thisArg ?? ctx.undefined, ...args));
|
|
24
15
|
};
|
|
25
16
|
f.dispose = () => handle.dispose();
|
|
26
17
|
f.alive = true;
|
|
@@ -44,30 +35,17 @@ export function call(
|
|
|
44
35
|
}
|
|
45
36
|
}
|
|
46
37
|
|
|
47
|
-
export function eq(
|
|
48
|
-
ctx: QuickJSContext,
|
|
49
|
-
a: QuickJSHandle,
|
|
50
|
-
b: QuickJSHandle
|
|
51
|
-
): boolean {
|
|
38
|
+
export function eq(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean {
|
|
52
39
|
return ctx.dump(call(ctx, "Object.is", undefined, a, b));
|
|
53
40
|
}
|
|
54
41
|
|
|
55
|
-
export function instanceOf(
|
|
56
|
-
ctx: QuickJSContext,
|
|
57
|
-
a: QuickJSHandle,
|
|
58
|
-
b: QuickJSHandle
|
|
59
|
-
): boolean {
|
|
42
|
+
export function instanceOf(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean {
|
|
60
43
|
return ctx.dump(call(ctx, "(a, b) => a instanceof b", undefined, a, b));
|
|
61
44
|
}
|
|
62
45
|
|
|
63
46
|
export function isHandleObject(ctx: QuickJSContext, h: QuickJSHandle): boolean {
|
|
64
47
|
return ctx.dump(
|
|
65
|
-
call(
|
|
66
|
-
ctx,
|
|
67
|
-
`a => typeof a === "object" && a !== null || typeof a === "function"`,
|
|
68
|
-
undefined,
|
|
69
|
-
h
|
|
70
|
-
)
|
|
48
|
+
call(ctx, `a => typeof a === "object" && a !== null || typeof a === "function"`, undefined, h),
|
|
71
49
|
);
|
|
72
50
|
}
|
|
73
51
|
|
|
@@ -77,10 +55,7 @@ export function json(ctx: QuickJSContext, target: any): QuickJSHandle {
|
|
|
77
55
|
return call(ctx, `JSON.parse`, undefined, ctx.newString(json));
|
|
78
56
|
}
|
|
79
57
|
|
|
80
|
-
export function consumeAll<T extends QuickJSHandle[], K>(
|
|
81
|
-
handles: T,
|
|
82
|
-
cb: (handles: T) => K
|
|
83
|
-
): K {
|
|
58
|
+
export function consumeAll<T extends QuickJSHandle[], K>(handles: T, cb: (handles: T) => K): K {
|
|
84
59
|
try {
|
|
85
60
|
return cb(handles);
|
|
86
61
|
} finally {
|
|
@@ -92,7 +67,7 @@ export function consumeAll<T extends QuickJSHandle[], K>(
|
|
|
92
67
|
|
|
93
68
|
export function mayConsume<T>(
|
|
94
69
|
[handle, shouldBeDisposed]: [QuickJSHandle, boolean],
|
|
95
|
-
fn: (h: QuickJSHandle) => T
|
|
70
|
+
fn: (h: QuickJSHandle) => T,
|
|
96
71
|
) {
|
|
97
72
|
try {
|
|
98
73
|
return fn(handle);
|
|
@@ -105,10 +80,10 @@ export function mayConsume<T>(
|
|
|
105
80
|
|
|
106
81
|
export function mayConsumeAll<T, H extends QuickJSHandle[]>(
|
|
107
82
|
handles: { [P in keyof H]: [QuickJSHandle, boolean] },
|
|
108
|
-
fn: (...args: H) => T
|
|
83
|
+
fn: (...args: H) => T,
|
|
109
84
|
) {
|
|
110
85
|
try {
|
|
111
|
-
return fn(...(handles.map(
|
|
86
|
+
return fn(...(handles.map(h => h[0]) as H));
|
|
112
87
|
} finally {
|
|
113
88
|
for (const [handle, shouldBeDisposed] of handles) {
|
|
114
89
|
if (shouldBeDisposed) {
|
|
@@ -122,8 +97,6 @@ function isQuickJSDeferredPromise(d: Disposable): d is QuickJSDeferredPromise {
|
|
|
122
97
|
return "handle" in d;
|
|
123
98
|
}
|
|
124
99
|
|
|
125
|
-
export function handleFrom(
|
|
126
|
-
d: QuickJSDeferredPromise | QuickJSHandle
|
|
127
|
-
): QuickJSHandle {
|
|
100
|
+
export function handleFrom(d: QuickJSDeferredPromise | QuickJSHandle): QuickJSHandle {
|
|
128
101
|
return isQuickJSDeferredPromise(d) ? d.handle : d;
|
|
129
102
|
}
|