@poe-platform/safe-js 0.1.137 → 0.1.139

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.
@@ -6527,6 +6527,64 @@ function serializedDateTime(value) {
6527
6527
  return Number.isNaN(time) ? null : time;
6528
6528
  }
6529
6529
 
6530
+ // packages/safe-js/src/interp/accessors.ts
6531
+ var accessorClosures = /* @__PURE__ */ new WeakMap();
6532
+ var getterAdapters = /* @__PURE__ */ new WeakMap();
6533
+ var setterAdapters = /* @__PURE__ */ new WeakMap();
6534
+ function accessorAdapter(closure, kind) {
6535
+ if (kind === "get") {
6536
+ let adapter2 = getterAdapters.get(closure);
6537
+ if (adapter2 === void 0) {
6538
+ adapter2 = () => void 0;
6539
+ getterAdapters.set(closure, adapter2);
6540
+ accessorClosures.set(adapter2, closure);
6541
+ }
6542
+ return adapter2;
6543
+ }
6544
+ let adapter = setterAdapters.get(closure);
6545
+ if (adapter === void 0) {
6546
+ adapter = () => {
6547
+ throw new TypeError("Accessor writes require sandbox execution.");
6548
+ };
6549
+ setterAdapters.set(closure, adapter);
6550
+ accessorClosures.set(adapter, closure);
6551
+ }
6552
+ return adapter;
6553
+ }
6554
+ function accessorClosure(adapter) {
6555
+ if (adapter === void 0) return void 0;
6556
+ const closure = accessorClosures.get(adapter);
6557
+ if (closure === void 0) throw new TypeError("Native accessors cannot execute in the sandbox.");
6558
+ return closure;
6559
+ }
6560
+ function retainedAccessorClosures(descriptor) {
6561
+ const closures = [];
6562
+ for (const adapter of [descriptor.get, descriptor.set]) {
6563
+ const closure = adapter === void 0 ? void 0 : accessorClosures.get(adapter);
6564
+ if (closure !== void 0) closures.push(closure);
6565
+ }
6566
+ return closures;
6567
+ }
6568
+ function readPropertyDescriptor(descriptor, receiver, context, allowNativeGetter = false) {
6569
+ if ("value" in descriptor) return descriptor.value;
6570
+ if (descriptor.get === void 0) return void 0;
6571
+ const getter = accessorClosures.get(descriptor.get);
6572
+ if (getter === void 0) {
6573
+ if (!allowNativeGetter) throw new TypeError("Native accessors cannot execute in the sandbox.");
6574
+ return Reflect.apply(descriptor.get, receiver, []);
6575
+ }
6576
+ if (context?.invokeClosure === void 0)
6577
+ throw new TypeError("Accessor reads require sandbox execution.");
6578
+ return context.invokeClosure(getter, [], receiver);
6579
+ }
6580
+ function writePropertyDescriptor(descriptor, receiver, value, context) {
6581
+ const setter = accessorClosure(descriptor.set);
6582
+ if (setter === void 0) throw new TypeError("Cannot assign to a getter-only property.");
6583
+ if (context?.invokeClosure === void 0)
6584
+ throw new TypeError("Accessor writes require sandbox execution.");
6585
+ return context.invokeClosure(setter, [value], receiver).then(() => void 0);
6586
+ }
6587
+
6530
6588
  // packages/safe-js/src/interp/collection-brands.ts
6531
6589
  var sandboxMapBrand = /* @__PURE__ */ Symbol("SandboxMap");
6532
6590
  var sandboxSetBrand = /* @__PURE__ */ Symbol("SandboxSet");
@@ -7317,15 +7375,23 @@ function registerIntrinsicPrototype(budget, prototype, constructor) {
7317
7375
  ...record2,
7318
7376
  descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(record2.value)))
7319
7377
  }));
7320
- const unchanged = (before, after) => before !== void 0 && after !== void 0 && Object.is(before.value, after.value) && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
7321
- intrinsicConstructors.set(constructor, () => records.every(({ target, value, descriptors, prototype: parent, explicit }) => {
7322
- const current = Object.getOwnPropertyDescriptors(value);
7323
- return getSandboxPrototype(target) === parent && hasExplicitSandboxPrototype(target) === explicit && Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
7324
- }));
7325
- budget.setRetainedValues(prototype, () => records.flatMap(({ target, value, descriptors, prototype: parent }) => [
7326
- ...getSandboxPrototype(target) === parent ? [] : [getSandboxPrototype(target)],
7327
- ...Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key, descriptor]) => unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value])
7328
- ]));
7378
+ const unchanged = (before, after) => before !== void 0 && after !== void 0 && Object.is(before.value, after.value) && before.get === after.get && before.set === after.set && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
7379
+ intrinsicConstructors.set(
7380
+ constructor,
7381
+ () => records.every(({ target, value, descriptors, prototype: parent, explicit }) => {
7382
+ const current = Object.getOwnPropertyDescriptors(value);
7383
+ return getSandboxPrototype(target) === parent && hasExplicitSandboxPrototype(target) === explicit && Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
7384
+ })
7385
+ );
7386
+ budget.setRetainedValues(
7387
+ prototype,
7388
+ () => records.flatMap(({ target, value, descriptors, prototype: parent }) => [
7389
+ ...getSandboxPrototype(target) === parent ? [] : [getSandboxPrototype(target)],
7390
+ ...Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(
7391
+ ([key, descriptor]) => unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value, ...retainedAccessorClosures(descriptor)]
7392
+ )
7393
+ ])
7394
+ );
7329
7395
  }
