poe-code 14.0.60 → 14.0.62
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 +313 -135
- 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-C7UCTQDN.js → chunk-F7TJSPDZ.js} +7 -3
- package/packages/safe-js/dist/chunks/chunk-F7TJSPDZ.js.map +7 -0
- package/packages/safe-js/dist/chunks/{chunk-MKJBQPBH.js → chunk-VKGWGZBH.js} +268 -126
- package/packages/safe-js/dist/chunks/chunk-VKGWGZBH.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/async.js +3 -0
- package/packages/safe-js/dist/interp/function-string.d.ts +2 -0
- package/packages/safe-js/dist/interp/function-string.js +21 -0
- package/packages/safe-js/dist/interp/globals/misc.js +11 -12
- package/packages/safe-js/dist/interp/globals/numeric-parsers.d.ts +5 -0
- package/packages/safe-js/dist/interp/globals/numeric-parsers.js +47 -0
- package/packages/safe-js/dist/interp/globals/object-array.js +2 -10
- package/packages/safe-js/dist/interp/interpreter.js +9 -14
- package/packages/safe-js/dist/interp/methods/function.d.ts +2 -0
- package/packages/safe-js/dist/interp/methods/function.js +10 -1
- package/packages/safe-js/dist/interp/methods/string.js +18 -0
- package/packages/safe-js/dist/interp/resources.d.ts +3 -0
- package/packages/safe-js/dist/interp/resources.js +11 -0
- package/packages/safe-js/dist/interp/string-coercion.js +16 -4
- package/packages/safe-js/dist/interp/values.d.ts +3 -0
- package/packages/safe-js/dist/interp/values.js +3 -0
- package/packages/safe-js/dist/migrate.js +1 -1
- package/packages/safe-js/dist/parse/function-source.d.ts +7 -0
- package/packages/safe-js/dist/parse/function-source.js +1 -0
- package/packages/safe-js/dist/parse/hash.d.ts +2 -2
- package/packages/safe-js/dist/parse/hash.js +23 -9
- package/packages/safe-js/dist/parse/parser.js +36 -23
- package/packages/safe-js/dist/restore.js +2 -1
- package/packages/safe-js/dist/run.js +16 -5
- package/packages/safe-js/dist/snapshot/dump-format.d.ts +1 -1
- package/packages/safe-js/dist/snapshot/dump-format.js +1 -1
- package/packages/safe-js/dist/snapshot/migration.js +2 -2
- package/packages/safe-js/dist/snapshot/restore.js +2 -0
- package/packages/safe-js/dist/chunks/chunk-C7UCTQDN.js.map +0 -7
- package/packages/safe-js/dist/chunks/chunk-MKJBQPBH.js.map +0 -7
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { boundIdentifiers } from "./bindings.js";
|
|
2
2
|
import { tokenize } from "./tokenizer.js";
|
|
3
3
|
import { assignIds } from "./assign-ids.js";
|
|
4
|
+
import { functionSources } from "./function-source.js";
|
|
4
5
|
import { formatParseError } from "./format-error.js";
|
|
5
6
|
import { createExportDefaultDeclaration, createExportNamedDeclaration } from "./parse-export.js";
|
|
6
7
|
import { createImportMeta, isImportMetaTokenSequence } from "./parse-import-meta.js";
|
|
@@ -42,7 +43,7 @@ const TOP_LEVEL_STATEMENT_KEYWORDS = new Set([
|
|
|
42
43
|
export function parse(source, filename = "<input>", owner) {
|
|
43
44
|
const compilation = new CompileScope(owner);
|
|
44
45
|
try {
|
|
45
|
-
const result = assignIds(
|
|
46
|
+
const result = assignIds(new Parser(tokenize(source, { allowRegexLiterals: true, compilation }), source, compilation).parseTopLevel());
|
|
46
47
|
const regexLiteral = findRegexLiteral(result);
|
|
47
48
|
if (regexLiteral !== undefined) {
|
|
48
49
|
throw new Error(`Regular expression literals are not supported at line ${regexLiteral.span.start.line}, column ${regexLiteral.span.start.column}.`);
|
|
@@ -66,7 +67,7 @@ export function parse(source, filename = "<input>", owner) {
|
|
|
66
67
|
export function parseModule(source, filename = "<input>", owner) {
|
|
67
68
|
const compilation = new CompileScope(owner);
|
|
68
69
|
try {
|
|
69
|
-
return assignIds(
|
|
70
|
+
return assignIds(new Parser(tokenize(source, { allowRegexLiterals: true, compilation }), source, compilation).parseModule());
|
|
70
71
|
}
|
|
71
72
|
catch (error) {
|
|
72
73
|
if (error instanceof DisallowedSyntaxError || error instanceof SandboxError) {
|
|
@@ -84,7 +85,7 @@ export function parseModule(source, filename = "<input>", owner) {
|
|
|
84
85
|
export function parseExecutableModule(source, filename = "<input>", owner) {
|
|
85
86
|
const compilation = new CompileScope(owner);
|
|
86
87
|
try {
|
|
87
|
-
const result = assignIds(
|
|
88
|
+
const result = assignIds(new Parser(tokenize(source, { allowRegexLiterals: true, compilation }), source, compilation).parseModule());
|
|
88
89
|
throwIfImportMetaAssignment(result);
|
|
89
90
|
return result;
|
|
90
91
|
}
|
|
@@ -101,14 +102,9 @@ export function parseExecutableModule(source, filename = "<input>", owner) {
|
|
|
101
102
|
compilation.dispose();
|
|
102
103
|
}
|
|
103
104
|
}
|
|
104
|
-
function parseTokens(tokens, compilation) {
|
|
105
|
-
return new Parser(tokens, compilation).parseTopLevel();
|
|
106
|
-
}
|
|
107
|
-
function parseModuleTokens(tokens, compilation) {
|
|
108
|
-
return new Parser(tokens, compilation).parseModule();
|
|
109
|
-
}
|
|
110
105
|
class Parser {
|
|
111
106
|
tokens;
|
|
107
|
+
source;
|
|
112
108
|
compilation;
|
|
113
109
|
functionContext;
|
|
114
110
|
index = 0;
|
|
@@ -119,12 +115,21 @@ class Parser {
|
|
|
119
115
|
scopes = [new Map()];
|
|
120
116
|
functionScopes = new WeakSet();
|
|
121
117
|
varNames = new WeakMap();
|
|
122
|
-
constructor(tokens, compilation, functionContext = "normal") {
|
|
118
|
+
constructor(tokens, source, compilation, functionContext = "normal") {
|
|
123
119
|
this.tokens = tokens;
|
|
120
|
+
this.source = source;
|
|
124
121
|
this.compilation = compilation;
|
|
125
122
|
this.functionContext = functionContext;
|
|
126
123
|
this.functionScopes.add(this.scopes[0]);
|
|
127
124
|
}
|
|
125
|
+
withFunctionSource(node) {
|
|
126
|
+
functionSources.set(node, {
|
|
127
|
+
text: this.source,
|
|
128
|
+
start: node.span.start.offset,
|
|
129
|
+
end: node.span.end.offset
|
|
130
|
+
});
|
|
131
|
+
return node;
|
|
132
|
+
}
|
|
128
133
|
parseTopLevel() {
|
|
129
134
|
if (this.isExportToken(this.currentToken())) {
|
|
130
135
|
throw new DisallowedSyntaxError("export", this.currentToken().start);
|
|
@@ -270,14 +275,14 @@ class Parser {
|
|
|
270
275
|
});
|
|
271
276
|
this.expectPunctuator("=>");
|
|
272
277
|
const body = this.parseArrowFunctionBody(params);
|
|
273
|
-
return {
|
|
278
|
+
return this.withFunctionSource({
|
|
274
279
|
type: "ArrowFunctionExpression",
|
|
275
280
|
async: isAsync,
|
|
276
281
|
body,
|
|
277
282
|
expression: body.type !== "BlockStatement",
|
|
278
283
|
params,
|
|
279
284
|
span: createSpan(start, body.span.end)
|
|
280
|
-
};
|
|
285
|
+
});
|
|
281
286
|
}
|
|
282
287
|
parseConditionalExpression() {
|
|
283
288
|
if (this.conditionalExpressionDepth >= MAX_CONDITIONAL_EXPRESSION_DEPTH) {
|
|
@@ -920,7 +925,7 @@ class Parser {
|
|
|
920
925
|
});
|
|
921
926
|
const generator = generatorToken !== undefined;
|
|
922
927
|
const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
|
|
923
|
-
return {
|
|
928
|
+
return this.withFunctionSource({
|
|
924
929
|
type: "FunctionDeclaration",
|
|
925
930
|
async: asyncToken !== undefined,
|
|
926
931
|
body,
|
|
@@ -928,7 +933,7 @@ class Parser {
|
|
|
928
933
|
id,
|
|
929
934
|
params,
|
|
930
935
|
span: createSpan(asyncToken?.start ?? functionToken.start, body.span.end)
|
|
931
|
-
};
|
|
936
|
+
});
|
|
932
937
|
}
|
|
933
938
|
parseVariableDeclarator(kind) {
|
|
934
939
|
const id = this.parseBindingTarget();
|
|
@@ -1669,7 +1674,11 @@ class Parser {
|
|
|
1669
1674
|
continue;
|
|
1670
1675
|
}
|
|
1671
1676
|
if (this.currentToken().type === "template") {
|
|
1672
|
-
const quasi = createTemplateLiteral(this.currentToken(), {
|
|
1677
|
+
const quasi = createTemplateLiteral(this.currentToken(), {
|
|
1678
|
+
allowMalformedEscapes: true,
|
|
1679
|
+
functionContext: this.functionContext,
|
|
1680
|
+
source: this.source
|
|
1681
|
+
}, this.compilation);
|
|
1673
1682
|
this.index += 1;
|
|
1674
1683
|
expression = {
|
|
1675
1684
|
node: {
|
|
@@ -1757,7 +1766,11 @@ class Parser {
|
|
|
1757
1766
|
if (token.type === "template") {
|
|
1758
1767
|
this.index += 1;
|
|
1759
1768
|
return {
|
|
1760
|
-
node: createTemplateLiteral(token, {
|
|
1769
|
+
node: createTemplateLiteral(token, {
|
|
1770
|
+
allowMalformedEscapes: false,
|
|
1771
|
+
functionContext: this.functionContext,
|
|
1772
|
+
source: this.source
|
|
1773
|
+
}, this.compilation),
|
|
1761
1774
|
parenthesized: false
|
|
1762
1775
|
};
|
|
1763
1776
|
}
|
|
@@ -1875,7 +1888,7 @@ class Parser {
|
|
|
1875
1888
|
});
|
|
1876
1889
|
const generator = generatorToken !== undefined;
|
|
1877
1890
|
const body = this.withFunctionContext(generator ? "generator" : "normal", () => this.parseBlockStatement(params));
|
|
1878
|
-
return {
|
|
1891
|
+
return this.withFunctionSource({
|
|
1879
1892
|
type: "FunctionExpression",
|
|
1880
1893
|
async: asyncToken !== undefined,
|
|
1881
1894
|
body,
|
|
@@ -1883,7 +1896,7 @@ class Parser {
|
|
|
1883
1896
|
id,
|
|
1884
1897
|
params,
|
|
1885
1898
|
span: createSpan(asyncToken?.start ?? functionToken.start, body.span.end)
|
|
1886
|
-
};
|
|
1899
|
+
});
|
|
1887
1900
|
}
|
|
1888
1901
|
parseArrayExpression() {
|
|
1889
1902
|
const start = this.expectPunctuator("[");
|
|
@@ -2139,7 +2152,7 @@ class Parser {
|
|
|
2139
2152
|
return parsedParams;
|
|
2140
2153
|
});
|
|
2141
2154
|
const body = this.withFunctionContext("normal", () => this.parseBlockStatement(params));
|
|
2142
|
-
return {
|
|
2155
|
+
return this.withFunctionSource({
|
|
2143
2156
|
type: "FunctionExpression",
|
|
2144
2157
|
async: asyncToken !== undefined,
|
|
2145
2158
|
body,
|
|
@@ -2148,7 +2161,7 @@ class Parser {
|
|
|
2148
2161
|
method: true,
|
|
2149
2162
|
params,
|
|
2150
2163
|
span: createSpan(asyncToken?.start ?? methodStart, body.span.end)
|
|
2151
|
-
};
|
|
2164
|
+
});
|
|
2152
2165
|
}
|
|
2153
2166
|
parseIdentifierName() {
|
|
2154
2167
|
const token = this.currentToken();
|
|
@@ -3033,7 +3046,7 @@ function createTemplateLiteral(token, options, compilation) {
|
|
|
3033
3046
|
quasis.push(createTemplateElement(token.start, raw, quasiStart, cursor, false, options));
|
|
3034
3047
|
const expressionStart = cursor + 2;
|
|
3035
3048
|
const expressionEnd = findTemplateExpressionEnd(raw, expressionStart);
|
|
3036
|
-
expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), options.functionContext, compilation));
|
|
3049
|
+
expressions.push(parseEmbeddedExpression(raw.slice(expressionStart, expressionEnd), positionWithinRaw(token.start, raw, expressionStart), options.functionContext, options.source, compilation));
|
|
3037
3050
|
quasiStart = expressionEnd + 1;
|
|
3038
3051
|
cursor = expressionEnd + 1;
|
|
3039
3052
|
continue;
|
|
@@ -3394,13 +3407,13 @@ function decodeHexEscape(value, start) {
|
|
|
3394
3407
|
end: index + 2
|
|
3395
3408
|
};
|
|
3396
3409
|
}
|
|
3397
|
-
function parseEmbeddedExpression(source, base, functionContext, compilation) {
|
|
3410
|
+
function parseEmbeddedExpression(source, base, functionContext, fullSource, compilation) {
|
|
3398
3411
|
const tokens = tokenize(source, { allowRegexLiterals: true, compilation }).map((token) => ({
|
|
3399
3412
|
...token,
|
|
3400
3413
|
start: rebasePosition(token.start, base),
|
|
3401
3414
|
end: rebasePosition(token.end, base)
|
|
3402
3415
|
}));
|
|
3403
|
-
return new Parser(tokens, compilation, functionContext).parseExpressionOnly();
|
|
3416
|
+
return new Parser(tokens, fullSource, compilation, functionContext).parseExpressionOnly();
|
|
3404
3417
|
}
|
|
3405
3418
|
export function findRegexLiteral(node) {
|
|
3406
3419
|
if (node === null || node === undefined) {
|
|
@@ -21,13 +21,14 @@ export function restore(snapshot, options, owner) {
|
|
|
21
21
|
validateSnapshotMigration(snapshot.migration, snapshot.sourceHash, owner);
|
|
22
22
|
if (snapshot.executionSemantics !== EXECUTION_SEMANTICS &&
|
|
23
23
|
snapshot.executionSemantics !== "jobs-v6" &&
|
|
24
|
+
snapshot.executionSemantics !== "jobs-v7" &&
|
|
24
25
|
(snapshot.executionSemantics !== undefined ||
|
|
25
26
|
snapshot.promiseReplay !== undefined ||
|
|
26
27
|
snapshot.replay !== undefined ||
|
|
27
28
|
snapshot.initialInputs !== undefined)) {
|
|
28
29
|
throw new SnapshotValidationError("unsupportedVersion", "$.executionSemantics", "incompatible execution semantics; resume with the SafeJS version that created this snapshot. Migration requires explicit reconciliation, not changing its version marker.");
|
|
29
30
|
}
|
|
30
|
-
const currentSourceHash = hashSource(options.source, owner);
|
|
31
|
+
const currentSourceHash = hashSource(options.source, owner, snapshot.executionSemantics !== "jobs-v6" && snapshot.executionSemantics !== "jobs-v7");
|
|
31
32
|
if (snapshot.sourceHash !== currentSourceHash) {
|
|
32
33
|
throw new SnapshotMismatchError(snapshot.sourceHash, currentSourceHash);
|
|
33
34
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
2
2
|
import { runWithExtensions } from "./realm.js";
|
|
3
3
|
import { hashParsedAst, hashSource } from "./parse/hash.js";
|
|
4
|
-
import { withRunResources } from "./interp/resources.js";
|
|
4
|
+
import { runResources, withRunResources } from "./interp/resources.js";
|
|
5
5
|
import { createReplayableRandom } from "./random.js";
|
|
6
6
|
import { attachErrorSpan, describeThrownValue, materializeWrappedErrorCause, replaceErrorStack } from "./error/shape.js";
|
|
7
7
|
import { findRegexLiteral, parseExecutableModule } from "./parse/parser.js";
|
|
@@ -76,7 +76,11 @@ export function run(source, options = {}) {
|
|
|
76
76
|
const restoredSnapshot = options.snapshot === undefined
|
|
77
77
|
? undefined
|
|
78
78
|
: restore(options.snapshot, { source }, operation.owner);
|
|
79
|
-
const executionSemantics = restoredSnapshot?.executionSemantics === "jobs-v6"
|
|
79
|
+
const executionSemantics = restoredSnapshot?.executionSemantics === "jobs-v6" ||
|
|
80
|
+
restoredSnapshot?.executionSemantics === "jobs-v7"
|
|
81
|
+
? restoredSnapshot.executionSemantics
|
|
82
|
+
: EXECUTION_SEMANTICS;
|
|
83
|
+
runResources.getStore().functionSourceText = executionSemantics === EXECUTION_SEMANTICS;
|
|
80
84
|
const convertInitialInput = (convert) => executionSemantics === "jobs-v6" ? convert() : promiseReplayContext.exit(convert);
|
|
81
85
|
if (restoredSnapshot !== undefined) {
|
|
82
86
|
leaveSnapshotRun = enterSnapshotRun(restoredSnapshot);
|
|
@@ -86,8 +90,8 @@ export function run(source, options = {}) {
|
|
|
86
90
|
const module = parseExecutableModule(source, filename, operation.owner);
|
|
87
91
|
promiseReplay.validateNodes(module);
|
|
88
92
|
const sourceHash = findRegexLiteral(module) === undefined
|
|
89
|
-
? hashSource(source, operation.owner)
|
|
90
|
-
: hashParsedAst(module);
|
|
93
|
+
? hashSource(source, operation.owner, executionSemantics === EXECUTION_SEMANTICS)
|
|
94
|
+
: hashParsedAst(module, executionSemantics === EXECUTION_SEMANTICS);
|
|
91
95
|
const hostCalls = new HostCallJournal(sourceHash, readHostCallSnapshot(restoredSnapshot), options.hostCallResumeProvider, restoredSnapshot?.replay, budget, operation.owner);
|
|
92
96
|
leaveHostReplay = hostCalls.dispose.bind(hostCalls);
|
|
93
97
|
promiseReplay.validateCallbacks(hostCalls.callbackPositions());
|
|
@@ -110,7 +114,14 @@ export function run(source, options = {}) {
|
|
|
110
114
|
signal: options.signal,
|
|
111
115
|
lifecycle
|
|
112
116
|
}));
|
|
113
|
-
const builtinBindings = createBuiltinBindings({
|
|
117
|
+
const builtinBindings = createBuiltinBindings({
|
|
118
|
+
compileOwner: operation.owner,
|
|
119
|
+
budget,
|
|
120
|
+
hostCalls,
|
|
121
|
+
sink: options.sink,
|
|
122
|
+
random: random?.generator.next,
|
|
123
|
+
clock: options.clock
|
|
124
|
+
});
|
|
114
125
|
const importMeta = convertInitialInput(() => deepCopyToSandbox(options.importMeta ?? {}));
|
|
115
126
|
if (restoredSnapshot?.migration !== undefined) {
|
|
116
127
|
if (Object.hasOwn(importMeta, "migration"))
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const DUMP_FORMAT_VERSION = 1;
|
|
2
|
-
export const EXECUTION_SEMANTICS = "jobs-
|
|
2
|
+
export const EXECUTION_SEMANTICS = "jobs-v8";
|
|
3
3
|
import { assertSnapshotGraphDepth } from "../graph-depth.js";
|
|
4
4
|
import { hasGuestObjectState } from "../interp/object-model.js";
|
|
5
5
|
import { sandboxErrorTypes } from "../error/shape.js";
|
|
@@ -3,8 +3,8 @@ import { decodeReplayData } from "./replay-data.js";
|
|
|
3
3
|
import { validateSnapshotData } from "./validation.js";
|
|
4
4
|
import { CompileScope } from "../interp/regex/compile-guard.js";
|
|
5
5
|
export function validateMigrationSemantics(value) {
|
|
6
|
-
if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7"].includes(value))
|
|
7
|
-
throw new TypeError("Migration requires a supported execution-semantics marker (jobs-v1 through jobs-
|
|
6
|
+
if (!["jobs-v1", "jobs-v2", "jobs-v3", "jobs-v4", "jobs-v5", "jobs-v6", "jobs-v7", "jobs-v8"].includes(value))
|
|
7
|
+
throw new TypeError("Migration requires a supported execution-semantics marker (jobs-v1 through jobs-v8).");
|
|
8
8
|
}
|
|
9
9
|
export function validateMigrationJournal(sourceHash, replay, hostCalls = [], owner) {
|
|
10
10
|
if (replay === undefined)
|
|
@@ -8,6 +8,7 @@ import { sandboxErrorTypes } from "../error/shape.js";
|
|
|
8
8
|
import { SnapshotMismatchError } from "../restore.js";
|
|
9
9
|
import { Scope, setSandboxProperty } from "../interp/interpreter.js";
|
|
10
10
|
import { getGuestFunctionProperties, getGuestFunctionProperty, getSandboxDataProperty, registerGuestClosure, setSandboxPrototype } from "../interp/object-model.js";
|
|
11
|
+
import { functionSources } from "../parse/function-source.js";
|
|
11
12
|
import { wrapCallerInjectedBindings } from "../interp/host-bridge.js";
|
|
12
13
|
import { restoreSandboxCollectionIterator } from "../interp/collection-iterator.js";
|
|
13
14
|
import { isSandboxMap, isSandboxSet } from "../interp/values.js";
|
|
@@ -454,6 +455,7 @@ function restoreClosureValue(astNodeId, capturedScopeId, state) {
|
|
|
454
455
|
throw new Error(`Snapshot references unknown closure AST node ${astNodeId}.`);
|
|
455
456
|
}
|
|
456
457
|
const baseClosure = createSandboxClosure({
|
|
458
|
+
sourceRange: functionSources.get(node),
|
|
457
459
|
async: node.async,
|
|
458
460
|
sandbox: true,
|
|
459
461
|
length: getFunctionLength(node.params),
|