poe-code 13.0.3 → 13.0.4
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 +14418 -13628
- 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-73LWNNUG.js → chunk-WGS5B4OT.js} +14505 -13744
- package/packages/safe-js/dist/chunks/chunk-WGS5B4OT.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-QCJ7UAMC.js → chunk-ZGWWEL43.js} +2 -2
- package/packages/safe-js/dist/cli.js +2 -2
- package/packages/safe-js/dist/core.js +1 -1
- package/packages/safe-js/dist/index.d.ts +11 -3
- package/packages/safe-js/dist/index.js +14 -6
- package/packages/safe-js/dist/index.js.map +4 -4
- package/packages/safe-js/dist/interp/async.d.ts +2 -0
- package/packages/safe-js/dist/interp/async.js +31 -15
- package/packages/safe-js/dist/interp/budget.d.ts +29 -0
- package/packages/safe-js/dist/interp/budget.js +143 -0
- package/packages/safe-js/dist/interp/globals/console-json.d.ts +2 -1
- package/packages/safe-js/dist/interp/globals/console-json.js +24 -6
- package/packages/safe-js/dist/interp/globals/regex.d.ts +2 -1
- package/packages/safe-js/dist/interp/globals/regex.js +24 -3
- package/packages/safe-js/dist/interp/host-bridge.d.ts +2 -1
- package/packages/safe-js/dist/interp/host-bridge.js +98 -55
- package/packages/safe-js/dist/interp/host-call.d.ts +3 -2
- package/packages/safe-js/dist/interp/host-call.js +91 -52
- package/packages/safe-js/dist/interp/interpreter.d.ts +4 -1
- package/packages/safe-js/dist/interp/interpreter.js +115 -79
- package/packages/safe-js/dist/interp/methods/string.d.ts +2 -1
- package/packages/safe-js/dist/interp/methods/string.js +111 -100
- package/packages/safe-js/dist/interp/regex/compile-guard.d.ts +33 -0
- package/packages/safe-js/dist/interp/regex/compile-guard.js +179 -0
- package/packages/safe-js/dist/interp/regex/parse.d.ts +2 -1
- package/packages/safe-js/dist/interp/regex/parse.js +87 -16
- package/packages/safe-js/dist/interp/values.d.ts +7 -2
- package/packages/safe-js/dist/interp/values.js +91 -9
- package/packages/safe-js/dist/modules/registry.d.ts +2 -1
- package/packages/safe-js/dist/modules/registry.js +1 -0
- package/packages/safe-js/dist/parse/hash.d.ts +2 -1
- package/packages/safe-js/dist/parse/hash.js +7 -4
- package/packages/safe-js/dist/parse/parser.d.ts +5 -3
- package/packages/safe-js/dist/parse/parser.js +53 -27
- package/packages/safe-js/dist/parse/tokenizer.d.ts +2 -0
- package/packages/safe-js/dist/parse/tokenizer.js +48 -26
- package/packages/safe-js/dist/parse.d.ts +3 -1
- package/packages/safe-js/dist/parse.js +3 -1
- package/packages/safe-js/dist/restore.d.ts +2 -1
- package/packages/safe-js/dist/restore.js +3 -3
- package/packages/safe-js/dist/run.js +289 -263
- package/packages/safe-js/dist/snapshot/migration.d.ts +3 -2
- package/packages/safe-js/dist/snapshot/migration.js +12 -5
- package/packages/safe-js/dist/snapshot/replay-data.d.ts +2 -1
- package/packages/safe-js/dist/snapshot/replay-data.js +172 -162
- package/packages/safe-js/dist/snapshot/replay-inputs.d.ts +2 -1
- package/packages/safe-js/dist/snapshot/replay-inputs.js +18 -11
- package/packages/safe-js/dist/snapshot/restore.d.ts +2 -2
- package/packages/safe-js/dist/snapshot/restore.js +142 -113
- package/packages/safe-js/dist/chunks/chunk-73LWNNUG.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-QCJ7UAMC.js.map → chunk-ZGWWEL43.js.map} +0 -0
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { HostCallJournal } from "../interp/host-call.js";
|
|
2
2
|
import { decodeReplayData } from "./replay-data.js";
|
|
3
3
|
import { validateSnapshotData } from "./validation.js";
|
|
4
|
+
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
4
5
|
export function validateMigrationSemantics(value) {
|
|
5
6
|
if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7"].includes(value))
|
|
6
7
|
throw new TypeError("Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v7).");
|
|
7
8
|
}
|
|
8
|
-
export function validateMigrationJournal(sourceHash, replay, hostCalls = []) {
|
|
9
|
+
export function validateMigrationJournal(sourceHash, replay, hostCalls = [], owner) {
|
|
9
10
|
if (replay === undefined)
|
|
10
11
|
throw new TypeError("Migration requires a complete host replay journal.");
|
|
11
12
|
if (!Array.isArray(hostCalls))
|
|
12
13
|
throw new TypeError("Invalid migration hostCalls.");
|
|
13
|
-
const journal = new HostCallJournal(sourceHash, hostCalls, undefined, replay);
|
|
14
|
+
const journal = new HostCallJournal(sourceHash, hostCalls, undefined, replay, owner?.budget, owner);
|
|
14
15
|
try {
|
|
15
16
|
const restored = journal.snapshotReplay();
|
|
16
17
|
for (const call of restored.calls) {
|
|
@@ -54,7 +55,7 @@ export function validateMigrationReconciliation(value, checkpointDigest, calls)
|
|
|
54
55
|
if (pending.size > 0)
|
|
55
56
|
throw new TypeError(`Migration requires external reconciliation for: ${[...pending.keys()].join(", ")}`);
|
|
56
57
|
}
|
|
57
|
-
export function validateSnapshotMigration(value, sourceHash) {
|
|
58
|
+
export function validateSnapshotMigration(value, sourceHash, owner) {
|
|
58
59
|
if (value === undefined)
|
|
59
60
|
return undefined;
|
|
60
61
|
validateSnapshotData(value);
|
|
@@ -65,7 +66,13 @@ export function validateSnapshotMigration(value, sourceHash) {
|
|
|
65
66
|
!Array.isArray(migration.history) ||
|
|
66
67
|
migration.history.length === 0)
|
|
67
68
|
throw new TypeError("Invalid snapshot migration history.");
|
|
68
|
-
|
|
69
|
+
const compilation = new CompileScope(owner);
|
|
70
|
+
try {
|
|
71
|
+
decodeReplayData(migration.state, {}, compilation);
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
compilation.dispose();
|
|
75
|
+
}
|
|
69
76
|
let previousTarget;
|
|
70
77
|
for (const entry of migration.history) {
|
|
71
78
|
if (entry === null ||
|
|
@@ -77,7 +84,7 @@ export function validateSnapshotMigration(value, sourceHash) {
|
|
|
77
84
|
(previousTarget !== undefined && previousTarget !== entry.sourceHash))
|
|
78
85
|
throw new TypeError("Invalid snapshot migration ancestry.");
|
|
79
86
|
validateMigrationSemantics(entry.executionSemantics);
|
|
80
|
-
const replay = validateMigrationJournal(entry.sourceHash, entry.replay);
|
|
87
|
+
const replay = validateMigrationJournal(entry.sourceHash, entry.replay, [], owner);
|
|
81
88
|
validateMigrationReconciliation(entry.reconciliation, entry.reconciliation?.checkpointDigest, replay.calls);
|
|
82
89
|
previousTarget = entry.targetSourceHash;
|
|
83
90
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
1
2
|
import { type Float32Data } from "./float32array.js";
|
|
2
3
|
import { type SandboxErrorName } from "../error/shape.js";
|
|
3
4
|
import { type SandboxClosure, type SandboxPromise, type SandboxValue } from "../interp/values.js";
|
|
@@ -66,5 +67,5 @@ export declare function decodeReplayData(input: unknown, options?: {
|
|
|
66
67
|
resolveCapability?: (id: string) => SandboxClosure | undefined;
|
|
67
68
|
resolvePromise?: (id: string) => SandboxPromise | undefined;
|
|
68
69
|
onCapabilityRestored?: (original: SandboxClosure, restored: SandboxClosure) => void;
|
|
69
|
-
}): SandboxValue;
|
|
70
|
+
}, parent?: CompileScope): SandboxValue;
|
|
70
71
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { MAX_DATA_DEPTH } from "../graph-depth.js";
|
|
2
|
+
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
2
3
|
import { float32DataProperties, isFloat32Array } from "../interp/float32.js";
|
|
3
4
|
import { decodeFloat32Storage, encodeFloat32Storage } from "./float32array.js";
|
|
4
5
|
import { sandboxErrorNames, sandboxErrorTypes } from "../error/shape.js";
|
|
@@ -130,178 +131,187 @@ export function encodeReplayData(value, options = {}) {
|
|
|
130
131
|
};
|
|
131
132
|
return { root: encode(value, 0, []), nodes };
|
|
132
133
|
}
|
|
133
|
-
export function decodeReplayData(input, options = {}) {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
const
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
const id = own(atom, "id");
|
|
157
|
-
if (typeof id !== "string" || id.length === 0)
|
|
158
|
-
throw new TypeError("Invalid replay capability reference.");
|
|
159
|
-
const capability = options.resolveCapability?.(id);
|
|
160
|
-
if (!isSandboxClosure(capability))
|
|
161
|
-
throw new TypeError(`Missing replay capability '${id}'.`);
|
|
162
|
-
return capability;
|
|
163
|
-
}
|
|
164
|
-
if (own(atom, "tag") === "undefined")
|
|
165
|
-
return undefined;
|
|
166
|
-
if (atom.tag === "number") {
|
|
167
|
-
switch (own(atom, "value")) {
|
|
168
|
-
case "NaN":
|
|
169
|
-
return NaN;
|
|
170
|
-
case "Infinity":
|
|
171
|
-
return Infinity;
|
|
172
|
-
case "-Infinity":
|
|
173
|
-
return -Infinity;
|
|
174
|
-
case "-0":
|
|
175
|
-
return -0;
|
|
176
|
-
default:
|
|
177
|
-
throw new TypeError("Invalid replay number.");
|
|
134
|
+
export function decodeReplayData(input, options = {}, parent) {
|
|
135
|
+
const compilation = new CompileScope(parent?.owner);
|
|
136
|
+
try {
|
|
137
|
+
validateSnapshotData(input);
|
|
138
|
+
const graph = record(input);
|
|
139
|
+
const nodes = list(own(graph, "nodes"));
|
|
140
|
+
const restored = new Map();
|
|
141
|
+
const decode = (entry, depth = 0) => {
|
|
142
|
+
if (depth > MAX_DATA_DEPTH)
|
|
143
|
+
throw new TypeError("Replay data exceeds the nesting limit.");
|
|
144
|
+
if (entry === null || typeof entry === "boolean" || typeof entry === "string")
|
|
145
|
+
return entry;
|
|
146
|
+
if (typeof entry === "number" && Number.isFinite(entry))
|
|
147
|
+
return entry;
|
|
148
|
+
const atom = record(entry);
|
|
149
|
+
if (own(atom, "tag") === "promise-capability") {
|
|
150
|
+
const id = own(atom, "id");
|
|
151
|
+
if (typeof id !== "string" || id.length === 0)
|
|
152
|
+
throw new TypeError("Invalid replay promise capability reference.");
|
|
153
|
+
const promise = options.resolvePromise?.(id);
|
|
154
|
+
if (!isSandboxPromise(promise))
|
|
155
|
+
throw new TypeError(`Missing replay promise capability '${id}'.`);
|
|
156
|
+
return promise;
|
|
178
157
|
}
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const id = Number(atom.id);
|
|
187
|
-
if (restored.has(id))
|
|
188
|
-
return restored.get(id);
|
|
189
|
-
const node = record(nodes[id]);
|
|
190
|
-
const kind = own(node, "kind");
|
|
191
|
-
if (Object.hasOwn(node, "errorType") &&
|
|
192
|
-
(kind !== "object" || !sandboxErrorNames.includes(node.errorType))) {
|
|
193
|
-
throw new TypeError("Invalid replay error metadata.");
|
|
194
|
-
}
|
|
195
|
-
const child = (value) => decode(value, depth + 1);
|
|
196
|
-
if (kind === "capability") {
|
|
197
|
-
const capabilityId = own(node, "id");
|
|
198
|
-
if (typeof capabilityId !== "string" || capabilityId.length === 0)
|
|
199
|
-
throw new TypeError("Invalid replay capability reference.");
|
|
200
|
-
const capability = options.resolveCapability?.(capabilityId);
|
|
201
|
-
if (!isSandboxClosure(capability))
|
|
202
|
-
throw new TypeError(`Missing replay capability '${capabilityId}'.`);
|
|
203
|
-
if (record(own(node, "properties")).tag === "undefined") {
|
|
204
|
-
restored.set(id, capability);
|
|
158
|
+
if (own(atom, "tag") === "capability") {
|
|
159
|
+
const id = own(atom, "id");
|
|
160
|
+
if (typeof id !== "string" || id.length === 0)
|
|
161
|
+
throw new TypeError("Invalid replay capability reference.");
|
|
162
|
+
const capability = options.resolveCapability?.(id);
|
|
163
|
+
if (!isSandboxClosure(capability))
|
|
164
|
+
throw new TypeError(`Missing replay capability '${id}'.`);
|
|
205
165
|
return capability;
|
|
206
166
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
throw new TypeError("Invalid replay
|
|
221
|
-
return properties;
|
|
167
|
+
if (own(atom, "tag") === "undefined")
|
|
168
|
+
return undefined;
|
|
169
|
+
if (atom.tag === "number") {
|
|
170
|
+
switch (own(atom, "value")) {
|
|
171
|
+
case "NaN":
|
|
172
|
+
return NaN;
|
|
173
|
+
case "Infinity":
|
|
174
|
+
return Infinity;
|
|
175
|
+
case "-Infinity":
|
|
176
|
+
return -Infinity;
|
|
177
|
+
case "-0":
|
|
178
|
+
return -0;
|
|
179
|
+
default:
|
|
180
|
+
throw new TypeError("Invalid replay number.");
|
|
222
181
|
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
const
|
|
182
|
+
}
|
|
183
|
+
if (atom.tag !== "ref" ||
|
|
184
|
+
!Number.isSafeInteger(atom.id) ||
|
|
185
|
+
Number(atom.id) < 0 ||
|
|
186
|
+
Number(atom.id) >= nodes.length) {
|
|
187
|
+
throw new TypeError("Invalid replay data reference.");
|
|
188
|
+
}
|
|
189
|
+
const id = Number(atom.id);
|
|
190
|
+
if (restored.has(id))
|
|
191
|
+
return restored.get(id);
|
|
192
|
+
const node = record(nodes[id]);
|
|
193
|
+
const kind = own(node, "kind");
|
|
194
|
+
if (Object.hasOwn(node, "errorType") &&
|
|
195
|
+
(kind !== "object" || !sandboxErrorNames.includes(node.errorType))) {
|
|
196
|
+
throw new TypeError("Invalid replay error metadata.");
|
|
197
|
+
}
|
|
198
|
+
const child = (value) => decode(value, depth + 1);
|
|
199
|
+
if (kind === "capability") {
|
|
200
|
+
const capabilityId = own(node, "id");
|
|
201
|
+
if (typeof capabilityId !== "string" || capabilityId.length === 0)
|
|
202
|
+
throw new TypeError("Invalid replay capability reference.");
|
|
203
|
+
const capability = options.resolveCapability?.(capabilityId);
|
|
204
|
+
if (!isSandboxClosure(capability))
|
|
205
|
+
throw new TypeError(`Missing replay capability '${capabilityId}'.`);
|
|
206
|
+
if (record(own(node, "properties")).tag === "undefined") {
|
|
207
|
+
restored.set(id, capability);
|
|
208
|
+
return capability;
|
|
209
|
+
}
|
|
210
|
+
const copy = createSandboxClosure({
|
|
211
|
+
...capability,
|
|
212
|
+
boundTarget: capability.boundTarget,
|
|
213
|
+
cancellationSignal: capability.cancellationSignal,
|
|
214
|
+
sandbox: capability.sandbox,
|
|
215
|
+
retainedValues: () => [capability],
|
|
216
|
+
properties: (closure) => {
|
|
217
|
+
restored.set(id, closure);
|
|
218
|
+
const properties = child(own(node, "properties"));
|
|
219
|
+
if (properties === null ||
|
|
220
|
+
typeof properties !== "object" ||
|
|
221
|
+
Array.isArray(properties) ||
|
|
222
|
+
isSandboxClosure(properties))
|
|
223
|
+
throw new TypeError("Invalid replay capability properties.");
|
|
224
|
+
return properties;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
options.onCapabilityRestored?.(capability, copy);
|
|
228
|
+
return copy;
|
|
229
|
+
}
|
|
230
|
+
if (kind === "float32array") {
|
|
231
|
+
if (typeof node.extensible !== "boolean")
|
|
232
|
+
throw new TypeError("Invalid Float32Array extensibility.");
|
|
233
|
+
const result = decodeFloat32Storage(node, child);
|
|
234
|
+
restored.set(id, result);
|
|
235
|
+
defineProperties(result, record(own(node, "properties")), child);
|
|
236
|
+
if (!node.extensible)
|
|
237
|
+
Object.preventExtensions(result);
|
|
238
|
+
return result;
|
|
239
|
+
}
|
|
240
|
+
if (kind === "map") {
|
|
241
|
+
const result = createSandboxMap();
|
|
242
|
+
restored.set(id, result);
|
|
243
|
+
for (const pair of list(own(node, "entries"))) {
|
|
244
|
+
const entries = list(pair);
|
|
245
|
+
if (entries.length !== 2)
|
|
246
|
+
throw new TypeError("Invalid replay map entry.");
|
|
247
|
+
result.entries.set(child(entries[0]), child(entries[1]));
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
if (kind === "set") {
|
|
252
|
+
const result = createSandboxSet();
|
|
253
|
+
restored.set(id, result);
|
|
254
|
+
for (const value of list(own(node, "values")))
|
|
255
|
+
result.values.add(child(value));
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
if (kind === "regex") {
|
|
259
|
+
if (typeof node.source !== "string" ||
|
|
260
|
+
typeof node.flags !== "string" ||
|
|
261
|
+
typeof node.lastIndex !== "number" ||
|
|
262
|
+
!Number.isFinite(node.lastIndex)) {
|
|
263
|
+
throw new TypeError("Invalid replay regular expression.");
|
|
264
|
+
}
|
|
265
|
+
const result = createSandboxRegex(node.source, node.flags, node.lastIndex, compilation);
|
|
266
|
+
restored.set(id, result);
|
|
267
|
+
return result;
|
|
268
|
+
}
|
|
269
|
+
if (kind === "arguments") {
|
|
270
|
+
const data = record(own(node, "data"));
|
|
271
|
+
validateArgumentsProperties(data, "arguments");
|
|
272
|
+
if (data.kind !== "arguments")
|
|
273
|
+
throw new TypeError("Invalid replay arguments.");
|
|
274
|
+
const args = createSandboxArguments([]);
|
|
275
|
+
restored.set(id, args);
|
|
276
|
+
if (!data.lengthBeforeCallee)
|
|
277
|
+
delete args.length;
|
|
278
|
+
defineProperties(args, record(data.properties), child);
|
|
279
|
+
if (data.iterator === null)
|
|
280
|
+
Reflect.deleteProperty(args, Symbol.iterator);
|
|
281
|
+
else
|
|
282
|
+
Object.defineProperty(args, Symbol.iterator, {
|
|
283
|
+
...record(data.iterator),
|
|
284
|
+
value: Array.prototype.values
|
|
285
|
+
});
|
|
286
|
+
if (!data.extensible)
|
|
287
|
+
Object.preventExtensions(args);
|
|
288
|
+
return args;
|
|
289
|
+
}
|
|
290
|
+
if (kind !== "array" && kind !== "object")
|
|
291
|
+
throw new TypeError("Invalid replay data node.");
|
|
292
|
+
if (typeof node.extensible !== "boolean" || typeof node.nullPrototype !== "boolean") {
|
|
293
|
+
throw new TypeError("Invalid replay object metadata.");
|
|
294
|
+
}
|
|
295
|
+
const result = kind === "array" ? [] : Object.create(node.nullPrototype ? null : Object.prototype);
|
|
296
|
+
if (Object.hasOwn(node, "errorType")) {
|
|
297
|
+
sandboxErrorTypes.set(result, node.errorType);
|
|
298
|
+
}
|
|
299
|
+
if (kind === "array" && node.nullPrototype)
|
|
300
|
+
Object.setPrototypeOf(result, null);
|
|
231
301
|
restored.set(id, result);
|
|
232
302
|
defineProperties(result, record(own(node, "properties")), child);
|
|
233
303
|
if (!node.extensible)
|
|
234
304
|
Object.preventExtensions(result);
|
|
235
305
|
return result;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
for (const pair of list(own(node, "entries"))) {
|
|
241
|
-
const entries = list(pair);
|
|
242
|
-
if (entries.length !== 2)
|
|
243
|
-
throw new TypeError("Invalid replay map entry.");
|
|
244
|
-
result.entries.set(child(entries[0]), child(entries[1]));
|
|
245
|
-
}
|
|
246
|
-
return result;
|
|
247
|
-
}
|
|
248
|
-
if (kind === "set") {
|
|
249
|
-
const result = createSandboxSet();
|
|
250
|
-
restored.set(id, result);
|
|
251
|
-
for (const value of list(own(node, "values")))
|
|
252
|
-
result.values.add(child(value));
|
|
253
|
-
return result;
|
|
254
|
-
}
|
|
255
|
-
if (kind === "regex") {
|
|
256
|
-
if (typeof node.source !== "string" ||
|
|
257
|
-
typeof node.flags !== "string" ||
|
|
258
|
-
typeof node.lastIndex !== "number" ||
|
|
259
|
-
!Number.isFinite(node.lastIndex)) {
|
|
260
|
-
throw new TypeError("Invalid replay regular expression.");
|
|
261
|
-
}
|
|
262
|
-
const result = createSandboxRegex(node.source, node.flags, node.lastIndex);
|
|
263
|
-
restored.set(id, result);
|
|
264
|
-
return result;
|
|
265
|
-
}
|
|
266
|
-
if (kind === "arguments") {
|
|
267
|
-
const data = record(own(node, "data"));
|
|
268
|
-
validateArgumentsProperties(data, "arguments");
|
|
269
|
-
if (data.kind !== "arguments")
|
|
270
|
-
throw new TypeError("Invalid replay arguments.");
|
|
271
|
-
const args = createSandboxArguments([]);
|
|
272
|
-
restored.set(id, args);
|
|
273
|
-
if (!data.lengthBeforeCallee)
|
|
274
|
-
delete args.length;
|
|
275
|
-
defineProperties(args, record(data.properties), child);
|
|
276
|
-
if (data.iterator === null)
|
|
277
|
-
Reflect.deleteProperty(args, Symbol.iterator);
|
|
278
|
-
else
|
|
279
|
-
Object.defineProperty(args, Symbol.iterator, {
|
|
280
|
-
...record(data.iterator),
|
|
281
|
-
value: Array.prototype.values
|
|
282
|
-
});
|
|
283
|
-
if (!data.extensible)
|
|
284
|
-
Object.preventExtensions(args);
|
|
285
|
-
return args;
|
|
286
|
-
}
|
|
287
|
-
if (kind !== "array" && kind !== "object")
|
|
288
|
-
throw new TypeError("Invalid replay data node.");
|
|
289
|
-
if (typeof node.extensible !== "boolean" || typeof node.nullPrototype !== "boolean") {
|
|
290
|
-
throw new TypeError("Invalid replay object metadata.");
|
|
291
|
-
}
|
|
292
|
-
const result = kind === "array" ? [] : Object.create(node.nullPrototype ? null : Object.prototype);
|
|
293
|
-
if (Object.hasOwn(node, "errorType")) {
|
|
294
|
-
sandboxErrorTypes.set(result, node.errorType);
|
|
295
|
-
}
|
|
296
|
-
if (kind === "array" && node.nullPrototype)
|
|
297
|
-
Object.setPrototypeOf(result, null);
|
|
298
|
-
restored.set(id, result);
|
|
299
|
-
defineProperties(result, record(own(node, "properties")), child);
|
|
300
|
-
if (!node.extensible)
|
|
301
|
-
Object.preventExtensions(result);
|
|
306
|
+
};
|
|
307
|
+
const result = decode(own(graph, "root"));
|
|
308
|
+
if (parent !== undefined)
|
|
309
|
+
compilation.forward(compilation.tickets, parent);
|
|
302
310
|
return result;
|
|
303
|
-
}
|
|
304
|
-
|
|
311
|
+
}
|
|
312
|
+
finally {
|
|
313
|
+
compilation.dispose();
|
|
314
|
+
}
|
|
305
315
|
}
|
|
306
316
|
function defineProperties(target, properties, decode) {
|
|
307
317
|
for (const [key, value] of Object.entries(properties)) {
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { type SandboxClosure, type SandboxPromise, type SandboxValue } from "../interp/values.js";
|
|
2
2
|
import { type ReplayData } from "./replay-data.js";
|
|
3
|
+
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
3
4
|
export type ReplayInputs = {
|
|
4
5
|
bindings: Record<string, SandboxValue>;
|
|
5
6
|
imports: Record<string, SandboxValue>;
|
|
6
7
|
entryPointArgs: SandboxValue[] | undefined;
|
|
7
8
|
importMeta: SandboxValue;
|
|
8
9
|
};
|
|
9
|
-
export declare function prepareReplayInputs(current: ReplayInputs, saved?: unknown, preparePromise?: (promise: SandboxPromise | undefined, id: string) => SandboxPromise, onCapabilityRestored?: (original: SandboxClosure, restored: SandboxClosure) => void): {
|
|
10
|
+
export declare function prepareReplayInputs(current: ReplayInputs, saved?: unknown, preparePromise?: (promise: SandboxPromise | undefined, id: string) => SandboxPromise, onCapabilityRestored?: (original: SandboxClosure, restored: SandboxClosure) => void, compilation?: CompileScope): {
|
|
10
11
|
values: ReplayInputs;
|
|
11
12
|
snapshot: ReplayData;
|
|
12
13
|
};
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { createSandboxPromise, isSandboxClosure, isSandboxMap, isSandboxSet, isSandboxPromise } from "../interp/values.js";
|
|
2
2
|
import { decodeReplayData, encodeReplayData } from "./replay-data.js";
|
|
3
|
+
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
3
4
|
const validationPromise = createSandboxPromise(Promise.resolve(undefined));
|
|
4
|
-
export function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestored) {
|
|
5
|
+
export function prepareReplayInputs(current, saved, preparePromise, onCapabilityRestored, compilation) {
|
|
5
6
|
const identities = new WeakMap();
|
|
6
7
|
const capabilities = new Map();
|
|
7
8
|
const promises = new Map();
|
|
@@ -30,7 +31,7 @@ export function prepareReplayInputs(current, saved, preparePromise, onCapability
|
|
|
30
31
|
: decodeReplayData(snapshot, {
|
|
31
32
|
resolveCapability: (id) => capabilities.get(id),
|
|
32
33
|
resolvePromise: (id) => promises.get(id)
|
|
33
|
-
}),
|
|
34
|
+
}, compilation),
|
|
34
35
|
snapshot
|
|
35
36
|
};
|
|
36
37
|
}
|
|
@@ -71,14 +72,20 @@ export function prepareReplayInputs(current, saved, preparePromise, onCapability
|
|
|
71
72
|
const value = readCapability(id);
|
|
72
73
|
return isSandboxClosure(value) ? value : undefined;
|
|
73
74
|
};
|
|
74
|
-
const
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
75
|
+
const validationScope = new CompileScope(compilation?.owner);
|
|
76
|
+
try {
|
|
77
|
+
const validated = decodeReplayData(saved, {
|
|
78
|
+
resolveCapability,
|
|
79
|
+
resolvePromise: (id) => {
|
|
80
|
+
readCapability(id);
|
|
81
|
+
return validationPromise;
|
|
82
|
+
}
|
|
83
|
+
}, validationScope);
|
|
84
|
+
assertReplayInputShape(validated);
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
validationScope.dispose();
|
|
88
|
+
}
|
|
82
89
|
const restored = decodeReplayData(saved, {
|
|
83
90
|
resolveCapability,
|
|
84
91
|
onCapabilityRestored,
|
|
@@ -88,7 +95,7 @@ export function prepareReplayInputs(current, saved, preparePromise, onCapability
|
|
|
88
95
|
promises.set(id, preparePromise(isSandboxPromise(value) ? value : undefined, id));
|
|
89
96
|
return promises.get(id);
|
|
90
97
|
}
|
|
91
|
-
});
|
|
98
|
+
}, compilation);
|
|
92
99
|
return { values: restored, snapshot: structuredClone(saved) };
|
|
93
100
|
}
|
|
94
101
|
function assertReplayInputShape(restored) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Budget } from "../interp/budget.js";
|
|
1
|
+
import { Budget, type CompileOwner } from "../interp/budget.js";
|
|
2
2
|
import { Scope } from "../interp/interpreter.js";
|
|
3
3
|
import { type SandboxValue } from "../interp/values.js";
|
|
4
4
|
import { type Module, type ParseResult } from "../parse/parser.js";
|
|
@@ -31,4 +31,4 @@ export type RestoredSnapshot = {
|
|
|
31
31
|
signal?: AbortSignal;
|
|
32
32
|
sourceHash: string;
|
|
33
33
|
};
|
|
34
|
-
export declare function restore(snapshot: SerializedSnapshot, options: RestoreOptions): RestoredSnapshot;
|
|
34
|
+
export declare function restore(snapshot: SerializedSnapshot, options: RestoreOptions, owner?: CompileOwner): RestoredSnapshot;
|