quickjs-emscripten-sync 1.8.4 → 1.9.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 +231 -150
- package/dist/index.d.ts +50 -7
- package/dist/quickjs-emscripten-sync.js +652 -387
- package/dist/quickjs-emscripten-sync.umd.cjs +17 -8
- package/package.json +5 -2
- package/src/index.test.ts +250 -5
- package/src/index.ts +126 -9
- package/src/jsonleak.test.ts +178 -0
- package/src/marshal/custom.ts +16 -2
- package/src/marshal/function.ts +6 -2
- package/src/marshal/hostref.ts +18 -0
- package/src/marshal/index.ts +25 -2
- package/src/marshal/mapset.ts +37 -0
- package/src/marshal/object.ts +4 -1
- package/src/marshal/primitive.ts +2 -11
- package/src/marshal/properties.ts +19 -6
- package/src/unmarshal/custom.ts +35 -4
- package/src/unmarshal/function.ts +2 -2
- package/src/unmarshal/hostref.ts +21 -0
- package/src/unmarshal/index.ts +21 -1
- package/src/unmarshal/mapset.ts +43 -0
- package/src/unmarshal/object.ts +16 -20
- package/src/unmarshal/primitive.ts +6 -17
- package/src/unmarshal/properties.ts +7 -6
- package/src/vmmap.ts +59 -69
- package/src/vmutil.ts +97 -12
- package/src/wrapper.ts +97 -30
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Intrinsics } from 'quickjs-emscripten';
|
|
2
|
+
import { QuickJSAsyncContext } from 'quickjs-emscripten';
|
|
2
3
|
import { QuickJSContext } from 'quickjs-emscripten';
|
|
3
4
|
import { QuickJSDeferredPromise } from 'quickjs-emscripten';
|
|
4
5
|
import { QuickJSHandle } from 'quickjs-emscripten';
|
|
@@ -13,6 +14,7 @@ export declare class Arena {
|
|
|
13
14
|
_map: VMMap;
|
|
14
15
|
_registeredMap: VMMap;
|
|
15
16
|
_registeredMapDispose: Set<any>;
|
|
17
|
+
_transientHandles: Set<QuickJSHandle>;
|
|
16
18
|
_sync: Set<any>;
|
|
17
19
|
_temporalSync: Set<any>;
|
|
18
20
|
_symbol: symbol;
|
|
@@ -24,6 +26,8 @@ export declare class Arena {
|
|
|
24
26
|
* Dispose of the arena and managed handles. This method won't dispose the VM itself, so the VM has to be disposed of manually.
|
|
25
27
|
*/
|
|
26
28
|
dispose(): void;
|
|
29
|
+
/** Allows `using arena = new Arena(...)` to dispose the arena automatically. */
|
|
30
|
+
[Symbol.dispose](): void;
|
|
27
31
|
/**
|
|
28
32
|
* Evaluate JS code in the VM and get the result as an object on the host side. It also converts and re-throws error objects when an error is thrown during evaluation.
|
|
29
33
|
*/
|
|
@@ -199,8 +203,12 @@ export declare class Arena {
|
|
|
199
203
|
_unwrapResult<T>(result: SuccessOrFail<T, QuickJSHandle>): T;
|
|
200
204
|
_unwrapResultAndUnmarshal(result: VmCallResult<QuickJSHandle> | undefined): any;
|
|
201
205
|
_isMarshalable: (t: unknown) => boolean | "json";
|
|
206
|
+
_marshalByReference: (t: unknown) => boolean;
|
|
207
|
+
_registerHostRef: (t: unknown, handle: QuickJSHandle) => QuickJSHandle;
|
|
202
208
|
_marshalFind: (t: unknown) => QuickJSHandle | undefined;
|
|
203
209
|
_marshalPre: (t: unknown, h: QuickJSHandle | QuickJSDeferredPromise, mode: true | "json" | undefined) => Wrapped<QuickJSHandle> | undefined;
|
|
210
|
+
_registerTransient: (handle: QuickJSHandle) => void;
|
|
211
|
+
_disposeTransient: (handle: QuickJSHandle) => void;
|
|
204
212
|
_marshalPreApply: (target: (...args: any[]) => any, that: unknown, args: unknown[]) => void;
|
|
205
213
|
_marshal: (target: any) => [QuickJSHandle, boolean];
|
|
206
214
|
_preUnmarshal: (t: any, h: QuickJSHandle) => Wrapped<any>;
|
|
@@ -215,6 +223,23 @@ export declare class Arena {
|
|
|
215
223
|
_unwrapHandle(target: QuickJSHandle): [QuickJSHandle, boolean];
|
|
216
224
|
}
|
|
217
225
|
|
|
226
|
+
/**
|
|
227
|
+
* An Arena backed by a {@link QuickJSAsyncContext}. In addition to everything
|
|
228
|
+
* `Arena` offers, it can evaluate code asynchronously with `evalCodeAsync`,
|
|
229
|
+
* which lets the VM await host promises (e.g. async module loaders or async
|
|
230
|
+
* functions exposed from the host) without manually pumping pending jobs.
|
|
231
|
+
*/
|
|
232
|
+
export declare class AsyncArena extends Arena {
|
|
233
|
+
asyncContext: QuickJSAsyncContext;
|
|
234
|
+
constructor(ctx: QuickJSAsyncContext, options?: Options);
|
|
235
|
+
/**
|
|
236
|
+
* Evaluate JS code asynchronously in the VM and get the result on the host
|
|
237
|
+
* side. Like `evalCode`, it converts and re-throws errors thrown during
|
|
238
|
+
* evaluation. Use this when the code awaits host-provided promises.
|
|
239
|
+
*/
|
|
240
|
+
evalCodeAsync<T = any>(code: string, filename?: string): Promise<T>;
|
|
241
|
+
}
|
|
242
|
+
|
|
218
243
|
export declare function call(ctx: QuickJSContext, code: string, thisArg?: QuickJSHandle, ...args: QuickJSHandle[]): QuickJSHandle;
|
|
219
244
|
|
|
220
245
|
/**
|
|
@@ -261,13 +286,21 @@ export declare type Options = {
|
|
|
261
286
|
compat?: boolean;
|
|
262
287
|
/** Experimental: use QuickJSContextEx, which wraps existing QuickJSContext. */
|
|
263
288
|
experimentalContextEx?: boolean;
|
|
289
|
+
/** Globally enable sync mode (default `true`). When `false`, objects are not wrapped with proxies and marshalled handles are disposed after use, so `arena.sync` has no effect but objects are not retained for their whole lifetime. Useful to avoid memory growth when frequently exchanging short-lived objects. */
|
|
290
|
+
syncEnabled?: boolean;
|
|
291
|
+
/** A callback that returns whether an object should be passed to the VM by reference (as an opaque HostRef) instead of being marshalled by value/proxy. The guest cannot read such objects, but can hold them and pass them back to the host, where they resolve to the original object. */
|
|
292
|
+
marshalByReference?: (target: any) => boolean;
|
|
264
293
|
};
|
|
265
294
|
|
|
266
295
|
declare type Options_2 = {
|
|
267
296
|
ctx: QuickJSContext;
|
|
268
297
|
unmarshal: (handle: QuickJSHandle) => unknown;
|
|
269
298
|
isMarshalable?: (target: unknown) => boolean | "json";
|
|
299
|
+
marshalByReference?: (target: unknown) => boolean;
|
|
300
|
+
registerHostRef?: (target: unknown, handle: QuickJSHandle) => QuickJSHandle;
|
|
270
301
|
find: (target: unknown) => QuickJSHandle | undefined;
|
|
302
|
+
registerTransient?: (handle: QuickJSHandle) => void;
|
|
303
|
+
disposeTransient?: (handle: QuickJSHandle) => void;
|
|
271
304
|
pre: (target: unknown, handle: QuickJSHandle | QuickJSDeferredPromise, mode: true | "json" | undefined) => QuickJSHandle | undefined;
|
|
272
305
|
preApply?: (target: (...args: any[]) => any, thisArg: unknown, args: unknown[]) => any;
|
|
273
306
|
custom?: Iterable<(obj: unknown, ctx: QuickJSContext) => QuickJSHandle | undefined>;
|
|
@@ -280,6 +313,8 @@ declare type Options_3 = {
|
|
|
280
313
|
find: (handle: QuickJSHandle) => unknown | undefined;
|
|
281
314
|
pre: <T = unknown>(target: T, handle: QuickJSHandle) => T | undefined;
|
|
282
315
|
custom?: Iterable<(obj: QuickJSHandle, ctx: QuickJSContext) => any>;
|
|
316
|
+
/** When true, resolve opaque HostRef handles back to their host value. */
|
|
317
|
+
hostRef?: boolean;
|
|
283
318
|
};
|
|
284
319
|
|
|
285
320
|
declare type QuickJSContextEx = QuickJSContext & {
|
|
@@ -288,19 +323,28 @@ declare type QuickJSContextEx = QuickJSContext & {
|
|
|
288
323
|
|
|
289
324
|
export declare function unmarshal(handle: QuickJSHandle, options: Options_3): any;
|
|
290
325
|
|
|
326
|
+
/**
|
|
327
|
+
* Bidirectional map between host values and QuickJS handles.
|
|
328
|
+
*
|
|
329
|
+
* Each registered pair gets a numeric id. A value may be registered under two
|
|
330
|
+
* keys (e.g. a proxy-wrapped object and the underlying object), each with its
|
|
331
|
+
* own handle, so every lookup direction is backed by an explicit map and id
|
|
332
|
+
* reverse-lookups, keeping `delete` O(1).
|
|
333
|
+
*/
|
|
291
334
|
export declare class VMMap {
|
|
292
335
|
ctx: QuickJSContext;
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
336
|
+
_keyToId: Map<any, number>;
|
|
337
|
+
_key2ToId: Map<any, number>;
|
|
338
|
+
_idToHandle: Map<number, QuickJSHandle>;
|
|
339
|
+
_idToHandle2: Map<number, QuickJSHandle>;
|
|
340
|
+
_idToKey: Map<number, any>;
|
|
341
|
+
_idToKey2: Map<number, any>;
|
|
298
342
|
_disposables: Set<QuickJSHandle>;
|
|
299
343
|
_mapGet: QuickJSHandle;
|
|
300
344
|
_mapSet: QuickJSHandle;
|
|
301
345
|
_mapDelete: QuickJSHandle;
|
|
302
346
|
_mapClear: QuickJSHandle;
|
|
303
|
-
|
|
347
|
+
_nextId: number;
|
|
304
348
|
constructor(ctx: QuickJSContext);
|
|
305
349
|
set(key: any, handle: QuickJSHandle, key2?: any, handle2?: QuickJSHandle): boolean;
|
|
306
350
|
merge(iteratable: Iterable<[any, QuickJSHandle | undefined] | [any, QuickJSHandle | undefined, any, QuickJSHandle | undefined]> | undefined): void;
|
|
@@ -315,7 +359,6 @@ export declare class VMMap {
|
|
|
315
359
|
dispose(): void;
|
|
316
360
|
get size(): number;
|
|
317
361
|
[Symbol.iterator](): Iterator<[any, QuickJSHandle, any, QuickJSHandle | undefined]>;
|
|
318
|
-
_get2(num: number): any;
|
|
319
362
|
_call(fn: QuickJSHandle, thisArg: QuickJSHandle | undefined, ...args: QuickJSHandle[]): QuickJSHandle;
|
|
320
363
|
}
|
|
321
364
|
|