7330
7396
  function releaseObjectPrototype(budget) {
7331
7397
  for (const prototype of intrinsicPrototypeRoots.get(budget) ?? []) budget.setRetainedValues(prototype, void 0);
@@ -7344,6 +7410,24 @@ function getSandboxPrototype(value, budget) {
7344
7410
  function hasExplicitSandboxPrototype(value) {
7345
7411
  return prototypes.has(value);
7346
7412
  }
7413
+ function getSandboxPropertyDescriptor(value, key, budget) {
7414
+ const hostProperties = isSandboxClosure(value) ? value.properties : void 0;
7415
+ if (isSandboxClosure(value) && !isGuestClosure(value))
7416
+ return hostProperties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(hostProperties, key);
7417
+ let current = value;
7418
+ let depth = 0;
7419
+ while (typeof current === "object" && current !== null && (Array.isArray(current) || isPrototypeRecord(current))) {
7420
+ const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
7421
+ const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
7422
+ if (descriptor !== void 0) return descriptor;
7423
+ current = getSandboxPrototype(current, budget);
7424
+ if (current !== null) {
7425
+ budget?.visitNode();
7426
+ assertSandboxDataDepth(++depth);
7427
+ }
7428
+ }
7429
+ return void 0;
7430
+ }
7347
7431
  function getSandboxDataProperty(value, key, budget) {
7348
7432
  let current = value;
7349
7433
  let depth = 0;
@@ -8907,7 +8991,7 @@ async function callRegexMethod(target, methodName, args, budget, context) {
8907
8991
  try {
8908
8992
  const input = await sandboxString(args[0], budget, context);
8909
8993
  if (methodName === "test") {
8910
- const exec = context?.getProperty === void 0 ? getSandboxDataProperty(target, "exec", budget) : context.getProperty(target, "exec");
8994
+ const exec = context?.getProperty === void 0 ? getSandboxDataProperty(target, "exec", budget) : await context.getProperty(target, "exec");
8911
8995
  if (isSandboxClosure(exec)) {
8912
8996
  const result = await invokeBuiltinClosure(exec, [input], budget, context, target);
8913
8997
  if (result !== null && typeof result !== "object") {
@@ -9011,6 +9095,7 @@ function functionString(value) {
9011
9095
  // packages/safe-js/src/interp/string-coercion.ts
9012
9096
  var defaultStringHook = /* @__PURE__ */ Symbol("defaultStringHook");
9013
9097
  var defaultValueHook = /* @__PURE__ */ Symbol("defaultValueHook");
9098
+ var joiningArrays = /* @__PURE__ */ new WeakSet();
9014
9099
  function sandboxNumber(value, budget, context) {
9015
9100
  if (value === null || typeof value !== "object") {
9016
9101
  if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
@@ -9025,12 +9110,30 @@ function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set
9025
9110
  }
9026
9111
  return objectToPrimitive(value, budget, context, joining, "string").then((primitive) => budget.allocateString(String(primitive)));
9027
9112
  }
9113
+ async function joinSandboxArray(value, length, separator, budget, context, joining = /* @__PURE__ */ new Set()) {
9114
+ if (joiningArrays.has(value)) return "";
9115
+ joiningArrays.add(value);
9116
+ let text = "";
9117
+ const release = retainValues(budget, () => [value, text, separator]);
9118
+ try {
9119
+ for (let index = 0; index < length; index++) {
9120
+ budget.visitNode();
9121
+ const element = await readCoercionProperty(value, String(index), context);
9122
+ const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
9123
+ text = budget.allocateString(text + (index === 0 ? "" : separator) + part);
9124
+ }
9125
+ return text;
9126
+ } finally {
9127
+ release();
9128
+ joiningArrays.delete(value);
9129
+ }
9130
+ }
9028
9131
  async function objectToPrimitive(value, budget, context, joining, hint) {
9029
9132
  const leaveCall = budget.enterCall();
9030
9133
  try {
9031
9134
  budget.visitNode();
9032
9135
  for (const name of hint === "string" ? ["toString", "valueOf"] : ["valueOf", "toString"]) {
9033
- const hook = conversionHook(value, name, budget);
9136
+ const hook = await conversionHook(value, name, budget, context);
9034
9137
  let result;
9035
9138
  if (hook === defaultStringHook) {
9036
9139
  result = await defaultToString(value, budget, context, joining);
@@ -9050,7 +9153,7 @@ async function objectToPrimitive(value, budget, context, joining, hint) {
9050
9153
  leaveCall();
9051
9154
  }
9052
9155
  }
9053
- function conversionHook(value, name, budget) {
9156
+ function conversionHook(value, name, budget, context) {
9054
9157
  const implicitBuiltin = !hasExplicitSandboxPrototype(value) && (Array.isArray(value) || isSandboxDate(value) || isFloat32Array(value) || sandboxErrorTypes.has(value) || isSandboxClosure(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxCollectionIterator(value) || isSandboxPromise(value) || isSandboxRegex(value) || isSandboxGenerator(value) || isGuestHostObject(value));
9055
9158
  let current = value;
9056
9159
  let depth = 0;
@@ -9058,9 +9161,7 @@ function conversionHook(value, name, budget) {
9058
9161
  const properties = isGuestClosure(current) ? getGuestFunctionProperties(current) : current;
9059
9162
  const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, name);
9060
9163
  if (descriptor !== void 0) {
9061
- if (!Object.hasOwn(descriptor, "value"))
9062
- throw new TypeError("String conversion requires sandbox data properties.");
9063
- return descriptor.value;
9164
+ return readPropertyDescriptor(descriptor, value, context);
9064
9165
  }
9065
9166
  const parent = getSandboxPrototype(current, budget);
9066
9167
  if (current === value && (implicitBuiltin || parent === null && !hasExplicitSandboxPrototype(value))) {
@@ -9079,7 +9180,8 @@ async function defaultToString(value, budget, context, joining) {
9079
9180
  if (isSandboxClosure(value)) return budget.allocateString(functionString(value));
9080
9181
  if (isSandboxMap(value)) return "[object Map]";
9081
9182
  if (isSandboxSet(value)) return "[object Set]";
9082
- if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "[object Map Iterator]" : "[object Set Iterator]";
9183
+ if (isSandboxCollectionIterator(value))
9184
+ return collectionIteratorState(value).collectionKind === "map" ? "[object Map Iterator]" : "[object Set Iterator]";
9083
9185
  if (isSandboxGenerator(value)) return "[object Generator]";
9084
9186
  if (isSandboxRegex(value)) {
9085
9187
  return budget.allocateString(
@@ -9089,35 +9191,20 @@ async function defaultToString(value, budget, context, joining) {
9089
9191
  if (isSandboxDate(value)) return budget.allocateString(dateString(value));
9090
9192
  if (Array.isArray(value) || isFloat32Array(value)) {
9091
9193
  if (Object.hasOwn(value, "join")) {
9092
- const join = ownDataValue(value, "join");
9194
+ const join = await readCoercionProperty(value, "join", context);
9093
9195
  if (!isSandboxClosure(join))
9094
9196
  return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
9095
9197
  return invokeBuiltinClosure(join, [], budget, context, value);
9096
9198
  }
9097
- if (joining.has(value)) return "";
9098
- joining.add(value);
9099
- let text = "";
9100
- const release = retainValues(budget, () => [text]);
9101
- try {
9102
- const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
9103
- for (let index = 0; index < length; index++) {
9104
- budget.visitNode();
9105
- const element = ownDataValue(value, String(index));
9106
- const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
9107
- text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
9108
- }
9109
- return text;
9110
- } finally {
9111
- release();
9112
- joining.delete(value);
9113
- }
9199
+ const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
9200
+ return joinSandboxArray(value, length, ",", budget, context, joining);
9114
9201
  }
9115
9202
  if (sandboxErrorTypes.has(value)) {
9116
- const nameValue = ownDataValue(value, "name");
9203
+ const nameValue = await readCoercionProperty(value, "name", context);
9117
9204
  const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
9118
9205
  const release = retainValues(budget, () => [name]);
9119
9206
  try {
9120
- const messageValue = ownDataValue(value, "message");
9207
+ const messageValue = await readCoercionProperty(value, "message", context);
9121
9208
  const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
9122
9209
  return name === "" ? message : message === "" ? name : `${name}: ${message}`;
9123
9210
  } finally {
@@ -9126,12 +9213,153 @@ async function defaultToString(value, budget, context, joining) {
9126
9213
  }
9127
9214
  return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
9128
9215
  }
9129
- function ownDataValue(value, name) {
9216
+ function readCoercionProperty(value, name, context) {
9217
+ if (context?.getProperty !== void 0) return context.getProperty(value, name);
9130
9218
  const descriptor = Object.getOwnPropertyDescriptor(value, name);
9131
- if (descriptor !== void 0 && !Object.hasOwn(descriptor, "value")) {
9132
- throw new TypeError("String conversion requires sandbox data properties.");
9219
+ return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, context);
9220
+ }
9221
+
9222
+ // packages/safe-js/src/interp/globals/object.ts
9223
+ function createObjectGlobal(methods, budget) {
9224
+ const construct = ([value]) => {
9225
+ if (value === null || value === void 0) {
9226
+ budget.chargeDataUsage(1);
9227
+ return /* @__PURE__ */ Object.create(null);
9228
+ }
9229
+ if (typeof value !== "object") {
9230
+ const box = createSandboxBox(value);
9231
+ budget.chargeDataUsage(measureSandboxData([box]));
9232
+ return box;
9233
+ }
9234
+ return value;
9235
+ };
9236
+ const constructor = createSandboxClosure({
9237
+ guest: true,
9238
+ sandbox: true,
9239
+ name: "Object",
9240
+ length: 1,
9241
+ call: construct,
9242
+ construct: (args, context) => {
9243
+ if (context?.newTarget === void 0 || context.newTarget === constructor)
9244
+ return construct(args);
9245
+ const value = construct([]);
9246
+ const prototype2 = context.getProperty(context.newTarget, "prototype");
9247
+ const finish = (prototype3) => {
9248
+ if (typeof prototype3 === "object" && prototype3 !== null)
9249
+ setSandboxPrototype(value, prototype3, budget);
9250
+ return value;
9251
+ };
9252
+ return prototype2 instanceof Promise ? prototype2.then(finish) : finish(prototype2);
9253
+ }
9254
+ });
9255
+ const properties = materializeFunctionProperties(constructor);
9256
+ const prototype = properties.prototype;
9257
+ Object.defineProperty(properties, "prototype", { writable: false });
9258
+ for (const [name, method] of Object.entries(methods)) {
9259
+ Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
9260
+ }
9261
+ const prototypeMethods = {
9262
+ toString: createSandboxClosure({
9263
+ sandbox: true,
9264
+ name: "toString",
9265
+ length: 0,
9266
+ call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
9267
+ }),
9268
+ valueOf: createSandboxClosure({
9269
+ sandbox: true,
9270
+ name: "valueOf",
9271
+ length: 0,
9272
+ call: (_args, context) => {
9273
+ const value = requireReceiver(context?.thisValue);
9274
+ return construct([value]);
9275
+ }
9276
+ }),
9277
+ hasOwnProperty: createSandboxClosure({
9278
+ sandbox: true,
9279
+ name: "hasOwnProperty",
9280
+ length: 1,
9281
+ call: async ([key], context) => hasOwnSandboxProperty(
9282
+ requireReceiver(context?.thisValue),
9283
+ await sandboxString(key, budget, context),
9284
+ false
9285
+ )
9286
+ }),
9287
+ propertyIsEnumerable: createSandboxClosure({
9288
+ sandbox: true,
9289
+ name: "propertyIsEnumerable",
9290
+ length: 1,
9291
+ call: async ([key], context) => hasOwnSandboxProperty(
9292
+ requireReceiver(context?.thisValue),
9293
+ await sandboxString(key, budget, context),
9294
+ true
9295
+ )
9296
+ }),
9297
+ isPrototypeOf: createSandboxClosure({
9298
+ sandbox: true,
9299
+ name: "isPrototypeOf",
9300
+ length: 1,
9301
+ call: ([value], context) => {
9302
+ if (typeof value !== "object" || value === null) return false;
9303
+ const receiver = requireReceiver(context?.thisValue);
9304
+ let depth = 0;
9305
+ for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
9306
+ budget.visitNode();
9307
+ assertSandboxDataDepth(depth++);
9308
+ if (current === receiver) return true;
9309
+ }
9310
+ return false;
9311
+ }
9312
+ })
9313
+ };
9314
+ for (const [name, method] of Object.entries(prototypeMethods)) {
9315
+ Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
9316
+ }
9317
+ markDescriptorObject(prototype);
9318
+ installObjectPrototype(budget, prototype, constructor);
9319
+ return constructor;
9320
+ }
9321
+ function requireReceiver(value) {
9322
+ if (value === null || value === void 0)
9323
+ throw new TypeError("Object method requires a non-null receiver.");
9324
+ return value;
9325
+ }
9326
+ function hasOwnSandboxProperty(value, key, enumerable) {
9327
+ requireReceiver(value);
9328
+ if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
9329
+ let properties;
9330
+ if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
9331
+ else if (isSandboxClosure(value)) {
9332
+ if (key === "length" || key === "name") return !enumerable;
9333
+ properties = value.properties ?? /* @__PURE__ */ Object.create(null);
9334
+ } else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
9335
+ return false;
9336
+ else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
9337
+ else properties = Object(value);
9338
+ const descriptor = Object.getOwnPropertyDescriptor(properties, key);
9339
+ return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
9340
+ }
9341
+ function typeTag(value) {
9342
+ if (isSandboxBox(value)) value = boxedValue(value);
9343
+ if (value === void 0) return "Undefined";
9344
+ if (value === null) return "Null";
9345
+ if (typeof value === "string") return "String";
9346
+ if (typeof value === "number") return "Number";
9347
+ if (typeof value === "boolean") return "Boolean";
9348
+ if (isSandboxClosure(value)) {
9349
+ while (value.boundTarget !== void 0) value = value.boundTarget;
9350
+ return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
9133
9351
  }
9134
- return descriptor?.value;
9352
+ if (Array.isArray(value)) return "Array";
9353
+ if (isSandboxDate(value)) return "Date";
9354
+ if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
9355
+ if (isSandboxRegex(value)) return "RegExp";
9356
+ if (isSandboxMap(value)) return "Map";
9357
+ if (isSandboxSet(value)) return "Set";
9358
+ if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "Map Iterator" : "Set Iterator";
9359
+ if (isSandboxPromise(value)) return "Promise";
9360
+ if (isSandboxGenerator(value)) return "Generator";
9361
+ if (isFloat32Array(value)) return "Float32Array";
9362
+ return "Object";
9135
9363
  }
9136
9364
 
9137
9365
  // packages/safe-js/src/interp/property-key.ts
@@ -9496,7 +9724,10 @@ async function bindPattern(pattern, value, context, evaluateNode2) {
9496
9724
  async function bindAssignmentPattern(pattern, value, context, evaluateNode2) {
9497
9725
  let nextValue = value;
9498
9726
  if (nextValue === void 0) {
9499
- const defaultValue = await evaluateNode2(pattern.right, context);
9727
+ const defaultValue = await evaluateNode2(pattern.right, {
9728
+ ...context,
9729
+ inferredName: pattern.left.type === "Identifier" ? pattern.left.name : void 0
9730
+ });
9500
9731
  if (defaultValue.kind !== "normal") {
9501
9732
  return {
9502
9733
  ok: false,
@@ -9511,12 +9742,34 @@ async function bindArrayPattern(pattern, value, context, evaluateNode2) {
9511
9742
  if (!Array.isArray(value)) {
9512
9743
  throw new TypeError("Array catch bindings require an array value.");
9513
9744
  }
9745
+ let cursor = 0;
9746
+ let done = false;
9747
+ const next = async () => {
9748
+ if (done || cursor >= value.length) {
9749
+ done = true;
9750
+ return { done: true, value: void 0 };
9751
+ }
9752
+ const key = cursor++;
9753
+ return {
9754
+ done: false,
9755
+ value: context.getProperty === void 0 ? getSandboxDataProperty(value, key, context.budget) : await context.getProperty(value, key)
9756
+ };
9757
+ };
9514
9758
  for (let index = 0; index < pattern.elements.length; index += 1) {
9515
9759
  const element = pattern.elements[index];
9516
9760
  if (element === null) {
9761
+ await next();
9517
9762
  continue;
9518
9763
  }
9519
- const elementValue = element.type === "RestElement" ? value.slice(index) : value[index];
9764
+ let elementValue;
9765
+ if (element.type === "RestElement") {
9766
+ const rest = [];
9767
+ for (let entry = await next(); !entry.done; entry = await next()) {
9768
+ context.budget.allocateArrayLength(rest.length + 1);
9769
+ rest.push(entry.value);
9770
+ }
9771
+ elementValue = rest;
9772
+ } else elementValue = (await next()).value;
9520
9773
  const binding = await bindPattern(element, elementValue, context, evaluateNode2);
9521
9774
  if (!binding.ok) {
9522
9775
  return binding;
@@ -9531,7 +9784,7 @@ async function bindObjectPattern(pattern, value, context, evaluateNode2) {
9531
9784
  const excludedKeys = /* @__PURE__ */ new Set();
9532
9785
  for (const property of pattern.properties) {
9533
9786
  if (property.type === "RestElement") {
9534
- const restValue = copyObjectRest(value, excludedKeys);
9787
+ const restValue = await copyObjectRest(value, excludedKeys, context);
9535
9788
  const binding2 = await bindPattern(property, restValue, context, evaluateNode2);
9536
9789
  if (!binding2.ok) {
9537
9790
  return binding2;
@@ -9545,7 +9798,7 @@ async function bindObjectPattern(pattern, value, context, evaluateNode2) {
9545
9798
  excludedKeys.add(String(key.value));
9546
9799
  const binding = await bindPattern(
9547
9800
  property.value,
9548
- context.getProperty === void 0 ? getSandboxDataProperty(value, key.value, context.budget) : context.getProperty(value, key.value),
9801
+ context.getProperty === void 0 ? getSandboxDataProperty(value, key.value, context.budget) : await context.getProperty(value, key.value),
9549
9802
  context,
9550
9803
  evaluateNode2
9551
9804
  );
@@ -9589,12 +9842,18 @@ function getStaticPropertyKey(property) {
9589
9842
  throw new TypeError(`Unsupported catch binding property key '${property.type}'.`);
9590
9843
  }
9591
9844
  }
9592
- function copyObjectRest(value, excludedKeys) {
9845
+ async function copyObjectRest(value, excludedKeys, context) {
9593
9846
  const rest = /* @__PURE__ */ Object.create(null);
9594
- for (const [key, entryValue] of ownEnumerableSandboxEntries(value, excludedKeys)) {
9595
- rest[key] = entryValue;
9847
+ const release = retainValues(context.budget, () => [value, rest]);
9848
+ try {
9849
+ for (const key of ownEnumerableSandboxKeys(value)) {
9850
+ if (excludedKeys.has(key) || !hasOwnSandboxProperty(value, key, true)) continue;
9851
+ rest[key] = context.getProperty === void 0 ? getSandboxDataProperty(value, key, context.budget) : await context.getProperty(value, key);
9852
+ }
9853
+ return rest;
9854
+ } finally {
9855
+ release();
9596
9856
  }
9597
- return rest;
9598
9857
  }
9599
9858
 
9600
9859
  // packages/safe-js/src/interp/running-state.ts
@@ -9670,6 +9929,18 @@ function getSandboxIterator(value, budget, context) {
9670
9929
  if (isSandboxSet(value)) {
9671
9930
  return collectionIterator(value.values);
9672
9931
  }
9932
+ if (Array.isArray(value) && context?.getProperty !== void 0) {
9933
+ let index = 0;
9934
+ return {
9935
+ asynchronous: true,
9936
+ snapshotIndex: () => index,
9937
+ next: async () => {
9938
+ if (index >= value.length) return { done: true, value: void 0 };
9939
+ budget?.visitNode();
9940
+ return { done: false, value: await context.getProperty(value, index++) };
9941
+ }
9942
+ };
9943
+ }
9673
9944
  if (typeof value !== "object" && typeof value !== "function" || value === null) {
9674
9945
  return void 0;
9675
9946
  }
@@ -10064,7 +10335,7 @@ async function callPromiseClosure(callback, args, thisValue, budget, context) {
10064
10335
  const values = args.map(
10065
10336
  (value) => value instanceof Error && !(value instanceof SandboxError) ? coerceThrownValue(value, budget, stack) : value
10066
10337
  );
10067
- let result = callback.call(values, { stack, thisValue });
10338
+ let result = callback.call(values, { ...context, stack, thisValue, newTarget: void 0 });
10068
10339
  if (callback.async !== true) result = await result;
10069
10340
  else if (isPromiseLike(result)) result = createSandboxPromise(Promise.resolve(result));
10070
10341
  if (isSandboxPromise(result) && result.synchronousPrefix !== void 0) {
@@ -10091,11 +10362,11 @@ function getPromisePrototype(budget) {
10091
10362
  target.promise.then(
10092
10363
  (value) => {
10093
10364
  consumeSettledHostCall(target);
10094
- return runPromiseReaction(onFulfilled, value, "fulfilled", budget, chained);
10365
+ return runPromiseReaction(onFulfilled, value, "fulfilled", budget, chained, context);
10095
10366
  },
10096
10367
  (reason) => {
10097
10368
  consumeSettledHostCall(target);
10098
- return runPromiseReaction(onRejected, reason, "rejected", budget, chained);
10369
+ return runPromiseReaction(onRejected, reason, "rejected", budget, chained, context);
10099
10370
  }
10100
10371
  )
10101
10372
  );
@@ -10107,12 +10378,18 @@ function getPromisePrototype(budget) {
10107
10378
  sandbox: true,
10108
10379
  call: ([onRejected], context) => {
10109
10380
  const target = context?.thisValue;
10110
- const then = readPromiseReceiverProperty(target, "then", prototype);
10111
- if (!isSandboxClosure(then)) throw new TypeError("Promise.catch requires a callable then.");
10112
- return then.call([void 0, onRejected], {
10113
- stack: context?.stack ?? [],
10114
- thisValue: target
10115
- });
10381
+ const invoke = (then2) => {
10382
+ if (!isSandboxClosure(then2))
10383
+ throw new TypeError("Promise.catch requires a callable then.");
10384
+ return then2.call([void 0, onRejected], {
10385
+ ...context,
10386
+ stack: context?.stack ?? [],
10387
+ thisValue: target,
10388
+ newTarget: void 0
10389
+ });
10390
+ };
10391
+ const then = readPromiseReceiverProperty(target, "then", prototype, context);
10392
+ return then instanceof Promise ? then.then(invoke) : invoke(then);
10116
10393
  },
10117
10394
  name: "catch"
10118
10395
  }),
@@ -10123,46 +10400,57 @@ function getPromisePrototype(budget) {
10123
10400
  if (typeof target !== "object" || target === null) {
10124
10401
  throw new TypeError("Promise.finally requires an object receiver.");
10125
10402
  }
10126
- validatePromiseConstructorProperty(target, prototype);
10127
- const then = readPromiseReceiverProperty(target, "then", prototype);
10128
- if (!isSandboxClosure(then))
10129
- throw new TypeError("Promise.finally requires a callable then.");
10130
- const handlers = isSandboxClosure(onFinally) ? ["fulfilled", "rejected"].map(
10131
- (state) => createSandboxClosure({
10132
- sandbox: true,
10133
- retainedValues: () => [onFinally],
10134
- call: async ([value]) => {
10135
- const result = await callPromiseClosure(
10136
- onFinally,
10137
- [],
10138
- void 0,
10139
- budget,
10140
- context
10141
- );
10142
- const pending = isSandboxPromise(result) && getPromiseMember("constructor", budget) === intrinsicPromiseConstructors.get(budget) ? result : createSandboxPromise(resolveSandboxValue(result, { budget }));
10143
- const cleanupThen = getPromiseMember("then", budget);
10144
- if (!isSandboxClosure(cleanupThen))
10145
- throw new TypeError("Promise cleanup requires a callable then.");
10146
- return callPromiseClosure(
10147
- cleanupThen,
10148
- [
10149
- createSandboxClosure({
10150
- sandbox: true,
10151
- retainedValues: () => [value],
10152
- call: () => {
10153
- if (state === "rejected") throw value;
10154
- return value;
10155
- }
10156
- })
10157
- ],
10158
- pending,
10159
- budget,
10160
- context
10161
- );
10162
- }
10163
- })
10164
- ) : [onFinally, onFinally];
10165
- return then.call(handlers, { stack: context?.stack ?? [], thisValue: target });
10403
+ const invoke = (then) => {
10404
+ if (!isSandboxClosure(then))
10405
+ throw new TypeError("Promise.finally requires a callable then.");
10406
+ const handlers = isSandboxClosure(onFinally) ? ["fulfilled", "rejected"].map(
10407
+ (state) => createSandboxClosure({
10408
+ sandbox: true,
10409
+ retainedValues: () => [onFinally],
10410
+ call: async ([value]) => {
10411
+ const result = await callPromiseClosure(
10412
+ onFinally,
10413
+ [],
10414
+ void 0,
10415
+ budget,
10416
+ context
10417
+ );
10418
+ const pending = isSandboxPromise(result) && getPromiseMember("constructor", budget) === intrinsicPromiseConstructors.get(budget) ? result : createSandboxPromise(resolveSandboxValue(result, { budget }));
10419
+ const cleanupThen = getPromiseMember("then", budget);
10420
+ if (!isSandboxClosure(cleanupThen))
10421
+ throw new TypeError("Promise cleanup requires a callable then.");
10422
+ return callPromiseClosure(
10423
+ cleanupThen,
10424
+ [
10425
+ createSandboxClosure({
10426
+ sandbox: true,
10427
+ retainedValues: () => [value],
10428
+ call: () => {
10429
+ if (state === "rejected") throw value;
10430
+ return value;
10431
+ }
10432
+ })
10433
+ ],
10434
+ pending,
10435
+ budget,
10436
+ context
10437
+ );
10438
+ }
10439
+ })
10440
+ ) : [onFinally, onFinally];
10441
+ return then.call(handlers, {
10442
+ ...context,
10443
+ stack: context?.stack ?? [],
10444
+ thisValue: target,
10445
+ newTarget: void 0
10446
+ });
10447
+ };
10448
+ const finish = () => {
10449
+ const then = readPromiseReceiverProperty(target, "then", prototype, context);
10450
+ return then instanceof Promise ? then.then(invoke) : invoke(then);
10451
+ };
10452
+ const validation = validatePromiseConstructorProperty(target, prototype, context);
10453
+ return validation instanceof Promise ? validation.then(finish) : finish();
10166
10454
  },
10167
10455
  name: "finally"
10168
10456
  })
@@ -10173,15 +10461,19 @@ function getPromisePrototype(budget) {
10173
10461
  promisePrototypes.set(budget, prototype);
10174
10462
  return prototype;
10175
10463
  }
10176
- function readPromiseReceiverProperty(receiver, property, prototype) {
10464
+ function readPromiseReceiverProperty(receiver, property, prototype, context) {
10465
+ if (!isSandboxPromise(receiver) && context?.getProperty !== void 0)
10466
+ return context.getProperty(receiver, property);
10177
10467
  const properties = isSandboxPromise(receiver) ? prototype : isSandboxClosure(receiver) ? receiver.properties : receiver;
10178
10468
  return typeof properties === "object" && properties !== null && Object.hasOwn(properties, property) ? properties[property] : void 0;
10179
10469
  }
10180
- function validatePromiseConstructorProperty(receiver, prototype) {
10181
- const constructor = readPromiseReceiverProperty(receiver, "constructor", prototype);
10182
- if (constructor !== void 0 && (typeof constructor !== "object" || constructor === null)) {
10183
- throw new TypeError("Promise constructor property must be an object.");
10184
- }
10470
+ function validatePromiseConstructorProperty(receiver, prototype, context) {
10471
+ const validate = (constructor2) => {
10472
+ if (constructor2 !== void 0 && (typeof constructor2 !== "object" || constructor2 === null))
10473
+ throw new TypeError("Promise constructor property must be an object.");
10474
+ };
10475
+ const constructor = readPromiseReceiverProperty(receiver, "constructor", prototype, context);
10476
+ return constructor instanceof Promise ? constructor.then(validate) : validate(constructor);
10185
10477
  }
10186
10478
  async function settleIterable(iterable, method, budget, constructor, context) {
10187
10479
  const capability = await createPromiseCapability(constructor, budget, context);
@@ -10216,7 +10508,7 @@ async function settleIterable(iterable, method, budget, constructor, context) {
10216
10508
  }
10217
10509
  };
10218
10510
  try {
10219
- const promiseResolve = readPromiseReceiverProperty(constructor, "resolve", prototype);
10511
+ const promiseResolve = await readPromiseReceiverProperty(constructor, "resolve", prototype, context);
10220
10512
  if (!isSandboxClosure(promiseResolve))
10221
10513
  throw new TypeError("Promise constructor requires a callable resolve.");
10222
10514
  const iterator = getSandboxIterator(iterable, budget, context);
@@ -10266,7 +10558,7 @@ async function settleIterable(iterable, method, budget, constructor, context) {
10266
10558
  });
10267
10559
  });
10268
10560
  remaining++;
10269
- const then = readPromiseReceiverProperty(entry, "then", prototype);
10561
+ const then = await readPromiseReceiverProperty(entry, "then", prototype, context);
10270
10562
  if (!isSandboxClosure(then))
10271
10563
  throw new TypeError("Promise resolver result requires a callable then.");
10272
10564
  await callPromiseClosure(then, handlers, entry, budget, context);
@@ -10353,7 +10645,11 @@ function resolveSandboxValueNow(value, options) {
10353
10645
  }
10354
10646
  );
10355
10647
  }
10356
- const then = getThenable(value);
10648
+ const then = getThenable(value, options.budget);
10649
+ if (then instanceof Promise)
10650
+ return then.then(
10651
+ (method) => method === void 0 ? budgetIfNeeded(value, options.budget) : resolveThenable(value, method, options)
10652
+ );
10357
10653
  if (then !== void 0) {
10358
10654
  return resolveThenable(value, then, options);
10359
10655
  }
@@ -10373,7 +10669,7 @@ function resolveThenable(value, then, options) {
10373
10669
  try {
10374
10670
  if (settlement.state === "fulfilled") {
10375
10671
  resolve(
10376
- isSandboxPromise(settlement.value) || getThenable(settlement.value) !== void 0 ? resolveSandboxValueNow(settlement.value, options) : budgetIfNeeded(settlement.value, options.budget)
10672
+ requiresPromiseResolution(settlement.value, options.budget) ? resolveSandboxValueNow(settlement.value, options) : budgetIfNeeded(settlement.value, options.budget)
10377
10673
  );
10378
10674
  } else {
10379
10675
  reject(budgetIfNeeded(settlement.value, options.budget));
@@ -10429,7 +10725,7 @@ function resolveThenable(value, then, options) {
10429
10725
  ).catch(reject);
10430
10726
  });
10431
10727
  }
10432
- function runPromiseReaction(handler, value, state, budget, self) {
10728
+ function runPromiseReaction(handler, value, state, budget, self, context) {
10433
10729
  return new Promise((resolve, reject) => {
10434
10730
  if (state === "rejected" && value instanceof SandboxError && (value.code === "budgetExceeded" || value.code === "reentry")) {
10435
10731
  reject(value);
@@ -10443,14 +10739,14 @@ function runPromiseReaction(handler, value, state, budget, self) {
10443
10739
  reject(
10444
10740
  createSubsetErrorValue("TypeError", "Promise cannot resolve to itself.", [], budget)
10445
10741
  );
10446
- } else if (isSandboxPromise(result) || getThenable(result) !== void 0) {
10742
+ } else if (requiresPromiseResolution(result, budget)) {
10447
10743
  resolve(resolvePromiseResult(result, budget, self));
10448
10744
  } else {
10449
10745
  resolve(budgetSandboxValue(result, budget));
10450
10746
  }
10451
10747
  };
10452
10748
  if (isSandboxClosure(handler)) {
10453
- callInPromiseJob(handler, [argument], void 0, { fulfilled, rejected: reject }).catch(
10749
+ callInPromiseJob(handler, [argument], void 0, { fulfilled, rejected: reject }, context).catch(
10454
10750
  reject
10455
10751
  );
10456
10752
  } else {
@@ -10461,10 +10757,10 @@ function runPromiseReaction(handler, value, state, budget, self) {
10461
10757
  }
10462
10758
  });
10463
10759
  }
10464
- function callInPromiseJob(handler, args, thisValue = void 0, completion) {
10760
+ function callInPromiseJob(handler, args, thisValue = void 0, completion, context) {
10465
10761
  return runPromiseJob(async () => {
10466
10762
  try {
10467
- let result = handler.call(args, { stack: [], thisValue });
10763
+ let result = handler.call(args, { ...context, stack: [], thisValue, newTarget: void 0 });
10468
10764
  if (handler.async !== true) result = await result;
10469
10765
  if (isSandboxPromise(result) && result.synchronousPrefix !== void 0) {
10470
10766
  await result.synchronousPrefix;
@@ -10497,7 +10793,7 @@ function resolvePromiseResult(result, budget, self) {
10497
10793
  settled = true;
10498
10794
  try {
10499
10795
  if (state === "rejected") reject(budgetSandboxValue(value, budget));
10500
- else if (isSandboxPromise(value) || getThenable(value) !== void 0) {
10796
+ else if (requiresPromiseResolution(value, budget)) {
10501
10797
  resolve(resolvePromiseResult(value, budget, self));
10502
10798
  } else {
10503
10799
  resolve(budgetSandboxValue(value, budget));
@@ -10545,11 +10841,23 @@ function resolvePromiseResult(result, budget, self) {
10545
10841
  function isSelfResolution(result, self) {
10546
10842
  return self !== void 0 && (result === self || isSandboxPromise(result) && result.promise === self.promise);
10547
10843
  }
10548
- function getThenable(value) {
10844
+ function requiresPromiseResolution(value, budget) {
10845
+ if (isSandboxPromise(value)) return true;
10846
+ const descriptor = getSandboxPropertyDescriptor(value, "then", budget);
10847
+ return descriptor !== void 0 && (!("value" in descriptor) || isSandboxClosure(descriptor.value));
10848
+ }
10849
+ function getThenable(value, budget) {
10549
10850
  if (typeof value !== "object" || value === null || isSandboxPromise(value)) {
10550
10851
  return void 0;
10551
10852
  }
10552
- const then = isSandboxClosure(value) ? value.properties?.then : value.then;
10853
+ const descriptor = getSandboxPropertyDescriptor(value, "then", budget);
10854
+ if (descriptor !== void 0 && !("value" in descriptor)) {
10855
+ const getter = accessorClosure(descriptor.get);
10856
+ if (getter === void 0) return void 0;
10857
+ const result = budget === void 0 ? getter.call([], { stack: [], thisValue: value }) : callPromiseClosure(getter, [], value, budget);
10858
+ return Promise.resolve(result).then((then2) => isSandboxClosure(then2) ? then2 : void 0);
10859
+ }
10860
+ const then = descriptor?.value;
10553
10861
  return isSandboxClosure(then) ? then : void 0;
10554
10862
  }
10555
10863
  function budgetIfNeeded(value, budget) {
@@ -10840,6 +11148,13 @@ function ownEnumerableSandboxEntries(value, excludedKeys) {
10840
11148
  else entries = Object.entries(Object(value));
10841
11149
  return excludedKeys === void 0 ? entries : entries.filter(([key]) => !excludedKeys.has(key));
10842
11150
  }
11151
+ function ownEnumerableSandboxKeys(value) {
11152
+ if (isGuestHostObject(value)) return getHostObjectKeys(value);
11153
+ if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
11154
+ if (isGuestClosure(value)) return Object.keys(value.properties ?? {});
11155
+ if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
11156
+ return Object.keys(Object(value));
11157
+ }
10843
11158
  function createSandboxPromise(promise, metadata = {}) {
10844
11159
  const original = metadata.trackReplay === false ? promise : promiseReplayContext.getStore()?.track(promise) ?? promise;
10845
11160
  const sandboxPromise = {
@@ -10994,6 +11309,7 @@ function measureSandboxData(values, options = {}) {
10994
11309
  for (const [key, descriptor] of boxedDataProperties(value)) {
10995
11310
  usage += key.length + 1;
10996
11311
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
11312
+ else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
10997
11313
  }
10998
11314
  return;
10999
11315
  }
@@ -11026,6 +11342,7 @@ function measureSandboxData(values, options = {}) {
11026
11342
  if (key === "length") continue;
11027
11343
  usage += key.length + 1;
11028
11344
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
11345
+ else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
11029
11346
  }
11030
11347
  return;
11031
11348
  }
@@ -11064,6 +11381,7 @@ function measureSandboxData(values, options = {}) {
11064
11381
  if (key === "prototype" || key === "name" || key === "length") continue;
11065
11382
  usage += key.length + 1;
11066
11383
  if ("value" in descriptor) visit(descriptor.value, depth + 1);
11384
+ else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
11067
11385
  }
11068
11386
  } else visit(value.properties, depth + 1);
11069
11387
  }
@@ -11107,7 +11425,8 @@ function measureSandboxData(values, options = {}) {
11107
11425
  const descriptor = descriptors[key];
11108
11426
  if (!descriptor.enumerable && !hasManagedDescriptors(value)) continue;
11109
11427
  usage += key.length;
11110
- visit("value" in descriptor ? descriptor.value : void 0, depth + 1);
11428
+ if ("value" in descriptor) visit(descriptor.value, depth + 1);
11429
+ else for (const closure of retainedAccessorClosures(descriptor)) visit(closure, depth + 1);
11111
11430
  }
11112
11431
  };
11113
11432
  for (const value of values) visit(value);
@@ -24451,7 +24770,10 @@ async function bindAssignmentPattern2(pattern, value, target, scope, context) {
24451
24770
  if (value !== void 0) {
24452
24771
  return bindPattern2(pattern.left, value, target, scope, context);
24453
24772
  }
24454
- const defaultValue = await context.evaluate(pattern.right);
24773
+ const defaultValue = await context.evaluate(
24774
+ pattern.right,
24775
+ pattern.left.type === "Identifier" ? pattern.left.name : void 0
24776
+ );
24455
24777
  if (defaultValue.kind !== "normal") {
24456
24778
  return { ok: false, result: defaultValue };
24457
24779
  }
@@ -24460,24 +24782,32 @@ async function bindAssignmentPattern2(pattern, value, target, scope, context) {
24460
24782
  async function bindArrayPattern2(pattern, value, target, scope, context) {
24461
24783
  const iterator = isSandboxCollectionIterator(value) ? value : void 0;
24462
24784
  const values = iterator === void 0 ? getArrayPatternValues(value) : void 0;
24785
+ let cursor = 0;
24786
+ let done = false;
24787
+ const next = async () => {
24788
+ if (iterator !== void 0) return nextCollectionIterator(iterator, context.budget);
24789
+ if (done || cursor >= values.length) {
24790
+ done = true;
24791
+ return { done: true, value: void 0 };
24792
+ }
24793
+ return { done: false, value: await context.getProperty(values, cursor++) };
24794
+ };
24463
24795
  for (let index = 0; index < pattern.elements.length; index += 1) {
24464
24796
  const element = pattern.elements[index];
24465
24797
  if (element === null) {
24466
- if (iterator !== void 0) nextCollectionIterator(iterator, context.budget);
24798
+ await next();
24467
24799
  continue;
24468
24800
  }
24469
24801
  let elementValue;
24470
- if (iterator === void 0) {
24471
- elementValue = element.type === "RestElement" ? values.slice(index) : values[index];
24472
- } else if (element.type === "RestElement") {
24802
+ if (element.type === "RestElement") {
24473
24803
  const rest = [];
24474
- for (let entry = nextCollectionIterator(iterator, context.budget); !entry.done; entry = nextCollectionIterator(iterator, context.budget)) {
24804
+ for (let entry = await next(); !entry.done; entry = await next()) {
24475
24805
  context.budget?.allocateArrayLength(rest.length + 1);
24476
24806
  rest.push(entry.value);
24477
24807
  }
24478
24808
  elementValue = rest;
24479
24809
  } else {
24480
- elementValue = nextCollectionIterator(iterator, context.budget).value;
24810
+ elementValue = (await next()).value;
24481
24811
  }
24482
24812
  const binding = await bindPattern2(element, elementValue, target, scope, context);
24483
24813
  if (!binding.ok) {
@@ -24495,7 +24825,7 @@ async function bindObjectPattern2(pattern, value, target, scope, context) {
24495
24825
  if (property.type === "RestElement") {
24496
24826
  const binding2 = await bindPattern2(
24497
24827
  property,
24498
- copyObjectRestValue(value, excludedKeys),
24828
+ await copyObjectRestValue(value, excludedKeys, context),
24499
24829
  target,
24500
24830
  scope,
24501
24831
  context
@@ -24512,7 +24842,7 @@ async function bindObjectPattern2(pattern, value, target, scope, context) {
24512
24842
  excludedKeys.add(String(key.value));
24513
24843
  const binding = await bindPattern2(
24514
24844
  property.value,
24515
- context.getProperty(value, key.value),
24845
+ await context.getProperty(value, key.value),
24516
24846
  target,
24517
24847
  scope,
24518
24848
  context
@@ -24538,7 +24868,7 @@ async function bindMemberExpression(pattern, value, scope, context) {
24538
24868
  if (!isIndexableValue(object.value)) {
24539
24869
  throw new TypeError("Assignment expressions require a sandbox object property.");
24540
24870
  }
24541
- context.setProperty(object.value, await context.toPropertyKey(property.value), value);
24871
+ await context.setProperty(object.value, await context.toPropertyKey(property.value), value);
24542
24872
  return { ok: true };
24543
24873
  }
24544
24874
  async function evaluatePatternKey(property, context) {
@@ -24589,12 +24919,18 @@ function describeRuntimeValue(value) {
24589
24919
  if (typeof value === "object") return value.constructor?.name ?? "Object";
24590
24920
  return typeof value;
24591
24921
  }
24592
- function copyObjectRestValue(value, excludedKeys) {
24922
+ async function copyObjectRestValue(value, excludedKeys, context) {
24593
24923
  const rest = /* @__PURE__ */ Object.create(null);
24594
- for (const [key, entryValue] of ownEnumerableSandboxEntries(value, excludedKeys)) {
24595
- defineProperty(rest, key, entryValue);
24924
+ const release = context.budget === void 0 ? () => void 0 : retainValues(context.budget, () => [value, rest]);
24925
+ try {
24926
+ for (const key of ownEnumerableSandboxKeys(value)) {
24927
+ if (excludedKeys.has(key) || !hasOwnSandboxProperty(value, key, true)) continue;
24928
+ defineProperty(rest, key, await context.getProperty(value, key));
24929
+ }
24930
+ return rest;
24931
+ } finally {
24932
+ release();
24596
24933
  }
24597
- return rest;
24598
24934
  }
24599
24935
  function isIndexableValue(value) {
24600
24936
  return typeof value === "object" && value !== null;
@@ -24728,144 +25064,6 @@ function getDatePrototype(value, budget, owner) {
24728
25064
  return prototype === value ? null : prototype ?? null;
24729
25065
  }
24730
25066
 
24731
- // packages/safe-js/src/interp/globals/object.ts
24732
- function createObjectGlobal(methods, budget) {
24733
- const construct = ([value]) => {
24734
- if (value === null || value === void 0) {
24735
- budget.chargeDataUsage(1);
24736
- return /* @__PURE__ */ Object.create(null);
24737
- }
24738
- if (typeof value !== "object") {
24739
- const box = createSandboxBox(value);
24740
- budget.chargeDataUsage(measureSandboxData([box]));
24741
- return box;
24742
- }
24743
- return value;
24744
- };
24745
- const constructor = createSandboxClosure({
24746
- guest: true,
24747
- sandbox: true,
24748
- name: "Object",
24749
- length: 1,
24750
- call: construct,
24751
- construct: (args, context) => {
24752
- if (context?.newTarget === void 0 || context.newTarget === constructor) return construct(args);
24753
- const value = construct([]);
24754
- const prototype2 = context.getProperty(context.newTarget, "prototype");
24755
- if (typeof prototype2 === "object" && prototype2 !== null) setSandboxPrototype(value, prototype2, budget);
24756
- return value;
24757
- }
24758
- });
24759
- const properties = materializeFunctionProperties(constructor);
24760
- const prototype = properties.prototype;
24761
- Object.defineProperty(properties, "prototype", { writable: false });
24762
- for (const [name, method] of Object.entries(methods)) {
24763
- Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
24764
- }
24765
- const prototypeMethods = {
24766
- toString: createSandboxClosure({
24767
- sandbox: true,
24768
- name: "toString",
24769
- length: 0,
24770
- call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
24771
- }),
24772
- valueOf: createSandboxClosure({
24773
- sandbox: true,
24774
- name: "valueOf",
24775
- length: 0,
24776
- call: (_args, context) => {
24777
- const value = requireReceiver(context?.thisValue);
24778
- return construct([value]);
24779
- }
24780
- }),
24781
- hasOwnProperty: createSandboxClosure({
24782
- sandbox: true,
24783
- name: "hasOwnProperty",
24784
- length: 1,
24785
- call: async ([key], context) => hasOwnSandboxProperty(
24786
- requireReceiver(context?.thisValue),
24787
- await sandboxString(key, budget, context),
24788
- false
24789
- )
24790
- }),
24791
- propertyIsEnumerable: createSandboxClosure({
24792
- sandbox: true,
24793
- name: "propertyIsEnumerable",
24794
- length: 1,
24795
- call: async ([key], context) => hasOwnSandboxProperty(
24796
- requireReceiver(context?.thisValue),
24797
- await sandboxString(key, budget, context),
24798
- true
24799
- )
24800
- }),
24801
- isPrototypeOf: createSandboxClosure({
24802
- sandbox: true,
24803
- name: "isPrototypeOf",
24804
- length: 1,
24805
- call: ([value], context) => {
24806
- if (typeof value !== "object" || value === null) return false;
24807
- const receiver = requireReceiver(context?.thisValue);
24808
- let depth = 0;
24809
- for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
24810
- budget.visitNode();
24811
- assertSandboxDataDepth(depth++);
24812
- if (current === receiver) return true;
24813
- }
24814
- return false;
24815
- }
24816
- })
24817
- };
24818
- for (const [name, method] of Object.entries(prototypeMethods)) {
24819
- Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
24820
- }
24821
- markDescriptorObject(prototype);
24822
- installObjectPrototype(budget, prototype, constructor);
24823
- return constructor;
24824
- }
24825
- function requireReceiver(value) {
24826
- if (value === null || value === void 0)
24827
- throw new TypeError("Object method requires a non-null receiver.");
24828
- return value;
24829
- }
24830
- function hasOwnSandboxProperty(value, key, enumerable) {
24831
- requireReceiver(value);
24832
- if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
24833
- let properties;
24834
- if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
24835
- else if (isSandboxClosure(value)) {
24836
- if (key === "length" || key === "name") return !enumerable;
24837
- properties = value.properties ?? /* @__PURE__ */ Object.create(null);
24838
- } else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
24839
- return false;
24840
- else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
24841
- else properties = Object(value);
24842
- const descriptor = Object.getOwnPropertyDescriptor(properties, key);
24843
- return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
24844
- }
24845
- function typeTag(value) {
24846
- if (isSandboxBox(value)) value = boxedValue(value);
24847
- if (value === void 0) return "Undefined";
24848
- if (value === null) return "Null";
24849
- if (typeof value === "string") return "String";
24850
- if (typeof value === "number") return "Number";
24851
- if (typeof value === "boolean") return "Boolean";
24852
- if (isSandboxClosure(value)) {
24853
- while (value.boundTarget !== void 0) value = value.boundTarget;
24854
- return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
24855
- }
24856
- if (Array.isArray(value)) return "Array";
24857
- if (isSandboxDate(value)) return "Date";
24858
- if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
24859
- if (isSandboxRegex(value)) return "RegExp";
24860
- if (isSandboxMap(value)) return "Map";
24861
- if (isSandboxSet(value)) return "Set";
24862
- if (isSandboxCollectionIterator(value)) return collectionIteratorState(value).collectionKind === "map" ? "Map Iterator" : "Set Iterator";
24863
- if (isSandboxPromise(value)) return "Promise";
24864
- if (isSandboxGenerator(value)) return "Generator";
24865
- if (isFloat32Array(value)) return "Float32Array";
24866
- return "Object";
24867
- }
24868
-
24869
25067
  // packages/safe-js/src/interp/globals/numeric-parsers.ts
24870
25068
  function createNumericParsers(budget) {
24871
25069
  return {
@@ -25471,12 +25669,17 @@ function createPrimitiveConstructor(options, budget) {
25471
25669
  const prototype = createSandboxBox(initial);
25472
25670
  const allocate = (value, context) => {
25473
25671
  const box = createSandboxBox(value);
25672
+ const finish = (prototype2) => {
25673
+ if (typeof prototype2 === "object" && prototype2 !== null)
25674
+ setSandboxPrototype(box, prototype2, budget);
25675
+ budget.chargeDataUsage(measureSandboxData([box]));
25676
+ return box;
25677
+ };
25474
25678
  if (context?.newTarget !== void 0 && context.newTarget !== constructor) {
25475
25679
  const prototype2 = context.getProperty(context.newTarget, "prototype");
25476
- if (typeof prototype2 === "object" && prototype2 !== null) setSandboxPrototype(box, prototype2, budget);
25680
+ return prototype2 instanceof Promise ? prototype2.then(finish) : finish(prototype2);
25477
25681
  }
25478
- budget.chargeDataUsage(measureSandboxData([box]));
25479
- return box;
25682
+ return finish(void 0);
25480
25683
  };
25481
25684
  const constructor = createSandboxClosure({
25482
25685
  guest: true,
@@ -25537,147 +25740,185 @@ function createPrimitiveConstructor(options, budget) {
25537
25740
  // packages/safe-js/src/interp/globals/object-array.ts
25538
25741
  function createObjectArrayGlobals(options) {
25539
25742
  return {
25540
- Object: createObjectGlobal({
25541
- keys: createSandboxClosure({
25542
- sandbox: true,
25543
- call: ([value]) => budgetSandboxValue2(getOwnEnumerableKeys(value), options.budget),
25544
- name: "keys"
25545
- }),
25546
- values: createSandboxClosure({
25547
- sandbox: true,
25548
- call: ([value]) => allocateProducedSandboxValue(getOwnEnumerableValues(value), options.budget),
25549
- name: "values"
25550
- }),
25551
- entries: createSandboxClosure({
25552
- sandbox: true,
25553
- call: ([value]) => allocateProducedSandboxValue(ownEnumerableSandboxEntries(value), options.budget),
25554
- name: "entries"
25555
- }),
25556
- hasOwn: createSandboxClosure({
25557
- sandbox: true,
25558
- call: ([value, key], context) => {
25559
- if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
25560
- const name = sandboxString(key, options.budget, context);
25561
- return typeof name === "string" ? hasOwnSandboxProperty(value, name, false) : name.then((property) => hasOwnSandboxProperty(value, property, false));
25562
- },
25563
- name: "hasOwn"
25564
- }),
25565
- getOwnPropertyDescriptor: createSandboxClosure({
25566
- sandbox: true,
25567
- call: async ([value, key], context) => {
25568
- const descriptor = Object.getOwnPropertyDescriptor(objectProperties(value), await sandboxString(key, options.budget, context));
25569
- if (descriptor !== void 0 && !("value" in descriptor)) throw new TypeError("Only data property descriptors are supported.");
25570
- return descriptor === void 0 ? void 0 : allocateProducedSandboxValue(descriptor, options.budget);
25571
- },
25572
- name: "getOwnPropertyDescriptor"
25573
- }),
25574
- getOwnPropertyNames: createSandboxClosure({
25575
- sandbox: true,
25576
- call: ([value]) => budgetSandboxValue2(Object.getOwnPropertyNames(objectProperties(value)), options.budget),
25577
- name: "getOwnPropertyNames"
25578
- }),
25579
- defineProperty: createSandboxClosure({
25580
- sandbox: true,
25581
- call: async ([value, key, descriptor], context) => {
25582
- defineDataProperty(value, await sandboxString(key, options.budget, context), dataDescriptor(descriptor), options.budget);
25583
- return value;
25584
- },
25585
- name: "defineProperty"
25586
- }),
25587
- defineProperties: createSandboxClosure({
25588
- sandbox: true,
25589
- call: ([value, descriptors]) => {
25590
- const properties = ownEnumerableSandboxEntries(descriptors).map(([key, descriptor]) => [key, dataDescriptor(descriptor)]);
25591
- for (const [key, descriptor] of properties) {
25592
- defineDataProperty(value, key, descriptor, options.budget);
25593
- }
25594
- return value;
25595
- },
25596
- name: "defineProperties"
25597
- }),
25598
- getPrototypeOf: createSandboxClosure({
25599
- sandbox: true,
25600
- call: ([value]) => {
25601
- if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
25602
- if (value !== null && value !== void 0 && typeof value !== "object") value = createSandboxBox(value);
25603
- objectProperties(value);
25604
- return getSandboxPrototype(value, options.budget);
25605
- },
25606
- name: "getPrototypeOf"
25607
- }),
25608
- setPrototypeOf: createSandboxClosure({
25609
- sandbox: true,
25610
- call: ([value, prototype]) => {
25611
- objectProperties(value, true);
25612
- if (prototype !== null) objectProperties(prototype);
25613
- setSandboxPrototype(value, prototype, options.budget);
25614
- return value;
25615
- },
25616
- name: "setPrototypeOf"
25617
- }),
25618
- create: createSandboxClosure({
25619
- sandbox: true,
25620
- call: ([prototype, descriptors]) => {
25621
- if (prototype !== null) objectProperties(prototype);
25622
- const value = /* @__PURE__ */ Object.create(null);
25623
- setSandboxPrototype(value, prototype, options.budget);
25624
- if (descriptors !== void 0) {
25625
- const properties = ownEnumerableSandboxEntries(descriptors).map(([key, descriptor]) => [key, dataDescriptor(descriptor)]);
25626
- for (const [key, descriptor] of properties) {
25627
- defineDataProperty(value, key, descriptor, options.budget);
25628
- }
25629
- }
25630
- return allocateProducedSandboxValue(value, options.budget);
25631
- },
25632
- name: "create"
25633
- }),
25634
- is: createSandboxClosure({
25635
- sandbox: true,
25636
- call: ([left, right]) => Reflect.apply(Object.is, Object, [left, right]),
25637
- name: "is"
25638
- }),
25639
- fromEntries: createSandboxClosure({
25640
- sandbox: true,
25641
- call: ([value], context) => {
25642
- const iterator = getSandboxIterator(value, options.budget, context);
25643
- if (iterator === void 0) {
25644
- throw new TypeError("Object.fromEntries requires an iterable.");
25645
- }
25646
- if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
25743
+ Object: createObjectGlobal(
25744
+ {
25745
+ keys: createSandboxClosure({
25746
+ sandbox: true,
25747
+ call: ([value]) => budgetSandboxValue2(ownEnumerableSandboxKeys(value), options.budget),
25748
+ name: "keys"
25749
+ }),
25750
+ values: createSandboxClosure({
25751
+ sandbox: true,
25752
+ call: ([value], context) => context === void 0 ? allocateProducedSandboxValue(
25753
+ ownEnumerableSandboxEntries(value).map(([, entry]) => entry),
25754
+ options.budget
25755
+ ) : getOwnEnumerableEntries(value, options.budget, context).then(
25756
+ (entries) => allocateProducedSandboxValue(
25757
+ entries.map(([, entry]) => entry),
25758
+ options.budget
25759
+ )
25760
+ ),
25761
+ name: "values"
25762
+ }),
25763
+ entries: createSandboxClosure({
25764
+ sandbox: true,
25765
+ call: ([value], context) => context === void 0 ? allocateProducedSandboxValue(ownEnumerableSandboxEntries(value), options.budget) : getOwnEnumerableEntries(value, options.budget, context).then(
25766
+ (entries) => allocateProducedSandboxValue(entries, options.budget)
25767
+ ),
25768
+ name: "entries"
25769
+ }),
25770
+ hasOwn: createSandboxClosure({
25771
+ sandbox: true,
25772
+ call: ([value, key], context) => {
25773
+ if (value === null || value === void 0)
25774
+ throw new TypeError("Cannot convert undefined or null to object.");
25775
+ const name = sandboxString(key, options.budget, context);
25776
+ return typeof name === "string" ? hasOwnSandboxProperty(value, name, false) : name.then((property) => hasOwnSandboxProperty(value, property, false));
25777
+ },
25778
+ name: "hasOwn"
25779
+ }),
25780
+ getOwnPropertyDescriptor: createSandboxClosure({
25781
+ sandbox: true,
25782
+ call: async ([value, key], context) => {
25783
+ const descriptor = Object.getOwnPropertyDescriptor(
25784
+ objectProperties(value),
25785
+ await sandboxString(key, options.budget, context)
25786
+ );
25787
+ if (descriptor === void 0) return void 0;
25647
25788
  return allocateProducedSandboxValue(
25648
- Object.setPrototypeOf(
25649
- Reflect.apply(Object.fromEntries, Object, [{ [Symbol.iterator]: () => iterator }]),
25650
- null
25651
- ),
25789
+ exposePropertyDescriptor(descriptor),
25652
25790
  options.budget
25653
25791
  );
25654
- }
25655
- return objectFromSandboxEntries(value, iterator, options.budget, context);
25656
- },
25657
- name: "fromEntries"
25658
- }),
25659
- freeze: createSandboxClosure({
25660
- sandbox: true,
25661
- call: ([value]) => {
25662
- if (isGuestHostObject(value)) throw new TypeError("Live host objects cannot be frozen.");
25663
- if (typeof value === "object" && value !== null) {
25664
- Object.freeze(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
25665
- }
25666
- return value;
25667
- },
25668
- name: "freeze"
25669
- }),
25670
- isFrozen: createSandboxClosure({
25671
- sandbox: true,
25672
- call: ([value]) => Object.isFrozen(isGuestClosure(value) ? materializeFunctionProperties(value) : value),
25673
- name: "isFrozen"
25674
- }),
25675
- assign: createSandboxClosure({
25676
- sandbox: true,
25677
- call: ([target, ...sources]) => assignSandboxValues(target, sources, options.budget),
25678
- name: "assign"
25679
- })
25680
- }, options.budget),
25792
+ },
25793
+ name: "getOwnPropertyDescriptor"
25794
+ }),
25795
+ getOwnPropertyDescriptors: createSandboxClosure({
25796
+ sandbox: true,
25797
+ call: ([value]) => {
25798
+ const descriptors = /* @__PURE__ */ Object.create(null);
25799
+ for (const [key, descriptor] of Object.entries(
25800
+ Object.getOwnPropertyDescriptors(objectProperties(value))
25801
+ ))
25802
+ defineOwnDataProperty(descriptors, key, exposePropertyDescriptor(descriptor));
25803
+ return allocateProducedSandboxValue(descriptors, options.budget);
25804
+ },
25805
+ name: "getOwnPropertyDescriptors"
25806
+ }),
25807
+ getOwnPropertyNames: createSandboxClosure({
25808
+ sandbox: true,
25809
+ call: ([value]) => budgetSandboxValue2(Object.getOwnPropertyNames(objectProperties(value)), options.budget),
25810
+ name: "getOwnPropertyNames"
25811
+ }),
25812
+ defineProperty: createSandboxClosure({
25813
+ sandbox: true,
25814
+ call: async ([value, key, descriptor], context) => {
25815
+ objectProperties(value, true);
25816
+ const property = await sandboxString(key, options.budget, context);
25817
+ defineDataProperty(
25818
+ value,
25819
+ property,
25820
+ await propertyDescriptor(descriptor, options.budget, context),
25821
+ options.budget
25822
+ );
25823
+ return value;
25824
+ },
25825
+ name: "defineProperty"
25826
+ }),
25827
+ defineProperties: createSandboxClosure({
25828
+ sandbox: true,
25829
+ call: async ([value, descriptors], context) => {
25830
+ await definePropertiesFromObject(value, descriptors, options.budget, context);
25831
+ return value;
25832
+ },
25833
+ name: "defineProperties"
25834
+ }),
25835
+ getPrototypeOf: createSandboxClosure({
25836
+ sandbox: true,
25837
+ call: ([value]) => {
25838
+ if (isSandboxDate(value))
25839
+ return getDatePrototype(value, options.budget, options.compileOwner);
25840
+ if (value !== null && value !== void 0 && typeof value !== "object")
25841
+ value = createSandboxBox(value);
25842
+ objectProperties(value);
25843
+ return getSandboxPrototype(value, options.budget);
25844
+ },
25845
+ name: "getPrototypeOf"
25846
+ }),
25847
+ setPrototypeOf: createSandboxClosure({
25848
+ sandbox: true,
25849
+ call: ([value, prototype]) => {
25850
+ objectProperties(value, true);
25851
+ if (prototype !== null) objectProperties(prototype);
25852
+ setSandboxPrototype(value, prototype, options.budget);
25853
+ return value;
25854
+ },
25855
+ name: "setPrototypeOf"
25856
+ }),
25857
+ create: createSandboxClosure({
25858
+ sandbox: true,
25859
+ call: async ([prototype, descriptors], context) => {
25860
+ if (prototype !== null) objectProperties(prototype);
25861
+ const value = /* @__PURE__ */ Object.create(null);
25862
+ setSandboxPrototype(value, prototype, options.budget);
25863
+ if (descriptors !== void 0) {
25864
+ await definePropertiesFromObject(value, descriptors, options.budget, context);
25865
+ }
25866
+ return allocateProducedSandboxValue(value, options.budget);
25867
+ },
25868
+ name: "create"
25869
+ }),
25870
+ is: createSandboxClosure({
25871
+ sandbox: true,
25872
+ call: ([left, right]) => Reflect.apply(Object.is, Object, [left, right]),
25873
+ name: "is"
25874
+ }),
25875
+ fromEntries: createSandboxClosure({
25876
+ sandbox: true,
25877
+ call: ([value], context) => {
25878
+ const iterator = getSandboxIterator(value, options.budget, context);
25879
+ if (iterator === void 0) {
25880
+ throw new TypeError("Object.fromEntries requires an iterable.");
25881
+ }
25882
+ if (context === void 0 && !iterator.generator && !iterator.asynchronous) {
25883
+ return allocateProducedSandboxValue(
25884
+ Object.setPrototypeOf(
25885
+ Reflect.apply(Object.fromEntries, Object, [
25886
+ { [Symbol.iterator]: () => iterator }
25887
+ ]),
25888
+ null
25889
+ ),
25890
+ options.budget
25891
+ );
25892
+ }
25893
+ return objectFromSandboxEntries(value, iterator, options.budget, context);
25894
+ },
25895
+ name: "fromEntries"
25896
+ }),
25897
+ freeze: createSandboxClosure({
25898
+ sandbox: true,
25899
+ call: ([value]) => {
25900
+ if (isGuestHostObject(value))
25901
+ throw new TypeError("Live host objects cannot be frozen.");
25902
+ if (typeof value === "object" && value !== null) {
25903
+ Object.freeze(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
25904
+ }
25905
+ return value;
25906
+ },
25907
+ name: "freeze"
25908
+ }),
25909
+ isFrozen: createSandboxClosure({
25910
+ sandbox: true,
25911
+ call: ([value]) => Object.isFrozen(isGuestClosure(value) ? materializeFunctionProperties(value) : value),
25912
+ name: "isFrozen"
25913
+ }),
25914
+ assign: createSandboxClosure({
25915
+ sandbox: true,
25916
+ call: ([target, ...sources], context) => assignSandboxValues(target, sources, options.budget, context),
25917
+ name: "assign"
25918
+ })
25919
+ },
25920
+ options.budget
25921
+ ),
25681
25922
  Array: createSandboxClosure({
25682
25923
  sandbox: true,
25683
25924
  call: (args) => createArrayFromConstructorArgs(args, options.budget),
@@ -25701,66 +25942,75 @@ function createObjectArrayGlobals(options) {
25701
25942
  })
25702
25943
  }
25703
25944
  }),
25704
- String: createPrimitiveConstructor({
25705
- call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
25706
- name: "String",
25707
- properties: {
25708
- raw: createSandboxClosure({
25709
- sandbox: true,
25710
- call: (args) => stringRaw(args, options.budget),
25711
- name: "raw"
25712
- }),
25713
- fromCharCode: createSandboxClosure({
25714
- sandbox: true,
25715
- call: (args) => options.budget.allocateString(Reflect.apply(String.fromCharCode, String, [...args])),
25716
- name: "fromCharCode"
25717
- }),
25718
- fromCodePoint: createSandboxClosure({
25719
- sandbox: true,
25720
- call: (args) => options.budget.allocateString(Reflect.apply(String.fromCodePoint, String, [...args])),
25721
- name: "fromCodePoint"
25722
- })
25723
- }
25724
- }, options.budget),
25725
- Number: createPrimitiveConstructor({
25726
- call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
25727
- name: "Number",
25728
- properties: {
25729
- isFinite: createSandboxClosure({
25730
- sandbox: true,
25731
- call: ([value]) => typeof value === "number" && Number.isFinite(value),
25732
- name: "isFinite"
25733
- }),
25734
- isNaN: createSandboxClosure({
25735
- sandbox: true,
25736
- call: ([value]) => typeof value === "number" && Number.isNaN(value),
25737
- name: "isNaN"
25738
- }),
25739
- isInteger: createSandboxClosure({
25740
- sandbox: true,
25741
- call: ([value]) => typeof value === "number" && Number.isInteger(value),
25742
- name: "isInteger"
25743
- }),
25744
- ...createNumericParsers(options.budget),
25745
- isSafeInteger: createSandboxClosure({
25746
- sandbox: true,
25747
- call: ([value]) => typeof value === "number" && Number.isSafeInteger(value),
25748
- name: "isSafeInteger"
25749
- }),
25750
- MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER,
25751
- MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER,
25752
- EPSILON: Number.EPSILON,
25753
- MAX_VALUE: Number.MAX_VALUE,
25754
- MIN_VALUE: Number.MIN_VALUE,
25755
- NaN: Number.NaN,
25756
- NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
25757
- POSITIVE_INFINITY: Number.POSITIVE_INFINITY
25758
- }
25759
- }, options.budget),
25760
- Boolean: createPrimitiveConstructor({
25761
- call: ([value]) => Boolean(value),
25762
- name: "Boolean"
25763
- }, options.budget)
25945
+ String: createPrimitiveConstructor(
25946
+ {
25947
+ call: (args, context) => sandboxString(args.length === 0 ? "" : args[0], options.budget, context),
25948
+ name: "String",
25949
+ properties: {
25950
+ raw: createSandboxClosure({
25951
+ sandbox: true,
25952
+ call: (args, context) => stringRaw(args, options.budget, context),
25953
+ name: "raw"
25954
+ }),
25955
+ fromCharCode: createSandboxClosure({
25956
+ sandbox: true,
25957
+ call: (args) => options.budget.allocateString(Reflect.apply(String.fromCharCode, String, [...args])),
25958
+ name: "fromCharCode"
25959
+ }),
25960
+ fromCodePoint: createSandboxClosure({
25961
+ sandbox: true,
25962
+ call: (args) => options.budget.allocateString(Reflect.apply(String.fromCodePoint, String, [...args])),
25963
+ name: "fromCodePoint"
25964
+ })
25965
+ }
25966
+ },
25967
+ options.budget
25968
+ ),
25969
+ Number: createPrimitiveConstructor(
25970
+ {
25971
+ call: (args, context) => sandboxNumber(args.length === 0 ? 0 : args[0], options.budget, context),
25972
+ name: "Number",
25973
+ properties: {
25974
+ isFinite: createSandboxClosure({
25975
+ sandbox: true,
25976
+ call: ([value]) => typeof value === "number" && Number.isFinite(value),
25977
+ name: "isFinite"
25978
+ }),
25979
+ isNaN: createSandboxClosure({
25980
+ sandbox: true,
25981
+ call: ([value]) => typeof value === "number" && Number.isNaN(value),
25982
+ name: "isNaN"
25983
+ }),
25984
+ isInteger: createSandboxClosure({
25985
+ sandbox: true,
25986
+ call: ([value]) => typeof value === "number" && Number.isInteger(value),
25987
+ name: "isInteger"
25988
+ }),
25989
+ ...createNumericParsers(options.budget),
25990
+ isSafeInteger: createSandboxClosure({
25991
+ sandbox: true,
25992
+ call: ([value]) => typeof value === "number" && Number.isSafeInteger(value),
25993
+ name: "isSafeInteger"
25994
+ }),
25995
+ MAX_SAFE_INTEGER: Number.MAX_SAFE_INTEGER,
25996
+ MIN_SAFE_INTEGER: Number.MIN_SAFE_INTEGER,
25997
+ EPSILON: Number.EPSILON,
25998
+ MAX_VALUE: Number.MAX_VALUE,
25999
+ MIN_VALUE: Number.MIN_VALUE,
26000
+ NaN: Number.NaN,
26001
+ NEGATIVE_INFINITY: Number.NEGATIVE_INFINITY,
26002
+ POSITIVE_INFINITY: Number.POSITIVE_INFINITY
26003
+ }
26004
+ },
26005
+ options.budget
26006
+ ),
26007
+ Boolean: createPrimitiveConstructor(
26008
+ {
26009
+ call: ([value]) => Boolean(value),
26010
+ name: "Boolean"
26011
+ },
26012
+ options.budget
26013
+ )
25764
26014
  };
25765
26015
  }
25766
26016
  async function objectFromSandboxEntries(items, iterator, budget, context) {
@@ -25770,7 +26020,15 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
25770
26020
  let value;
25771
26021
  let failure;
25772
26022
  const retained = {};
25773
- budget.setRetainedValues(retained, () => [items, iterator.retainedValue, object, entry, key, value, failure]);
26023
+ budget.setRetainedValues(retained, () => [
26024
+ items,
26025
+ iterator.retainedValue,
26026
+ object,
26027
+ entry,
26028
+ key,
26029
+ value,
26030
+ failure
26031
+ ]);
25774
26032
  const checkData = createDataCheckpoint(budget, context);
25775
26033
  const closeOnThrow = async (error) => {
25776
26034
  failure = isCapturedException(error) ? error.reason : error;
@@ -25799,8 +26057,8 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
25799
26057
  if (typeof entry !== "object" || entry === null) {
25800
26058
  throw new TypeError("Object.fromEntries requires entry objects.");
25801
26059
  }
25802
- key = context?.getProperty !== void 0 ? context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, budget);
25803
- value = context?.getProperty !== void 0 ? context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, budget);
26060
+ key = context?.getProperty !== void 0 ? await context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, budget);
26061
+ value = context?.getProperty !== void 0 ? await context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, budget);
25804
26062
  const property = await sandboxString(key, budget, context);
25805
26063
  const growth = property.length + 1 + (budget.limits.dataSize === void 0 ? 0 : measureSandboxData([value]));
25806
26064
  budget.visitNode();
@@ -25817,7 +26075,7 @@ async function objectFromSandboxEntries(items, iterator, budget, context) {
25817
26075
  budget.setRetainedValues(retained, void 0);
25818
26076
  }
25819
26077
  }
25820
- function assignSandboxValues(target, sources, budget) {
26078
+ function assignSandboxValues(target, sources, budget, context) {
25821
26079
  if (target === null || target === void 0) {
25822
26080
  throw new TypeError("Object.assign(target, ...sources) requires a non-null target.");
25823
26081
  }
@@ -25828,50 +26086,120 @@ function assignSandboxValues(target, sources, budget) {
25828
26086
  if (!isGuestClosure(target) && !isAssignableSandboxTarget(target)) {
25829
26087
  throw new TypeError("Object.assign(target, ...sources) requires an object or array target.");
25830
26088
  }
25831
- for (const source of sources) {
25832
- if (source === null || source === void 0) {
25833
- continue;
25834
- }
25835
- for (const [key, value] of ownEnumerableSandboxEntries(source)) {
25836
- setSandboxProperty(target, key, value, budget);
26089
+ if (context === void 0) {
26090
+ for (const source of sources) {
26091
+ if (source === null || source === void 0) continue;
26092
+ for (const [key, value] of ownEnumerableSandboxEntries(source))
26093
+ setSandboxProperty(target, key, value, budget);
25837
26094
  }
26095
+ return target;
25838
26096
  }
25839
- return target;
26097
+ return (async () => {
26098
+ const release = retainValues(budget, () => [target, ...sources]);
26099
+ try {
26100
+ for (const source of sources) {
26101
+ if (source === null || source === void 0) continue;
26102
+ for (const key of ownEnumerableSandboxKeys(source)) {
26103
+ if (!hasOwnSandboxProperty(source, key, true)) continue;
26104
+ const value = await (context.getProperty !== void 0 ? context.getProperty(source, key) : getSandboxDataProperty(source, key, budget));
26105
+ await setSandboxProperty(target, key, value, budget, true, context);
26106
+ }
26107
+ }
26108
+ return target;
26109
+ } finally {
26110
+ release();
26111
+ }
26112
+ })();
25840
26113
  }
25841
26114
  function objectProperties(value, mutable = false) {
25842
26115
  if (isSandboxDate(value)) {
25843
26116
  if (mutable) throw new TypeError("Date own properties and prototypes are not supported.");
25844
26117
  return value;
25845
26118
  }
25846
- if (isGuestHostObject(value)) throw new TypeError("Live host object descriptors are not supported.");
26119
+ if (isGuestHostObject(value))
26120
+ throw new TypeError("Live host object descriptors are not supported.");
25847
26121
  if (isGuestClosure(value)) return materializeFunctionProperties(value);
25848
26122
  if (isSandboxClosure(value)) {
25849
26123
  if (mutable) throw new TypeError("Host function properties are read only.");
25850
26124
  return value.properties ?? /* @__PURE__ */ Object.create(null);
25851
26125
  }
25852
- if (!isAssignableSandboxTarget(value)) throw new TypeError("Expected a sandbox object or function.");
26126
+ if (!isAssignableSandboxTarget(value))
26127
+ throw new TypeError("Expected a sandbox object or function.");
25853
26128
  return value;
25854
26129
  }
25855
- function dataDescriptor(input) {
25856
- const source = objectProperties(input);
26130
+ function exposePropertyDescriptor(descriptor) {
26131
+ return "value" in descriptor ? descriptor : {
26132
+ get: accessorClosure(descriptor.get),
26133
+ set: accessorClosure(descriptor.set),
26134
+ enumerable: descriptor.enumerable,
26135
+ configurable: descriptor.configurable
26136
+ };
26137
+ }
26138
+ async function propertyDescriptor(input, budget, context) {
26139
+ objectProperties(input);
25857
26140
  const descriptor = {};
25858
- for (const field of ["get", "set", "value", "writable", "enumerable", "configurable"]) {
25859
- const entry = Object.getOwnPropertyDescriptor(source, field);
25860
- if (entry === void 0) continue;
25861
- if (!("value" in entry) || field === "get" || field === "set") {
25862
- throw new TypeError("Only data property descriptors are supported.");
26141
+ const release = retainValues(budget, () => [
26142
+ input,
26143
+ descriptor.value,
26144
+ ...retainedAccessorClosures(descriptor)
26145
+ ]);
26146
+ try {
26147
+ for (const field of [
26148
+ "enumerable",
26149
+ "configurable",
26150
+ "value",
26151
+ "writable",
26152
+ "get",
26153
+ "set"
26154
+ ]) {
26155
+ if (getSandboxPropertyDescriptor(input, field, budget) === void 0 && !hasOwnSandboxProperty(input, field, false))
26156
+ continue;
26157
+ const value = await (context?.getProperty !== void 0 ? context.getProperty(input, field) : getSandboxDataProperty(input, field, budget));
26158
+ if (field === "get" || field === "set") {
26159
+ if (value !== void 0 && !isSandboxClosure(value))
26160
+ throw new TypeError("Accessor must be a function or undefined.");
26161
+ descriptor[field] = value === void 0 ? void 0 : accessorAdapter(value, field);
26162
+ } else if (field === "value") {
26163
+ descriptor.value = value;
26164
+ } else {
26165
+ descriptor[field] = Boolean(value);
26166
+ }
25863
26167
  }
25864
- if (field === "value") descriptor.value = entry.value;
25865
- else descriptor[field] = Boolean(entry.value);
26168
+ if (("get" in descriptor || "set" in descriptor) && ("value" in descriptor || "writable" in descriptor))
26169
+ throw new TypeError("A property cannot be both a data property and an accessor.");
26170
+ return descriptor;
26171
+ } finally {
26172
+ release();
26173
+ }
26174
+ }
26175
+ async function definePropertiesFromObject(target, descriptors, budget, context) {
26176
+ objectProperties(target, true);
26177
+ const properties = [];
26178
+ const release = retainValues(budget, () => [
26179
+ target,
26180
+ descriptors,
26181
+ properties,
26182
+ ...properties.flatMap(([, descriptor]) => retainedAccessorClosures(descriptor))
26183
+ ]);
26184
+ try {
26185
+ for (const key of ownEnumerableSandboxKeys(descriptors)) {
26186
+ if (!hasOwnSandboxProperty(descriptors, key, true)) continue;
26187
+ const descriptor = await (context?.getProperty !== void 0 ? context.getProperty(descriptors, key) : getSandboxDataProperty(descriptors, key, budget));
26188
+ properties.push([key, await propertyDescriptor(descriptor, budget, context)]);
26189
+ }
26190
+ for (const [key, descriptor] of properties) defineDataProperty(target, key, descriptor, budget);
26191
+ } finally {
26192
+ release();
25866
26193
  }
25867
- return descriptor;
25868
26194
  }
25869
26195
  function defineDataProperty(target, key, descriptor, budget) {
25870
26196
  budget.visitNode();
25871
- if (isFloat32Array(target)) throw new TypeError("Typed array property descriptors are not supported.");
26197
+ if (isFloat32Array(target))
26198
+ throw new TypeError("Typed array property descriptors are not supported.");
25872
26199
  const properties = objectProperties(target, true);
25873
26200
  if (Array.isArray(properties)) {
25874
- if (key === "length" && "value" in descriptor) budget.allocateArrayLength(Number(descriptor.value));
26201
+ if (key === "length" && "value" in descriptor)
26202
+ budget.allocateArrayLength(Number(descriptor.value));
25875
26203
  else {
25876
26204
  const index = Number(key);
25877
26205
  if (Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === key) {
@@ -25900,7 +26228,15 @@ async function arrayFromSandboxValues(args, budget, context) {
25900
26228
  let currentValue;
25901
26229
  let failure;
25902
26230
  const retained = {};
25903
- budget.setRetainedValues(retained, () => [items, iterator?.retainedValue, mapFn, constructor, result, currentValue, failure]);
26231
+ budget.setRetainedValues(retained, () => [
26232
+ items,
26233
+ iterator?.retainedValue,
26234
+ mapFn,
26235
+ constructor,
26236
+ result,
26237
+ currentValue,
26238
+ failure
26239
+ ]);
25904
26240
  const checkData = createDataCheckpoint(budget, context);
25905
26241
  const closeOnThrow = async (error) => {
25906
26242
  failure = isCapturedException(error) ? error.reason : error;
@@ -25914,30 +26250,46 @@ async function arrayFromSandboxValues(args, budget, context) {
25914
26250
  try {
25915
26251
  let length = 0;
25916
26252
  if (iterator === void 0) {
25917
- const number = await sandboxNumber(read("length"), budget, context);
26253
+ const number = await sandboxNumber(await read("length"), budget, context);
25918
26254
  length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
25919
26255
  }
25920
- result = isSandboxClosure(constructor) && constructor.construct !== void 0 ? await invokeBuiltinClosure(constructor, iterator === void 0 ? [length] : [], budget, context, void 0, true) : createArrayFromConstructorArgs([length], budget);
26256
+ result = isSandboxClosure(constructor) && constructor.construct !== void 0 ? await invokeBuiltinClosure(
26257
+ constructor,
26258
+ iterator === void 0 ? [length] : [],
26259
+ budget,
26260
+ context,
26261
+ void 0,
26262
+ true
26263
+ ) : createArrayFromConstructorArgs([length], budget);
25921
26264
  checkData(result, 0, true);
25922
26265
  let index = 0;
25923
26266
  while (iterator !== void 0 || index < length) {
25924
26267
  try {
25925
26268
  budget.visitNode();
25926
- if (iterator !== void 0 && index >= Number.MAX_SAFE_INTEGER) throw new TypeError("Array.from input is too long.");
26269
+ if (iterator !== void 0 && index >= Number.MAX_SAFE_INTEGER)
26270
+ throw new TypeError("Array.from input is too long.");
25927
26271
  } catch (error) {
25928
26272
  await closeOnThrow(error);
25929
26273
  }
25930
26274
  if (iterator !== void 0) {
25931
26275
  const next = await iterator.next();
25932
- if (typeof next !== "object" || next === null) throw new TypeError("Iterator result must be an object.");
26276
+ if (typeof next !== "object" || next === null)
26277
+ throw new TypeError("Iterator result must be an object.");
25933
26278
  if (next.done) break;
25934
26279
  currentValue = next.value;
25935
26280
  } else {
25936
- currentValue = read(index);
26281
+ currentValue = await read(index);
25937
26282
  }
25938
26283
  try {
25939
26284
  if (Array.isArray(result)) budget.allocateArrayLength(index + 1);
25940
- if (mapFn !== void 0) currentValue = await invokeBuiltinClosure(mapFn, [currentValue, index], budget, context, thisValue);
26285
+ if (mapFn !== void 0)
26286
+ currentValue = await invokeBuiltinClosure(
26287
+ mapFn,
26288
+ [currentValue, index],
26289
+ budget,
26290
+ context,
26291
+ thisValue
26292
+ );
25941
26293
  const key = String(index);
25942
26294
  const growth = key.length + 1 + (Array.isArray(result) ? Math.max(0, index + 1 - result.length) : 0) + (budget.limits.dataSize === void 0 ? 0 : measureSandboxData([currentValue]));
25943
26295
  budget.visitNode();
@@ -25975,19 +26327,60 @@ function createArrayFromConstructorArgs(args, budget) {
25975
26327
  release();
25976
26328
  }
25977
26329
  }
25978
- function getOwnEnumerableKeys(value) {
25979
- if (isGuestHostObject(value)) return getHostObjectKeys(value);
25980
- return ownEnumerableSandboxEntries(value).map(([key]) => key);
25981
- }
25982
- function getOwnEnumerableValues(value) {
25983
- return ownEnumerableSandboxEntries(value).map(([, entryValue]) => entryValue);
26330
+ async function getOwnEnumerableEntries(value, budget, context) {
26331
+ const entries = [];
26332
+ const release = retainValues(budget, () => [value, entries]);
26333
+ try {
26334
+ for (const key of ownEnumerableSandboxKeys(value)) {
26335
+ if (!hasOwnSandboxProperty(value, key, true)) continue;
26336
+ entries.push([
26337
+ key,
26338
+ await (context?.getProperty !== void 0 ? context.getProperty(value, key) : getSandboxDataProperty(value, key, budget))
26339
+ ]);
26340
+ }
26341
+ return entries;
26342
+ } finally {
26343
+ release();
26344
+ }
25984
26345
  }
25985
26346
  function budgetSandboxValue2(value, budget) {
25986
26347
  const sandboxValue = deepCopyToSandbox(value);
25987
26348
  return allocateProducedSandboxValue(sandboxValue, budget);
25988
26349
  }
25989
- function stringRaw(args, budget) {
26350
+ function stringRaw(args, budget, context) {
25990
26351
  const [template, ...substitutions] = args;
26352
+ if (context?.getProperty !== void 0)
26353
+ return (async () => {
26354
+ if (template === null || template === void 0)
26355
+ throw new TypeError("String.raw requires a template object.");
26356
+ const raw2 = await context.getProperty(template, "raw");
26357
+ if (raw2 === null || raw2 === void 0)
26358
+ throw new TypeError("String.raw requires raw strings.");
26359
+ const number = await sandboxNumber(
26360
+ await context.getProperty(raw2, "length"),
26361
+ budget,
26362
+ context
26363
+ );
26364
+ const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
26365
+ let result2 = "";
26366
+ const retained = {};
26367
+ budget.setRetainedValues(retained, () => [raw2, result2]);
26368
+ try {
26369
+ for (let index = 0; index < length; index++) {
26370
+ budget.visitNode();
26371
+ result2 = budget.allocateString(
26372
+ result2 + await sandboxString(await context.getProperty(raw2, index), budget, context)
26373
+ );
26374
+ if (index + 1 < length && index < substitutions.length)
26375
+ result2 = budget.allocateString(
26376
+ result2 + await sandboxString(substitutions[index], budget, context)
26377
+ );
26378
+ }
26379
+ return result2;
26380
+ } finally {
26381
+ budget.setRetainedValues(retained, void 0);
26382
+ }
26383
+ })();
25991
26384
  const raw = getTemplateRawParts(template);
25992
26385
  let result = "";
25993
26386
  for (let index = 0; index < raw.length; index += 1) {
@@ -26024,7 +26417,7 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
26024
26417
  parent = result.value;
26025
26418
  if (parent !== null && (!isSandboxClosure(parent) || parent.construct === void 0))
26026
26419
  throw new TypeError("Class extends value is not a constructor or null.");
26027
- prototypeParent = parent === null ? null : callContext.getProperty(parent, "prototype");
26420
+ prototypeParent = parent === null ? null : await callContext.getProperty(parent, "prototype");
26028
26421
  if (prototypeParent !== null && typeof prototypeParent !== "object")
26029
26422
  throw new TypeError("Class extends value has an invalid prototype.");
26030
26423
  }
@@ -26064,7 +26457,7 @@ async function evaluateClass(node, context, evaluateNode2, callContext) {
26064
26457
  };
26065
26458
  if (!derived) {
26066
26459
  thisValue = {};
26067
- const targetPrototype = invocation.getProperty(newTarget, "prototype");
26460
+ const targetPrototype = await invocation.getProperty(newTarget, "prototype");
26068
26461
  if (typeof targetPrototype === "object" && targetPrototype !== null)
26069
26462
  setSandboxPrototype(thisValue, targetPrototype, context.budget);
26070
26463
  }
@@ -26209,7 +26602,13 @@ function getArrayMember(value, property, options) {
26209
26602
  return createSandboxClosure({
26210
26603
  sandbox: true,
26211
26604
  name: `Array#${property}`,
26212
- call: (args, context) => callArrayMethod(context?.thisValue, property, args, { ...options, context }, context?.stack ?? [])
26605
+ call: (args, context) => callArrayMethod(
26606
+ context?.thisValue,
26607
+ property,
26608
+ args,
26609
+ { ...options, context },
26610
+ context?.stack ?? []
26611
+ )
26213
26612
  });
26214
26613
  }
26215
26614
  return void 0;
@@ -26225,7 +26624,8 @@ function isArrayMethodName(property) {
26225
26624
  return typeof property === "string" && arrayMethodNames.has(property);
26226
26625
  }
26227
26626
  async function callArrayMethod(receiver, methodName, args, options, stack = []) {
26228
- if (receiver === null || receiver === void 0) throw new TypeError("Array method requires a receiver.");
26627
+ if (receiver === null || receiver === void 0)
26628
+ throw new TypeError("Array method requires a receiver.");
26229
26629
  if (typeof receiver !== "object") {
26230
26630
  receiver = createSandboxBox(receiver);
26231
26631
  options.budget.chargeDataUsage(measureSandboxData([receiver]));
@@ -26262,38 +26662,44 @@ async function callArrayMethod(receiver, methodName, args, options, stack = [])
26262
26662
  }
26263
26663
  }
26264
26664
  async function arrayLikeView(receiver, options) {
26265
- const rawLength = options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
26665
+ const rawLength = options.context?.getProperty !== void 0 ? await options.context.getProperty(receiver, "length") : getSandboxDataProperty(receiver, "length", options.budget);
26266
26666
  const number = await sandboxNumber(rawLength, options.budget, options.context);
26267
26667
  const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
26268
- const view = new Proxy(/* @__PURE__ */ Object.create(null), {
26269
- get: (_target, key) => {
26270
- options.budget.visitNode();
26271
- if (key === "length") return length;
26272
- if (typeof key !== "string") return void 0;
26273
- return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, key) : getSandboxDataProperty(receiver, key, options.budget);
26274
- },
26275
- has: (_target, key) => {
26276
- options.budget.visitNode();
26277
- if (typeof key === "string" && options.hasProperty !== void 0) return options.hasProperty(receiver, key);
26278
- for (let current = receiver; current !== null; current = getSandboxPrototype(current, options.budget)) {
26668
+ const view = new Proxy(
26669
+ /* @__PURE__ */ Object.create(null),
26670
+ {
26671
+ get: (_target, key) => {
26672
+ options.budget.visitNode();
26673
+ if (key === "length") return length;
26674
+ if (typeof key !== "string") return void 0;
26675
+ return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, key) : getSandboxDataProperty(receiver, key, options.budget);
26676
+ },
26677
+ has: (_target, key) => {
26678
+ options.budget.visitNode();
26679
+ if (typeof key === "string" && options.hasProperty !== void 0)
26680
+ return options.hasProperty(receiver, key);
26681
+ for (let current = receiver; current !== null; current = getSandboxPrototype(current, options.budget)) {
26682
+ options.budget.visitNode();
26683
+ if (Object.hasOwn(current, key)) return true;
26684
+ }
26685
+ return false;
26686
+ },
26687
+ set: (_target, key, entry) => {
26688
+ options.budget.visitNode();
26689
+ if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
26690
+ if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
26691
+ else if (!Reflect.set(receiver, key, entry))
26692
+ throw new TypeError(`Cannot assign property '${key}'.`);
26693
+ return true;
26694
+ },
26695
+ deleteProperty: (_target, key) => {
26279
26696
  options.budget.visitNode();
26280
- if (Object.hasOwn(current, key)) return true;
26697
+ if (typeof key === "string" && options.deleteProperty !== void 0)
26698
+ return options.deleteProperty(receiver, key);
26699
+ return Reflect.deleteProperty(receiver, key);
26281
26700
  }
26282
- return false;
26283
- },
26284
- set: (_target, key, entry) => {
26285
- options.budget.visitNode();
26286
- if (typeof key !== "string") throw new TypeError("Array indices must be string keys.");
26287
- if (options.setProperty !== void 0) options.setProperty(receiver, key, entry);
26288
- else if (!Reflect.set(receiver, key, entry)) throw new TypeError(`Cannot assign property '${key}'.`);
26289
- return true;
26290
- },
26291
- deleteProperty: (_target, key) => {
26292
- options.budget.visitNode();
26293
- if (typeof key === "string" && options.deleteProperty !== void 0) return options.deleteProperty(receiver, key);
26294
- return Reflect.deleteProperty(receiver, key);
26295
26701
  }
26296
- });
26702
+ );
26297
26703
  arrayLikeSources.set(view, receiver);
26298
26704
  return view;
26299
26705
  }
@@ -26397,166 +26803,371 @@ async function callArrayMethodUnlocked(value, methodName, args, options, stack)
26397
26803
  );
26398
26804
  case "flat":
26399
26805
  return budgetProducedValue(
26400
- flattenArray(value, toIntegerOrInfinity(args[0] ?? 1), options.budget),
26806
+ await flattenArray(
26807
+ value,
26808
+ args[0] === void 0 ? 1 : toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context)),
26809
+ options
26810
+ ),
26401
26811
  options.budget
26402
26812
  );
26403
26813
  case "includes":
26404
- return Reflect.apply(Array.prototype.includes, value, [...args]);
26405
26814
  case "indexOf":
26406
- return Reflect.apply(Array.prototype.indexOf, value, [...args]);
26407
- case "lastIndexOf":
26408
- return Reflect.apply(Array.prototype.lastIndexOf, value, [...args]);
26409
- case "join":
26410
- return options.budget.allocateString(Reflect.apply(Array.prototype.join, value, [...args]));
26815
+ case "lastIndexOf": {
26816
+ const length = value.length;
26817
+ if (length === 0) return methodName === "includes" ? false : -1;
26818
+ const reverse = methodName === "lastIndexOf";
26819
+ const start = reverse && args.length < 2 ? length - 1 : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
26820
+ let index = reverse ? Math.min(start < 0 ? length + start : start, length - 1) : start < 0 ? Math.max(length + start, 0) : start;
26821
+ for (; index >= 0 && index < length; index += reverse ? -1 : 1) {
26822
+ options.budget.visitNode();
26823
+ if (methodName !== "includes" && !(index in value)) continue;
26824
+ const entry = await readArrayElement(value, index, options);
26825
+ if (entry === args[0] || methodName === "includes" && Number.isNaN(entry) && Number.isNaN(args[0]))
26826
+ return methodName === "includes" ? true : index;
26827
+ }
26828
+ return methodName === "includes" ? false : -1;
26829
+ }
26830
+ case "join": {
26831
+ const length = value.length;
26832
+ const separator = args[0] === void 0 ? "," : await sandboxString(args[0], options.budget, options.context);
26833
+ return joinSandboxArray(
26834
+ arrayLikeSources.get(value) ?? value,
26835
+ length,
26836
+ separator,
26837
+ options.budget,
26838
+ options.context
26839
+ );
26840
+ }
26411
26841
  case "slice": {
26412
26842
  const length = value.length;
26413
- const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
26843
+ const start = toIntegerOrInfinity(
26844
+ await sandboxNumber(args[0], options.budget, options.context)
26845
+ );
26414
26846
  const end = args[1] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context));
26415
26847
  const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
26416
26848
  const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
26417
26849
  const count = Math.max(final - first, 0);
26418
26850
  options.budget.allocateArrayLength(count);
26419
26851
  const result = new Array(count);
26420
- for (let index = 0; index < count; index += 1) {
26421
- options.budget.visitNode();
26422
- if (first + index in value) result[index] = value[first + index];
26852
+ const release = retainValues(options.budget, () => [result]);
26853
+ try {
26854
+ for (let index = 0; index < count; index += 1) {
26855
+ options.budget.visitNode();
26856
+ if (first + index in value)
26857
+ result[index] = await readArrayElement(value, first + index, options);
26858
+ }
26859
+ return budgetProducedValue(result, options.budget);
26860
+ } finally {
26861
+ release();
26862
+ }
26863
+ }
26864
+ case "concat": {
26865
+ const result = [];
26866
+ const retained = {};
26867
+ options.budget.setRetainedValues(retained, () => [result]);
26868
+ try {
26869
+ for (const entry of [value, ...args]) {
26870
+ if (!Array.isArray(entry)) {
26871
+ options.budget.allocateArrayLength(result.length + 1);
26872
+ result.push(entry);
26873
+ continue;
26874
+ }
26875
+ const start = result.length;
26876
+ const length = entry.length;
26877
+ options.budget.allocateArrayLength(start + length);
26878
+ result.length += length;
26879
+ for (let index = 0; index < length; index++) {
26880
+ options.budget.visitNode();
26881
+ if (index in entry)
26882
+ result[start + index] = await readArrayElement(entry, index, options);
26883
+ }
26884
+ }
26885
+ return budgetProducedValue(result, options.budget);
26886
+ } finally {
26887
+ options.budget.setRetainedValues(retained, void 0);
26423
26888
  }
26424
- return budgetProducedValue(result, options.budget);
26425
26889
  }
26426
- case "concat":
26427
- return budgetProducedValue(
26428
- Reflect.apply(Array.prototype.concat, value, [...args]),
26429
- options.budget
26430
- );
26431
26890
  case "splice": {
26432
- const removed = Reflect.apply(Array.prototype.splice, value, [...args]);
26891
+ const length = value.length;
26892
+ const start = toIntegerOrInfinity(
26893
+ await sandboxNumber(args[0], options.budget, options.context)
26894
+ );
26895
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
26896
+ const inserted = Math.max(args.length - 2, 0);
26897
+ const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(
26898
+ Math.max(
26899
+ toIntegerOrInfinity(
26900
+ await sandboxNumber(args[1], options.budget, options.context)
26901
+ ),
26902
+ 0
26903
+ ),
26904
+ length - first
26905
+ );
26906
+ const nextLength = length + inserted - deleted;
26907
+ if (nextLength > Number.MAX_SAFE_INTEGER)
26908
+ throw new TypeError("Array-like length exceeds the safe integer limit.");
26909
+ options.budget.allocateArrayLength(deleted);
26910
+ const removed = new Array(deleted);
26911
+ const retained = {};
26912
+ options.budget.setRetainedValues(retained, () => [removed]);
26913
+ try {
26914
+ for (let index = 0; index < deleted; index++) {
26915
+ options.budget.visitNode();
26916
+ if (first + index in value)
26917
+ removed[index] = await readArrayElement(value, first + index, options);
26918
+ }
26919
+ if (inserted < deleted) {
26920
+ for (let index = first; index < length - deleted; index++)
26921
+ await moveArrayElement(value, index + deleted, index + inserted, options);
26922
+ for (let index = length; index > nextLength; index--)
26923
+ deleteArrayElement(value, index - 1, options);
26924
+ } else if (inserted > deleted) {
26925
+ for (let index = length - deleted; index > first; index--)
26926
+ await moveArrayElement(value, index + deleted - 1, index + inserted - 1, options);
26927
+ }
26928
+ for (let index = 0; index < inserted; index++)
26929
+ await writeArrayProperty(value, first + index, args[index + 2], options);
26930
+ await writeArrayProperty(value, "length", nextLength, options);
26931
+ } finally {
26932
+ options.budget.setRetainedValues(retained, void 0);
26933
+ }
26433
26934
  budgetProducedValue(removed, options.budget);
26434
26935
  budgetProducedValue(value, options.budget);
26435
26936
  return removed;
26436
26937
  }
26437
- case "fill":
26438
- Reflect.apply(Array.prototype.fill, value, [...args]);
26938
+ case "fill": {
26939
+ const length = value.length;
26940
+ const start = toIntegerOrInfinity(
26941
+ await sandboxNumber(args[1], options.budget, options.context)
26942
+ );
26943
+ const end = args[2] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[2], options.budget, options.context));
26944
+ const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
26945
+ const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
26946
+ for (let index = first; index < final; index++)
26947
+ await writeArrayProperty(value, index, args[0], options);
26439
26948
  budgetProducedValue(value, options.budget);
26440
26949
  return value;
26441
- case "copyWithin":
26442
- Reflect.apply(Array.prototype.copyWithin, value, [...args]);
26950
+ }
26951
+ case "copyWithin": {
26952
+ const length = value.length;
26953
+ const target = toIntegerOrInfinity(
26954
+ await sandboxNumber(args[0], options.budget, options.context)
26955
+ );
26956
+ const start = toIntegerOrInfinity(
26957
+ await sandboxNumber(args[1], options.budget, options.context)
26958
+ );
26959
+ const end = args[2] === void 0 ? length : toIntegerOrInfinity(await sandboxNumber(args[2], options.budget, options.context));
26960
+ let to = target < 0 ? Math.max(length + target, 0) : Math.min(target, length);
26961
+ let from = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
26962
+ const final = end < 0 ? Math.max(length + end, 0) : Math.min(end, length);
26963
+ let count = Math.min(final - from, length - to);
26964
+ const direction = from < to && to < from + count ? -1 : 1;
26965
+ if (direction < 0) {
26966
+ from += count - 1;
26967
+ to += count - 1;
26968
+ }
26969
+ while (count-- > 0) {
26970
+ await moveArrayElement(value, from, to, options);
26971
+ from += direction;
26972
+ to += direction;
26973
+ }
26443
26974
  budgetProducedValue(value, options.budget);
26444
26975
  return value;
26445
- case "at":
26446
- return budgetProducedValue(
26447
- Reflect.apply(Array.prototype.at, value, [...args]),
26448
- options.budget
26976
+ }
26977
+ case "at": {
26978
+ const length = value.length;
26979
+ const index = toIntegerOrInfinity(
26980
+ await sandboxNumber(args[0], options.budget, options.context)
26449
26981
  );
26982
+ const actual = index < 0 ? length + index : index;
26983
+ return actual < 0 || actual >= length ? void 0 : budgetProducedValue(await readArrayElement(value, actual, options), options.budget);
26984
+ }
26450
26985
  case "sort":
26451
- if (args[0] === void 0) {
26452
- Reflect.apply(Array.prototype.sort, value, []);
26986
+ await sortArray(
26987
+ value,
26988
+ args[0] === void 0 ? void 0 : getRequiredCallback(methodName, args[0]),
26989
+ options,
26990
+ stack
26991
+ );
26992
+ budgetProducedValue(value, options.budget);
26993
+ return value;
26994
+ case "reverse": {
26995
+ const length = value.length;
26996
+ let lowerValue;
26997
+ let upperValue;
26998
+ const release = retainValues(options.budget, () => [lowerValue, upperValue]);
26999
+ try {
27000
+ for (let lower = 0; lower < Math.floor(length / 2); lower++) {
27001
+ options.budget.visitNode();
27002
+ lowerValue = upperValue = void 0;
27003
+ const upper = length - lower - 1;
27004
+ const lowerExists = lower in value;
27005
+ lowerValue = lowerExists ? await readArrayElement(value, lower, options) : void 0;
27006
+ const upperExists = upper in value;
27007
+ upperValue = upperExists ? await readArrayElement(value, upper, options) : void 0;
27008
+ if (lowerExists && upperExists) {
27009
+ await writeArrayProperty(value, lower, upperValue, options);
27010
+ await writeArrayProperty(value, upper, lowerValue, options);
27011
+ } else if (!lowerExists && upperExists) {
27012
+ await writeArrayProperty(value, lower, upperValue, options);
27013
+ deleteArrayElement(value, upper, options);
27014
+ } else if (lowerExists) {
27015
+ deleteArrayElement(value, lower, options);
27016
+ await writeArrayProperty(value, upper, lowerValue, options);
27017
+ }
27018
+ }
26453
27019
  budgetProducedValue(value, options.budget);
26454
27020
  return value;
27021
+ } finally {
27022
+ release();
26455
27023
  }
26456
- await sortArray(value, getRequiredCallback(methodName, args[0]), options, stack);
26457
- budgetProducedValue(value, options.budget);
26458
- return value;
26459
- case "reverse":
26460
- Reflect.apply(Array.prototype.reverse, value, []);
26461
- budgetProducedValue(value, options.budget);
26462
- return value;
27024
+ }
26463
27025
  case "toSorted": {
26464
27026
  const length = value.length;
26465
27027
  options.budget.allocateArrayLength(length);
26466
27028
  const result = new Array(length);
26467
- for (let index = 0; index < length; index += 1) {
26468
- options.budget.visitNode();
26469
- result[index] = value[index];
26470
- }
26471
- if (args[0] === void 0) {
26472
- result.sort();
26473
- } else {
26474
- await sortArray(result, getRequiredCallback(methodName, args[0]), options, stack);
27029
+ const release = retainValues(options.budget, () => [result]);
27030
+ try {
27031
+ for (let index = 0; index < length; index += 1) {
27032
+ options.budget.visitNode();
27033
+ result[index] = await readArrayElement(value, index, options);
27034
+ }
27035
+ await sortArray(
27036
+ result,
27037
+ args[0] === void 0 ? void 0 : getRequiredCallback(methodName, args[0]),
27038
+ options,
27039
+ stack
27040
+ );
27041
+ return budgetProducedValue(result, options.budget);
27042
+ } finally {
27043
+ release();
26475
27044
  }
26476
- return budgetProducedValue(result, options.budget);
26477
27045
  }
26478
27046
  case "toReversed": {
26479
27047
  const length = value.length;
26480
27048
  options.budget.allocateArrayLength(length);
26481
27049
  const result = new Array(length);
26482
- for (let index = 0; index < length; index += 1) {
26483
- options.budget.visitNode();
26484
- result[index] = value[length - index - 1];
27050
+ const release = retainValues(options.budget, () => [result]);
27051
+ try {
27052
+ for (let index = 0; index < length; index += 1) {
27053
+ options.budget.visitNode();
27054
+ result[index] = await readArrayElement(value, length - index - 1, options);
27055
+ }
27056
+ return budgetProducedValue(result, options.budget);
27057
+ } finally {
27058
+ release();
26485
27059
  }
26486
- return budgetProducedValue(result, options.budget);
26487
27060
  }
26488
27061
  case "toSpliced": {
26489
27062
  const length = value.length;
26490
- const start = toIntegerOrInfinity(await sandboxNumber(args[0], options.budget, options.context));
27063
+ const start = toIntegerOrInfinity(
27064
+ await sandboxNumber(args[0], options.budget, options.context)
27065
+ );
26491
27066
  const first = start < 0 ? Math.max(length + start, 0) : Math.min(start, length);
26492
27067
  const inserted = Math.max(args.length - 2, 0);
26493
- const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(Math.max(toIntegerOrInfinity(await sandboxNumber(args[1], options.budget, options.context)), 0), length - first);
27068
+ const deleted = args.length === 0 ? 0 : args.length === 1 ? length - first : Math.min(
27069
+ Math.max(
27070
+ toIntegerOrInfinity(
27071
+ await sandboxNumber(args[1], options.budget, options.context)
27072
+ ),
27073
+ 0
27074
+ ),
27075
+ length - first
27076
+ );
26494
27077
  const resultLength = length + inserted - deleted;
26495
- if (resultLength > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
27078
+ if (resultLength > Number.MAX_SAFE_INTEGER)
27079
+ throw new TypeError("Array-like length exceeds the safe integer limit.");
26496
27080
  options.budget.allocateArrayLength(resultLength);
26497
27081
  const result = new Array(resultLength);
26498
- for (let index = 0; index < resultLength; index += 1) {
26499
- options.budget.visitNode();
26500
- result[index] = index < first ? value[index] : index < first + inserted ? args[index - first + 2] : value[index - inserted + deleted];
27082
+ const release = retainValues(options.budget, () => [result]);
27083
+ try {
27084
+ for (let index = 0; index < resultLength; index += 1) {
27085
+ options.budget.visitNode();
27086
+ result[index] = index < first ? await readArrayElement(value, index, options) : index < first + inserted ? args[index - first + 2] : await readArrayElement(value, index - inserted + deleted, options);
27087
+ }
27088
+ return budgetProducedValue(result, options.budget);
27089
+ } finally {
27090
+ release();
26501
27091
  }
26502
- return budgetProducedValue(result, options.budget);
26503
27092
  }
26504
27093
  case "with": {
26505
27094
  const length = value.length;
26506
- const index = toIntegerOrInfinity(args[0]);
27095
+ const index = toIntegerOrInfinity(
27096
+ options.context === void 0 ? args[0] : await sandboxNumber(args[0], options.budget, options.context)
27097
+ );
26507
27098
  const actualIndex = index < 0 ? length + index : index;
26508
27099
  if (actualIndex < 0 || actualIndex >= length) {
26509
27100
  throw new RangeError("Invalid index");
26510
27101
  }
26511
27102
  options.budget.allocateArrayLength(length);
26512
27103
  const result = [];
26513
- for (let position = 0; position < length; position += 1) {
26514
- options.budget.visitNode();
26515
- result[position] = position === actualIndex ? args[1] : Array.isArray(value) && !Object.hasOwn(value, position) ? void 0 : value[position];
27104
+ const release = retainValues(options.budget, () => [result]);
27105
+ try {
27106
+ for (let position = 0; position < length; position += 1) {
27107
+ options.budget.visitNode();
27108
+ result[position] = position === actualIndex ? args[1] : await readArrayElement(value, position, options);
27109
+ }
27110
+ return budgetProducedValue(result, options.budget);
27111
+ } finally {
27112
+ release();
26516
27113
  }
26517
- return budgetProducedValue(result, options.budget);
26518
27114
  }
26519
27115
  case "push": {
26520
- const nextLength = appendArrayValues(value, args);
27116
+ const nextLength = await appendArrayValues(value, args, options);
26521
27117
  budgetProducedValue(value, options.budget);
26522
27118
  return nextLength;
26523
27119
  }
26524
27120
  case "pop":
26525
- return budgetProducedValue(Reflect.apply(Array.prototype.pop, value, []), options.budget);
26526
- case "shift":
26527
- return budgetProducedValue(Reflect.apply(Array.prototype.shift, value, []), options.budget);
27121
+ case "shift": {
27122
+ const length = value.length;
27123
+ if (length === 0) {
27124
+ await writeArrayProperty(value, "length", 0, options);
27125
+ return void 0;
27126
+ }
27127
+ const result = await readArrayElement(value, methodName === "pop" ? length - 1 : 0, options);
27128
+ const retained = {};
27129
+ options.budget.setRetainedValues(retained, () => [result]);
27130
+ try {
27131
+ if (methodName === "shift")
27132
+ for (let index = 1; index < length; index++)
27133
+ await moveArrayElement(value, index, index - 1, options);
27134
+ deleteArrayElement(value, length - 1, options);
27135
+ await writeArrayProperty(value, "length", length - 1, options);
27136
+ return budgetProducedValue(result, options.budget);
27137
+ } finally {
27138
+ options.budget.setRetainedValues(retained, void 0);
27139
+ }
27140
+ }
26528
27141
  case "unshift": {
26529
- const nextLength = prependArrayValues(value, args);
27142
+ const nextLength = await prependArrayValues(value, args, options);
26530
27143
  budgetProducedValue(value, options.budget);
26531
27144
  return nextLength;
26532
27145
  }
26533
27146
  }
26534
27147
  }
26535
- function appendArrayValues(target, values) {
27148
+ async function appendArrayValues(target, values, options) {
26536
27149
  let length = target.length;
26537
- if (length + values.length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
27150
+ if (length + values.length > Number.MAX_SAFE_INTEGER)
27151
+ throw new TypeError("Array-like length exceeds the safe integer limit.");
26538
27152
  for (const value of values) {
26539
- target[length++] = value;
27153
+ await writeArrayProperty(target, length++, value, options);
26540
27154
  }
26541
- target.length = length;
27155
+ await writeArrayProperty(target, "length", length, options);
26542
27156
  return length;
26543
27157
  }
26544
- function prependArrayValues(target, values) {
27158
+ async function prependArrayValues(target, values, options) {
26545
27159
  const originalLength = target.length;
26546
27160
  const length = originalLength + values.length;
26547
- if (length > Number.MAX_SAFE_INTEGER) throw new TypeError("Array-like length exceeds the safe integer limit.");
27161
+ if (length > Number.MAX_SAFE_INTEGER)
27162
+ throw new TypeError("Array-like length exceeds the safe integer limit.");
26548
27163
  for (let index = values.length === 0 ? -1 : originalLength - 1; index >= 0; index -= 1) {
26549
27164
  const targetIndex = index + values.length;
26550
- if (index in target) {
26551
- target[targetIndex] = target[index];
26552
- } else {
26553
- delete target[targetIndex];
26554
- }
27165
+ await moveArrayElement(target, index, targetIndex, options);
26555
27166
  }
26556
27167
  for (let index = 0; index < values.length; index += 1) {
26557
- target[index] = values[index];
27168
+ await writeArrayProperty(target, index, values[index], options);
26558
27169
  }
26559
- target.length = length;
27170
+ await writeArrayProperty(target, "length", length, options);
26560
27171
  return length;
26561
27172
  }
26562
27173
  function isCallbackArrayMethod(methodName) {
@@ -26571,6 +27182,33 @@ function getRequiredCallback(methodName, value) {
26571
27182
  }
26572
27183
  return value;
26573
27184
  }
27185
+ function readArrayElement(value, index, options) {
27186
+ const receiver = arrayLikeSources.get(value) ?? value;
27187
+ return options.context?.getProperty !== void 0 ? options.context.getProperty(receiver, index) : getSandboxDataProperty(receiver, index, options.budget);
27188
+ }
27189
+ function writeArrayProperty(value, key, entry, options) {
27190
+ options.budget.visitNode();
27191
+ const receiver = arrayLikeSources.get(value) ?? value;
27192
+ if (Array.isArray(receiver)) {
27193
+ if (key === "length") options.budget.allocateArrayLength(Number(entry));
27194
+ else if (typeof key === "number") options.budget.allocateArrayLength(key + 1);
27195
+ }
27196
+ if (options.setProperty !== void 0) return options.setProperty(receiver, String(key), entry);
27197
+ if (!Reflect.set(receiver, key, entry))
27198
+ throw new TypeError(`Cannot assign to read only property '${key}'.`);
27199
+ }
27200
+ function deleteArrayElement(value, index, options) {
27201
+ options.budget.visitNode();
27202
+ const receiver = arrayLikeSources.get(value) ?? value;
27203
+ const deleted = options.deleteProperty === void 0 ? Reflect.deleteProperty(receiver, String(index)) : options.deleteProperty(receiver, String(index));
27204
+ if (!deleted) throw new TypeError(`Cannot delete property '${index}'.`);
27205
+ }
27206
+ async function moveArrayElement(value, from, to, options) {
27207
+ options.budget.visitNode();
27208
+ if (from in value)
27209
+ await writeArrayProperty(value, to, await readArrayElement(value, from, options), options);
27210
+ else deleteArrayElement(value, to, options);
27211
+ }
26574
27212
  async function mapArray(value, callback, options, stack, thisValue) {
26575
27213
  const length = value.length;
26576
27214
  options.budget.allocateArrayLength(length);
@@ -26584,7 +27222,7 @@ async function mapArray(value, callback, options, stack, thisValue) {
26584
27222
  }
26585
27223
  result[index] = await callArrayCallback(
26586
27224
  callback,
26587
- value[index],
27225
+ await readArrayElement(value, index, options),
26588
27226
  index,
26589
27227
  value,
26590
27228
  options,
@@ -26607,7 +27245,7 @@ async function filterArray(value, callback, options, stack, thisValue) {
26607
27245
  if (!(index in value)) {
26608
27246
  continue;
26609
27247
  }
26610
- const entry = value[index];
27248
+ const entry = await readArrayElement(value, index, options);
26611
27249
  if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
26612
27250
  result.push(entry);
26613
27251
  }
@@ -26621,7 +27259,7 @@ async function findInArray(value, callback, options, stack, thisValue) {
26621
27259
  const length = value.length;
26622
27260
  for (let index = 0; index < length; index += 1) {
26623
27261
  options.budget.visitNode();
26624
- const entry = index in value ? value[index] : void 0;
27262
+ const entry = await readArrayElement(value, index, options);
26625
27263
  if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
26626
27264
  return entry;
26627
27265
  }
@@ -26632,7 +27270,7 @@ async function findIndexInArray(value, callback, options, stack, thisValue) {
26632
27270
  const length = value.length;
26633
27271
  for (let index = 0; index < length; index += 1) {
26634
27272
  options.budget.visitNode();
26635
- const entry = index in value ? value[index] : void 0;
27273
+ const entry = await readArrayElement(value, index, options);
26636
27274
  if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
26637
27275
  return index;
26638
27276
  }
@@ -26643,7 +27281,7 @@ async function findLastInArray(value, callback, options, stack, thisValue) {
26643
27281
  const length = value.length;
26644
27282
  for (let index = length - 1; index >= 0; index -= 1) {
26645
27283
  options.budget.visitNode();
26646
- const entry = index in value ? value[index] : void 0;
27284
+ const entry = await readArrayElement(value, index, options);
26647
27285
  if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
26648
27286
  return entry;
26649
27287
  }
@@ -26654,7 +27292,7 @@ async function findLastIndexInArray(value, callback, options, stack, thisValue)
26654
27292
  const length = value.length;
26655
27293
  for (let index = length - 1; index >= 0; index -= 1) {
26656
27294
  options.budget.visitNode();
26657
- const entry = index in value ? value[index] : void 0;
27295
+ const entry = await readArrayElement(value, index, options);
26658
27296
  if (await callArrayCallback(callback, entry, index, value, options, stack, thisValue)) {
26659
27297
  return index;
26660
27298
  }
@@ -26668,7 +27306,15 @@ async function someInArray(value, callback, options, stack, thisValue) {
26668
27306
  if (!(index in value)) {
26669
27307
  continue;
26670
27308
  }
26671
- if (await callArrayCallback(callback, value[index], index, value, options, stack, thisValue)) {
27309
+ if (await callArrayCallback(
27310
+ callback,
27311
+ await readArrayElement(value, index, options),
27312
+ index,
27313
+ value,
27314
+ options,
27315
+ stack,
27316
+ thisValue
27317
+ )) {
26672
27318
  return true;
26673
27319
  }
26674
27320
  }
@@ -26681,7 +27327,15 @@ async function everyInArray(value, callback, options, stack, thisValue) {
26681
27327
  if (!(index in value)) {
26682
27328
  continue;
26683
27329
  }
26684
- if (!await callArrayCallback(callback, value[index], index, value, options, stack, thisValue)) {
27330
+ if (!await callArrayCallback(
27331
+ callback,
27332
+ await readArrayElement(value, index, options),
27333
+ index,
27334
+ value,
27335
+ options,
27336
+ stack,
27337
+ thisValue
27338
+ )) {
26685
27339
  return false;
26686
27340
  }
26687
27341
  }
@@ -26696,7 +27350,15 @@ async function reduceArray(value, callback, hasInitialValue, initialValue, optio
26696
27350
  if (start < 0) {
26697
27351
  throw new TypeError("Reduce of empty array with no initial value.");
26698
27352
  }
26699
- return reduceFromLeft(value, callback, value[start], start + 1, length, options, stack);
27353
+ return reduceFromLeft(
27354
+ value,
27355
+ callback,
27356
+ await readArrayElement(value, start, options),
27357
+ start + 1,
27358
+ length,
27359
+ options,
27360
+ stack
27361
+ );
26700
27362
  }
26701
27363
  async function reduceRightArray(value, callback, hasInitialValue, initialValue, options, stack) {
26702
27364
  const length = value.length;
@@ -26707,7 +27369,15 @@ async function reduceRightArray(value, callback, hasInitialValue, initialValue,
26707
27369
  if (start < 0) {
26708
27370
  throw new TypeError("Reduce of empty array with no initial value.");
26709
27371
  }
26710
- return reduceFromRight(value, callback, value[start], start - 1, length, options, stack);
27372
+ return reduceFromRight(
27373
+ value,
27374
+ callback,
27375
+ await readArrayElement(value, start, options),
27376
+ start - 1,
27377
+ length,
27378
+ options,
27379
+ stack
27380
+ );
26711
27381
  }
26712
27382
  async function reduceFromLeft(value, callback, accumulator, startIndex, length, options, stack) {
26713
27383
  let current = accumulator;
@@ -26719,7 +27389,16 @@ async function reduceFromLeft(value, callback, accumulator, startIndex, length,
26719
27389
  if (!(index in value)) {
26720
27390
  continue;
26721
27391
  }
26722
- current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
27392
+ current = await options.callClosure(
27393
+ callback,
27394
+ [
27395
+ current,
27396
+ await readArrayElement(value, index, options),
27397
+ index,
27398
+ arrayLikeSources.get(value) ?? value
27399
+ ],
27400
+ stack
27401
+ );
26723
27402
  }
26724
27403
  return current;
26725
27404
  } finally {
@@ -26736,7 +27415,16 @@ async function reduceFromRight(value, callback, accumulator, startIndex, length,
26736
27415
  if (!(index in value)) {
26737
27416
  continue;
26738
27417
  }
26739
- current = await options.callClosure(callback, [current, value[index], index, arrayLikeSources.get(value) ?? value], stack);
27418
+ current = await options.callClosure(
27419
+ callback,
27420
+ [
27421
+ current,
27422
+ await readArrayElement(value, index, options),
27423
+ index,
27424
+ arrayLikeSources.get(value) ?? value
27425
+ ],
27426
+ stack
27427
+ );
26740
27428
  }
26741
27429
  return current;
26742
27430
  } finally {
@@ -26750,7 +27438,15 @@ async function forEachArray(value, callback, options, stack, thisValue) {
26750
27438
  if (!(index in value)) {
26751
27439
  continue;
26752
27440
  }
26753
- await callArrayCallback(callback, value[index], index, value, options, stack, thisValue);
27441
+ await callArrayCallback(
27442
+ callback,
27443
+ await readArrayElement(value, index, options),
27444
+ index,
27445
+ value,
27446
+ options,
27447
+ stack,
27448
+ thisValue
27449
+ );
26754
27450
  }
26755
27451
  }
26756
27452
  async function flatMapArray(value, callback, options, stack, thisValue) {
@@ -26765,7 +27461,7 @@ async function flatMapArray(value, callback, options, stack, thisValue) {
26765
27461
  }
26766
27462
  const mapped = await callArrayCallback(
26767
27463
  callback,
26768
- value[index],
27464
+ await readArrayElement(value, index, options),
26769
27465
  index,
26770
27466
  value,
26771
27467
  options,
@@ -26778,7 +27474,7 @@ async function flatMapArray(value, callback, options, stack, thisValue) {
26778
27474
  if (!(mappedIndex in mapped)) {
26779
27475
  continue;
26780
27476
  }
26781
- result.push(mapped[mappedIndex]);
27477
+ result.push(await readArrayElement(mapped, mappedIndex, options));
26782
27478
  options.budget.allocateArrayLength(result.length);
26783
27479
  }
26784
27480
  continue;
@@ -26791,23 +27487,31 @@ async function flatMapArray(value, callback, options, stack, thisValue) {
26791
27487
  options.budget.setRetainedValues(result, void 0);
26792
27488
  }
26793
27489
  }
26794
- function flattenArray(value, depth, budget) {
27490
+ async function flattenArray(value, depth, options) {
26795
27491
  const result = [];
26796
- appendFlattenedEntries(value, depth, result, budget);
26797
- return result;
27492
+ const retained = {};
27493
+ options.budget.setRetainedValues(retained, () => [result]);
27494
+ try {
27495
+ await appendFlattenedEntries(value, depth, result, options);
27496
+ return result;
27497
+ } finally {
27498
+ options.budget.setRetainedValues(retained, void 0);
27499
+ }
26798
27500
  }
26799
- function appendFlattenedEntries(value, depth, result, budget) {
26800
- for (let index = 0; index < value.length; index += 1) {
27501
+ async function appendFlattenedEntries(value, depth, result, options) {
27502
+ const length = value.length;
27503
+ for (let index = 0; index < length; index += 1) {
27504
+ options.budget.visitNode();
26801
27505
  if (!(index in value)) {
26802
27506
  continue;
26803
27507
  }
26804
- const entry = value[index];
27508
+ const entry = await readArrayElement(value, index, options);
26805
27509
  if (depth > 0 && Array.isArray(entry)) {
26806
- appendFlattenedEntries(entry, depth - 1, result, budget);
27510
+ await appendFlattenedEntries(entry, depth - 1, result, options);
26807
27511
  continue;
26808
27512
  }
26809
27513
  result.push(entry);
26810
- budget.allocateArrayLength(result.length);
27514
+ options.budget.allocateArrayLength(result.length);
26811
27515
  }
26812
27516
  }
26813
27517
  async function sortArray(value, comparator, options, stack) {
@@ -26822,7 +27526,7 @@ async function sortArray(value, comparator, options, stack) {
26822
27526
  if (!(index in value)) {
26823
27527
  continue;
26824
27528
  }
26825
- const entry = value[index];
27529
+ const entry = await readArrayElement(value, index, options);
26826
27530
  if (entry === void 0) {
26827
27531
  undefinedCount += 1;
26828
27532
  continue;
@@ -26840,14 +27544,14 @@ async function sortArray(value, comparator, options, stack) {
26840
27544
  }
26841
27545
  currentEntry = void 0;
26842
27546
  for (let index = 0; index < definedValues.length; index += 1) {
26843
- value[index] = definedValues[index];
27547
+ await writeArrayProperty(value, index, definedValues[index], options);
26844
27548
  }
26845
27549
  for (let index = 0; index < undefinedCount; index += 1) {
26846
- value[definedValues.length + index] = void 0;
27550
+ await writeArrayProperty(value, definedValues.length + index, void 0, options);
26847
27551
  }
26848
27552
  for (let index = definedValues.length + undefinedCount; index < length; index += 1) {
26849
27553
  options.budget.visitNode();
26850
- delete value[index];
27554
+ deleteArrayElement(value, index, options);
26851
27555
  }
26852
27556
  } finally {
26853
27557
  options.budget.setRetainedValues(definedValues, void 0);
@@ -26855,11 +27559,30 @@ async function sortArray(value, comparator, options, stack) {
26855
27559
  }
26856
27560
  async function compareEntries(left, right, comparator, options, stack) {
26857
27561
  options.budget.visitNode();
26858
- const result = Number(await options.callClosure(comparator, [left, right], stack));
27562
+ if (comparator === void 0) {
27563
+ const leftString = await sandboxString(left, options.budget, options.context);
27564
+ const release = retainValues(options.budget, () => [leftString]);
27565
+ try {
27566
+ const rightString = await sandboxString(right, options.budget, options.context);
27567
+ return leftString < rightString ? -1 : leftString > rightString ? 1 : 0;
27568
+ } finally {
27569
+ release();
27570
+ }
27571
+ }
27572
+ const result = await sandboxNumber(
27573
+ await options.callClosure(comparator, [left, right], stack),
27574
+ options.budget,
27575
+ options.context
27576
+ );
26859
27577
  return Number.isNaN(result) ? 0 : result;
26860
27578
  }
26861
27579
  async function callArrayCallback(callback, value, index, array, options, stack, thisValue) {
26862
- return options.callClosure(callback, [value, index, arrayLikeSources.get(array) ?? array], stack, thisValue);
27580
+ return options.callClosure(
27581
+ callback,
27582
+ [value, index, arrayLikeSources.get(array) ?? array],
27583
+ stack,
27584
+ thisValue
27585
+ );
26863
27586
  }
26864
27587
  function findNextDefinedIndex(value, startIndex, direction, length, budget) {
26865
27588
  for (let index = startIndex; direction > 0 ? index < length : index >= 0; index += direction) {
@@ -26944,7 +27667,8 @@ function getFunctionMember(target, property, options) {
26944
27667
  while (current !== null) {
26945
27668
  if (isGuestClosure(current)) {
26946
27669
  const value = getGuestFunctionProperty(current, String(property));
26947
- if (value !== void 0 || Object.hasOwn(current.properties ?? {}, String(property))) return value;
27670
+ if (value !== void 0 || Object.hasOwn(current.properties ?? {}, String(property)))
27671
+ return value;
26948
27672
  } else if (isSandboxClosure(current)) {
26949
27673
  if (current.properties !== void 0 && Object.hasOwn(current.properties, String(property)))
26950
27674
  return current.properties[String(property)];
@@ -26960,7 +27684,8 @@ function getFunctionMember(target, property, options) {
26960
27684
  }
26961
27685
  }
26962
27686
  if (current === null) return void 0;
26963
- if (property === "toString" && runResources.getStore()?.functionSourceText === false) return void 0;
27687
+ if (property === "toString" && runResources.getStore()?.functionSourceText === false)
27688
+ return void 0;
26964
27689
  if (!isFunctionMethodName(property)) {
26965
27690
  return void 0;
26966
27691
  }
@@ -26968,13 +27693,13 @@ function getFunctionMember(target, property, options) {
26968
27693
  sandbox: true,
26969
27694
  name: `Function#${property}`,
26970
27695
  ...property === "toString" ? { length: 0 } : {},
26971
- call: (args, context) => callFunctionMethod(context?.thisValue, property, args, options, context?.stack ?? [])
27696
+ call: (args, context) => callFunctionMethod(context?.thisValue, property, args, options, context?.stack ?? [], context)
26972
27697
  });
26973
27698
  }
26974
27699
  function isFunctionMethodName(property) {
26975
27700
  return typeof property === "string" && functionMethodNames.has(property);
26976
27701
  }
26977
- function callFunctionMethod(target, methodName, args, options, stack) {
27702
+ function callFunctionMethod(target, methodName, args, options, stack, context) {
26978
27703
  if (!isSandboxClosure(target)) {
26979
27704
  throw new TypeError(`Function#${methodName} requires a callable receiver.`);
26980
27705
  }
@@ -26985,28 +27710,46 @@ function callFunctionMethod(target, methodName, args, options, stack) {
26985
27710
  const thisValue = args[0];
26986
27711
  if (methodName === "bind") {
26987
27712
  const boundArgs = args.slice(1);
26988
- const bound = createSandboxClosure({
26989
- guest: true,
26990
- sandbox: true,
26991
- name: `bound ${target.name ?? ""}`,
26992
- length: target.length === void 0 ? void 0 : Math.max(0, target.length - boundArgs.length),
26993
- boundTarget: target,
26994
- retainedValues: () => [target, thisValue, ...boundArgs],
26995
- call: (callArgs, context) => options.callClosure(target, [...boundArgs, ...callArgs], context?.stack ?? [], thisValue),
26996
- ...target.construct === void 0 ? {} : {
26997
- construct: (callArgs, context) => options.callClosure(
26998
- target,
26999
- [...boundArgs, ...callArgs],
27000
- context?.stack ?? [],
27001
- void 0,
27002
- true,
27003
- context?.newTarget === bound ? target : context?.newTarget
27004
- )
27005
- }
27006
- });
27007
- if (hasExplicitSandboxPrototype(target))
27008
- setSandboxPrototype(bound, getSandboxPrototype(target, options.budget), options.budget);
27009
- return bound;
27713
+ const bind = (length, name) => {
27714
+ const bound = createSandboxClosure({
27715
+ guest: true,
27716
+ sandbox: true,
27717
+ name: `bound ${name}`,
27718
+ length,
27719
+ boundTarget: target,
27720
+ retainedValues: () => [target, thisValue, ...boundArgs, bound.name],
27721
+ call: (callArgs, context2) => options.callClosure(target, [...boundArgs, ...callArgs], context2?.stack ?? [], thisValue),
27722
+ ...target.construct === void 0 ? {} : {
27723
+ construct: (callArgs, context2) => options.callClosure(
27724
+ target,
27725
+ [...boundArgs, ...callArgs],
27726
+ context2?.stack ?? [],
27727
+ void 0,
27728
+ true,
27729
+ context2?.newTarget === bound ? target : context2?.newTarget
27730
+ )
27731
+ }
27732
+ });
27733
+ if (hasExplicitSandboxPrototype(target))
27734
+ setSandboxPrototype(bound, getSandboxPrototype(target, options.budget), options.budget);
27735
+ return bound;
27736
+ };
27737
+ if (context?.getProperty === void 0)
27738
+ return bind(
27739
+ target.length === void 0 ? void 0 : Math.max(0, target.length - boundArgs.length),
27740
+ target.name ?? ""
27741
+ );
27742
+ return (async () => {
27743
+ const properties = target.properties;
27744
+ const defaultName = target.name;
27745
+ const hasLength = !isGuestClosure(target) || target.properties === void 0 || Object.hasOwn(target.properties, "length");
27746
+ const length = hasLength ? await context.getProperty(target, "length") : void 0;
27747
+ const name = !isGuestClosure(target) && !Object.hasOwn(properties ?? {}, "name") ? defaultName : await context.getProperty(target, "name");
27748
+ return bind(
27749
+ typeof length === "number" && !Number.isNaN(length) ? Math.max(0, Math.trunc(length) - boundArgs.length) : 0,
27750
+ typeof name === "string" ? name : ""
27751
+ );
27752
+ })();
27010
27753
  }
27011
27754
  if (methodName === "call") {
27012
27755
  return options.callClosure(target, args.slice(1), stack, thisValue);
@@ -27018,7 +27761,24 @@ function callFunctionMethod(target, methodName, args, options, stack) {
27018
27761
  if (!Array.isArray(applyArgs)) {
27019
27762
  throw new TypeError("Function#apply requires an array or nullish arguments value.");
27020
27763
  }
27021
- return options.callClosure(target, applyArgs, stack, thisValue);
27764
+ if (context?.getProperty === void 0)
27765
+ return options.callClosure(target, applyArgs, stack, thisValue);
27766
+ return (async () => {
27767
+ const values = [];
27768
+ const length = applyArgs.length;
27769
+ options.budget?.allocateArrayLength(length);
27770
+ const retained = {};
27771
+ options.budget?.setRetainedValues(retained, () => values);
27772
+ try {
27773
+ for (let index = 0; index < length; index++) {
27774
+ options.budget?.visitNode();
27775
+ values.push(await context.getProperty(applyArgs, index));
27776
+ }
27777
+ return await options.callClosure(target, values, stack, thisValue);
27778
+ } finally {
27779
+ options.budget?.setRetainedValues(retained, void 0);
27780
+ }
27781
+ })();
27022
27782
  }
27023
27783
 
27024
27784
  // packages/safe-js/src/interp/methods/collection-callback.ts
@@ -27330,15 +28090,24 @@ function createCollectionGlobals(options) {
27330
28090
  context,
27331
28091
  retainedValues: () => [key, value],
27332
28092
  append: (entry) => {
27333
- if (typeof entry !== "object" || entry === null) throw new TypeError("Map constructor requires entry objects.");
27334
- key = context?.getProperty !== void 0 ? context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, options.budget);
27335
- value = context?.getProperty !== void 0 ? context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, options.budget);
27336
- const added = map.entries.has(key) ? 0 : 1;
27337
- const growth = added + (options.budget.limits.dataSize === void 0 ? 0 : measureSandboxData([key, value]));
27338
- options.budget.allocateCollectionEntries(map.entries.size + added);
27339
- map.entries.set(key, value);
27340
- key = value = void 0;
27341
- return growth;
28093
+ if (typeof entry !== "object" || entry === null)
28094
+ throw new TypeError("Map constructor requires entry objects.");
28095
+ const store = (entryValue) => {
28096
+ value = entryValue;
28097
+ const added = map.entries.has(key) ? 0 : 1;
28098
+ const growth = added + (options.budget.limits.dataSize === void 0 ? 0 : measureSandboxData([key, value]));
28099
+ options.budget.allocateCollectionEntries(map.entries.size + added);
28100
+ map.entries.set(key, value);
28101
+ key = value = void 0;
28102
+ return growth;
28103
+ };
28104
+ const readValue = (entryKey) => {
28105
+ key = entryKey;
28106
+ const result2 = context?.getProperty !== void 0 ? context.getProperty(entry, 1) : getSandboxDataProperty(entry, 1, options.budget);
28107
+ return result2 instanceof Promise ? result2.then(store) : store(result2);
28108
+ };
28109
+ const result = context?.getProperty !== void 0 ? context.getProperty(entry, 0) : getSandboxDataProperty(entry, 0, options.budget);
28110
+ return result instanceof Promise ? result.then(readValue) : readValue(result);
27342
28111
  }
27343
28112
  });
27344
28113
  },
@@ -27376,7 +28145,13 @@ function isSandboxMapConstructor(value) {
27376
28145
  function isSandboxSetConstructor(value) {
27377
28146
  return typeof value === "object" && value !== null && setConstructors.has(value);
27378
28147
  }
27379
- function populateCollection(source, collection, { name, budget, context, append, retainedValues }) {
28148
+ function populateCollection(source, collection, {
28149
+ name,
28150
+ budget,
28151
+ context,
28152
+ append,
28153
+ retainedValues
28154
+ }) {
27380
28155
  budget.allocateCollectionEntries(0);
27381
28156
  if (source === void 0 || source === null) return collection;
27382
28157
  const iterator = getSandboxIterator(source, budget, context);
@@ -27384,7 +28159,14 @@ function populateCollection(source, collection, { name, budget, context, append,
27384
28159
  let entry;
27385
28160
  let failure;
27386
28161
  const retained = {};
27387
- budget.setRetainedValues(retained, () => [source, iterator.retainedValue, collection, entry, failure, ...retainedValues?.() ?? []]);
28162
+ budget.setRetainedValues(retained, () => [
28163
+ source,
28164
+ iterator.retainedValue,
28165
+ collection,
28166
+ entry,
28167
+ failure,
28168
+ ...retainedValues?.() ?? []
28169
+ ]);
27388
28170
  const checkData = createDataCheckpoint(budget, context);
27389
28171
  const closeOnThrow = (error) => {
27390
28172
  failure = isCapturedException(error) ? error.reason : error;
@@ -27394,21 +28176,29 @@ function populateCollection(source, collection, { name, budget, context, append,
27394
28176
  };
27395
28177
  try {
27396
28178
  const closing = iterator.return?.();
27397
- if (iterator.generator || iterator.asynchronous) return Promise.resolve(closing).then(() => {
27398
- throw error;
27399
- }, rethrow);
28179
+ if (iterator.generator || iterator.asynchronous)
28180
+ return Promise.resolve(closing).then(() => {
28181
+ throw error;
28182
+ }, rethrow);
27400
28183
  } catch (closeError) {
27401
28184
  return rethrow(closeError);
27402
28185
  }
27403
28186
  throw error;
27404
28187
  };
27405
28188
  const consume = (result) => {
27406
- if (typeof result !== "object" || result === null) throw new TypeError("Iterator result must be an object.");
28189
+ if (typeof result !== "object" || result === null)
28190
+ throw new TypeError("Iterator result must be an object.");
27407
28191
  if (result.done) return true;
27408
28192
  entry = result.value;
27409
28193
  try {
27410
28194
  budget.visitNode();
27411
28195
  const growth = append(entry);
28196
+ if (growth instanceof Promise)
28197
+ return growth.then((size) => {
28198
+ entry = void 0;
28199
+ checkData(collection, size);
28200
+ return false;
28201
+ }).catch(closeOnThrow);
27412
28202
  entry = void 0;
27413
28203
  checkData(collection, growth);
27414
28204
  } catch (error) {
@@ -27416,7 +28206,7 @@ function populateCollection(source, collection, { name, budget, context, append,
27416
28206
  }
27417
28207
  return false;
27418
28208
  };
27419
- if (iterator.generator || iterator.asynchronous) {
28209
+ if (iterator.generator || iterator.asynchronous || context !== void 0) {
27420
28210
  return (async () => {
27421
28211
  try {
27422
28212
  checkData(collection, 0, true);
@@ -28220,7 +29010,8 @@ async function evaluateTaggedTemplateExpression(node, context) {
28220
29010
  if (node.tag.type === "MemberExpression") return evaluateMemberAccess(node.tag, context, async (member) => {
28221
29011
  if (member.kind === "nullish") throw new TypeError("Tagged template tag must be a function.");
28222
29012
  const key = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
28223
- return invokeTag(getPropertyValue(member.object, key, context), member.superReceiver === void 0 ? member.object : member.superReceiver.value);
29013
+ const receiver = member.superReceiver === void 0 ? member.object : member.superReceiver.value;
29014
+ return invokeTag(await getPropertyValue(member.object, key, context, receiver), receiver);
28224
29015
  });
28225
29016
  const tag = await evaluateNode(node.tag, context);
28226
29017
  return tag.kind === "normal" ? invokeTag(tag.value, void 0) : tag;
@@ -28315,7 +29106,8 @@ async function evaluateBinaryExpression(node, context) {
28315
29106
  if (isSandboxBox(rightValue) && (!equality || left.value !== null && left.value !== void 0 && typeof left.value !== "object"))
28316
29107
  rightValue = await toNumericPrimitive(rightValue, context);
28317
29108
  }
28318
- const value = applyBinaryOperator(node, leftValue, rightValue, context);
29109
+ const operation = applyBinaryOperator(node, leftValue, rightValue, context);
29110
+ const value = operation instanceof Promise ? await operation : operation;
28319
29111
  return {
28320
29112
  kind: "normal",
28321
29113
  hasValue: true,
@@ -28406,8 +29198,17 @@ async function evaluateMemberAssignmentExpression(node, context) {
28406
29198
  if (member.object === null || member.object === void 0) {
28407
29199
  throw new TypeError("Cannot assign properties of null or undefined.");
28408
29200
  }
28409
- property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
28410
- current = getPropertyValue(member.object, property, context);
29201
+ property = await toPropertyKey(
29202
+ member.property,
29203
+ context.budget,
29204
+ createCoercionContext(context)
29205
+ );
29206
+ current = await getPropertyValue(
29207
+ member.object,
29208
+ property,
29209
+ context,
29210
+ member.superReceiver === void 0 ? member.object : member.superReceiver.value
29211
+ );
28411
29212
  }
28412
29213
  if (node.operator === "&&=" && !isTruthy(current)) {
28413
29214
  return {
@@ -28443,9 +29244,22 @@ async function evaluateMemberAssignmentExpression(node, context) {
28443
29244
  throw new TypeError("Cannot assign properties of null or undefined.");
28444
29245
  }
28445
29246
  operands = [value];
28446
- property ??= await toPropertyKey(member.property, context.budget, createCoercionContext(context));
28447
- if (member.superReceiver === void 0) setSandboxProperty(member.object, property, value, context.budget);
28448
- else setSuperProperty(member.object, member.superReceiver.value, property, value, context.budget);
29247
+ property ??= await toPropertyKey(
29248
+ member.property,
29249
+ context.budget,
29250
+ createCoercionContext(context)
29251
+ );
29252
+ if (member.superReceiver === void 0)
29253
+ await setSandboxProperty(
29254
+ member.object,
29255
+ property,
29256
+ value,
29257
+ context.budget,
29258
+ true,
29259
+ createCoercionContext(context)
29260
+ );
29261
+ else
29262
+ await setSuperProperty(member.object, member.superReceiver.value, property, value, context);
28449
29263
  return {
28450
29264
  kind: "normal",
28451
29265
  hasValue: true,
@@ -29520,11 +30334,11 @@ async function evaluateMemberUpdateExpression(node, context) {
29520
30334
  }
29521
30335
  const property = await toPropertyKey(member.property, context.budget, createCoercionContext(context));
29522
30336
  const current = toNumber(
29523
- await toNumericPrimitive(getPropertyValue(member.object, property, context), context)
30337
+ await toNumericPrimitive(await getPropertyValue(member.object, property, context, member.superReceiver === void 0 ? member.object : member.superReceiver.value), context)
29524
30338
  );
29525
30339
  const next = node.operator === "++" ? current + 1 : current - 1;
29526
- if (member.superReceiver === void 0) setSandboxProperty(member.object, property, next, context.budget);
29527
- else setSuperProperty(member.object, member.superReceiver.value, property, next, context.budget);
30340
+ if (member.superReceiver === void 0) await setSandboxProperty(member.object, property, next, context.budget, true, createCoercionContext(context));
30341
+ else await setSuperProperty(member.object, member.superReceiver.value, property, next, context);
29528
30342
  return {
29529
30343
  kind: "normal",
29530
30344
  hasValue: true,
@@ -29541,28 +30355,38 @@ async function evaluateMemberExpression(node, context) {
29541
30355
  return {
29542
30356
  kind: "normal",
29543
30357
  hasValue: true,
29544
- value: getPropertyValue(member.object, await toPropertyKey(member.property, context.budget, createCoercionContext(context)), context)
30358
+ value: await getPropertyValue(
30359
+ member.object,
30360
+ await toPropertyKey(member.property, context.budget, createCoercionContext(context)),
30361
+ context,
30362
+ member.superReceiver === void 0 ? member.object : member.superReceiver.value
30363
+ )
29545
30364
  };
29546
30365
  });
29547
30366
  }
29548
- function getPropertyValue(target, property, context) {
30367
+ function getPropertyValue(target, property, context, receiver = target) {
29549
30368
  if (isGuestHostObject(target)) return getHostObjectMember(target, String(property));
30369
+ const descriptor = getSandboxPropertyDescriptor(target, property, context.budget);
30370
+ if (descriptor !== void 0)
30371
+ return readPropertyDescriptor(descriptor, receiver, createCoercionContext(context), true);
29550
30372
  if (typeof target === "string" || typeof target === "number" || typeof target === "boolean") {
29551
30373
  const prototype = getBoxedPrototype(target, context.budget);
29552
30374
  if (prototype !== void 0) {
29553
30375
  if (typeof target === "string" && (property === "length" || getStringIndex(property) !== void 0))
29554
30376
  return getStringMember(target, property, context.budget);
29555
- return getMemberValue(prototype, property, context);
30377
+ return getPropertyValue(prototype, property, context, receiver);
29556
30378
  }
29557
30379
  }
29558
30380
  if (typeof target === "string") return getStringMember(target, property, context.budget);
29559
30381
  if (typeof target === "number") return getNumberMember(property, context.budget);
29560
30382
  if (typeof target === "boolean") return void 0;
29561
30383
  if (isFloat32Array(target)) return getFloat32Member(target, property, context.budget);
29562
- if (isSandboxDate(target)) return getDateMember(property, context.budget, context.compilation?.owner);
30384
+ if (isSandboxDate(target))
30385
+ return getDateMember(property, context.budget, context.compilation?.owner);
29563
30386
  if (isSandboxMap(target)) return getMapMember(target, property, createMapMethodOptions(context));
29564
30387
  if (isSandboxSet(target)) return getSetMember(target, property, createSetMethodOptions(context));
29565
- if (isSandboxCollectionIterator(target)) return getCollectionIteratorMember(target, property, context.budget);
30388
+ if (isSandboxCollectionIterator(target))
30389
+ return getCollectionIteratorMember(target, property, context.budget);
29566
30390
  if (isSandboxGenerator(target)) return getGeneratorMember(target, property, context.budget);
29567
30391
  if (isSandboxClosure(target)) return getClosureMemberValue(target, property, context);
29568
30392
  if (isSandboxPromise(target)) return getPromiseMember(property, context.budget);
@@ -29576,16 +30400,24 @@ function createPatternContext(context, scope = context.scope, evaluate = evaluat
29576
30400
  const evaluationContext = { ...context, scope };
29577
30401
  return {
29578
30402
  budget: context.budget,
29579
- evaluate: (node) => evaluate(node, evaluationContext),
30403
+ evaluate: (node, inferredName) => evaluate(node, { ...evaluationContext, inferredName }),
29580
30404
  toPropertyKey: (value) => toPropertyKey(value, context.budget, createCoercionContext(evaluationContext)),
29581
30405
  getProperty: (value, key) => getPropertyValue(value, key, evaluationContext),
29582
- setProperty: (target, key, value) => setSandboxProperty(target, key, value, context.budget)
30406
+ setProperty: (target, key, value) => setSandboxProperty(
30407
+ target,
30408
+ key,
30409
+ value,
30410
+ context.budget,
30411
+ true,
30412
+ createCoercionContext(evaluationContext)
30413
+ )
29583
30414
  };
29584
30415
  }
29585
30416
  async function evaluateCallExpression(node, context) {
29586
30417
  if (node.callee.type === "Super") {
29587
30418
  const construction = context.functionEnvironment?.construction;
29588
- if (construction === void 0) throw new ReferenceError("Super constructor binding is unavailable.");
30419
+ if (construction === void 0)
30420
+ throw new ReferenceError("Super constructor binding is unavailable.");
29589
30421
  const args = await evaluateCallArguments(node.arguments, context);
29590
30422
  if (!args.ok) return args.result;
29591
30423
  return { kind: "normal", hasValue: true, value: await construction.superCall(args.value) };
@@ -29740,7 +30572,7 @@ async function evaluateMemberCallExpression(node, context) {
29740
30572
  property: await toPropertyKey(reference.property, context.budget, createCoercionContext(context))
29741
30573
  };
29742
30574
  if (member.superReceiver !== void 0)
29743
- return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.superReceiver.value);
30575
+ return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context, member.superReceiver.value), context, member.superReceiver.value);
29744
30576
  if ((typeof member.object === "string" || typeof member.object === "number" || typeof member.object === "boolean") && getBoxedPrototype(member.object, context.budget) !== void 0) {
29745
30577
  if (isDefaultBoxedMethod(member.object, member.property, context.budget)) {
29746
30578
  if (typeof member.object === "string" && isStringMethodName(member.property))
@@ -29748,7 +30580,7 @@ async function evaluateMemberCallExpression(node, context) {
29748
30580
  if (typeof member.object === "number" && isNumberMethodName(member.property))
29749
30581
  return evaluateNumberMethodCall(node, member.object, member.property, context);
29750
30582
  }
29751
- return evaluateResolvedCallExpression(node, getPropertyValue(member.object, member.property, context), context, member.object);
30583
+ return evaluateResolvedCallExpression(node, await getPropertyValue(member.object, member.property, context), context, member.object);
29752
30584
  }
29753
30585
  if (typeof member.object === "string" && isStringMethodName(member.property)) {
29754
30586
  return evaluateStringMethodCall(node, member.object, member.property, context);
@@ -29829,7 +30661,7 @@ async function evaluateMemberCallExpression(node, context) {
29829
30661
  return evaluateResolvedCallExpression(node, memberValue, context, member.object);
29830
30662
  }
29831
30663
  if (isSandboxClosure(member.object)) {
29832
- const memberValue = getClosureMemberValue(member.object, member.property, context);
30664
+ const memberValue = await getPropertyValue(member.object, member.property, context);
29833
30665
  if (memberValue === void 0) {
29834
30666
  throw new TypeError(`Function#${String(member.property)} is not a supported method.`);
29835
30667
  }
@@ -29856,7 +30688,7 @@ async function evaluateMemberCallExpression(node, context) {
29856
30688
  }
29857
30689
  return evaluateResolvedCallExpression(
29858
30690
  node,
29859
- getMemberValue(member.object, member.property, context),
30691
+ await getPropertyValue(member.object, member.property, context),
29860
30692
  context,
29861
30693
  member.object
29862
30694
  );
@@ -30058,7 +30890,8 @@ function applyBinaryOperator(node, left, right, context) {
30058
30890
  return true;
30059
30891
  }
30060
30892
  if (isFloat32ArrayConstructor(right)) return isFloat32Array(left);
30061
- if (isDateConstructor(right)) return isSandboxDate(left) && getDatePrototype(left, context.budget, context.compilation?.owner) !== null;
30893
+ if (isDateConstructor(right))
30894
+ return isSandboxDate(left) && getDatePrototype(left, context.budget, context.compilation?.owner) !== null;
30062
30895
  if (isSandboxSetConstructor(right) && isSandboxSet(left)) {
30063
30896
  return true;
30064
30897
  }
@@ -30067,16 +30900,20 @@ function applyBinaryOperator(node, left, right, context) {
30067
30900
  }
30068
30901
  if (isGuestClosure(right)) {
30069
30902
  if (typeof left !== "object" || left === null) return false;
30070
- const prototype = getGuestFunctionProperty(right, "prototype");
30071
- if (typeof prototype !== "object" || prototype === null) {
30072
- throw new TypeError("Function has a non-object prototype in instanceof check.");
30073
- }
30074
- let depth = 0;
30075
- for (let current = getSandboxPrototype(left, context.budget); current !== null; current = getSandboxPrototype(current, context.budget)) {
30076
- context.budget.visitNode();
30077
- assertSandboxDataDepth(depth++);
30078
- if (current === prototype) return true;
30079
- }
30903
+ const check = (prototype2) => {
30904
+ if (typeof prototype2 !== "object" || prototype2 === null) {
30905
+ throw new TypeError("Function has a non-object prototype in instanceof check.");
30906
+ }
30907
+ let depth = 0;
30908
+ for (let current = getSandboxPrototype(left, context.budget); current !== null; current = getSandboxPrototype(current, context.budget)) {
30909
+ context.budget.visitNode();
30910
+ assertSandboxDataDepth(depth++);
30911
+ if (current === prototype2) return true;
30912
+ }
30913
+ return false;
30914
+ };
30915
+ const prototype = getPropertyValue(right, "prototype", context);
30916
+ return prototype instanceof Promise ? prototype.then(check) : check(prototype);
30080
30917
  }
30081
30918
  return false;
30082
30919
  case "in":
@@ -30247,7 +31084,7 @@ async function toNumericPrimitive(value, context) {
30247
31084
  }
30248
31085
  if (isIndexableSandboxValue(value)) {
30249
31086
  for (const methodName of ["valueOf", "toString"]) {
30250
- const method = getMemberValue(value, methodName, context);
31087
+ const method = await getPropertyValue(value, methodName, context);
30251
31088
  if (methodName === "toString" && method === void 0 && !Object.hasOwn(value, methodName)) {
30252
31089
  return toString(value);
30253
31090
  }
@@ -30335,13 +31172,18 @@ function getArrayMemberValue(target, property, context) {
30335
31172
  }
30336
31173
  return getArrayMember(target, property, createArrayMethodOptions(context));
30337
31174
  }
30338
- function setSandboxProperty(target, property, value, budget, checkInherited = true) {
31175
+ function setSandboxProperty(target, property, value, budget, checkInherited = true, context) {
30339
31176
  if (isSandboxDate(target)) throw new TypeError("Date own properties are not supported.");
30340
31177
  if (isGuestHostObject(target)) {
30341
31178
  setHostObjectMember(target, String(property), value);
30342
31179
  return;
30343
31180
  }
30344
31181
  const prototypeOwner = target;
31182
+ if (checkInherited) {
31183
+ const descriptor2 = getSandboxPropertyDescriptor(target, property, budget);
31184
+ if (descriptor2 !== void 0 && !("value" in descriptor2))
31185
+ return writePropertyDescriptor(descriptor2, target, value, context);
31186
+ }
30345
31187
  if (isGuestClosure(target)) target = materializeFunctionProperties(target);
30346
31188
  if (isFloat32Array(target)) {
30347
31189
  setFloat32Member(target, property, value);
@@ -30377,15 +31219,18 @@ function setSandboxProperty(target, property, value, budget, checkInherited = tr
30377
31219
  const properties = isSandboxClosure(prototype) ? prototype.properties : prototype;
30378
31220
  const inherited = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
30379
31221
  if (inherited === void 0) continue;
30380
- if (inherited.writable !== true) throw new TypeError(`Cannot assign to read only property '${key}'.`);
31222
+ if (inherited.writable !== true)
31223
+ throw new TypeError(`Cannot assign to read only property '${key}'.`);
30381
31224
  break;
30382
31225
  }
30383
31226
  }
30384
31227
  defineSandboxProperty(target, key, value);
30385
31228
  }
30386
31229
  }
30387
- function setSuperProperty(base, receiver, key, value, budget) {
30388
- if (typeof base !== "object" || base === null) throw new TypeError("Cannot assign a property of null.");
31230
+ function setSuperProperty(base, receiver, key, value, context) {
31231
+ const budget = context.budget;
31232
+ if (typeof base !== "object" || base === null)
31233
+ throw new TypeError("Cannot assign a property of null.");
30389
31234
  let depth = 0;
30390
31235
  for (let current = base; current !== null; current = getSandboxPrototype(current, budget)) {
30391
31236
  budget.visitNode();
@@ -30393,11 +31238,15 @@ function setSuperProperty(base, receiver, key, value, budget) {
30393
31238
  const properties = isSandboxClosure(current) ? current.properties : current;
30394
31239
  const descriptor = properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key);
30395
31240
  if (descriptor === void 0) continue;
30396
- if (descriptor.writable !== true) throw new TypeError(`Cannot assign to read only property '${key}'.`);
31241
+ if (!("value" in descriptor))
31242
+ return writePropertyDescriptor(descriptor, receiver, value, createCoercionContext(context));
31243
+ if (descriptor.writable !== true)
31244
+ throw new TypeError(`Cannot assign to read only property '${key}'.`);
30397
31245
  break;
30398
31246
  }
30399
- if (typeof receiver !== "object" || receiver === null) throw new TypeError("Super assignment requires an object receiver.");
30400
- setSandboxProperty(receiver, key, value, budget, false);
31247
+ if (typeof receiver !== "object" || receiver === null)
31248
+ throw new TypeError("Super assignment requires an object receiver.");
31249
+ return setSandboxProperty(receiver, key, value, budget, false);
30401
31250
  }
30402
31251
  function deleteSandboxProperty(target, property) {
30403
31252
  if (isGuestHostObject(target)) return deleteHostObjectMember(target, String(property));
@@ -30461,7 +31310,7 @@ function createArrayMethodOptions(context) {
30461
31310
  budget: context.budget,
30462
31311
  context: createCoercionContext(context),
30463
31312
  hasProperty: (value, property) => hasSandboxProperty(value, property, context),
30464
- setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget),
31313
+ setProperty: (value, property, entry) => setSandboxProperty(value, property, entry, context.budget, true, createCoercionContext(context)),
30465
31314
  deleteProperty: deleteSandboxProperty,
30466
31315
  callClosure: (closure, args, stack, thisValue) => invokeSandboxClosure(closure, args, context, stack, void 0, thisValue)
30467
31316
  };
@@ -30599,11 +31448,12 @@ async function evaluateObjectSpread(node, context) {
30599
31448
  };
30600
31449
  }
30601
31450
  if (isGuestHostObject(value.value)) {
30602
- const entries = [];
31451
+ const entries2 = [];
30603
31452
  for (const key of getHostObjectKeys(value.value)) {
30604
- if (hasHostObjectMember(value.value, key, true)) entries.push([key, getHostObjectMember(value.value, key)]);
31453
+ if (hasHostObjectMember(value.value, key, true))
31454
+ entries2.push([key, getHostObjectMember(value.value, key)]);
30605
31455
  }
30606
- return { ok: true, value: entries };
31456
+ return { ok: true, value: entries2 };
30607
31457
  }
30608
31458
  if (isSandboxClosure(value.value) && !isGuestClosure(value.value) || isSandboxPromise(value.value)) {
30609
31459
  throw new TypeError(
@@ -30613,10 +31463,17 @@ async function evaluateObjectSpread(node, context) {
30613
31463
  const spreadValue = isGuestClosure(value.value) ? value.value.properties ?? {} : Object(value.value);
30614
31464
  const keys = Object.keys(spreadValue);
30615
31465
  context.budget.allocateArrayLength(keys.length);
30616
- return {
30617
- ok: true,
30618
- value: keys.map((key) => [key, spreadValue[key]])
30619
- };
31466
+ const entries = [];
31467
+ const release = retainValues(context.budget, () => [value.value, entries]);
31468
+ try {
31469
+ for (const key of keys) {
31470
+ if (!hasOwnSandboxProperty(value.value, key, true)) continue;
31471
+ entries.push([key, await getPropertyValue(value.value, key, context)]);
31472
+ }
31473
+ return { ok: true, value: entries };
31474
+ } finally {
31475
+ release();
31476
+ }
30620
31477
  }
30621
31478
  function describeObjectSpreadValue(value) {
30622
31479
  if (value === null) {
@@ -30765,7 +31622,7 @@ function executeAsyncFunction(execute, budget, signal) {
30765
31622
  try {
30766
31623
  const value = await execute(completePrefix);
30767
31624
  resolve(
30768
- isSandboxPromise(value) || getThenable(value) !== void 0 ? awaitSandboxValue(
31625
+ requiresPromiseResolution(value, budget) ? awaitSandboxValue(
30769
31626
  createSandboxPromise(resolveSandboxValue(value, { budget }), {
30770
31627
  trackReplay: false
30771
31628
  }),
@@ -32191,19 +33048,29 @@ async function stringifyJson(value, replacer, indent, budget, context) {
32191
33048
  return budget.allocateString(output);
32192
33049
  }
32193
33050
  async function stringifyProperty(key, holder, state, indent = "") {
32194
- let value = getOwnDataValue(holder, key);
32195
- if (isSandboxDate(value)) {
32196
- value = dateMethods.get("toJSON").invoke(value, []);
32197
- } else if (isStringifyContainer(value)) {
32198
- const toJSON = getOwnDataValue(value, "toJSON");
32199
- if (isSandboxClosure(toJSON)) {
32200
- value = await callStringifyClosure(toJSON, [key], value, state);
33051
+ let value = await getStringifyProperty(holder, key, state);
33052
+ const release = retainValues(state.budget, () => [holder, value]);
33053
+ try {
33054
+ if (isSandboxDate(value)) {
33055
+ value = dateMethods.get("toJSON").invoke(value, []);
33056
+ } else if (isStringifyContainer(value)) {
33057
+ const toJSON = await getStringifyProperty(value, "toJSON", state);
33058
+ if (isSandboxClosure(toJSON)) {
33059
+ value = await callStringifyClosure(toJSON, [key], value, state);
33060
+ }
33061
+ }
33062
+ if (state.replacer !== void 0) {
33063
+ value = await callStringifyClosure(
33064
+ state.replacer,
33065
+ [key, toSandboxValue(value)],
33066
+ holder,
33067
+ state
33068
+ );
32201
33069
  }
33070
+ return await stringifyValue(value, state, indent);
33071
+ } finally {
33072
+ release();
32202
33073
  }
32203
- if (state.replacer !== void 0) {
32204
- value = await callStringifyClosure(state.replacer, [key, toSandboxValue(value)], holder, state);
32205
- }
32206
- return stringifyValue(value, state, indent);
32207
33074
  }
32208
33075
  async function stringifyValue(value, state, indent) {
32209
33076
  if (isSandboxBox(value)) {
@@ -32239,10 +33106,12 @@ async function stringifyValue(value, state, indent) {
32239
33106
  }
32240
33107
  async function stringifyArray(value, state, indent) {
32241
33108
  enterStringifyObject(value, state);
33109
+ const entries = [];
33110
+ const release = retainValues(state.budget, () => entries);
32242
33111
  try {
32243
33112
  const nextIndent = indent + state.gap;
32244
- const entries = [];
32245
- for (let index = 0; index < value.length; index += 1) {
33113
+ const length = value.length;
33114
+ for (let index = 0; index < length; index += 1) {
32246
33115
  entries.push(await stringifyProperty(String(index), value, state, nextIndent) ?? "null");
32247
33116
  }
32248
33117
  if (entries.length === 0) {
@@ -32256,14 +33125,16 @@ ${nextIndent}${entries.join(`,
32256
33125
  ${nextIndent}`)}
32257
33126
  ${indent}]`;
32258
33127
  } finally {
33128
+ release();
32259
33129
  leaveStringifyObject(value, state);
32260
33130
  }
32261
33131
  }
32262
33132
  async function stringifyObject(value, state, indent) {
32263
33133
  enterStringifyObject(value, state);
33134
+ const entries = [];
33135
+ const release = retainValues(state.budget, () => entries);
32264
33136
  try {
32265
33137
  const nextIndent = indent + state.gap;
32266
- const entries = [];
32267
33138
  for (const key of Object.keys(value)) {
32268
33139
  const serialized = await stringifyProperty(key, value, state, nextIndent);
32269
33140
  if (serialized !== void 0) {
@@ -32281,6 +33152,7 @@ ${nextIndent}${entries.join(`,
32281
33152
  ${nextIndent}`)}
32282
33153
  ${indent}}`;
32283
33154
  } finally {
33155
+ release();
32284
33156
  leaveStringifyObject(value, state);
32285
33157
  }
32286
33158
  }
@@ -32336,15 +33208,10 @@ function toSandboxValue(value) {
32336
33208
  `JSON.stringify(value) produced an unsupported value of type ${typeof value}.`
32337
33209
  );
32338
33210
  }
32339
- function getOwnDataValue(target, key) {
32340
- const descriptor = Object.getOwnPropertyDescriptor(target, key);
32341
- if (descriptor === void 0) {
32342
- return void 0;
32343
- }
32344
- if ("get" in descriptor || "set" in descriptor) {
32345
- throw new TypeError(`JSON.stringify(value) cannot serialize accessor property ${key}.`);
32346
- }
32347
- return descriptor.value;
33211
+ function getStringifyProperty(target, key, state) {
33212
+ if (state.context?.getProperty !== void 0) return state.context.getProperty(target, key);
33213
+ const descriptor = getSandboxPropertyDescriptor(target, key, state.budget);
33214
+ return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, target, state.context);
32348
33215
  }
32349
33216
  function copyJsonToSandbox(value, budget) {
32350
33217
  if (value === null || value === void 0 || typeof value === "boolean" || typeof value === "number") {
@@ -34602,4 +35469,4 @@ export {
34602
35469
  FileSnapshotBackend,
34603
35470
  run
34604
35471
  };
34605
- //# sourceMappingURL=chunk-VZV6W7GY.js.map
35472
+ //# sourceMappingURL=chunk-EZAX76DY.js.map