poe-code 13.0.3 → 13.0.5
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 +14421 -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-BI5UBZ7A.js} +14508 -13744
- package/packages/safe-js/dist/chunks/chunk-BI5UBZ7A.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-QCJ7UAMC.js → chunk-FH5X7CUS.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 +95 -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-FH5X7CUS.js.map} +0 -0
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { Budget } from "../interp/budget.js";
|
|
1
|
+
import { Budget, SandboxError } from "../interp/budget.js";
|
|
2
|
+
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
2
3
|
import { decodeFloat32Storage } from "./float32array.js";
|
|
3
4
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
4
5
|
import { SnapshotMismatchError } from "../restore.js";
|
|
5
6
|
import { Scope } from "../interp/interpreter.js";
|
|
6
7
|
import { wrapCallerInjectedBindings } from "../interp/host-bridge.js";
|
|
7
|
-
import { createSandboxArguments, createSandboxClosure, createSandboxGenerator, createSandboxMap, createSandboxPromise, createSandboxRegex, createSandboxSet,
|
|
8
|
+
import { createSandboxArguments, createSandboxClosure, createSandboxGenerator, createSandboxMap, createSandboxPromise, createSandboxRegex, createSandboxSet, reconcileCompiledValues } from "../interp/values.js";
|
|
8
9
|
import { createGeneratorChannel, restoreGeneratorChannel } from "../interp/generator.js";
|
|
9
10
|
import { hashSource } from "../parse/hash.js";
|
|
10
11
|
import { getFunctionLength } from "../parse/bindings.js";
|
|
@@ -14,70 +15,84 @@ import { interpret } from "../interp/interpreter.js";
|
|
|
14
15
|
import { bindPattern } from "../interp/patterns.js";
|
|
15
16
|
import { resolvePendingHostCallResumePolicy } from "./policy.js";
|
|
16
17
|
import { validateInterpreterSnapshot, validateSnapshotSourceHash } from "./validation.js";
|
|
17
|
-
export function restore(snapshot, options) {
|
|
18
|
+
export function restore(snapshot, options, owner) {
|
|
18
19
|
const budget = options.budget ?? new Budget();
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const operation = budget.acquireCompileOwner(false, owner);
|
|
21
|
+
const compilation = new CompileScope(operation.owner);
|
|
21
22
|
try {
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
23
|
+
validateSnapshotSourceHash(snapshot);
|
|
24
|
+
let currentSourceHash;
|
|
25
|
+
try {
|
|
26
|
+
currentSourceHash = hashSource(options.source, operation.owner);
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
if (error instanceof SandboxError)
|
|
30
|
+
throw error;
|
|
31
|
+
throw new Error(`source changed since snapshot was taken (hash ${snapshot.sourceHash} expected, but current source could not be hashed); pass --reset to discard`);
|
|
32
|
+
}
|
|
33
|
+
if (snapshot.sourceHash !== currentSourceHash) {
|
|
34
|
+
throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
|
|
35
|
+
}
|
|
36
|
+
const ast = parseModule(options.source, "<input>", operation.owner);
|
|
37
|
+
const nodeById = indexAstNodes(ast);
|
|
38
|
+
validateInterpreterSnapshot(snapshot, nodeById, budget);
|
|
39
|
+
const currentNode = nodeById.get(snapshot.currentAstNodeId);
|
|
40
|
+
if (currentNode === undefined) {
|
|
41
|
+
throw new Error(`Snapshot references unknown AST node ${snapshot.currentAstNodeId}.`);
|
|
42
|
+
}
|
|
43
|
+
const state = {
|
|
42
44
|
budget,
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
45
|
+
compilation,
|
|
46
|
+
heap: snapshot.heap ?? {},
|
|
47
|
+
heapValueById: new Map(),
|
|
48
|
+
moduleBindings: restoreModuleBindings(snapshot.moduleBindings, options.modules, {
|
|
49
|
+
budget,
|
|
50
|
+
compileOwner: operation.owner,
|
|
51
|
+
signal: options.signal
|
|
52
|
+
}),
|
|
53
|
+
nodeById,
|
|
54
|
+
pendingPromiseById: new Map(),
|
|
55
|
+
serializedScopeById: new Map(snapshot.scopeChain.map((frame) => [frame.id, frame])),
|
|
56
|
+
scopeById: new Map(),
|
|
57
|
+
scopeFrameById: new Map()
|
|
58
|
+
};
|
|
59
|
+
const pendingPromises = snapshot.pendingPromises.map((entry) => restorePendingPromise(entry, state));
|
|
60
|
+
const scopeChain = snapshot.scopeChain.map((frame) => restoreScopeFrame(frame, state));
|
|
61
|
+
const currentScopeId = snapshot.callStack.at(-1)?.scopeId ?? scopeChain.at(-1)?.id;
|
|
62
|
+
if (currentScopeId === undefined) {
|
|
63
|
+
throw new Error("Snapshot does not contain a scope to resume.");
|
|
64
|
+
}
|
|
65
|
+
const currentScope = state.scopeById.get(currentScopeId);
|
|
66
|
+
if (currentScope === undefined) {
|
|
67
|
+
throw new Error(`Snapshot references unknown scope ${String(currentScopeId)}.`);
|
|
68
|
+
}
|
|
69
|
+
const callStack = snapshot.callStack.map((frame) => restoreCallFrame(frame, state));
|
|
70
|
+
reconcileCompiledValues(budget, [
|
|
71
|
+
...currentScope.retainedValues(),
|
|
72
|
+
...budget.retainedValues(),
|
|
73
|
+
...pendingPromises.flatMap((pending) => Object.values(pending).filter(isSandboxSnapshotValue))
|
|
74
|
+
], compilation);
|
|
75
|
+
return {
|
|
76
|
+
ast,
|
|
77
|
+
budget,
|
|
78
|
+
callStack,
|
|
79
|
+
currentAstNodeId: snapshot.currentAstNodeId,
|
|
80
|
+
currentNode,
|
|
81
|
+
currentScope,
|
|
82
|
+
moduleBindings: state.moduleBindings,
|
|
83
|
+
pendingPromises,
|
|
84
|
+
scopeChain: scopeChain.map((frame) => ({
|
|
85
|
+
...frame,
|
|
86
|
+
scope: state.scopeById.get(frame.id) ?? currentScope
|
|
87
|
+
})),
|
|
88
|
+
signal: options.signal,
|
|
89
|
+
sourceHash: snapshot.sourceHash
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
compilation.dispose();
|
|
94
|
+
operation.release();
|
|
95
|
+
}
|
|
81
96
|
}
|
|
82
97
|
function isSandboxSnapshotValue(value) {
|
|
83
98
|
return value !== undefined && !(value instanceof Promise);
|
|
@@ -229,7 +244,7 @@ function deserializeValue(value, state) {
|
|
|
229
244
|
return restoreGeneratorValue(value, state);
|
|
230
245
|
}
|
|
231
246
|
if (isSerializedRegexValue(value)) {
|
|
232
|
-
return createSandboxRegex(value.source, value.flags, value.lastIndex);
|
|
247
|
+
return createSandboxRegex(value.source, value.flags, value.lastIndex, state.compilation);
|
|
233
248
|
}
|
|
234
249
|
const object = Object.create(null);
|
|
235
250
|
for (const [key, entry] of Object.entries(value)) {
|
|
@@ -255,6 +270,7 @@ function restoreGeneratorValue(value, state) {
|
|
|
255
270
|
restoreParentScope(value.capturedScopeId, state);
|
|
256
271
|
const result = await interpret(node.body, {
|
|
257
272
|
budget: state.budget,
|
|
273
|
+
compileOwner: state.compilation.owner,
|
|
258
274
|
...(value.state === "suspended"
|
|
259
275
|
? {
|
|
260
276
|
generatorResume: {
|
|
@@ -438,28 +454,60 @@ function restoreClosureValue(astNodeId, capturedScopeId, state) {
|
|
|
438
454
|
return restoredClosure;
|
|
439
455
|
}
|
|
440
456
|
async function executeRestoredClosure(node, capturedScopeId, closure, args, thisValue, state) {
|
|
441
|
-
const
|
|
442
|
-
const
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
const
|
|
457
|
+
const operation = state.budget.acquireCompileOwner(false, state.compilation.owner);
|
|
458
|
+
const compilation = new CompileScope(operation.owner);
|
|
459
|
+
state = { ...state, compilation };
|
|
460
|
+
try {
|
|
461
|
+
const capturedScope = state.scopeById.get(capturedScopeId) ?? restoreParentScope(capturedScopeId, state);
|
|
462
|
+
const wrapperScope = node.type === "FunctionExpression" && node.id !== undefined
|
|
463
|
+
? capturedScope.child()
|
|
464
|
+
: capturedScope;
|
|
465
|
+
const scope = wrapperScope.child();
|
|
466
|
+
if (node.type === "FunctionExpression" && node.id !== undefined) {
|
|
467
|
+
wrapperScope.declare(node.id.name, "const", closure);
|
|
468
|
+
}
|
|
469
|
+
if (node.type !== "ArrowFunctionExpression") {
|
|
470
|
+
scope.declare("this", "const", thisValue);
|
|
471
|
+
state.budget.allocateArrayLength(args.length);
|
|
472
|
+
scope.declare("arguments", "let", createSandboxArguments(args));
|
|
473
|
+
}
|
|
474
|
+
for (let index = 0; index < node.params.length; index += 1) {
|
|
475
|
+
const param = node.params[index];
|
|
476
|
+
if (param.type === "RestElement") {
|
|
477
|
+
const rest = args.slice(index);
|
|
478
|
+
state.budget.allocateArrayLength(rest.length);
|
|
479
|
+
const binding = await bindPattern(param, rest, { kind: "let" }, scope, {
|
|
480
|
+
evaluate: async (defaultNode) => {
|
|
481
|
+
const result = await interpret(defaultNode, {
|
|
482
|
+
budget: state.budget,
|
|
483
|
+
compilation,
|
|
484
|
+
scope,
|
|
485
|
+
useScopeDirectly: true
|
|
486
|
+
});
|
|
487
|
+
return result.ok
|
|
488
|
+
? {
|
|
489
|
+
kind: "normal",
|
|
490
|
+
hasValue: "returnValue" in result,
|
|
491
|
+
value: result.returnValue
|
|
492
|
+
}
|
|
493
|
+
: { kind: "error", error: result.error };
|
|
494
|
+
}
|
|
495
|
+
});
|
|
496
|
+
if (!binding.ok) {
|
|
497
|
+
if (binding.result.kind === "error") {
|
|
498
|
+
throw binding.result.error;
|
|
499
|
+
}
|
|
500
|
+
if (binding.result.kind === "throw") {
|
|
501
|
+
throw binding.result.value;
|
|
502
|
+
}
|
|
503
|
+
}
|
|
504
|
+
break;
|
|
505
|
+
}
|
|
506
|
+
const binding = await bindPattern(param, args[index], { kind: "let" }, scope, {
|
|
460
507
|
evaluate: async (defaultNode) => {
|
|
461
508
|
const result = await interpret(defaultNode, {
|
|
462
509
|
budget: state.budget,
|
|
510
|
+
compilation,
|
|
463
511
|
scope,
|
|
464
512
|
useScopeDirectly: true
|
|
465
513
|
});
|
|
@@ -480,41 +528,22 @@ async function executeRestoredClosure(node, capturedScopeId, closure, args, this
|
|
|
480
528
|
throw binding.result.value;
|
|
481
529
|
}
|
|
482
530
|
}
|
|
483
|
-
break;
|
|
484
531
|
}
|
|
485
|
-
const
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
scope,
|
|
490
|
-
useScopeDirectly: true
|
|
491
|
-
});
|
|
492
|
-
return result.ok
|
|
493
|
-
? {
|
|
494
|
-
kind: "normal",
|
|
495
|
-
hasValue: "returnValue" in result,
|
|
496
|
-
value: result.returnValue
|
|
497
|
-
}
|
|
498
|
-
: { kind: "error", error: result.error };
|
|
499
|
-
}
|
|
532
|
+
const result = await interpret(node.body, {
|
|
533
|
+
budget: state.budget,
|
|
534
|
+
compilation,
|
|
535
|
+
scope
|
|
500
536
|
});
|
|
501
|
-
if (!
|
|
502
|
-
|
|
503
|
-
throw binding.result.error;
|
|
504
|
-
}
|
|
505
|
-
if (binding.result.kind === "throw") {
|
|
506
|
-
throw binding.result.value;
|
|
507
|
-
}
|
|
537
|
+
if (!result.ok) {
|
|
538
|
+
throw new Error(result.error.message);
|
|
508
539
|
}
|
|
540
|
+
reconcileCompiledValues(state.budget, [...scope.retainedValues(), ...state.budget.retainedValues(), result.returnValue], compilation);
|
|
541
|
+
return result.returnValue;
|
|
509
542
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
});
|
|
514
|
-
if (!result.ok) {
|
|
515
|
-
throw new Error(result.error.message);
|
|
543
|
+
finally {
|
|
544
|
+
compilation.dispose();
|
|
545
|
+
operation.release();
|
|
516
546
|
}
|
|
517
|
-
return result.returnValue;
|
|
518
547
|
}
|
|
519
548
|
function restorePromiseValue(id, state) {
|
|
520
549
|
return (state.pendingPromiseById.get(id) ??
|