poe-code 13.0.2 → 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.
Files changed (58) hide show
  1. package/dist/index.js +14764 -13923
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +1 -1
  5. package/packages/safe-js/dist/chunks/{chunk-RIQRHKCB.js → chunk-WGS5B4OT.js} +14518 -13706
  6. package/packages/safe-js/dist/chunks/chunk-WGS5B4OT.js.map +7 -0
  7. package/packages/safe-js/dist/chunks/{chunk-JP474LP7.js → chunk-ZGWWEL43.js} +2 -2
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.js +1 -1
  10. package/packages/safe-js/dist/index.d.ts +11 -3
  11. package/packages/safe-js/dist/index.js +14 -6
  12. package/packages/safe-js/dist/index.js.map +4 -4
  13. package/packages/safe-js/dist/interp/async.d.ts +2 -0
  14. package/packages/safe-js/dist/interp/async.js +31 -15
  15. package/packages/safe-js/dist/interp/budget.d.ts +29 -0
  16. package/packages/safe-js/dist/interp/budget.js +143 -0
  17. package/packages/safe-js/dist/interp/globals/console-json.d.ts +2 -1
  18. package/packages/safe-js/dist/interp/globals/console-json.js +24 -6
  19. package/packages/safe-js/dist/interp/globals/regex.d.ts +2 -1
  20. package/packages/safe-js/dist/interp/globals/regex.js +24 -3
  21. package/packages/safe-js/dist/interp/host-bridge.d.ts +2 -1
  22. package/packages/safe-js/dist/interp/host-bridge.js +98 -55
  23. package/packages/safe-js/dist/interp/host-call.d.ts +3 -2
  24. package/packages/safe-js/dist/interp/host-call.js +91 -52
  25. package/packages/safe-js/dist/interp/interpreter.d.ts +4 -1
  26. package/packages/safe-js/dist/interp/interpreter.js +115 -79
  27. package/packages/safe-js/dist/interp/methods/array.js +136 -71
  28. package/packages/safe-js/dist/interp/methods/string.d.ts +2 -1
  29. package/packages/safe-js/dist/interp/methods/string.js +111 -100
  30. package/packages/safe-js/dist/interp/regex/compile-guard.d.ts +33 -0
  31. package/packages/safe-js/dist/interp/regex/compile-guard.js +179 -0
  32. package/packages/safe-js/dist/interp/regex/parse.d.ts +2 -1
  33. package/packages/safe-js/dist/interp/regex/parse.js +87 -16
  34. package/packages/safe-js/dist/interp/values.d.ts +7 -2
  35. package/packages/safe-js/dist/interp/values.js +91 -9
  36. package/packages/safe-js/dist/modules/registry.d.ts +2 -1
  37. package/packages/safe-js/dist/modules/registry.js +1 -0
  38. package/packages/safe-js/dist/parse/hash.d.ts +2 -1
  39. package/packages/safe-js/dist/parse/hash.js +7 -4
  40. package/packages/safe-js/dist/parse/parser.d.ts +5 -3
  41. package/packages/safe-js/dist/parse/parser.js +53 -27
  42. package/packages/safe-js/dist/parse/tokenizer.d.ts +2 -0
  43. package/packages/safe-js/dist/parse/tokenizer.js +48 -26
  44. package/packages/safe-js/dist/parse.d.ts +3 -1
  45. package/packages/safe-js/dist/parse.js +3 -1
  46. package/packages/safe-js/dist/restore.d.ts +2 -1
  47. package/packages/safe-js/dist/restore.js +3 -3
  48. package/packages/safe-js/dist/run.js +289 -263
  49. package/packages/safe-js/dist/snapshot/migration.d.ts +3 -2
  50. package/packages/safe-js/dist/snapshot/migration.js +12 -5
  51. package/packages/safe-js/dist/snapshot/replay-data.d.ts +2 -1
  52. package/packages/safe-js/dist/snapshot/replay-data.js +172 -162
  53. package/packages/safe-js/dist/snapshot/replay-inputs.d.ts +2 -1
  54. package/packages/safe-js/dist/snapshot/replay-inputs.js +18 -11
  55. package/packages/safe-js/dist/snapshot/restore.d.ts +2 -2
  56. package/packages/safe-js/dist/snapshot/restore.js +142 -113
  57. package/packages/safe-js/dist/chunks/chunk-RIQRHKCB.js.map +0 -7
  58. /package/packages/safe-js/dist/chunks/{chunk-JP474LP7.js.map → chunk-ZGWWEL43.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, measureSandboxData } from "../interp/values.js";
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
- validateSnapshotSourceHash(snapshot);
20
- let currentSourceHash;
20
+ const operation = budget.acquireCompileOwner(false, owner);
21
+ const compilation = new CompileScope(operation.owner);
21
22
  try {
22
- currentSourceHash = hashSource(options.source);
23
- }
24
- catch {
25
- throw new Error(`source changed since snapshot was taken (hash ${snapshot.sourceHash} expected, but current source could not be hashed); pass --reset to discard`);
26
- }
27
- if (snapshot.sourceHash !== currentSourceHash) {
28
- throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
29
- }
30
- const ast = parseModule(options.source);
31
- const nodeById = indexAstNodes(ast);
32
- validateInterpreterSnapshot(snapshot, nodeById, budget);
33
- const currentNode = nodeById.get(snapshot.currentAstNodeId);
34
- if (currentNode === undefined) {
35
- throw new Error(`Snapshot references unknown AST node ${snapshot.currentAstNodeId}.`);
36
- }
37
- const state = {
38
- budget,
39
- heap: snapshot.heap ?? {},
40
- heapValueById: new Map(),
41
- moduleBindings: restoreModuleBindings(snapshot.moduleBindings, options.modules, {
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
- signal: options.signal
44
- }),
45
- nodeById,
46
- pendingPromiseById: new Map(),
47
- serializedScopeById: new Map(snapshot.scopeChain.map((frame) => [frame.id, frame])),
48
- scopeById: new Map(),
49
- scopeFrameById: new Map()
50
- };
51
- const pendingPromises = snapshot.pendingPromises.map((entry) => restorePendingPromise(entry, state));
52
- const scopeChain = snapshot.scopeChain.map((frame) => restoreScopeFrame(frame, state));
53
- const currentScopeId = snapshot.callStack.at(-1)?.scopeId ?? scopeChain.at(-1)?.id;
54
- if (currentScopeId === undefined) {
55
- throw new Error("Snapshot does not contain a scope to resume.");
56
- }
57
- const currentScope = state.scopeById.get(currentScopeId);
58
- if (currentScope === undefined) {
59
- throw new Error(`Snapshot references unknown scope ${String(currentScopeId)}.`);
60
- }
61
- budget.reconcileDataUsage(measureSandboxData([
62
- ...currentScope.retainedValues(),
63
- ...pendingPromises.flatMap((pending) => Object.values(pending).filter(isSandboxSnapshotValue))
64
- ]));
65
- return {
66
- ast,
67
- budget,
68
- callStack: snapshot.callStack.map((frame) => restoreCallFrame(frame, state)),
69
- currentAstNodeId: snapshot.currentAstNodeId,
70
- currentNode,
71
- currentScope,
72
- moduleBindings: state.moduleBindings,
73
- pendingPromises,
74
- scopeChain: scopeChain.map((frame) => ({
75
- ...frame,
76
- scope: state.scopeById.get(frame.id) ?? currentScope
77
- })),
78
- signal: options.signal,
79
- sourceHash: snapshot.sourceHash
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 capturedScope = state.scopeById.get(capturedScopeId) ?? restoreParentScope(capturedScopeId, state);
442
- const wrapperScope = node.type === "FunctionExpression" && node.id !== undefined
443
- ? capturedScope.child()
444
- : capturedScope;
445
- const scope = wrapperScope.child();
446
- if (node.type === "FunctionExpression" && node.id !== undefined) {
447
- wrapperScope.declare(node.id.name, "const", closure);
448
- }
449
- if (node.type !== "ArrowFunctionExpression") {
450
- scope.declare("this", "const", thisValue);
451
- state.budget.allocateArrayLength(args.length);
452
- scope.declare("arguments", "let", createSandboxArguments(args));
453
- }
454
- for (let index = 0; index < node.params.length; index += 1) {
455
- const param = node.params[index];
456
- if (param.type === "RestElement") {
457
- const rest = args.slice(index);
458
- state.budget.allocateArrayLength(rest.length);
459
- const binding = await bindPattern(param, rest, { kind: "let" }, scope, {
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 binding = await bindPattern(param, args[index], { kind: "let" }, scope, {
486
- evaluate: async (defaultNode) => {
487
- const result = await interpret(defaultNode, {
488
- budget: state.budget,
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 (!binding.ok) {
502
- if (binding.result.kind === "error") {
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
- const result = await interpret(node.body, {
511
- budget: state.budget,
512
- scope
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) ??