quickjs-emscripten-sync 1.3.0 → 1.5.1
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 +60 -37
- package/dist/index.d.ts +29 -22
- package/dist/quickjs-emscripten-sync.mjs +842 -0
- package/dist/quickjs-emscripten-sync.umd.js +15 -15
- package/package.json +12 -21
- package/src/default.ts +2 -2
- package/src/index.test.ts +159 -65
- package/src/index.ts +67 -66
- package/src/marshal/custom.test.ts +50 -0
- package/src/marshal/custom.ts +36 -0
- package/src/marshal/function.test.ts +60 -72
- package/src/marshal/function.ts +15 -18
- package/src/marshal/index.test.ts +88 -84
- package/src/marshal/index.ts +16 -18
- package/src/marshal/json.test.ts +32 -38
- package/src/marshal/json.ts +5 -7
- package/src/marshal/object.test.ts +52 -79
- package/src/marshal/object.ts +8 -15
- package/src/marshal/primitive.test.ts +16 -21
- package/src/marshal/primitive.ts +11 -10
- package/src/marshal/promise.test.ts +21 -22
- package/src/marshal/promise.ts +6 -13
- package/src/marshal/properties.test.ts +21 -26
- package/src/marshal/properties.ts +15 -17
- package/src/unmarshal/custom.test.ts +50 -0
- package/src/unmarshal/custom.ts +31 -0
- package/src/unmarshal/function.test.ts +52 -74
- package/src/unmarshal/function.ts +13 -22
- package/src/unmarshal/index.test.ts +58 -50
- package/src/unmarshal/index.ts +12 -13
- package/src/unmarshal/object.test.ts +37 -43
- package/src/unmarshal/object.ts +16 -20
- package/src/unmarshal/primitive.test.ts +15 -15
- package/src/unmarshal/primitive.ts +11 -18
- package/src/unmarshal/promise.test.ts +13 -13
- package/src/unmarshal/promise.ts +10 -19
- package/src/unmarshal/properties.test.ts +8 -8
- package/src/unmarshal/properties.ts +44 -45
- package/src/util.test.ts +2 -7
- package/src/util.ts +3 -8
- package/src/vmmap.test.ts +72 -88
- package/src/vmmap.ts +26 -44
- package/src/vmutil.test.ts +73 -89
- package/src/vmutil.ts +24 -47
- package/src/wrapper.test.ts +108 -148
- package/src/wrapper.ts +59 -62
- package/dist/quickjs-emscripten-sync.es.js +0 -951
- package/src/marshal/symbol.test.ts +0 -24
- package/src/marshal/symbol.ts +0 -20
- package/src/unmarshal/symbol.test.ts +0 -25
- package/src/unmarshal/symbol.ts +0 -12
package/src/vmutil.test.ts
CHANGED
|
@@ -15,16 +15,15 @@ import {
|
|
|
15
15
|
} from "./vmutil";
|
|
16
16
|
|
|
17
17
|
test("fn", async () => {
|
|
18
|
-
const
|
|
19
|
-
const vm = quickjs.createVm();
|
|
18
|
+
const ctx = (await getQuickJS()).newContext();
|
|
20
19
|
|
|
21
|
-
const f = fn(
|
|
22
|
-
expect(
|
|
20
|
+
const f = fn(ctx, "(a, b) => a + b");
|
|
21
|
+
expect(ctx.getNumber(f(undefined, ctx.newNumber(1), ctx.newNumber(2)))).toBe(3);
|
|
23
22
|
|
|
24
|
-
const obj =
|
|
25
|
-
|
|
26
|
-
const f2 = fn(
|
|
27
|
-
expect(
|
|
23
|
+
const obj = ctx.newObject();
|
|
24
|
+
ctx.setProp(obj, "a", ctx.newNumber(2));
|
|
25
|
+
const f2 = fn(ctx, "(function() { return this.a + 1; })");
|
|
26
|
+
expect(ctx.getNumber(f2(obj))).toBe(3);
|
|
28
27
|
|
|
29
28
|
obj.dispose();
|
|
30
29
|
expect(f.alive).toBe(true);
|
|
@@ -33,199 +32,184 @@ test("fn", async () => {
|
|
|
33
32
|
f.dispose();
|
|
34
33
|
expect(f.alive).toBe(false);
|
|
35
34
|
expect(f2.alive).toBe(false);
|
|
36
|
-
|
|
35
|
+
ctx.dispose();
|
|
37
36
|
});
|
|
38
37
|
|
|
39
38
|
test("call", async () => {
|
|
40
|
-
const
|
|
41
|
-
const vm = quickjs.createVm();
|
|
39
|
+
const ctx = (await getQuickJS()).newContext();
|
|
42
40
|
|
|
43
41
|
expect(
|
|
44
|
-
|
|
45
|
-
call(vm, "(a, b) => a + b", undefined, vm.newNumber(1), vm.newNumber(2))
|
|
46
|
-
)
|
|
42
|
+
ctx.getNumber(call(ctx, "(a, b) => a + b", undefined, ctx.newNumber(1), ctx.newNumber(2))),
|
|
47
43
|
).toBe(3);
|
|
48
44
|
|
|
49
|
-
const obj =
|
|
50
|
-
|
|
51
|
-
expect(
|
|
52
|
-
vm.getNumber(call(vm, "(function() { return this.a + 1; })", obj))
|
|
53
|
-
).toBe(3);
|
|
45
|
+
const obj = ctx.newObject();
|
|
46
|
+
ctx.setProp(obj, "a", ctx.newNumber(2));
|
|
47
|
+
expect(ctx.getNumber(call(ctx, "(function() { return this.a + 1; })", obj))).toBe(3);
|
|
54
48
|
|
|
55
49
|
obj.dispose();
|
|
56
|
-
|
|
50
|
+
ctx.dispose();
|
|
57
51
|
});
|
|
58
52
|
|
|
59
53
|
test("eq", async () => {
|
|
60
|
-
const
|
|
61
|
-
const vm = quickjs.createVm();
|
|
54
|
+
const ctx = (await getQuickJS()).newContext();
|
|
62
55
|
|
|
63
|
-
const math1 =
|
|
64
|
-
const math2 =
|
|
65
|
-
const obj =
|
|
56
|
+
const math1 = ctx.unwrapResult(ctx.evalCode("Math"));
|
|
57
|
+
const math2 = ctx.unwrapResult(ctx.evalCode("Math"));
|
|
58
|
+
const obj = ctx.newObject();
|
|
66
59
|
expect(math1 === math2).toBe(false);
|
|
67
|
-
expect(eq(
|
|
68
|
-
expect(eq(
|
|
60
|
+
expect(eq(ctx, math1, math2)).toBe(true);
|
|
61
|
+
expect(eq(ctx, math1, obj)).toBe(false);
|
|
69
62
|
|
|
70
63
|
math1.dispose();
|
|
71
64
|
math2.dispose();
|
|
72
65
|
obj.dispose();
|
|
73
|
-
|
|
66
|
+
ctx.dispose();
|
|
74
67
|
});
|
|
75
68
|
|
|
76
69
|
test("instanceOf", async () => {
|
|
77
|
-
const
|
|
78
|
-
const vm = quickjs.createVm();
|
|
70
|
+
const ctx = (await getQuickJS()).newContext();
|
|
79
71
|
|
|
80
|
-
const pr =
|
|
81
|
-
const func =
|
|
82
|
-
const p =
|
|
83
|
-
expect(instanceOf(
|
|
84
|
-
expect(instanceOf(
|
|
72
|
+
const pr = ctx.unwrapResult(ctx.evalCode("Promise"));
|
|
73
|
+
const func = ctx.unwrapResult(ctx.evalCode("(function() {})"));
|
|
74
|
+
const p = ctx.unwrapResult(ctx.evalCode("Promise.resolve()"));
|
|
75
|
+
expect(instanceOf(ctx, p, pr)).toBe(true);
|
|
76
|
+
expect(instanceOf(ctx, p, func)).toBe(false);
|
|
85
77
|
|
|
86
78
|
p.dispose();
|
|
87
79
|
pr.dispose();
|
|
88
80
|
func.dispose();
|
|
89
|
-
|
|
81
|
+
ctx.dispose();
|
|
90
82
|
});
|
|
91
83
|
|
|
92
84
|
test("isHandleObject", async () => {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
expect(isHandleObject(vm, num)).toBe(false);
|
|
85
|
+
const ctx = (await getQuickJS()).newContext();
|
|
86
|
+
|
|
87
|
+
const obj = ctx.newObject();
|
|
88
|
+
expect(isHandleObject(ctx, obj)).toBe(true);
|
|
89
|
+
const func = ctx.newFunction("", () => {});
|
|
90
|
+
expect(isHandleObject(ctx, func)).toBe(true);
|
|
91
|
+
const array = ctx.newArray();
|
|
92
|
+
expect(isHandleObject(ctx, array)).toBe(true);
|
|
93
|
+
const num = ctx.newNumber(NaN);
|
|
94
|
+
expect(isHandleObject(ctx, num)).toBe(false);
|
|
104
95
|
|
|
105
96
|
obj.dispose();
|
|
106
97
|
func.dispose();
|
|
107
98
|
array.dispose();
|
|
108
|
-
|
|
99
|
+
ctx.dispose();
|
|
109
100
|
});
|
|
110
101
|
|
|
111
102
|
test("json", async () => {
|
|
112
|
-
const
|
|
113
|
-
const vm = quickjs.createVm();
|
|
103
|
+
const ctx = (await getQuickJS()).newContext();
|
|
114
104
|
|
|
115
|
-
const handle = json(
|
|
105
|
+
const handle = json(ctx, {
|
|
116
106
|
hoge: { foo: ["bar"] },
|
|
117
107
|
});
|
|
118
|
-
expect(
|
|
119
|
-
|
|
120
|
-
).toBe(true);
|
|
121
|
-
expect(vm.typeof(json(vm, undefined))).toBe("undefined");
|
|
108
|
+
expect(ctx.dump(call(ctx, `a => a.hoge.foo[0] === "bar"`, undefined, handle))).toBe(true);
|
|
109
|
+
expect(ctx.typeof(json(ctx, undefined))).toBe("undefined");
|
|
122
110
|
|
|
123
111
|
handle.dispose();
|
|
124
|
-
|
|
112
|
+
ctx.dispose();
|
|
125
113
|
});
|
|
126
114
|
|
|
127
115
|
test("consumeAll", async () => {
|
|
128
|
-
const
|
|
129
|
-
const vm = quickjs.createVm();
|
|
116
|
+
const ctx = (await getQuickJS()).newContext();
|
|
130
117
|
|
|
131
118
|
const o = {};
|
|
132
119
|
|
|
133
|
-
const handles = [
|
|
120
|
+
const handles = [ctx.newObject(), ctx.newObject()];
|
|
134
121
|
expect(
|
|
135
122
|
consumeAll(
|
|
136
123
|
handles,
|
|
137
|
-
vi.fn(() => o)
|
|
138
|
-
)
|
|
124
|
+
vi.fn(() => o),
|
|
125
|
+
),
|
|
139
126
|
).toBe(o);
|
|
140
|
-
expect(handles.every(
|
|
127
|
+
expect(handles.every(h => !h.alive)).toBe(true);
|
|
141
128
|
|
|
142
|
-
const handles2 = [
|
|
129
|
+
const handles2 = [ctx.newObject(), ctx.newObject()];
|
|
143
130
|
expect(() =>
|
|
144
131
|
consumeAll(handles2, () => {
|
|
145
132
|
throw new Error("qes error");
|
|
146
|
-
})
|
|
133
|
+
}),
|
|
147
134
|
).toThrow("qes error");
|
|
148
|
-
expect(handles2.every(
|
|
135
|
+
expect(handles2.every(h => !h.alive)).toBe(true);
|
|
149
136
|
|
|
150
|
-
|
|
137
|
+
ctx.dispose();
|
|
151
138
|
});
|
|
152
139
|
|
|
153
140
|
test("mayConsume", async () => {
|
|
154
|
-
const
|
|
155
|
-
const vm = quickjs.createVm();
|
|
141
|
+
const ctx = (await getQuickJS()).newContext();
|
|
156
142
|
|
|
157
143
|
const o = {};
|
|
158
144
|
|
|
159
|
-
const handle =
|
|
145
|
+
const handle = ctx.newArray();
|
|
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
|
|
|
168
154
|
mayConsume([handle, true], () => {});
|
|
169
155
|
expect(handle.alive).toBe(false);
|
|
170
156
|
|
|
171
|
-
const handle2 =
|
|
157
|
+
const handle2 = ctx.newArray();
|
|
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
|
|
|
179
|
-
|
|
165
|
+
ctx.dispose();
|
|
180
166
|
});
|
|
181
167
|
|
|
182
168
|
test("mayConsumeAll", async () => {
|
|
183
|
-
const
|
|
184
|
-
const vm = quickjs.createVm();
|
|
169
|
+
const ctx = (await getQuickJS()).newContext();
|
|
185
170
|
|
|
186
171
|
const o = {};
|
|
187
172
|
|
|
188
173
|
const handles: [QuickJSHandle, boolean][] = [
|
|
189
|
-
[
|
|
190
|
-
[
|
|
174
|
+
[ctx.newObject(), false],
|
|
175
|
+
[ctx.newObject(), true],
|
|
191
176
|
];
|
|
192
177
|
expect(
|
|
193
178
|
mayConsumeAll(
|
|
194
179
|
handles,
|
|
195
|
-
vi.fn((..._: any[]) => o)
|
|
196
|
-
)
|
|
180
|
+
vi.fn((..._: any[]) => o),
|
|
181
|
+
),
|
|
197
182
|
).toBe(o);
|
|
198
183
|
expect(handles[0][0].alive).toBe(true);
|
|
199
184
|
expect(handles[1][0].alive).toBe(false);
|
|
200
185
|
|
|
201
186
|
const handles2: [QuickJSHandle, boolean][] = [
|
|
202
|
-
[
|
|
203
|
-
[
|
|
187
|
+
[ctx.newObject(), false],
|
|
188
|
+
[ctx.newObject(), true],
|
|
204
189
|
];
|
|
205
190
|
expect(() =>
|
|
206
191
|
mayConsumeAll(handles2, (..._args) => {
|
|
207
192
|
throw new Error("qes error");
|
|
208
|
-
})
|
|
193
|
+
}),
|
|
209
194
|
).toThrow("qes error");
|
|
210
195
|
expect(handles2[0][0].alive).toBe(true);
|
|
211
196
|
expect(handles2[1][0].alive).toBe(false);
|
|
212
197
|
|
|
213
198
|
handles[0][0].dispose();
|
|
214
199
|
handles2[0][0].dispose();
|
|
215
|
-
|
|
200
|
+
ctx.dispose();
|
|
216
201
|
});
|
|
217
202
|
|
|
218
203
|
test("handleFrom", async () => {
|
|
219
|
-
const
|
|
220
|
-
const vm = quickjs.createVm();
|
|
204
|
+
const ctx = (await getQuickJS()).newContext();
|
|
221
205
|
|
|
222
|
-
const handle =
|
|
223
|
-
const promise =
|
|
206
|
+
const handle = ctx.newObject();
|
|
207
|
+
const promise = ctx.newPromise();
|
|
224
208
|
|
|
225
209
|
expect(handleFrom(handle) === handle).toBe(true);
|
|
226
210
|
expect(handleFrom(promise) === promise.handle).toBe(true);
|
|
227
211
|
|
|
228
212
|
handle.dispose();
|
|
229
213
|
promise.dispose();
|
|
230
|
-
|
|
214
|
+
ctx.dispose();
|
|
231
215
|
});
|
package/src/vmutil.ts
CHANGED
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
Disposable,
|
|
3
|
-
|
|
3
|
+
QuickJSContext,
|
|
4
4
|
QuickJSHandle,
|
|
5
5
|
QuickJSDeferredPromise,
|
|
6
6
|
} from "quickjs-emscripten";
|
|
7
7
|
|
|
8
8
|
export function fn(
|
|
9
|
-
|
|
10
|
-
code: string
|
|
11
|
-
): ((
|
|
12
|
-
|
|
13
|
-
...args: QuickJSHandle[]
|
|
14
|
-
|
|
15
|
-
Disposable {
|
|
16
|
-
const handle = vm.unwrapResult(vm.evalCode(code));
|
|
17
|
-
const f = (
|
|
18
|
-
thisArg: QuickJSHandle | undefined,
|
|
19
|
-
...args: QuickJSHandle[]
|
|
20
|
-
): any => {
|
|
21
|
-
return vm.unwrapResult(
|
|
22
|
-
vm.callFunction(handle, thisArg ?? vm.undefined, ...args)
|
|
23
|
-
);
|
|
9
|
+
ctx: QuickJSContext,
|
|
10
|
+
code: string,
|
|
11
|
+
): ((thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]) => QuickJSHandle) & Disposable {
|
|
12
|
+
const handle = ctx.unwrapResult(ctx.evalCode(code));
|
|
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;
|
|
@@ -31,12 +22,12 @@ export function fn(
|
|
|
31
22
|
}
|
|
32
23
|
|
|
33
24
|
export function call(
|
|
34
|
-
|
|
25
|
+
ctx: QuickJSContext,
|
|
35
26
|
code: string,
|
|
36
27
|
thisArg?: QuickJSHandle,
|
|
37
28
|
...args: QuickJSHandle[]
|
|
38
29
|
): QuickJSHandle {
|
|
39
|
-
const f = fn(
|
|
30
|
+
const f = fn(ctx, code);
|
|
40
31
|
try {
|
|
41
32
|
return f(thisArg, ...args);
|
|
42
33
|
} finally {
|
|
@@ -44,39 +35,27 @@ export function call(
|
|
|
44
35
|
}
|
|
45
36
|
}
|
|
46
37
|
|
|
47
|
-
export function eq(
|
|
48
|
-
return
|
|
38
|
+
export function eq(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean {
|
|
39
|
+
return ctx.dump(call(ctx, "Object.is", undefined, a, b));
|
|
49
40
|
}
|
|
50
41
|
|
|
51
|
-
export function instanceOf(
|
|
52
|
-
|
|
53
|
-
a: QuickJSHandle,
|
|
54
|
-
b: QuickJSHandle
|
|
55
|
-
): boolean {
|
|
56
|
-
return vm.dump(call(vm, "(a, b) => a instanceof b", undefined, a, b));
|
|
42
|
+
export function instanceOf(ctx: QuickJSContext, a: QuickJSHandle, b: QuickJSHandle): boolean {
|
|
43
|
+
return ctx.dump(call(ctx, "(a, b) => a instanceof b", undefined, a, b));
|
|
57
44
|
}
|
|
58
45
|
|
|
59
|
-
export function isHandleObject(
|
|
60
|
-
return
|
|
61
|
-
call(
|
|
62
|
-
vm,
|
|
63
|
-
`a => typeof a === "object" && a !== null || typeof a === "function"`,
|
|
64
|
-
undefined,
|
|
65
|
-
a
|
|
66
|
-
)
|
|
46
|
+
export function isHandleObject(ctx: QuickJSContext, h: QuickJSHandle): boolean {
|
|
47
|
+
return ctx.dump(
|
|
48
|
+
call(ctx, `a => typeof a === "object" && a !== null || typeof a === "function"`, undefined, h),
|
|
67
49
|
);
|
|
68
50
|
}
|
|
69
51
|
|
|
70
|
-
export function json(
|
|
52
|
+
export function json(ctx: QuickJSContext, target: any): QuickJSHandle {
|
|
71
53
|
const json = JSON.stringify(target);
|
|
72
|
-
if (!json) return
|
|
73
|
-
return call(
|
|
54
|
+
if (!json) return ctx.undefined;
|
|
55
|
+
return call(ctx, `JSON.parse`, undefined, ctx.newString(json));
|
|
74
56
|
}
|
|
75
57
|
|
|
76
|
-
export function consumeAll<T extends QuickJSHandle[], K>(
|
|
77
|
-
handles: T,
|
|
78
|
-
cb: (handles: T) => K
|
|
79
|
-
): K {
|
|
58
|
+
export function consumeAll<T extends QuickJSHandle[], K>(handles: T, cb: (handles: T) => K): K {
|
|
80
59
|
try {
|
|
81
60
|
return cb(handles);
|
|
82
61
|
} finally {
|
|
@@ -88,7 +67,7 @@ export function consumeAll<T extends QuickJSHandle[], K>(
|
|
|
88
67
|
|
|
89
68
|
export function mayConsume<T>(
|
|
90
69
|
[handle, shouldBeDisposed]: [QuickJSHandle, boolean],
|
|
91
|
-
fn: (h: QuickJSHandle) => T
|
|
70
|
+
fn: (h: QuickJSHandle) => T,
|
|
92
71
|
) {
|
|
93
72
|
try {
|
|
94
73
|
return fn(handle);
|
|
@@ -101,10 +80,10 @@ export function mayConsume<T>(
|
|
|
101
80
|
|
|
102
81
|
export function mayConsumeAll<T, H extends QuickJSHandle[]>(
|
|
103
82
|
handles: { [P in keyof H]: [QuickJSHandle, boolean] },
|
|
104
|
-
fn: (...args: H) => T
|
|
83
|
+
fn: (...args: H) => T,
|
|
105
84
|
) {
|
|
106
85
|
try {
|
|
107
|
-
return fn(...(handles.map(
|
|
86
|
+
return fn(...(handles.map(h => h[0]) as H));
|
|
108
87
|
} finally {
|
|
109
88
|
for (const [handle, shouldBeDisposed] of handles) {
|
|
110
89
|
if (shouldBeDisposed) {
|
|
@@ -118,8 +97,6 @@ function isQuickJSDeferredPromise(d: Disposable): d is QuickJSDeferredPromise {
|
|
|
118
97
|
return "handle" in d;
|
|
119
98
|
}
|
|
120
99
|
|
|
121
|
-
export function handleFrom(
|
|
122
|
-
d: QuickJSDeferredPromise | QuickJSHandle
|
|
123
|
-
): QuickJSHandle {
|
|
100
|
+
export function handleFrom(d: QuickJSDeferredPromise | QuickJSHandle): QuickJSHandle {
|
|
124
101
|
return isQuickJSDeferredPromise(d) ? d.handle : d;
|
|
125
102
|
}
|