poe-code 14.0.83 → 14.0.84
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/dist/index.js +588 -93
- package/dist/index.js.map +4 -4
- package/dist/metafile.json +1 -1
- package/package.json +1 -1
- package/packages/safe-js/dist/chunks/{chunk-37V6Q4K3.js → chunk-2EZQJQ2C.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-PT7PBLVT.js → chunk-CYVI4ZUK.js} +536 -85
- package/packages/safe-js/dist/chunks/chunk-CYVI4ZUK.js.map +7 -0
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/interp/array-buffer.d.ts +12 -0
- package/packages/safe-js/dist/interp/array-buffer.js +33 -0
- package/packages/safe-js/dist/interp/float32.d.ts +6 -1
- package/packages/safe-js/dist/interp/float32.js +38 -10
- package/packages/safe-js/dist/interp/globals/array-buffer.d.ts +3 -0
- package/packages/safe-js/dist/interp/globals/array-buffer.js +112 -0
- package/packages/safe-js/dist/interp/globals/float32array.d.ts +1 -1
- package/packages/safe-js/dist/interp/globals/float32array.js +104 -15
- package/packages/safe-js/dist/interp/globals.d.ts +1 -0
- package/packages/safe-js/dist/interp/globals.js +2 -0
- package/packages/safe-js/dist/interp/host-bridge.d.ts +1 -0
- package/packages/safe-js/dist/interp/host-bridge.js +21 -0
- package/packages/safe-js/dist/interp/host-call.js +26 -2
- package/packages/safe-js/dist/interp/methods/array-iterator.js +1 -1
- package/packages/safe-js/dist/interp/object-model.js +6 -0
- package/packages/safe-js/dist/interp/values.d.ts +1 -1
- package/packages/safe-js/dist/interp/values.js +47 -5
- package/packages/safe-js/dist/lint/rules/known-globals.d.ts +1 -1
- package/packages/safe-js/dist/lint/rules/known-globals.js +1 -0
- package/packages/safe-js/dist/snapshot/array-buffer.d.ts +13 -0
- package/packages/safe-js/dist/snapshot/array-buffer.js +40 -0
- package/packages/safe-js/dist/snapshot/dump-format.js +25 -9
- package/packages/safe-js/dist/snapshot/float32array.d.ts +8 -1
- package/packages/safe-js/dist/snapshot/float32array.js +23 -5
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +5 -0
- package/packages/safe-js/dist/snapshot/replay-data.js +35 -10
- package/packages/safe-js/dist/snapshot/restore.js +13 -1
- package/packages/safe-js/dist/snapshot/serialize.d.ts +5 -2
- package/packages/safe-js/dist/snapshot/serialize.js +20 -11
- package/packages/safe-js/dist/snapshot/validation.js +11 -1
- package/packages/safe-js/dist/chunks/chunk-PT7PBLVT.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-37V6Q4K3.js.map → chunk-2EZQJQ2C.js.map} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash, randomUUID } from "node:crypto";
|
|
2
|
-
import { float32DataProperties, float32Storage, isFloat32Array } from "./float32.js";
|
|
2
|
+
import { float32DataProperties, float32Storage, float32ViewLayouts, isFloat32Array } from "./float32.js";
|
|
3
|
+
import { arrayBufferDataProperties, arrayBufferLength, arrayBufferOptions, isSandboxArrayBuffer } from "./array-buffer.js";
|
|
3
4
|
import { copyNativeDate, serializedDateTime } from "./date.js";
|
|
4
5
|
import { cloneSandboxValue, createSandboxClosure, defineOwnDataProperty, isArrayIndexKey, measureSandboxData } from "./values.js";
|
|
5
6
|
import { CompileScope } from "./regex/compile-guard.js";
|
|
@@ -585,8 +586,26 @@ function normalize(value, seen) {
|
|
|
585
586
|
const date = copyNativeDate(value);
|
|
586
587
|
if (date !== undefined)
|
|
587
588
|
return Object.assign(Object.create(null), { $type: "date", time: serializedDateTime(date) });
|
|
589
|
+
if (isSandboxArrayBuffer(value)) {
|
|
590
|
+
arrayBufferLength(value);
|
|
591
|
+
const properties = Object.create(null);
|
|
592
|
+
const entries = [];
|
|
593
|
+
for (const [key, descriptor] of arrayBufferDataProperties(value)) {
|
|
594
|
+
if (typeof key === "symbol")
|
|
595
|
+
throw new TypeError("ArrayBuffer symbol properties require an explicit host-call identity.");
|
|
596
|
+
entries.push([key, descriptor]);
|
|
597
|
+
}
|
|
598
|
+
for (const [key, descriptor] of entries.sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0))
|
|
599
|
+
defineOwnDataProperty(properties, key, normalize(descriptor.value, seen));
|
|
600
|
+
return Object.assign(Object.create(null), { $type: "arraybuffer",
|
|
601
|
+
bytes: normalize(Array.from(new Uint8Array(value)), seen), ...arrayBufferOptions(value), properties });
|
|
602
|
+
}
|
|
588
603
|
if (isFloat32Array(value)) {
|
|
589
604
|
const storage = float32Storage(value);
|
|
605
|
+
const resizable = arrayBufferOptions(storage.buffer) !== undefined;
|
|
606
|
+
const layout = resizable ? float32ViewLayouts.get(value) : undefined;
|
|
607
|
+
if (resizable && layout === undefined)
|
|
608
|
+
throw new TypeError("Resizable Float32Array host-call identity requires known view layout.");
|
|
590
609
|
const properties = Object.create(null);
|
|
591
610
|
for (const [key, descriptor] of float32DataProperties(value).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0)) {
|
|
592
611
|
defineOwnDataProperty(properties, key, normalize(descriptor.value, seen));
|
|
@@ -596,7 +615,12 @@ function normalize(value, seen) {
|
|
|
596
615
|
bytes: normalize(Array.from(new Uint8Array(storage.buffer)), seen),
|
|
597
616
|
byteOffset: storage.byteOffset,
|
|
598
617
|
length: storage.length,
|
|
599
|
-
properties
|
|
618
|
+
properties,
|
|
619
|
+
...(resizable || Reflect.ownKeys(storage.buffer).length > 0
|
|
620
|
+
? { buffer: normalize(storage.buffer, seen) } : {}),
|
|
621
|
+
...(layout === undefined ? {} : { viewLayout: {
|
|
622
|
+
byteOffset: layout.byteOffset, length: layout.length ?? null
|
|
623
|
+
} })
|
|
600
624
|
});
|
|
601
625
|
}
|
|
602
626
|
if (Array.isArray(value)) {
|
|
@@ -18,7 +18,7 @@ export async function nextArrayIterator(value, budget, context) {
|
|
|
18
18
|
?? getSandboxPropertyDescriptor(source, key, budget) ?? { value: undefined }, source, context);
|
|
19
19
|
try {
|
|
20
20
|
budget.visitNode();
|
|
21
|
-
const number = isFloat32Array(source) ? float32Storage(source).length
|
|
21
|
+
const number = isFloat32Array(source) ? float32Storage(source, true).length
|
|
22
22
|
: await sandboxNumber(await read("length"), budget, context);
|
|
23
23
|
const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
|
|
24
24
|
if (index >= length) {
|
|
@@ -10,6 +10,7 @@ import { getHostObjectMember, isGuestHostObject, isLiveCapability } from "./host
|
|
|
10
10
|
import { errorPrototypes } from "./error-prototypes.js";
|
|
11
11
|
import { float32Properties, isFloat32Array, isFloat32Index } from "./float32.js";
|
|
12
12
|
import { float32Prototypes } from "./float32-prototypes.js";
|
|
13
|
+
import { arrayBufferPrototypes, isSandboxArrayBuffer } from "./array-buffer.js";
|
|
13
14
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
14
15
|
import { boxedValue, isSandboxBox } from "./boxed.js";
|
|
15
16
|
import { isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, getPromiseProperties, isSandboxRegex, getRegexProperties, getCollectionProperties, isSandboxSet } from "./values.js";
|
|
@@ -279,12 +280,15 @@ export function releaseObjectPrototype(budget) {
|
|
|
279
280
|
generatorPrototypes.delete(budget);
|
|
280
281
|
errorPrototypes.delete(budget);
|
|
281
282
|
float32Prototypes.delete(budget);
|
|
283
|
+
arrayBufferPrototypes.delete(budget);
|
|
282
284
|
initialRegexDescriptors.delete(budget);
|
|
283
285
|
intrinsicPrototypes.delete(budget);
|
|
284
286
|
}
|
|
285
287
|
export function getSandboxPrototype(value, budget) {
|
|
286
288
|
if (prototypes.has(value))
|
|
287
289
|
return prototypes.get(value) ?? null;
|
|
290
|
+
if (isSandboxArrayBuffer(value))
|
|
291
|
+
return budget === undefined ? null : arrayBufferPrototypes.get(budget) ?? null;
|
|
288
292
|
if (isFloat32Array(value))
|
|
289
293
|
return budget === undefined ? null : float32Prototypes.get(budget) ?? null;
|
|
290
294
|
// Host transport records are data-only. Resolve their default prototype in
|
|
@@ -427,6 +431,8 @@ export function setSandboxPrototype(value, prototype, budget) {
|
|
|
427
431
|
prototypes.set(value, prototype);
|
|
428
432
|
}
|
|
429
433
|
function isPrototypeRecord(value) {
|
|
434
|
+
if (isSandboxArrayBuffer(value))
|
|
435
|
+
return true;
|
|
430
436
|
if (isFloat32Array(value))
|
|
431
437
|
return true;
|
|
432
438
|
if (isGuestClosure(value))
|
|
@@ -17,7 +17,7 @@ declare const sandboxRegexBrand: unique symbol;
|
|
|
17
17
|
declare const sandboxRegexPattern: unique symbol;
|
|
18
18
|
declare const sandboxRetainedValues: unique symbol;
|
|
19
19
|
export type SandboxPrimitive = string | number | bigint | boolean | symbol | null | undefined;
|
|
20
|
-
export type SandboxValue = SandboxPrimitive | Date | Float32Array | SandboxObject | SandboxArray | SandboxClosure | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | SandboxMap | SandboxSet | SandboxPromise | SandboxRegex;
|
|
20
|
+
export type SandboxValue = SandboxPrimitive | Date | Float32Array | ArrayBuffer | SandboxObject | SandboxArray | SandboxClosure | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | SandboxMap | SandboxSet | SandboxPromise | SandboxRegex;
|
|
21
21
|
export type SandboxObject = {
|
|
22
22
|
[key: string]: SandboxValue;
|
|
23
23
|
[key: symbol]: SandboxValue;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { bindOtelSpan, getBoundOtelSpan } from "../observability/otel.js";
|
|
2
|
+
import { arrayBufferDataProperties, arrayBufferLength, copyArrayBufferStorage, isSandboxArrayBuffer } from "./array-buffer.js";
|
|
2
3
|
import { internalSymbols } from "./internal-symbols.js";
|
|
3
4
|
import { getIntrinsicIdentity } from "./intrinsics.js";
|
|
4
5
|
import { getGeneratorProperties } from "./generator-properties.js";
|
|
@@ -399,12 +400,11 @@ export function measureSandboxData(values, options = {}) {
|
|
|
399
400
|
const prototype = getSandboxPrototype(value);
|
|
400
401
|
if (prototype !== null)
|
|
401
402
|
visit(prototype, depth + 1);
|
|
403
|
+
if (isSandboxArrayBuffer(value))
|
|
404
|
+
usage += arrayBufferLength(value);
|
|
402
405
|
if (isFloat32Array(value)) {
|
|
403
406
|
const storage = float32Storage(value);
|
|
404
|
-
|
|
405
|
-
seen.add(storage.buffer);
|
|
406
|
-
usage += storage.byteLength;
|
|
407
|
-
}
|
|
407
|
+
visit(storage.buffer, depth + 1);
|
|
408
408
|
for (const [key, descriptor] of float32Properties(value)) {
|
|
409
409
|
usage += 1;
|
|
410
410
|
if (typeof key === "string")
|
|
@@ -587,7 +587,7 @@ export function measureSandboxData(values, options = {}) {
|
|
|
587
587
|
if (descriptor !== undefined)
|
|
588
588
|
descriptors.push([key, descriptor]);
|
|
589
589
|
}
|
|
590
|
-
const includeNonEnumerable = isSandboxDate(value) || sandboxErrorTypes.has(value) || hasManagedDescriptors(value);
|
|
590
|
+
const includeNonEnumerable = isSandboxDate(value) || isSandboxArrayBuffer(value) || sandboxErrorTypes.has(value) || hasManagedDescriptors(value);
|
|
591
591
|
for (const [key, descriptor] of descriptors) {
|
|
592
592
|
if (!descriptor.enumerable && !includeNonEnumerable)
|
|
593
593
|
continue;
|
|
@@ -804,6 +804,20 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
804
804
|
}
|
|
805
805
|
return sandboxPromise;
|
|
806
806
|
}
|
|
807
|
+
if (isSandboxArrayBuffer(value)) {
|
|
808
|
+
const existing = state.seen.get(value);
|
|
809
|
+
if (existing !== undefined)
|
|
810
|
+
return existing;
|
|
811
|
+
const copy = copyArrayBufferStorage(value, state);
|
|
812
|
+
state.seen.set(value, copy);
|
|
813
|
+
for (const [key, descriptor] of arrayBufferDataProperties(value)) {
|
|
814
|
+
Object.defineProperty(copy, key, { ...descriptor,
|
|
815
|
+
value: copyToSandbox(descriptor.value, state, joinPath(path, key), cloneSandboxCollections, depth + 1) });
|
|
816
|
+
}
|
|
817
|
+
if (!Object.isExtensible(value))
|
|
818
|
+
Object.preventExtensions(copy);
|
|
819
|
+
return copy;
|
|
820
|
+
}
|
|
807
821
|
if (nodeTypes.isDate(value)) {
|
|
808
822
|
const existing = state.seen.get(value);
|
|
809
823
|
if (existing !== undefined)
|
|
@@ -827,6 +841,7 @@ function copyToSandbox(value, state, path = "<root>", cloneSandboxCollections =
|
|
|
827
841
|
return existing;
|
|
828
842
|
const copy = copyFloat32Storage(value, state);
|
|
829
843
|
state.seen.set(value, copy);
|
|
844
|
+
copyToSandbox(float32Storage(value).buffer, state, `${path}.buffer`, cloneSandboxCollections, depth + 1);
|
|
830
845
|
for (const [key, descriptor] of float32DataProperties(value)) {
|
|
831
846
|
Object.defineProperty(copy, key, {
|
|
832
847
|
...descriptor,
|
|
@@ -1021,6 +1036,7 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
1021
1036
|
return existing;
|
|
1022
1037
|
const copy = copyFloat32Storage(value, state);
|
|
1023
1038
|
state.seen.set(value, copy);
|
|
1039
|
+
copyFromSandbox(float32Storage(value).buffer, state, `${path}.buffer`, options, depth + 1);
|
|
1024
1040
|
for (const [key, descriptor] of float32DataProperties(value)) {
|
|
1025
1041
|
Object.defineProperty(copy, key, {
|
|
1026
1042
|
...descriptor,
|
|
@@ -1031,6 +1047,20 @@ function copyFromSandbox(value, state, path = "<root>", options, depth = 0) {
|
|
|
1031
1047
|
Object.preventExtensions(copy);
|
|
1032
1048
|
return copy;
|
|
1033
1049
|
}
|
|
1050
|
+
if (isSandboxArrayBuffer(value)) {
|
|
1051
|
+
const existing = state.seen.get(value);
|
|
1052
|
+
if (existing !== undefined)
|
|
1053
|
+
return existing;
|
|
1054
|
+
const copy = copyArrayBufferStorage(value, state);
|
|
1055
|
+
state.seen.set(value, copy);
|
|
1056
|
+
for (const [key, descriptor] of arrayBufferDataProperties(value)) {
|
|
1057
|
+
Object.defineProperty(copy, key, { ...descriptor,
|
|
1058
|
+
value: copyFromSandbox(descriptor.value, state, joinPath(path, key), options, depth + 1) });
|
|
1059
|
+
}
|
|
1060
|
+
if (!Object.isExtensible(value))
|
|
1061
|
+
Object.preventExtensions(copy);
|
|
1062
|
+
return copy;
|
|
1063
|
+
}
|
|
1034
1064
|
if (isSandboxDate(value)) {
|
|
1035
1065
|
const existing = state.seen.get(value);
|
|
1036
1066
|
if (existing !== undefined)
|
|
@@ -1188,6 +1218,18 @@ function allocateSandboxValue(value, budget, seen) {
|
|
|
1188
1218
|
budget.allocateString(value);
|
|
1189
1219
|
return;
|
|
1190
1220
|
}
|
|
1221
|
+
if (isSandboxArrayBuffer(value)) {
|
|
1222
|
+
if (seen.has(value))
|
|
1223
|
+
return;
|
|
1224
|
+
seen.add(value);
|
|
1225
|
+
budget.allocateArrayLength(arrayBufferLength(value));
|
|
1226
|
+
for (const [key, descriptor] of arrayBufferDataProperties(value)) {
|
|
1227
|
+
if (typeof key === "string")
|
|
1228
|
+
budget.allocateString(key);
|
|
1229
|
+
allocateSandboxValue(descriptor.value, budget, seen);
|
|
1230
|
+
}
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1191
1233
|
if (isSandboxBox(value)) {
|
|
1192
1234
|
if (seen.has(value))
|
|
1193
1235
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const KNOWN_RUNTIME_GLOBALS: readonly ["AggregateError", "Array", "Boolean", "BigInt", "Date", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "Error", "EvalError", "Infinity", "isFinite", "isNaN", "JSON", "Map", "Float32Array", "Math", "NaN", "Number", "Object", "parseFloat", "parseInt", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "String", "Symbol", "structuredClone", "SyntaxError", "TypeError", "URIError", "console"];
|
|
1
|
+
export declare const KNOWN_RUNTIME_GLOBALS: readonly ["AggregateError", "Array", "ArrayBuffer", "Boolean", "BigInt", "Date", "decodeURI", "decodeURIComponent", "encodeURI", "encodeURIComponent", "Error", "EvalError", "Infinity", "isFinite", "isNaN", "JSON", "Map", "Float32Array", "Math", "NaN", "Number", "Object", "parseFloat", "parseInt", "Promise", "RangeError", "ReferenceError", "RegExp", "Set", "String", "Symbol", "structuredClone", "SyntaxError", "TypeError", "URIError", "console"];
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { GuestObjectState } from "./guest-heap.js";
|
|
2
|
+
export type ArrayBufferData<TReference> = {
|
|
3
|
+
kind: "arraybuffer";
|
|
4
|
+
} & ({
|
|
5
|
+
bytes: number[];
|
|
6
|
+
maxByteLength?: number;
|
|
7
|
+
} | {
|
|
8
|
+
buffer: TReference;
|
|
9
|
+
});
|
|
10
|
+
export declare function captureArrayBufferState<T>(value: ArrayBuffer, encode: (value: unknown) => T): GuestObjectState<T>;
|
|
11
|
+
export declare function encodeArrayBufferStorage<T>(value: ArrayBuffer, id: number, buffers: WeakMap<ArrayBuffer, number>, reference: (id: number) => T): ArrayBufferData<T>;
|
|
12
|
+
export declare function validateArrayBufferStorage(value: Record<string, unknown>): void;
|
|
13
|
+
export declare function decodeArrayBufferStorage(value: Record<string, unknown>, resolve: (reference: unknown) => unknown): ArrayBuffer;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { arrayBufferLength, arrayBufferOptions, isSandboxArrayBuffer } from "../interp/array-buffer.js";
|
|
2
|
+
import { float32Storage, isFloat32Array } from "../interp/float32.js";
|
|
3
|
+
import { getSandboxPrototype, hasExplicitSandboxPrototype } from "../interp/object-model.js";
|
|
4
|
+
import { serializePropertyDescriptors } from "./property-descriptors.js";
|
|
5
|
+
export function captureArrayBufferState(value, encode) {
|
|
6
|
+
return { properties: serializePropertyDescriptors(value, encode),
|
|
7
|
+
...(hasExplicitSandboxPrototype(value) ? { prototype: encode(getSandboxPrototype(value)) } : {}) };
|
|
8
|
+
}
|
|
9
|
+
export function encodeArrayBufferStorage(value, id, buffers, reference) {
|
|
10
|
+
arrayBufferLength(value);
|
|
11
|
+
const existing = buffers.get(value);
|
|
12
|
+
if (existing === undefined)
|
|
13
|
+
buffers.set(value, id);
|
|
14
|
+
return { kind: "arraybuffer", ...(existing === undefined ? { bytes: Array.from(new Uint8Array(value)), ...arrayBufferOptions(value) } : { buffer: reference(existing) }) };
|
|
15
|
+
}
|
|
16
|
+
export function validateArrayBufferStorage(value) {
|
|
17
|
+
if (Object.hasOwn(value, "bytes") === Object.hasOwn(value, "buffer"))
|
|
18
|
+
throw new TypeError("ArrayBuffer requires one backing storage description.");
|
|
19
|
+
if (Object.hasOwn(value, "bytes") && (!Array.isArray(value.bytes) ||
|
|
20
|
+
value.bytes.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)))
|
|
21
|
+
throw new TypeError("Invalid ArrayBuffer bytes.");
|
|
22
|
+
if (Object.hasOwn(value, "maxByteLength") && (!Array.isArray(value.bytes) ||
|
|
23
|
+
!Number.isSafeInteger(value.maxByteLength) || Number(value.maxByteLength) < value.bytes.length))
|
|
24
|
+
throw new TypeError("Invalid ArrayBuffer maximum length.");
|
|
25
|
+
}
|
|
26
|
+
export function decodeArrayBufferStorage(value, resolve) {
|
|
27
|
+
validateArrayBufferStorage(value);
|
|
28
|
+
if (Array.isArray(value.bytes)) {
|
|
29
|
+
const buffer = Reflect.construct(ArrayBuffer, [value.bytes.length,
|
|
30
|
+
Object.hasOwn(value, "maxByteLength") ? { maxByteLength: value.maxByteLength } : undefined]);
|
|
31
|
+
new Uint8Array(buffer).set(value.bytes);
|
|
32
|
+
return buffer;
|
|
33
|
+
}
|
|
34
|
+
const referenced = resolve(value.buffer);
|
|
35
|
+
if (isSandboxArrayBuffer(referenced))
|
|
36
|
+
return referenced;
|
|
37
|
+
if (isFloat32Array(referenced))
|
|
38
|
+
return float32Storage(referenced).buffer;
|
|
39
|
+
throw new TypeError("Invalid ArrayBuffer backing reference.");
|
|
40
|
+
}
|
|
@@ -12,8 +12,10 @@ import { sandboxErrorTypes } from "../error/shape.js";
|
|
|
12
12
|
import { getSandboxArgumentEntries, isSandboxArguments } from "../interp/arguments.js";
|
|
13
13
|
import { serializeArguments } from "./arguments.js";
|
|
14
14
|
import { requiresArrayEntries, serializeArray } from "./arrays.js";
|
|
15
|
-
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
16
|
-
import {
|
|
15
|
+
import { float32DataProperties, float32Storage, isFloat32Array } from "../interp/float32.js";
|
|
16
|
+
import { encodeFloat32Layout } from "./float32array.js";
|
|
17
|
+
import { isSandboxArrayBuffer } from "../interp/array-buffer.js";
|
|
18
|
+
import { captureArrayBufferState, encodeArrayBufferStorage } from "./array-buffer.js";
|
|
17
19
|
import { dateDataProperties, isSandboxDate } from "../interp/date.js";
|
|
18
20
|
import { serializeDate } from "./date-properties.js";
|
|
19
21
|
import { boxedDataProperties, isSandboxBox } from "../interp/boxed.js";
|
|
@@ -109,7 +111,7 @@ function serializeDumpValue(value, path, state) {
|
|
|
109
111
|
if (hasGuestObjectState(value) && !(state.trustedRunReplay && (isSandboxDate(value) || isSandboxPromise(value) || isPromiseResolvingFunction(value)))) {
|
|
110
112
|
throw new TypeError("Guest function properties and prototype links cannot be serialized.");
|
|
111
113
|
}
|
|
112
|
-
if (isSandboxRegExpIterator(value) || (isSandboxRegex(value) && hasCustomRegexProperties(value)) || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value))
|
|
114
|
+
if (isSandboxArrayBuffer(value) || isSandboxRegExpIterator(value) || (isSandboxRegex(value) && hasCustomRegexProperties(value)) || isSandboxBox(value) || isSandboxDate(value) || isFloat32Array(value))
|
|
113
115
|
return serializeHeapReference(value, path, state);
|
|
114
116
|
if (Array.isArray(value)) {
|
|
115
117
|
const reference = serializeHeapReference(value, path, state);
|
|
@@ -186,11 +188,17 @@ function serializeHeapReference(value, path, state) {
|
|
|
186
188
|
return serialized === SKIP_VALUE ? { kind: "undefined" } : serialized;
|
|
187
189
|
});
|
|
188
190
|
}
|
|
191
|
+
else if (isSandboxArrayBuffer(value)) {
|
|
192
|
+
state.heap[String(id)] = { ...encodeArrayBufferStorage(value, id, state.float32Buffers, id => ({ kind: "ref", id })),
|
|
193
|
+
state: captureArrayBufferState(value, entry => {
|
|
194
|
+
const serialized = serializeDumpValue(entry, `${path}.<buffer>`, state);
|
|
195
|
+
return serialized === SKIP_VALUE ? { kind: "undefined" } : serialized;
|
|
196
|
+
}) };
|
|
197
|
+
}
|
|
189
198
|
else if (isFloat32Array(value)) {
|
|
190
|
-
const
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
}));
|
|
199
|
+
const backing = float32Storage(value);
|
|
200
|
+
const storage = { kind: "float32array", ...encodeFloat32Layout(value),
|
|
201
|
+
buffer: serializeHeapReference(backing.buffer, `${path}.buffer`, state) };
|
|
194
202
|
const entries = Object.create(null);
|
|
195
203
|
state.heap[String(id)] = { ...storage, entries };
|
|
196
204
|
for (const [key, descriptor] of float32DataProperties(value)) {
|
|
@@ -271,6 +279,7 @@ function indexHeapContainers(snapshot) {
|
|
|
271
279
|
(isSandboxRegex(value) && hasCustomRegexProperties(value)) ||
|
|
272
280
|
isSandboxDate(value) ||
|
|
273
281
|
isFloat32Array(value) ||
|
|
282
|
+
isSandboxArrayBuffer(value) ||
|
|
274
283
|
(Array.isArray(value) && requiresArrayEntries(value)) ||
|
|
275
284
|
isSandboxArguments(value) ||
|
|
276
285
|
sandboxErrorTypes.has(value)) {
|
|
@@ -305,9 +314,14 @@ function collectContainerStats(value, stats, ancestors, guestValues, depth = 0)
|
|
|
305
314
|
stat.expanded = true;
|
|
306
315
|
ancestors.add(value);
|
|
307
316
|
const guestEntries = [];
|
|
308
|
-
|
|
317
|
+
if (isFloat32Array(value))
|
|
318
|
+
guestEntries.push(float32Storage(value).buffer);
|
|
319
|
+
const guest = isSandboxArrayBuffer(value)
|
|
320
|
+
? { kind: "arraybuffer", state: captureArrayBufferState(value, entry => { guestEntries.push(entry); return null; }) }
|
|
321
|
+
: captureGuestHeapNode(value, entry => { guestEntries.push(entry); return null; });
|
|
309
322
|
if (guest !== undefined) {
|
|
310
|
-
|
|
323
|
+
if (!isSandboxArrayBuffer(value))
|
|
324
|
+
guestValues.add(value);
|
|
311
325
|
for (const entry of guestEntries) {
|
|
312
326
|
collectContainerStats(entry, stats, ancestors, guestValues, depth + 1);
|
|
313
327
|
if (entry !== null && typeof entry === "object")
|
|
@@ -316,6 +330,8 @@ function collectContainerStats(value, stats, ancestors, guestValues, depth = 0)
|
|
|
316
330
|
ancestors.delete(value);
|
|
317
331
|
return;
|
|
318
332
|
}
|
|
333
|
+
for (const entry of guestEntries)
|
|
334
|
+
collectContainerStats(entry, stats, ancestors, guestValues, depth + 1);
|
|
319
335
|
if (!Array.isArray(value) && !isPlainObject(value) && !isFloat32Array(value) && !isSandboxDate(value)) {
|
|
320
336
|
ancestors.delete(value);
|
|
321
337
|
return;
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import type { GuestObjectState } from "./guest-heap.js";
|
|
2
|
+
import type { Budget } from "../interp/budget.js";
|
|
2
3
|
export declare function captureFloat32State<T>(value: Float32Array, encode: (value: unknown) => T): GuestObjectState<T>;
|
|
3
4
|
export declare function restoreFloat32Properties<T>(value: Float32Array, state: GuestObjectState<T>, decode: (value: T) => unknown): void;
|
|
4
5
|
export type Float32Data<TReference> = {
|
|
5
6
|
kind: "float32array";
|
|
6
7
|
byteOffset: number;
|
|
7
8
|
length: number;
|
|
9
|
+
lengthTracking?: true;
|
|
8
10
|
} & ({
|
|
9
11
|
bytes: number[];
|
|
10
12
|
} | {
|
|
11
13
|
buffer: TReference;
|
|
12
14
|
});
|
|
15
|
+
export declare function encodeFloat32Layout(value: Float32Array): {
|
|
16
|
+
byteOffset: number;
|
|
17
|
+
length: number;
|
|
18
|
+
lengthTracking?: true;
|
|
19
|
+
};
|
|
13
20
|
export declare function encodeFloat32Storage<TReference>(value: Float32Array, id: number, buffers: WeakMap<ArrayBuffer, number>, reference: (id: number) => TReference): Float32Data<TReference>;
|
|
14
21
|
export declare function validateFloat32Storage(value: Record<string, unknown>): void;
|
|
15
|
-
export declare function decodeFloat32Storage(value: Record<string, unknown>, resolve: (reference: unknown) => unknown): Float32Array;
|
|
22
|
+
export declare function decodeFloat32Storage(value: Record<string, unknown>, resolve: (reference: unknown) => unknown, budget?: Budget): Float32Array;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { float32Properties, float32Storage, isFloat32Array, isFloat32Index } from "../interp/float32.js";
|
|
1
|
+
import { float32Properties, float32Storage, float32ViewLayouts, restoreFloat32View, isFloat32Array, isFloat32Index } from "../interp/float32.js";
|
|
2
2
|
import { getSandboxPrototype, hasExplicitSandboxPrototype } from "../interp/object-model.js";
|
|
3
3
|
import { restorePropertyDescriptors, serializePropertyDescriptors } from "./property-descriptors.js";
|
|
4
|
+
import { arrayBufferOptions, isSandboxArrayBuffer } from "../interp/array-buffer.js";
|
|
4
5
|
export function captureFloat32State(value, encode) {
|
|
5
6
|
const metadata = Object.defineProperties(Object.create(null), Object.fromEntries(float32Properties(value)));
|
|
6
7
|
if (!Object.isExtensible(value))
|
|
@@ -18,6 +19,16 @@ export function restoreFloat32Properties(value, state, decode) {
|
|
|
18
19
|
if (!Object.isExtensible(metadata))
|
|
19
20
|
Object.preventExtensions(value);
|
|
20
21
|
}
|
|
22
|
+
export function encodeFloat32Layout(value) {
|
|
23
|
+
const storage = float32Storage(value);
|
|
24
|
+
if (arrayBufferOptions(storage.buffer) === undefined)
|
|
25
|
+
return { byteOffset: storage.byteOffset, length: storage.length };
|
|
26
|
+
const layout = float32ViewLayouts.get(value);
|
|
27
|
+
if (layout === undefined)
|
|
28
|
+
throw new TypeError("Resizable Float32Array snapshots require known view layout.");
|
|
29
|
+
return { byteOffset: layout.byteOffset, length: layout.length ?? 0,
|
|
30
|
+
...(layout.length === undefined ? { lengthTracking: true } : {}) };
|
|
31
|
+
}
|
|
21
32
|
export function encodeFloat32Storage(value, id, buffers, reference) {
|
|
22
33
|
const storage = float32Storage(value);
|
|
23
34
|
const existing = buffers.get(storage.buffer);
|
|
@@ -33,6 +44,8 @@ export function encodeFloat32Storage(value, id, buffers, reference) {
|
|
|
33
44
|
};
|
|
34
45
|
}
|
|
35
46
|
export function validateFloat32Storage(value) {
|
|
47
|
+
if (Object.hasOwn(value, "lengthTracking") && (value.lengthTracking !== true || value.length !== 0 || Object.hasOwn(value, "bytes")))
|
|
48
|
+
throw new TypeError("Invalid Float32Array length-tracking layout.");
|
|
36
49
|
if (!Number.isSafeInteger(value.length) ||
|
|
37
50
|
Number(value.length) < 0 ||
|
|
38
51
|
!Number.isSafeInteger(value.byteOffset) ||
|
|
@@ -48,7 +61,7 @@ export function validateFloat32Storage(value) {
|
|
|
48
61
|
throw new TypeError("Invalid Float32Array backing bytes.");
|
|
49
62
|
}
|
|
50
63
|
}
|
|
51
|
-
export function decodeFloat32Storage(value, resolve) {
|
|
64
|
+
export function decodeFloat32Storage(value, resolve, budget) {
|
|
52
65
|
validateFloat32Storage(value);
|
|
53
66
|
let buffer;
|
|
54
67
|
if (Array.isArray(value.bytes)) {
|
|
@@ -57,9 +70,14 @@ export function decodeFloat32Storage(value, resolve) {
|
|
|
57
70
|
}
|
|
58
71
|
else {
|
|
59
72
|
const referenced = resolve(value.buffer);
|
|
60
|
-
if (
|
|
73
|
+
if (isSandboxArrayBuffer(referenced))
|
|
74
|
+
buffer = referenced;
|
|
75
|
+
else if (isFloat32Array(referenced))
|
|
76
|
+
buffer = float32Storage(referenced).buffer;
|
|
77
|
+
else
|
|
61
78
|
throw new TypeError("Invalid Float32Array backing reference.");
|
|
62
|
-
buffer = float32Storage(referenced).buffer;
|
|
63
79
|
}
|
|
64
|
-
|
|
80
|
+
if (value.lengthTracking === true && arrayBufferOptions(buffer) === undefined)
|
|
81
|
+
throw new TypeError("Length-tracking layout requires resizable backing storage.");
|
|
82
|
+
return restoreFloat32View(buffer, Number(value.byteOffset), value.lengthTracking === true ? undefined : Number(value.length), budget);
|
|
65
83
|
}
|
|
@@ -4,6 +4,7 @@ import { type SerializedSymbol, type SerializedSymbolProperty } from "./symbols.
|
|
|
4
4
|
import { type CollectionIterationMethod } from "../interp/collection-iterator.js";
|
|
5
5
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
6
6
|
import { type Float32Data } from "./float32array.js";
|
|
7
|
+
import { type ArrayBufferData } from "./array-buffer.js";
|
|
7
8
|
import { type SandboxErrorName } from "../error/shape.js";
|
|
8
9
|
import { type SandboxClosure, type SandboxPromise, type SandboxValue } from "../interp/values.js";
|
|
9
10
|
import { type SerializedArguments } from "./arguments.js";
|
|
@@ -69,6 +70,10 @@ type DataNode = {
|
|
|
69
70
|
} | (Float32Data<Atom> & {
|
|
70
71
|
properties: Properties;
|
|
71
72
|
extensible: boolean;
|
|
73
|
+
}) | (ArrayBufferData<Atom> & {
|
|
74
|
+
properties: Properties;
|
|
75
|
+
extensible: boolean;
|
|
76
|
+
symbolEntries?: Array<SerializedSymbolProperty<Atom>>;
|
|
72
77
|
}) | {
|
|
73
78
|
kind: "capability";
|
|
74
79
|
id: string;
|
|
@@ -10,8 +10,10 @@ import { isSandboxCollectionIterator, restoreSandboxCollectionIterator, snapshot
|
|
|
10
10
|
import { isSandboxRegExpIterator, regexpIteratorState, restoreSandboxRegExpIterator } from "../interp/regexp-iterator.js";
|
|
11
11
|
import { hasGuestObjectState, hasNullObjectPrototype, setSandboxPrototype } from "../interp/object-model.js";
|
|
12
12
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
13
|
-
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
14
|
-
import { decodeFloat32Storage,
|
|
13
|
+
import { float32DataProperties, float32Storage, isFloat32Array } from "../interp/float32.js";
|
|
14
|
+
import { decodeFloat32Storage, encodeFloat32Layout } from "./float32array.js";
|
|
15
|
+
import { arrayBufferDataProperties, isSandboxArrayBuffer } from "../interp/array-buffer.js";
|
|
16
|
+
import { decodeArrayBufferStorage, encodeArrayBufferStorage } from "./array-buffer.js";
|
|
15
17
|
import { dateDataProperties, isSandboxDate, restoreDateTime, serializedDateTime } from "../interp/date.js";
|
|
16
18
|
import { createRawJson, isRawJson } from "../interp/raw-json.js";
|
|
17
19
|
import { boxedDataProperties, createSandboxBox, nativeBoxedValue } from "../interp/boxed.js";
|
|
@@ -119,11 +121,22 @@ export function encodeReplayData(value, options = {}) {
|
|
|
119
121
|
...(Object.isExtensible(entry) ? {} : { extensible: false })
|
|
120
122
|
};
|
|
121
123
|
}
|
|
124
|
+
else if (isSandboxArrayBuffer(entry)) {
|
|
125
|
+
const storage = encodeArrayBufferStorage(entry, id, float32Buffers, id => ({ tag: "ref", id }));
|
|
126
|
+
const properties = Object.create(null);
|
|
127
|
+
for (const [key, descriptor] of arrayBufferDataProperties(entry)) {
|
|
128
|
+
if (typeof key === "symbol")
|
|
129
|
+
continue;
|
|
130
|
+
properties[key] = { value: child(descriptor.value, key), configurable: descriptor.configurable === true,
|
|
131
|
+
enumerable: descriptor.enumerable === true, writable: descriptor.writable === true };
|
|
132
|
+
}
|
|
133
|
+
let symbolIndex = 0;
|
|
134
|
+
const symbolEntries = serializeSymbolProperties(entry, value => encode(value, depth + 1, [...path, { symbol: Math.floor(symbolIndex++ / 2) }]));
|
|
135
|
+
nodes[id] = { ...storage, properties, extensible: Object.isExtensible(entry), symbolEntries };
|
|
136
|
+
}
|
|
122
137
|
else if (isFloat32Array(entry)) {
|
|
123
|
-
const
|
|
124
|
-
|
|
125
|
-
id
|
|
126
|
-
}));
|
|
138
|
+
const backing = float32Storage(entry);
|
|
139
|
+
const storage = { kind: "float32array", ...encodeFloat32Layout(entry), buffer: child(backing.buffer, "<buffer>") };
|
|
127
140
|
const properties = Object.create(null);
|
|
128
141
|
for (const [key, descriptor] of float32DataProperties(entry)) {
|
|
129
142
|
properties[key] = {
|
|
@@ -227,7 +240,7 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
227
240
|
const graph = record(input);
|
|
228
241
|
const nodes = list(own(graph, "nodes"));
|
|
229
242
|
const restored = new Map();
|
|
230
|
-
const
|
|
243
|
+
const initializeValues = [];
|
|
231
244
|
const decode = (entry, depth = 0) => {
|
|
232
245
|
if (depth > MAX_DATA_DEPTH)
|
|
233
246
|
throw new TypeError("Replay data exceeds the nesting limit.");
|
|
@@ -378,10 +391,22 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
378
391
|
Object.preventExtensions(result);
|
|
379
392
|
return result;
|
|
380
393
|
}
|
|
394
|
+
if (kind === "arraybuffer") {
|
|
395
|
+
if (typeof node.extensible !== "boolean")
|
|
396
|
+
throw new TypeError("Invalid ArrayBuffer extensibility.");
|
|
397
|
+
const result = decodeArrayBufferStorage(node, child);
|
|
398
|
+
restored.set(id, result);
|
|
399
|
+
initializeValues.push(() => {
|
|
400
|
+
defineProperties(result, record(own(node, "properties")), child, node.symbolEntries);
|
|
401
|
+
if (!node.extensible)
|
|
402
|
+
Object.preventExtensions(result);
|
|
403
|
+
});
|
|
404
|
+
return result;
|
|
405
|
+
}
|
|
381
406
|
if (kind === "float32array") {
|
|
382
407
|
if (typeof node.extensible !== "boolean")
|
|
383
408
|
throw new TypeError("Invalid Float32Array extensibility.");
|
|
384
|
-
const result = decodeFloat32Storage(node, child);
|
|
409
|
+
const result = decodeFloat32Storage(node, child, compilation.owner?.budget);
|
|
385
410
|
restored.set(id, result);
|
|
386
411
|
defineProperties(result, record(own(node, "properties")), child);
|
|
387
412
|
if (!node.extensible)
|
|
@@ -421,7 +446,7 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
421
446
|
const collection = child(own(node, "collection"));
|
|
422
447
|
if (collection !== undefined && !isSandboxMap(collection) && !isSandboxSet(collection))
|
|
423
448
|
throw new TypeError("Invalid replay collection iterator source.");
|
|
424
|
-
|
|
449
|
+
initializeValues.push(() => { restoreSandboxCollectionIterator({ collection, collectionKind, method, index, exhausted }, result); });
|
|
425
450
|
defineProperties(result, record(own(node, "properties")), child);
|
|
426
451
|
if (!node.extensible)
|
|
427
452
|
Object.preventExtensions(result);
|
|
@@ -503,7 +528,7 @@ export function decodeReplayData(input, options = {}, parent) {
|
|
|
503
528
|
return result;
|
|
504
529
|
};
|
|
505
530
|
const result = decode(own(graph, "root"));
|
|
506
|
-
for (const initialize of
|
|
531
|
+
for (const initialize of initializeValues)
|
|
507
532
|
initialize();
|
|
508
533
|
if (parent !== undefined)
|
|
509
534
|
compilation.forward(compilation.tickets, parent);
|
|
@@ -18,6 +18,7 @@ import { runAsyncPrefix } from "../interp/jobs.js";
|
|
|
18
18
|
import { toPropertyKey } from "../interp/property-key.js";
|
|
19
19
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
20
20
|
import { decodeFloat32Storage, restoreFloat32Properties } from "./float32array.js";
|
|
21
|
+
import { decodeArrayBufferStorage } from "./array-buffer.js";
|
|
21
22
|
import { restoreDateTime } from "../interp/date.js";
|
|
22
23
|
import { createRawJson } from "../interp/raw-json.js";
|
|
23
24
|
import { createSandboxBox } from "../interp/boxed.js";
|
|
@@ -456,10 +457,21 @@ function restoreHeapValue(id, state) {
|
|
|
456
457
|
restoreRegexProperties(value, serialized, entry => deserializeValue(entry, state));
|
|
457
458
|
return value;
|
|
458
459
|
}
|
|
460
|
+
if (serialized.kind === "arraybuffer") {
|
|
461
|
+
initializeIntrinsicRealm(state);
|
|
462
|
+
const value = decodeArrayBufferStorage(serialized, reference => deserializeValue(reference, state));
|
|
463
|
+
state.heapValueById.set(id, value);
|
|
464
|
+
state.initializeIterators.push(() => {
|
|
465
|
+
if (serialized.state.prototype !== undefined)
|
|
466
|
+
setSandboxPrototype(value, deserializeValue(serialized.state.prototype, state), state.budget);
|
|
467
|
+
restorePropertyDescriptors(value, serialized.state.properties, entry => deserializeValue(entry, state));
|
|
468
|
+
});
|
|
469
|
+
return value;
|
|
470
|
+
}
|
|
459
471
|
if (serialized.kind === "float32array") {
|
|
460
472
|
if (serialized.state !== undefined)
|
|
461
473
|
initializeIntrinsicRealm(state);
|
|
462
|
-
const value = decodeFloat32Storage(serialized, (reference) => deserializeValue(reference, state));
|
|
474
|
+
const value = decodeFloat32Storage(serialized, (reference) => deserializeValue(reference, state), state.budget);
|
|
463
475
|
state.heapValueById.set(id, value);
|
|
464
476
|
if (serialized.state !== undefined) {
|
|
465
477
|
const objectState = serialized.state;
|
|
@@ -8,6 +8,7 @@ import { type GuestHeapNode, type GuestObjectState } from "./guest-heap.js";
|
|
|
8
8
|
import { type SerializedArguments } from "./arguments.js";
|
|
9
9
|
import { type SerializedArray } from "./arrays.js";
|
|
10
10
|
import { type Float32Data } from "./float32array.js";
|
|
11
|
+
import { type ArrayBufferData } from "./array-buffer.js";
|
|
11
12
|
import { type SerializedDate } from "./date-properties.js";
|
|
12
13
|
import { type SandboxBox } from "../interp/boxed.js";
|
|
13
14
|
import { type BoxedData } from "./boxed.js";
|
|
@@ -51,7 +52,9 @@ export type SerializedReferenceValue = {
|
|
|
51
52
|
kind: "ref";
|
|
52
53
|
id: number;
|
|
53
54
|
};
|
|
54
|
-
export type SerializedHeapValue =
|
|
55
|
+
export type SerializedHeapValue = (ArrayBufferData<SerializedReferenceValue> & {
|
|
56
|
+
state: GuestObjectState<SerializedSnapshotValue>;
|
|
57
|
+
}) | GuestHeapNode<SerializedSnapshotValue> | {
|
|
55
58
|
kind: "regexp-iterator";
|
|
56
59
|
matcher: SerializedSnapshotValue;
|
|
57
60
|
input: SerializedSnapshotValue;
|
|
@@ -112,7 +115,7 @@ export type RuntimePromiseValue = {
|
|
|
112
115
|
id: SnapshotId;
|
|
113
116
|
promise?: Promise<unknown>;
|
|
114
117
|
};
|
|
115
|
-
export type RuntimeSnapshotValue = bigint | symbol | SandboxBox | Date | Float32Array | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxClosure | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
118
|
+
export type RuntimeSnapshotValue = bigint | symbol | SandboxBox | Date | Float32Array | ArrayBuffer | boolean | null | number | string | undefined | RuntimeClosureValue | SandboxClosure | SandboxGenerator | SandboxCollectionIterator | SandboxRegExpIterator | RuntimePromiseValue | SandboxMap | SandboxRegex | SandboxSet | RuntimeSnapshotValue[] | {
|
|
116
119
|
[key: string]: RuntimeSnapshotValue;
|
|
117
120
|
};
|
|
118
121
|
export type RuntimeScopeFrame = {
|