poe-code 14.0.79 → 14.0.81
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 +772 -341
- 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-B3AL4KJ3.js → chunk-2LNBLFJ3.js} +2 -2
- package/packages/safe-js/dist/chunks/{chunk-BGSPSHLP.js → chunk-ZSYBRZU6.js} +644 -292
- package/packages/safe-js/dist/chunks/chunk-ZSYBRZU6.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/graph-depth.js +2 -1
- package/packages/safe-js/dist/index.js +2 -2
- package/packages/safe-js/dist/interp/async.d.ts +1 -1
- package/packages/safe-js/dist/interp/async.js +65 -43
- package/packages/safe-js/dist/interp/bound-function-state.d.ts +7 -0
- package/packages/safe-js/dist/interp/bound-function-state.js +1 -0
- package/packages/safe-js/dist/interp/bound-function.d.ts +4 -0
- package/packages/safe-js/dist/interp/bound-function.js +18 -0
- package/packages/safe-js/dist/interp/generator-properties.d.ts +3 -0
- package/packages/safe-js/dist/interp/generator-properties.js +9 -0
- package/packages/safe-js/dist/interp/generator-prototypes.d.ts +6 -0
- package/packages/safe-js/dist/interp/generator-prototypes.js +1 -0
- package/packages/safe-js/dist/interp/globals/function.d.ts +2 -0
- package/packages/safe-js/dist/interp/globals/function.js +32 -0
- package/packages/safe-js/dist/interp/globals/generator.d.ts +2 -0
- package/packages/safe-js/dist/interp/globals/generator.js +51 -0
- package/packages/safe-js/dist/interp/globals/object-array.js +28 -7
- package/packages/safe-js/dist/interp/globals/object.js +2 -1
- package/packages/safe-js/dist/interp/globals.d.ts +1 -0
- package/packages/safe-js/dist/interp/globals.js +4 -0
- package/packages/safe-js/dist/interp/instanceof.d.ts +4 -0
- package/packages/safe-js/dist/interp/instanceof.js +58 -0
- package/packages/safe-js/dist/interp/interpreter.js +16 -47
- package/packages/safe-js/dist/interp/iteration.js +76 -5
- package/packages/safe-js/dist/interp/methods/function.d.ts +5 -2
- package/packages/safe-js/dist/interp/methods/function.js +55 -42
- package/packages/safe-js/dist/interp/methods/generator.d.ts +4 -1
- package/packages/safe-js/dist/interp/methods/generator.js +12 -6
- package/packages/safe-js/dist/interp/object-model.d.ts +1 -0
- package/packages/safe-js/dist/interp/object-model.js +69 -17
- package/packages/safe-js/dist/interp/string-coercion.js +3 -2
- package/packages/safe-js/dist/interp/values.js +21 -3
- package/packages/safe-js/dist/snapshot/guest-heap-validation.js +27 -3
- package/packages/safe-js/dist/snapshot/guest-heap.d.ts +9 -0
- package/packages/safe-js/dist/snapshot/guest-heap.js +11 -0
- package/packages/safe-js/dist/snapshot/restore.js +61 -7
- package/packages/safe-js/dist/chunks/chunk-BGSPSHLP.js.map +0 -7
- /package/packages/safe-js/dist/chunks/{chunk-B3AL4KJ3.js.map → chunk-2LNBLFJ3.js.map} +0 -0
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
resolveFsConfig,
|
|
23
23
|
splitFrontmatter,
|
|
24
24
|
withBrokenPipeGuard
|
|
25
|
-
} from "./chunks/chunk-
|
|
25
|
+
} from "./chunks/chunk-2LNBLFJ3.js";
|
|
26
26
|
import {
|
|
27
27
|
Budget,
|
|
28
28
|
SandboxError,
|
|
@@ -34,7 +34,7 @@ import {
|
|
|
34
34
|
replaceErrorStack,
|
|
35
35
|
restore,
|
|
36
36
|
run
|
|
37
|
-
} from "./chunks/chunk-
|
|
37
|
+
} from "./chunks/chunk-ZSYBRZU6.js";
|
|
38
38
|
import "./chunks/chunk-M2DLCGEF.js";
|
|
39
39
|
import "./chunks/chunk-Q7USUEL7.js";
|
|
40
40
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -7,6 +7,7 @@ import { regexpIteratorState, isSandboxRegExpIterator } from "./interp/regexp-it
|
|
|
7
7
|
import { isSandboxMap, isSandboxSet } from "./interp/collection-brands.js";
|
|
8
8
|
import { boxedDataProperties, isSandboxBox } from "./interp/boxed.js";
|
|
9
9
|
import { regexGuestProperties } from "./interp/regexp-properties.js";
|
|
10
|
+
import { generatorGuestProperties } from "./interp/generator-properties.js";
|
|
10
11
|
export const MAX_DATA_DEPTH = 1_024;
|
|
11
12
|
export class SnapshotBudgetError extends Error {
|
|
12
13
|
code = "budgetExceeded";
|
|
@@ -67,7 +68,7 @@ function walkGraphDepth(root, rootPath, assertDepth) {
|
|
|
67
68
|
}
|
|
68
69
|
}
|
|
69
70
|
function graphEntries(value) {
|
|
70
|
-
const properties = regexGuestProperties.get(value);
|
|
71
|
+
const properties = regexGuestProperties.get(value) ?? generatorGuestProperties.get(value);
|
|
71
72
|
if (properties !== undefined)
|
|
72
73
|
return Reflect.ownKeys(properties).flatMap(key => {
|
|
73
74
|
const descriptor = Object.getOwnPropertyDescriptor(properties, key);
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
runWithSpawnUsageAccumulator,
|
|
27
27
|
splitFrontmatter,
|
|
28
28
|
supportsSpawnMode
|
|
29
|
-
} from "./chunks/chunk-
|
|
29
|
+
} from "./chunks/chunk-2LNBLFJ3.js";
|
|
30
30
|
import {
|
|
31
31
|
Budget,
|
|
32
32
|
FileSnapshotBackend,
|
|
@@ -50,7 +50,7 @@ import {
|
|
|
50
50
|
registerPendingHostCallPolicy,
|
|
51
51
|
restore,
|
|
52
52
|
run
|
|
53
|
-
} from "./chunks/chunk-
|
|
53
|
+
} from "./chunks/chunk-ZSYBRZU6.js";
|
|
54
54
|
import "./chunks/chunk-M2DLCGEF.js";
|
|
55
55
|
import "./chunks/chunk-Q7USUEL7.js";
|
|
56
56
|
import "./chunks/chunk-4YIDX44G.js";
|
|
@@ -70,7 +70,7 @@ export type EvaluateAsyncNode = (node: ParseResult, context: AsyncEvaluationCont
|
|
|
70
70
|
export declare function emitResumeBreakpoint(context: AsyncEvaluationContext, breakpoint: ResumeBreakpoint): void;
|
|
71
71
|
export declare function evaluateArrowFunctionExpression(node: ArrowFunctionExpression, context: AsyncEvaluationContext, evaluateNode: EvaluateAsyncNode): Promise<AsyncEvaluationResult>;
|
|
72
72
|
export declare function evaluateFunctionExpression(node: FunctionExpression, context: AsyncEvaluationContext, evaluateNode: EvaluateAsyncNode): Promise<AsyncEvaluationResult>;
|
|
73
|
-
export declare function createInterpretedClosure(node: ArrowFunctionExpression | FunctionDeclaration | FunctionExpression, context: AsyncEvaluationContext, evaluateNode: EvaluateAsyncNode, homeObject?: SandboxObject | SandboxClosure): SandboxClosure;
|
|
73
|
+
export declare function createInterpretedClosure(node: ArrowFunctionExpression | FunctionDeclaration | FunctionExpression, context: AsyncEvaluationContext, evaluateNode: EvaluateAsyncNode, homeObject?: SandboxObject | SandboxClosure, initializeGeneratorPrototype?: boolean): SandboxClosure;
|
|
74
74
|
export declare function executeAsyncFunction(execute: (onSuspend: () => void) => Promise<SandboxValue>, budget: Budget, signal?: AbortSignal, callContext?: SandboxCallContext): import("./values.js").SandboxPromise;
|
|
75
75
|
export declare function evaluateAwaitExpression(node: AwaitExpression, context: AsyncEvaluationContext, evaluateNode: EvaluateAsyncNode): Promise<AsyncEvaluationResult>;
|
|
76
76
|
export declare function executeClosure(node: ArrowFunctionExpression | FunctionDeclaration | FunctionExpression, args: readonly SandboxValue[], thisValue: SandboxValue, context: AsyncEvaluationContext, evaluateNode: EvaluateAsyncNode): Promise<SandboxValue>;
|
|
@@ -7,7 +7,9 @@ import { CompileScope } from "./regex/compile-guard.js";
|
|
|
7
7
|
import { awaitSandboxValue } from "./cancel.js";
|
|
8
8
|
import { hoistVarDeclarations } from "./var-hoist.js";
|
|
9
9
|
import { createCoercionContext, createPatternContext } from "./interpreter.js";
|
|
10
|
-
import { getGuestFunctionProperty, setSandboxPrototype } from "./object-model.js";
|
|
10
|
+
import { getGuestFunctionProperty, markDescriptorObject, materializeFunctionProperties, setSandboxPrototype } from "./object-model.js";
|
|
11
|
+
import { generatorPrototypes } from "./generator-prototypes.js";
|
|
12
|
+
import { retainValues, runResources } from "./resources.js";
|
|
11
13
|
import { functionSources } from "../parse/function-source.js";
|
|
12
14
|
import { registerClosureOrigin, registerGeneratorOrigin } from "./closure-origin.js";
|
|
13
15
|
import { boundIdentifiers, containsParameterExpression, getFunctionLength, hoistedVarDeclarations } from "../parse/bindings.js";
|
|
@@ -42,12 +44,12 @@ export async function evaluateFunctionExpression(node, context, evaluateNode) {
|
|
|
42
44
|
value: closure
|
|
43
45
|
};
|
|
44
46
|
}
|
|
45
|
-
export function createInterpretedClosure(node, context, evaluateNode, homeObject) {
|
|
47
|
+
export function createInterpretedClosure(node, context, evaluateNode, homeObject, initializeGeneratorPrototype = true) {
|
|
46
48
|
if (node.type !== "ArrowFunctionExpression") {
|
|
47
49
|
context = { ...context, functionEnvironment: { homeObject } };
|
|
48
50
|
}
|
|
49
51
|
if (node.type !== "ArrowFunctionExpression" && node.generator) {
|
|
50
|
-
return createGeneratorClosure(node, context, evaluateNode);
|
|
52
|
+
return createGeneratorClosure(node, context, evaluateNode, initializeGeneratorPrototype);
|
|
51
53
|
}
|
|
52
54
|
const construct = node.type !== "ArrowFunctionExpression" &&
|
|
53
55
|
!(node.type === "FunctionExpression" && node.method === true) &&
|
|
@@ -123,7 +125,9 @@ export function executeAsyncFunction(execute, budget, signal, callContext) {
|
|
|
123
125
|
});
|
|
124
126
|
return createSandboxPromise(promise, { synchronousPrefix });
|
|
125
127
|
}
|
|
126
|
-
function createGeneratorClosure(node, context, evaluateNode) {
|
|
128
|
+
function createGeneratorClosure(node, context, evaluateNode, initializePrototype) {
|
|
129
|
+
const prototypes = !initializePrototype || runResources.getStore()?.functionSourceText === false ? undefined
|
|
130
|
+
: generatorPrototypes.get(context.budget)?.get(node.async === true);
|
|
127
131
|
const closure = createSandboxClosure({
|
|
128
132
|
sourceRange: functionSources.get(node),
|
|
129
133
|
guest: true,
|
|
@@ -133,48 +137,66 @@ function createGeneratorClosure(node, context, evaluateNode) {
|
|
|
133
137
|
...(node.id === undefined ? { name: context.inferredName } : { name: node.id.name }),
|
|
134
138
|
retainedValues: () => [...context.scope.retainedValues(), context.functionEnvironment?.homeObject, context.functionEnvironment?.newTarget],
|
|
135
139
|
call: async (args, callContext) => {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
...closureContext,
|
|
146
|
-
functionBody: node.body,
|
|
147
|
-
asyncGenerator: node.async,
|
|
148
|
-
generatorBlockScopes: new Map(),
|
|
149
|
-
generatorExpressionStates: new Map(),
|
|
150
|
-
captureGeneratorScope: (suspendedScope, blocks, completions, expressions) => {
|
|
151
|
-
origin.suspendedScope = suspendedScope;
|
|
152
|
-
origin.blockScopes = blocks;
|
|
153
|
-
origin.finallyCompletions = completions;
|
|
154
|
-
origin.expressionStates = expressions;
|
|
155
|
-
},
|
|
156
|
-
generatorYield: (value, yieldNodeId) => {
|
|
157
|
-
generator.state = "suspended";
|
|
158
|
-
return generatorYield(value, yieldNodeId);
|
|
159
|
-
},
|
|
160
|
-
scope
|
|
161
|
-
});
|
|
162
|
-
if (result.kind === "error") {
|
|
163
|
-
throw result.error;
|
|
164
|
-
}
|
|
165
|
-
if (result.kind === "throw") {
|
|
166
|
-
throw result.value;
|
|
167
|
-
}
|
|
168
|
-
const value = result.hasValue ? result.value : undefined;
|
|
169
|
-
return node.async ? awaitSandboxValue(value, context.signal, context.budget, createCoercionContext(context)) : value;
|
|
140
|
+
// Native generators select their instance prototype before initializing parameters.
|
|
141
|
+
const candidate = prototypes === undefined ? undefined : getGuestFunctionProperty(closure, "prototype");
|
|
142
|
+
const prototype = typeof candidate === "object" && candidate !== null ? candidate : prototypes?.instancePrototype;
|
|
143
|
+
const releasePrototype = prototype === undefined ? undefined : retainValues(context.budget, () => [prototype]);
|
|
144
|
+
try {
|
|
145
|
+
const closureContext = {
|
|
146
|
+
...context,
|
|
147
|
+
compilation: callContext?.compilation ?? context.compilation,
|
|
148
|
+
callStack: [...(callContext?.stack ?? context.callStack)]
|
|
170
149
|
};
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
150
|
+
const scope = await createClosureScope(node, args, callContext?.thisValue, closureContext, evaluateNode);
|
|
151
|
+
const channel = createGeneratorChannel((generatorYield) => {
|
|
152
|
+
const execute = async () => {
|
|
153
|
+
const result = await evaluateNode(node.body, {
|
|
154
|
+
...closureContext,
|
|
155
|
+
functionBody: node.body,
|
|
156
|
+
asyncGenerator: node.async,
|
|
157
|
+
generatorBlockScopes: new Map(),
|
|
158
|
+
generatorExpressionStates: new Map(),
|
|
159
|
+
captureGeneratorScope: (suspendedScope, blocks, completions, expressions) => {
|
|
160
|
+
origin.suspendedScope = suspendedScope;
|
|
161
|
+
origin.blockScopes = blocks;
|
|
162
|
+
origin.finallyCompletions = completions;
|
|
163
|
+
origin.expressionStates = expressions;
|
|
164
|
+
},
|
|
165
|
+
generatorYield: (value, yieldNodeId) => {
|
|
166
|
+
generator.state = "suspended";
|
|
167
|
+
return generatorYield(value, yieldNodeId);
|
|
168
|
+
},
|
|
169
|
+
scope
|
|
170
|
+
});
|
|
171
|
+
if (result.kind === "error") {
|
|
172
|
+
throw result.error;
|
|
173
|
+
}
|
|
174
|
+
if (result.kind === "throw") {
|
|
175
|
+
throw result.value;
|
|
176
|
+
}
|
|
177
|
+
const value = result.hasValue ? result.value : undefined;
|
|
178
|
+
return node.async ? awaitSandboxValue(value, context.signal, context.budget, createCoercionContext(context)) : value;
|
|
179
|
+
};
|
|
180
|
+
return node.async ? runAsyncPrefix(execute) : execute();
|
|
181
|
+
});
|
|
182
|
+
const generator = createSandboxGenerator(channel, { async: node.async });
|
|
183
|
+
if (prototype !== undefined)
|
|
184
|
+
setSandboxPrototype(generator, prototype, context.budget);
|
|
185
|
+
const origin = registerGeneratorOrigin(generator, node, scope, closureContext);
|
|
186
|
+
return generator;
|
|
187
|
+
}
|
|
188
|
+
finally {
|
|
189
|
+
releasePrototype?.();
|
|
190
|
+
}
|
|
176
191
|
}
|
|
177
192
|
});
|
|
193
|
+
if (prototypes !== undefined) {
|
|
194
|
+
const prototype = Object.create(null);
|
|
195
|
+
markDescriptorObject(prototype);
|
|
196
|
+
setSandboxPrototype(prototype, prototypes.instancePrototype);
|
|
197
|
+
Object.defineProperty(materializeFunctionProperties(closure), "prototype", { value: prototype, writable: true });
|
|
198
|
+
setSandboxPrototype(closure, prototypes.functionPrototype);
|
|
199
|
+
}
|
|
178
200
|
registerClosureOrigin(closure, node, context);
|
|
179
201
|
return closure;
|
|
180
202
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const boundFunctionStates = new WeakMap();
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { type SandboxClosure } from "./values.js";
|
|
2
|
+
import { type BoundFunctionState } from "./bound-function-state.js";
|
|
3
|
+
import type { FunctionMethodOptions } from "./methods/function.js";
|
|
4
|
+
export declare function createBoundFunction(state: BoundFunctionState, name: string | undefined, length: number | undefined, callClosure: FunctionMethodOptions["callClosure"]): SandboxClosure;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createSandboxClosure } from "./values.js";
|
|
2
|
+
import { boundFunctionStates } from "./bound-function-state.js";
|
|
3
|
+
export function createBoundFunction(state, name, length, callClosure) {
|
|
4
|
+
const bound = createSandboxClosure({
|
|
5
|
+
guest: true,
|
|
6
|
+
sandbox: true,
|
|
7
|
+
name,
|
|
8
|
+
length,
|
|
9
|
+
boundTarget: state.target,
|
|
10
|
+
retainedValues: () => [state.target, state.thisValue, ...state.args, bound.name],
|
|
11
|
+
call: (args, context) => callClosure(state.target, [...state.args, ...args], context?.stack ?? [], state.thisValue),
|
|
12
|
+
...(state.target.construct === undefined ? {} : {
|
|
13
|
+
construct: (args, context) => callClosure(state.target, [...state.args, ...args], context?.stack ?? [], undefined, true, context?.newTarget === bound ? state.target : context?.newTarget)
|
|
14
|
+
})
|
|
15
|
+
});
|
|
16
|
+
boundFunctionStates.set(bound, state);
|
|
17
|
+
return bound;
|
|
18
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export const generatorGuestProperties = new WeakMap();
|
|
2
|
+
export function getGeneratorProperties(value) {
|
|
3
|
+
let properties = generatorGuestProperties.get(value);
|
|
4
|
+
if (properties === undefined) {
|
|
5
|
+
properties = Object.create(null);
|
|
6
|
+
generatorGuestProperties.set(value, properties);
|
|
7
|
+
}
|
|
8
|
+
return properties;
|
|
9
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const generatorPrototypes = new WeakMap();
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { invokeBuiltinClosure } from "../builtin-call.js";
|
|
2
|
+
import { callFunctionMethod } from "../methods/function.js";
|
|
3
|
+
import { getSandboxPrototype, installFunctionPrototype, materializeFunctionProperties, registerIntrinsicFunction, setSandboxPrototype } from "../object-model.js";
|
|
4
|
+
import { createSandboxClosure } from "../values.js";
|
|
5
|
+
import { ordinaryHasInstance } from "../instanceof.js";
|
|
6
|
+
export function createFunctionPrototype(budget, installHasInstance = true) {
|
|
7
|
+
const prototype = createSandboxClosure({ guest: true, sandbox: true, name: "", length: 0, call: () => undefined });
|
|
8
|
+
const properties = materializeFunctionProperties(prototype);
|
|
9
|
+
// Invocation support does not grant the host's dynamic source constructor.
|
|
10
|
+
Object.defineProperty(properties, "constructor", { value: undefined, writable: true, configurable: true });
|
|
11
|
+
for (const [name, length] of [["call", 1], ["apply", 2], ["bind", 1], ["toString", 0]]) {
|
|
12
|
+
Object.defineProperty(properties, name, { writable: true, configurable: true,
|
|
13
|
+
value: createSandboxClosure({ guest: true, sandbox: true, name, length,
|
|
14
|
+
call: (args, context) => callFunctionMethod(context?.thisValue, name, args, {
|
|
15
|
+
budget,
|
|
16
|
+
callClosure: (target, values, stack, thisValue, construct, newTarget) => context?.invokeClosure !== undefined
|
|
17
|
+
? context.invokeClosure(target, values, thisValue, construct, newTarget)
|
|
18
|
+
: invokeBuiltinClosure(target, values, budget, { ...context, stack, thisValue, newTarget }, thisValue, construct)
|
|
19
|
+
}, context?.stack ?? [], context)
|
|
20
|
+
})
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
const hasInstance = installHasInstance ? createSandboxClosure({ guest: true, sandbox: true, name: "[Symbol.hasInstance]", length: 1,
|
|
24
|
+
call: ([value], context) => ordinaryHasInstance(value, context?.thisValue, budget, context)
|
|
25
|
+
}) : undefined;
|
|
26
|
+
if (hasInstance !== undefined)
|
|
27
|
+
Object.defineProperty(properties, Symbol.hasInstance, { value: hasInstance });
|
|
28
|
+
setSandboxPrototype(prototype, getSandboxPrototype(Object.create(null), budget));
|
|
29
|
+
installFunctionPrototype(budget, prototype);
|
|
30
|
+
if (hasInstance !== undefined)
|
|
31
|
+
registerIntrinsicFunction(budget, hasInstance);
|
|
32
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { generatorPrototypes } from "../generator-prototypes.js";
|
|
2
|
+
import { registerBuiltinIdentities, resolveIntrinsicIdentity } from "../intrinsics.js";
|
|
3
|
+
import { callGeneratorMethod } from "../methods/generator.js";
|
|
4
|
+
import { getSandboxPrototype, registerIntrinsicFunction, registerIntrinsicObject, setSandboxPrototype } from "../object-model.js";
|
|
5
|
+
import { createSandboxClosure } from "../values.js";
|
|
6
|
+
export function createGeneratorPrototypes(budget) {
|
|
7
|
+
const asyncIteratorPrototype = Object.create(null);
|
|
8
|
+
const asyncIterator = createSandboxClosure({ guest: true, sandbox: true,
|
|
9
|
+
name: "[Symbol.asyncIterator]", length: 0, call: (_args, context) => context?.thisValue });
|
|
10
|
+
Object.defineProperty(asyncIteratorPrototype, Symbol.asyncIterator, {
|
|
11
|
+
value: asyncIterator, writable: true, configurable: true
|
|
12
|
+
});
|
|
13
|
+
setSandboxPrototype(asyncIteratorPrototype, getSandboxPrototype(Object.create(null), budget));
|
|
14
|
+
registerBuiltinIdentities(budget, { "%AsyncIteratorPrototype%": asyncIteratorPrototype });
|
|
15
|
+
registerIntrinsicObject(budget, asyncIteratorPrototype);
|
|
16
|
+
registerIntrinsicFunction(budget, asyncIterator);
|
|
17
|
+
const state = new Map();
|
|
18
|
+
for (const async of [false, true]) {
|
|
19
|
+
const tag = async ? "AsyncGenerator" : "Generator";
|
|
20
|
+
const functionPrototype = Object.create(null);
|
|
21
|
+
const instancePrototype = Object.create(null);
|
|
22
|
+
setSandboxPrototype(functionPrototype, resolveIntrinsicIdentity(budget, JSON.stringify(["%FunctionPrototype%"])));
|
|
23
|
+
setSandboxPrototype(instancePrototype, async ? asyncIteratorPrototype
|
|
24
|
+
: resolveIntrinsicIdentity(budget, JSON.stringify(["%IteratorPrototype%"])));
|
|
25
|
+
Object.defineProperties(functionPrototype, {
|
|
26
|
+
prototype: { value: instancePrototype, configurable: true },
|
|
27
|
+
// Do not expose native dynamic-source constructors through this graph.
|
|
28
|
+
constructor: { value: undefined, configurable: true },
|
|
29
|
+
[Symbol.toStringTag]: { value: `${tag}Function`, configurable: true }
|
|
30
|
+
});
|
|
31
|
+
Object.defineProperties(instancePrototype, {
|
|
32
|
+
constructor: { value: functionPrototype, configurable: true },
|
|
33
|
+
[Symbol.toStringTag]: { value: tag, configurable: true }
|
|
34
|
+
});
|
|
35
|
+
for (const method of ["next", "return", "throw"]) {
|
|
36
|
+
Object.defineProperty(instancePrototype, method, { writable: true, configurable: true,
|
|
37
|
+
value: createSandboxClosure({ guest: true, sandbox: true, name: method, length: 1,
|
|
38
|
+
call: ([value], context) => callGeneratorMethod(context?.thisValue, method, value, budget, context, async)
|
|
39
|
+
})
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
registerBuiltinIdentities(budget, {
|
|
43
|
+
[`%${tag}Prototype%`]: instancePrototype,
|
|
44
|
+
[`%${tag}FunctionPrototype%`]: functionPrototype
|
|
45
|
+
});
|
|
46
|
+
registerIntrinsicObject(budget, functionPrototype);
|
|
47
|
+
registerIntrinsicObject(budget, instancePrototype);
|
|
48
|
+
state.set(async, { functionPrototype, instancePrototype });
|
|
49
|
+
}
|
|
50
|
+
generatorPrototypes.set(budget, state);
|
|
51
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isFatalSandboxError } from "../budget.js";
|
|
2
|
+
import { getGeneratorProperties } from "../generator-properties.js";
|
|
2
3
|
import { accessorAdapter, accessorClosure, readPropertyDescriptor, retainedAccessorClosures } from "../accessors.js";
|
|
3
4
|
import { invokeBuiltinClosure } from "../builtin-call.js";
|
|
4
5
|
import { createDataCheckpoint } from "../data-checkpoint.js";
|
|
@@ -19,7 +20,7 @@ import { toPropertyKey } from "../property-key.js";
|
|
|
19
20
|
import { createNumericParsers } from "./numeric-parsers.js";
|
|
20
21
|
import { createPrimitiveConstructor } from "./primitives.js";
|
|
21
22
|
import { arrayMethodNames, callArrayMethod } from "../methods/array.js";
|
|
22
|
-
import { getSandboxDataProperty, getSandboxPropertyDescriptor, getSandboxPrototype, installArrayPrototype, isGuestClosure, markDescriptorObject, materializeFunctionProperties, registerIntrinsicObject, setSandboxPrototype } from "../object-model.js";
|
|
23
|
+
import { getSandboxDataProperty, getSandboxPropertyDescriptor, getSandboxPrototype, installArrayPrototype, isGuestClosure, markDescriptorObject, materializeFunctionProperties, registerIntrinsicObject, registerIntrinsicFunction, setSandboxPrototype } from "../object-model.js";
|
|
23
24
|
import { allocateProducedSandboxValue, createSandboxClosure, deepCopyToSandbox, defineOwnDataProperty, isSandboxClosure, isSandboxGenerator, isSandboxMap, isSandboxPromise, getPromiseProperties, isSandboxRegex, getRegexProperties, getCollectionProperties, isSandboxSet, measureSandboxData, ownEnumerableSandboxKeys as getOwnEnumerableKeys, ownSandboxSymbolKeys, ownEnumerableSandboxEntries as getDirectEntries } from "../values.js";
|
|
24
25
|
export function createObjectArrayGlobals(options) {
|
|
25
26
|
return {
|
|
@@ -180,14 +181,14 @@ export function createObjectArrayGlobals(options) {
|
|
|
180
181
|
call: ([value]) => {
|
|
181
182
|
if (isGuestHostObject(value))
|
|
182
183
|
throw new TypeError("Live host objects cannot be made non-extensible.");
|
|
183
|
-
Object.preventExtensions(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
184
|
+
Object.preventExtensions(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
184
185
|
return value;
|
|
185
186
|
},
|
|
186
187
|
name: "preventExtensions"
|
|
187
188
|
}),
|
|
188
189
|
isExtensible: createSandboxClosure({
|
|
189
190
|
sandbox: true,
|
|
190
|
-
call: ([value]) => Object.isExtensible(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
191
|
+
call: ([value]) => Object.isExtensible(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
191
192
|
name: "isExtensible"
|
|
192
193
|
}),
|
|
193
194
|
seal: createSandboxClosure({
|
|
@@ -195,14 +196,14 @@ export function createObjectArrayGlobals(options) {
|
|
|
195
196
|
call: ([value]) => {
|
|
196
197
|
if (isGuestHostObject(value))
|
|
197
198
|
throw new TypeError("Live host objects cannot be sealed.");
|
|
198
|
-
Object.seal(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
199
|
+
Object.seal(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
199
200
|
return value;
|
|
200
201
|
},
|
|
201
202
|
name: "seal"
|
|
202
203
|
}),
|
|
203
204
|
isSealed: createSandboxClosure({
|
|
204
205
|
sandbox: true,
|
|
205
|
-
call: ([value]) => Object.isSealed(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
206
|
+
call: ([value]) => Object.isSealed(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
206
207
|
name: "isSealed"
|
|
207
208
|
}),
|
|
208
209
|
freeze: createSandboxClosure({
|
|
@@ -211,7 +212,7 @@ export function createObjectArrayGlobals(options) {
|
|
|
211
212
|
if (isGuestHostObject(value))
|
|
212
213
|
throw new TypeError("Live host objects cannot be frozen.");
|
|
213
214
|
if (typeof value === "object" && value !== null) {
|
|
214
|
-
Object.freeze(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
215
|
+
Object.freeze(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value);
|
|
215
216
|
}
|
|
216
217
|
return value;
|
|
217
218
|
},
|
|
@@ -219,7 +220,7 @@ export function createObjectArrayGlobals(options) {
|
|
|
219
220
|
}),
|
|
220
221
|
isFrozen: createSandboxClosure({
|
|
221
222
|
sandbox: true,
|
|
222
|
-
call: ([value]) => Object.isFrozen(isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
223
|
+
call: ([value]) => Object.isFrozen(isSandboxGenerator(value) ? getGeneratorProperties(value) : isSandboxPromise(value) ? getPromiseProperties(value) : isGuestClosure(value) ? materializeFunctionProperties(value) : isSandboxRegex(value) ? getRegexProperties(value) : isSandboxMap(value) || isSandboxSet(value) ? getCollectionProperties(value) : value),
|
|
223
224
|
name: "isFrozen"
|
|
224
225
|
}),
|
|
225
226
|
assign: createSandboxClosure({
|
|
@@ -331,6 +332,21 @@ function createArrayGlobal(budget) {
|
|
|
331
332
|
guest: true, sandbox: true, name: "[Symbol.iterator]", length: 0,
|
|
332
333
|
call: (_args, context) => context?.thisValue
|
|
333
334
|
}), writable: true, configurable: true });
|
|
335
|
+
const iteratorTagGetter = createSandboxClosure({ guest: true, sandbox: true,
|
|
336
|
+
name: "get [Symbol.toStringTag]", length: 0, call: () => "Iterator" });
|
|
337
|
+
const iteratorTagSetter = createSandboxClosure({ guest: true, sandbox: true,
|
|
338
|
+
name: "set [Symbol.toStringTag]", length: 1, call: ([value], context) => {
|
|
339
|
+
const receiver = context?.thisValue;
|
|
340
|
+
if (receiver === iterablePrototype || receiver === null || typeof receiver !== "object")
|
|
341
|
+
throw new TypeError("Iterator tag setter requires a distinct object receiver.");
|
|
342
|
+
defineOwnDataProperty(objectProperties(receiver, true), Symbol.toStringTag, value);
|
|
343
|
+
createDataCheckpoint(budget, context)(receiver, 0, true);
|
|
344
|
+
return undefined;
|
|
345
|
+
}
|
|
346
|
+
});
|
|
347
|
+
Object.defineProperty(iterablePrototype, Symbol.toStringTag, {
|
|
348
|
+
get: accessorAdapter(iteratorTagGetter, "get"), set: accessorAdapter(iteratorTagSetter, "set"), configurable: true
|
|
349
|
+
});
|
|
334
350
|
setSandboxPrototype(iterablePrototype, getSandboxPrototype(Object.create(null), budget));
|
|
335
351
|
setSandboxPrototype(iteratorPrototype, iterablePrototype);
|
|
336
352
|
Object.defineProperties(iteratorPrototype, {
|
|
@@ -340,6 +356,9 @@ function createArrayGlobal(budget) {
|
|
|
340
356
|
[Symbol.toStringTag]: { value: "Array Iterator", configurable: true }
|
|
341
357
|
});
|
|
342
358
|
registerBuiltinIdentities(budget, { "%ArrayIteratorPrototype%": iteratorPrototype, "%IteratorPrototype%": iterablePrototype });
|
|
359
|
+
registerIntrinsicFunction(budget, iterablePrototype[Symbol.iterator]);
|
|
360
|
+
registerIntrinsicFunction(budget, iteratorTagGetter);
|
|
361
|
+
registerIntrinsicFunction(budget, iteratorTagSetter);
|
|
343
362
|
registerIntrinsicObject(budget, iterablePrototype);
|
|
344
363
|
registerIntrinsicObject(budget, iteratorPrototype);
|
|
345
364
|
for (const method of ["keys", "values", "entries"]) {
|
|
@@ -556,6 +575,8 @@ function reflectionProperties(value) {
|
|
|
556
575
|
return objectProperties(value);
|
|
557
576
|
}
|
|
558
577
|
export function objectProperties(value, mutable = false) {
|
|
578
|
+
if (isSandboxGenerator(value))
|
|
579
|
+
return getGeneratorProperties(value);
|
|
559
580
|
if (isSandboxPromise(value))
|
|
560
581
|
return getPromiseProperties(value);
|
|
561
582
|
if (isSandboxMap(value) || isSandboxSet(value))
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { assertSandboxDataDepth } from "../../graph-depth.js";
|
|
2
|
+
import { getGeneratorProperties } from "../generator-properties.js";
|
|
2
3
|
import { readPropertyDescriptor } from "../accessors.js";
|
|
3
4
|
import { isSandboxArguments } from "../arguments.js";
|
|
4
5
|
import { isSandboxDate } from "../date.js";
|
|
@@ -153,7 +154,7 @@ export function hasOwnSandboxProperty(value, key, enumerable) {
|
|
|
153
154
|
else if (isSandboxPromise(value))
|
|
154
155
|
properties = getPromiseProperties(value);
|
|
155
156
|
else if (isSandboxGenerator(value))
|
|
156
|
-
|
|
157
|
+
properties = getGeneratorProperties(value);
|
|
157
158
|
else if (isSandboxRegex(value))
|
|
158
159
|
properties = getRegexProperties(value);
|
|
159
160
|
else
|
|
@@ -3,6 +3,7 @@ import type { RunClock } from "../run.js";
|
|
|
3
3
|
export declare function createBuiltinBindings(options: Parameters<typeof createConsoleJsonGlobals>[0] & {
|
|
4
4
|
random?: () => number;
|
|
5
5
|
clock?: RunClock;
|
|
6
|
+
functionHasInstance?: boolean;
|
|
6
7
|
}): {
|
|
7
8
|
RegExp: import("./values.js").SandboxClosure;
|
|
8
9
|
Promise: import("./values.js").SandboxClosure;
|
|
@@ -7,6 +7,8 @@ import { createRegexGlobals } from "./globals/regex.js";
|
|
|
7
7
|
import { createMiscGlobals } from "./globals/misc.js";
|
|
8
8
|
import { createUriGlobals } from "./globals/uri.js";
|
|
9
9
|
import { createObjectArrayGlobals } from "./globals/object-array.js";
|
|
10
|
+
import { createFunctionPrototype } from "./globals/function.js";
|
|
11
|
+
import { createGeneratorPrototypes } from "./globals/generator.js";
|
|
10
12
|
import { createPromiseGlobals } from "./promise.js";
|
|
11
13
|
import { createDateGlobal } from "./globals/date.js";
|
|
12
14
|
import { createSymbolGlobal } from "./globals/symbol.js";
|
|
@@ -28,6 +30,8 @@ export function createBuiltinBindings(options) {
|
|
|
28
30
|
...createPromiseGlobals(options),
|
|
29
31
|
...createRegexGlobals(options)
|
|
30
32
|
};
|
|
33
|
+
createFunctionPrototype(options.budget, options.functionHasInstance);
|
|
34
|
+
createGeneratorPrototypes(options.budget);
|
|
31
35
|
registerBuiltinIdentities(options.budget, bindings);
|
|
32
36
|
return bindings;
|
|
33
37
|
}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { Budget } from "./budget.js";
|
|
2
|
+
import { type SandboxCallContext, type SandboxValue } from "./values.js";
|
|
3
|
+
export declare function evaluateInstanceof(value: SandboxValue, constructor: SandboxValue, budget: Budget, context?: SandboxCallContext): Promise<boolean>;
|
|
4
|
+
export declare function ordinaryHasInstance(value: SandboxValue, constructor: SandboxValue, budget: Budget, context?: SandboxCallContext): Promise<boolean>;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { assertSandboxDataDepth } from "../graph-depth.js";
|
|
2
|
+
import { readPropertyDescriptor } from "./accessors.js";
|
|
3
|
+
import { invokeBuiltinClosure } from "./builtin-call.js";
|
|
4
|
+
import { isFloat32Array } from "./float32.js";
|
|
5
|
+
import { isFloat32ArrayConstructor } from "./globals/float32array.js";
|
|
6
|
+
import { isSandboxErrorConstructorInstance } from "./globals/error.js";
|
|
7
|
+
import { getSandboxPropertyDescriptor, getSandboxPrototype, isGuestClosure } from "./object-model.js";
|
|
8
|
+
import { isSandboxClosure } from "./values.js";
|
|
9
|
+
export async function evaluateInstanceof(value, constructor, budget, context) {
|
|
10
|
+
if (constructor === null || typeof constructor !== "object")
|
|
11
|
+
throw new TypeError("Right-hand side of 'instanceof' must be an object.");
|
|
12
|
+
const method = await readInstanceProperty(constructor, Symbol.hasInstance, budget, context);
|
|
13
|
+
if (method !== undefined && method !== null) {
|
|
14
|
+
if (!isSandboxClosure(method))
|
|
15
|
+
throw new TypeError("Symbol.hasInstance must be callable.");
|
|
16
|
+
return Boolean(await invokeBuiltinClosure(method, [value], budget, context, constructor));
|
|
17
|
+
}
|
|
18
|
+
if (!isSandboxClosure(constructor))
|
|
19
|
+
throw new TypeError("Right-hand side of 'instanceof' is not a function.");
|
|
20
|
+
return ordinaryHasInstance(value, constructor, budget, context);
|
|
21
|
+
}
|
|
22
|
+
export async function ordinaryHasInstance(value, constructor, budget, context) {
|
|
23
|
+
if (!isSandboxClosure(constructor))
|
|
24
|
+
return false;
|
|
25
|
+
if (constructor.boundTarget !== undefined) {
|
|
26
|
+
budget.visitNode();
|
|
27
|
+
return evaluateInstanceof(value, constructor.boundTarget, budget, context);
|
|
28
|
+
}
|
|
29
|
+
// These existing built-ins do not yet have ordinary prototype graphs.
|
|
30
|
+
if (isFloat32ArrayConstructor(constructor))
|
|
31
|
+
return isFloat32Array(value);
|
|
32
|
+
if (isSandboxErrorConstructorInstance(value, constructor))
|
|
33
|
+
return true;
|
|
34
|
+
if (!isGuestClosure(constructor) || typeof value !== "object" || value === null)
|
|
35
|
+
return false;
|
|
36
|
+
const prototype = await readInstanceProperty(constructor, "prototype", budget, context);
|
|
37
|
+
if (typeof prototype !== "object" || prototype === null)
|
|
38
|
+
throw new TypeError("Function has a non-object prototype in instanceof check.");
|
|
39
|
+
let depth = 0;
|
|
40
|
+
for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
|
|
41
|
+
budget.visitNode();
|
|
42
|
+
assertSandboxDataDepth(depth++);
|
|
43
|
+
if (current === prototype)
|
|
44
|
+
return true;
|
|
45
|
+
}
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
async function readInstanceProperty(value, key, budget, context) {
|
|
49
|
+
if (context?.getProperty !== undefined)
|
|
50
|
+
return context.getProperty(value, key);
|
|
51
|
+
const descriptor = getSandboxPropertyDescriptor(value, key, budget);
|
|
52
|
+
if (descriptor === undefined)
|
|
53
|
+
return undefined;
|
|
54
|
+
return readPropertyDescriptor(descriptor, value, {
|
|
55
|
+
...context, stack: context?.stack ?? [], thisValue: value,
|
|
56
|
+
invokeClosure: context?.invokeClosure ?? ((closure, args, receiver) => invokeBuiltinClosure(closure, args, budget, context, receiver))
|
|
57
|
+
});
|
|
58
|
+
}
|