poe-code 14.0.7 → 14.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/index.js +511 -125
  2. package/dist/index.js.map +4 -4
  3. package/dist/metafile.json +1 -1
  4. package/package.json +3 -3
  5. package/packages/safe-js/dist/chunks/{chunk-BWVASPJX.js → chunk-MO3YD4ID.js} +479 -111
  6. package/packages/safe-js/dist/chunks/chunk-MO3YD4ID.js.map +7 -0
  7. package/packages/safe-js/dist/chunks/{chunk-ETKM3KPA.js → chunk-RXLDJ6LQ.js} +2 -2
  8. package/packages/safe-js/dist/cli.js +2 -2
  9. package/packages/safe-js/dist/core.d.ts +1 -1
  10. package/packages/safe-js/dist/core.js +1 -1
  11. package/packages/safe-js/dist/index.d.ts +1 -1
  12. package/packages/safe-js/dist/index.js +2 -2
  13. package/packages/safe-js/dist/index.js.map +1 -1
  14. package/packages/safe-js/dist/interp/async.js +1 -0
  15. package/packages/safe-js/dist/interp/globals/object-array.d.ts +2 -2
  16. package/packages/safe-js/dist/interp/globals/object-array.js +32 -4
  17. package/packages/safe-js/dist/interp/globals/object.d.ts +4 -0
  18. package/packages/safe-js/dist/interp/globals/object.js +153 -0
  19. package/packages/safe-js/dist/interp/globals.d.ts +1 -1
  20. package/packages/safe-js/dist/interp/host-capabilities.d.ts +21 -1
  21. package/packages/safe-js/dist/interp/host-capabilities.js +191 -4
  22. package/packages/safe-js/dist/interp/interpreter.js +27 -9
  23. package/packages/safe-js/dist/interp/iteration.js +3 -0
  24. package/packages/safe-js/dist/interp/object-model.d.ts +3 -1
  25. package/packages/safe-js/dist/interp/object-model.js +39 -9
  26. package/packages/safe-js/dist/interp/values.d.ts +2 -0
  27. package/packages/safe-js/dist/interp/values.js +13 -6
  28. package/packages/safe-js/dist/realm.js +15 -2
  29. package/packages/safe-js/dist/run.js +2 -0
  30. package/packages/safe-js/dist/chunks/chunk-BWVASPJX.js.map +0 -7
  31. /package/packages/safe-js/dist/chunks/{chunk-ETKM3KPA.js.map → chunk-RXLDJ6LQ.js.map} +0 -0
@@ -6331,6 +6331,10 @@ function serializedDateTime(value) {
6331
6331
  }
6332
6332
 
6333
6333
  // packages/safe-js/src/interp/host-capabilities.ts
6334
+ import { types as types3 } from "node:util";
6335
+ var MAX_INDEXED_LENGTH = 65536;
6336
+ var MAX_NAMED_KEYS = 65536;
6337
+ var MAX_NAMED_KEY_CODE_UNITS = 1048576;
6334
6338
  var hostObjects = /* @__PURE__ */ new WeakMap();
6335
6339
  var guestObjects = /* @__PURE__ */ new WeakMap();
6336
6340
  var guestCallbacks = /* @__PURE__ */ new WeakMap();
@@ -6355,8 +6359,48 @@ function revokeGuestReference(reference, owner) {
6355
6359
  }
6356
6360
  function createLiveHostObject(definition, controller) {
6357
6361
  const input = readDataRecord(definition, "Host object definition");
6358
- if (Object.keys(input).some((key) => key !== "properties" && key !== "methods"))
6362
+ if (Object.keys(input).some((key) => !["properties", "methods", "indexed", "named"].includes(key)))
6359
6363
  throw new TypeError("Unknown host object definition field.");
6364
+ let indexed;
6365
+ if (input.indexed !== void 0) {
6366
+ const data = readDataRecord(input.indexed, "Indexed host capability");
6367
+ if (Object.keys(data).some((key) => !["length", "get", "maxLength"].includes(key)))
6368
+ throw new TypeError("Unknown indexed host capability field.");
6369
+ if (typeof data.length !== "function" || typeof data.get !== "function")
6370
+ throw new TypeError("Indexed length and get must be synchronous functions.");
6371
+ if (typeof data.maxLength !== "number" || !Number.isInteger(data.maxLength) || data.maxLength < 1 || data.maxLength > MAX_INDEXED_LENGTH)
6372
+ throw new RangeError(`Indexed maxLength must be an integer from 1 to ${MAX_INDEXED_LENGTH}.`);
6373
+ indexed = {
6374
+ length: data.length,
6375
+ get: data.get,
6376
+ maxLength: data.maxLength
6377
+ };
6378
+ }
6379
+ let named;
6380
+ if (input.named !== void 0) {
6381
+ const data = readDataRecord(input.named, "Named host capability");
6382
+ if (Object.keys(data).some(
6383
+ (key) => !["keys", "get", "maxKeys", "maxKeyCodeUnits", "enumerable"].includes(key)
6384
+ ))
6385
+ throw new TypeError("Unknown named host capability field.");
6386
+ if (typeof data.keys !== "function" || typeof data.get !== "function")
6387
+ throw new TypeError("Named keys and get must be synchronous functions.");
6388
+ if (typeof data.maxKeys !== "number" || !Number.isInteger(data.maxKeys) || data.maxKeys < 1 || data.maxKeys > MAX_NAMED_KEYS)
6389
+ throw new RangeError(`Named maxKeys must be an integer from 1 to ${MAX_NAMED_KEYS}.`);
6390
+ if (typeof data.maxKeyCodeUnits !== "number" || !Number.isInteger(data.maxKeyCodeUnits) || data.maxKeyCodeUnits < 1 || data.maxKeyCodeUnits > MAX_NAMED_KEY_CODE_UNITS)
6391
+ throw new RangeError(
6392
+ `Named maxKeyCodeUnits must be an integer from 1 to ${MAX_NAMED_KEY_CODE_UNITS}.`
6393
+ );
6394
+ if (data.enumerable !== void 0 && typeof data.enumerable !== "boolean")
6395
+ throw new TypeError("Named enumerable must be a boolean.");
6396
+ named = {
6397
+ keys: data.keys,
6398
+ get: data.get,
6399
+ maxKeys: data.maxKeys,
6400
+ maxKeyCodeUnits: data.maxKeyCodeUnits,
6401
+ enumerable: data.enumerable
6402
+ };
6403
+ }
6360
6404
  const properties = /* @__PURE__ */ new Map();
6361
6405
  for (const [name, inputProperty] of Object.entries(
6362
6406
  readDataRecord(input.properties ?? {}, "Host properties")
@@ -6376,6 +6420,8 @@ function createLiveHostObject(definition, controller) {
6376
6420
  for (const name of [...properties.keys(), ...Object.keys(operations)]) {
6377
6421
  if (["constructor", "prototype", "__proto__"].includes(name))
6378
6422
  throw new TypeError(`Reserved host member '${name}'.`);
6423
+ if (indexed !== void 0 && (name === "length" || canonicalIndex(name) !== void 0))
6424
+ throw new TypeError(`Conflicting indexed host member '${name}'.`);
6379
6425
  }
6380
6426
  controller.assertActive();
6381
6427
  controller.chargeWork(properties.size + Object.keys(operations).length + 1);
@@ -6387,7 +6433,7 @@ function createLiveHostObject(definition, controller) {
6387
6433
  controller.method(operation)
6388
6434
  ])
6389
6435
  );
6390
- const state = { host, guest, controller, properties, methods };
6436
+ const state = { host, guest, controller, properties, methods, indexed, named };
6391
6437
  hostObjects.set(host, state);
6392
6438
  guestObjects.set(guest, state);
6393
6439
  return host;
@@ -6444,15 +6490,29 @@ function revokeHostObject(value, owner) {
6444
6490
  throw new TypeError("Foreign host object.");
6445
6491
  state.properties.clear();
6446
6492
  state.methods.clear();
6493
+ state.indexed = void 0;
6494
+ state.named = void 0;
6447
6495
  }
6448
6496
  function getHostObjectMember(value, key) {
6449
6497
  const state = guestObjects.get(value);
6450
6498
  state.controller.assertActive();
6451
6499
  state.controller.chargeWork();
6500
+ if (state.indexed !== void 0) {
6501
+ if (key === "length") return indexedLength(state);
6502
+ const index = canonicalIndex(key);
6503
+ if (index !== void 0) {
6504
+ if (index >= state.indexed.maxLength || index >= indexedLength(state)) return void 0;
6505
+ return state.controller.read(() => state.indexed.get(index));
6506
+ }
6507
+ }
6452
6508
  const property = state.properties.get(key);
6453
6509
  if (property !== void 0)
6454
6510
  return property.get === void 0 ? void 0 : state.controller.read(property.get);
6455
- return state.methods.get(key);
6511
+ const method = state.methods.get(key);
6512
+ if (method !== void 0) return method;
6513
+ if (state.named !== void 0 && namedKeys(state).includes(key))
6514
+ return state.controller.read(() => state.named.get(key));
6515
+ return void 0;
6456
6516
  }
6457
6517
  function setHostObjectMember(value, key, entry) {
6458
6518
  const state = guestObjects.get(value);
@@ -6465,7 +6525,106 @@ function setHostObjectMember(value, key, entry) {
6465
6525
  function getHostObjectKeys(value) {
6466
6526
  const state = guestObjects.get(value);
6467
6527
  state.controller.assertActive();
6468
- return [...state.properties.keys(), ...state.methods.keys()];
6528
+ const length = state.indexed === void 0 ? 0 : indexedLength(state);
6529
+ const names = state.named === void 0 || state.named.enumerable === false ? [] : namedKeys(state).filter(
6530
+ (key) => !state.properties.has(key) && !state.methods.has(key) && !(state.indexed !== void 0 && (key === "length" || canonicalIndex(key) !== void 0))
6531
+ );
6532
+ const size = length + state.properties.size + state.methods.size + names.length;
6533
+ state.controller.checkLength(size);
6534
+ state.controller.chargeWork(size + 1);
6535
+ return [
6536
+ ...Array.from({ length }, (_entry, index) => String(index)),
6537
+ ...state.properties.keys(),
6538
+ ...state.methods.keys(),
6539
+ ...names
6540
+ ];
6541
+ }
6542
+ function hasHostObjectMember(value, key, enumerableOnly = false) {
6543
+ const state = guestObjects.get(value);
6544
+ state.controller.assertActive();
6545
+ state.controller.chargeWork();
6546
+ if (state.indexed !== void 0) {
6547
+ if (key === "length") return !enumerableOnly;
6548
+ const index = canonicalIndex(key);
6549
+ if (index !== void 0) return index < state.indexed.maxLength && index < indexedLength(state);
6550
+ }
6551
+ if (state.properties.has(key) || state.methods.has(key)) return true;
6552
+ return state.named !== void 0 && !(enumerableOnly && state.named.enumerable === false) && namedKeys(state).includes(key);
6553
+ }
6554
+ function measureHostObjectData(value) {
6555
+ const state = guestObjects.get(value);
6556
+ let size = state.indexed === void 0 ? 0 : 16;
6557
+ if (state.named !== void 0) size += 24;
6558
+ for (const key of state.properties.keys()) size += key.length + 1;
6559
+ for (const key of state.methods.keys()) size += key.length + 1;
6560
+ return size;
6561
+ }
6562
+ function getHostObjectIterator(value) {
6563
+ const state = guestObjects.get(value);
6564
+ state.controller.assertActive();
6565
+ if (state.indexed === void 0) return void 0;
6566
+ let index = 0;
6567
+ let exhausted = false;
6568
+ return {
6569
+ next: () => {
6570
+ state.controller.assertActive();
6571
+ state.controller.chargeWork();
6572
+ if (exhausted) return { done: true, value: void 0 };
6573
+ if (index >= indexedLength(state)) {
6574
+ exhausted = true;
6575
+ return { done: true, value: void 0 };
6576
+ }
6577
+ const position = index++;
6578
+ return { done: false, value: state.controller.read(() => state.indexed.get(position)) };
6579
+ }
6580
+ };
6581
+ }
6582
+ function indexedLength(state) {
6583
+ state.controller.chargeWork();
6584
+ const length = state.controller.read(state.indexed.length);
6585
+ if (typeof length !== "number" || !Number.isInteger(length) || length < 0 || length > state.indexed.maxLength)
6586
+ throw new RangeError("Indexed length must be a non-negative integer within maxLength.");
6587
+ state.controller.checkLength(length);
6588
+ return length;
6589
+ }
6590
+ function canonicalIndex(key) {
6591
+ const index = Number(key);
6592
+ return Number.isInteger(index) && index >= 0 && index < 4294967295 && String(index) === key ? index : void 0;
6593
+ }
6594
+ function namedKeys(state) {
6595
+ const named = state.named;
6596
+ return state.controller.read(named.keys, (value) => {
6597
+ if (!Array.isArray(value) || types3.isProxy(value))
6598
+ throw new TypeError("Named keys must be a dense own-data array of strings, not a proxy.");
6599
+ const length = Object.getOwnPropertyDescriptor(value, "length").value;
6600
+ if (length > named.maxKeys) throw new RangeError("Named keys exceed maxKeys.");
6601
+ state.controller.checkLength(length);
6602
+ state.controller.chargeWork(length + 1);
6603
+ if (Reflect.ownKeys(value).length !== length + 1)
6604
+ throw new TypeError("Named keys must contain only dense own-data indices and length.");
6605
+ const result = [];
6606
+ const seen = /* @__PURE__ */ new Set();
6607
+ let units = 0;
6608
+ for (let index = 0; index < length; index++) {
6609
+ const descriptor = Object.getOwnPropertyDescriptor(value, String(index));
6610
+ if (descriptor === void 0 || !("value" in descriptor) || typeof descriptor.value !== "string")
6611
+ throw new TypeError(
6612
+ "Named keys require dense own string data, not accessors or sparse arrays."
6613
+ );
6614
+ const key = descriptor.value;
6615
+ units += key.length;
6616
+ if (units > named.maxKeyCodeUnits)
6617
+ throw new RangeError("Named keys exceed maximum UTF-16 code units.");
6618
+ state.controller.chargeWork(key.length);
6619
+ if (seen.has(key)) throw new TypeError("Named keys must be distinct.");
6620
+ if (["constructor", "prototype", "__proto__"].includes(key))
6621
+ throw new TypeError(`Reserved named host member '${key}'.`);
6622
+ seen.add(key);
6623
+ result.push(key);
6624
+ }
6625
+ state.controller.checkTemporaryDataSize(1 + length + units);
6626
+ return result;
6627
+ });
6469
6628
  }
6470
6629
 
6471
6630
  // packages/safe-js/src/interp/values.ts
@@ -6588,7 +6747,7 @@ async function flushPromiseJobs() {
6588
6747
  import { AsyncLocalStorage as AsyncLocalStorage2 } from "node:async_hooks";
6589
6748
 
6590
6749
  // packages/safe-js/src/snapshot/validation.ts
6591
- import { types as types3 } from "node:util";
6750
+ import { types as types4 } from "node:util";
6592
6751
 
6593
6752
  // packages/safe-js/src/interp/arguments.ts
6594
6753
  var sandboxArgumentsBrand = /* @__PURE__ */ Symbol("SandboxArguments");
@@ -6718,6 +6877,8 @@ function graphEntries(value) {
6718
6877
  var guestClosures = /* @__PURE__ */ new WeakSet();
6719
6878
  var functionProperties = /* @__PURE__ */ new WeakMap();
6720
6879
  var prototypes = /* @__PURE__ */ new WeakMap();
6880
+ var intrinsicPrototypes = /* @__PURE__ */ new WeakMap();
6881
+ var intrinsicConstructors = /* @__PURE__ */ new WeakMap();
6721
6882
  var descriptorObjects = /* @__PURE__ */ new WeakSet();
6722
6883
  function registerGuestClosure(closure) {
6723
6884
  guestClosures.add(closure);
@@ -6762,27 +6923,49 @@ function getGuestFunctionProperty(closure, key) {
6762
6923
  }
6763
6924
  return properties === void 0 ? void 0 : Object.getOwnPropertyDescriptor(properties, key)?.value;
6764
6925
  }
6765
- function getSandboxPrototype(value) {
6766
- return prototypes.get(value) ?? null;
6926
+ function installObjectPrototype(budget, prototype, constructor) {
6927
+ prototypes.set(prototype, null);
6928
+ intrinsicPrototypes.set(budget, prototype);
6929
+ const records = [prototype, materializeFunctionProperties(constructor)].map((value) => ({
6930
+ value,
6931
+ descriptors: new Map(Object.entries(Object.getOwnPropertyDescriptors(value)))
6932
+ }));
6933
+ const unchanged = (before, after) => before !== void 0 && after !== void 0 && before.value === after.value && before.writable === after.writable && before.configurable === after.configurable && before.enumerable === after.enumerable;
6934
+ intrinsicConstructors.set(constructor, () => records.every(({ value, descriptors }) => {
6935
+ const current = Object.getOwnPropertyDescriptors(value);
6936
+ return Object.keys(current).length === descriptors.size && Object.keys(current).every((key) => unchanged(descriptors.get(key), current[key]));
6937
+ }));
6938
+ budget.setRetainedValues(prototype, () => records.flatMap(({ value, descriptors }) => Object.entries(Object.getOwnPropertyDescriptors(value)).flatMap(([key, descriptor]) => unchanged(descriptors.get(key), descriptor) ? [] : [key, descriptor.value])));
6939
+ }
6940
+ function releaseObjectPrototype(budget) {
6941
+ const prototype = intrinsicPrototypes.get(budget);
6942
+ if (prototype !== void 0) budget.setRetainedValues(prototype, void 0);
6943
+ intrinsicPrototypes.delete(budget);
6944
+ }
6945
+ function getSandboxPrototype(value, budget) {
6946
+ if (prototypes.has(value)) return prototypes.get(value) ?? null;
6947
+ return budget !== void 0 && isPrototypeRecord(value) ? intrinsicPrototypes.get(budget) ?? null : null;
6767
6948
  }
6768
6949
  function setSandboxPrototype(value, prototype, budget) {
6950
+ if (budget !== void 0 && intrinsicPrototypes.get(budget) === value && prototype !== null) {
6951
+ throw new TypeError("Object.prototype has an immutable null prototype.");
6952
+ }
6769
6953
  if (!isPrototypeRecord(value) || prototype !== null && !isPrototypeRecord(prototype)) {
6770
6954
  throw new TypeError(
6771
6955
  "Prototype links require ordinary sandbox objects; callable and exotic prototype chains are not supported."
6772
6956
  );
6773
6957
  }
6774
- if (getSandboxPrototype(value) === prototype) return;
6958
+ if (prototypes.has(value) && getSandboxPrototype(value, budget) === prototype) return;
6775
6959
  if (!Object.isExtensible(isGuestClosure(value) ? materializeFunctionProperties(value) : value)) {
6776
6960
  throw new TypeError("Cannot change the prototype of a non-extensible object.");
6777
6961
  }
6778
6962
  let depth = 0;
6779
- for (let current = prototype; current !== null; current = getSandboxPrototype(current)) {
6963
+ for (let current = prototype; current !== null; current = getSandboxPrototype(current, budget)) {
6780
6964
  budget?.visitNode();
6781
6965
  assertSandboxDataDepth(depth++);
6782
6966
  if (current === value) throw new TypeError("Cyclic prototype value.");
6783
6967
  }
6784
- if (prototype === null) prototypes.delete(value);
6785
- else prototypes.set(value, prototype);
6968
+ prototypes.set(value, prototype);
6786
6969
  }
6787
6970
  function isPrototypeRecord(value) {
6788
6971
  if (isGuestHostObject(value)) return false;
@@ -6798,6 +6981,8 @@ function hasManagedDescriptors(value) {
6798
6981
  return descriptorObjects.has(value);
6799
6982
  }
6800
6983
  function hasGuestObjectState(value) {
6984
+ const intrinsicUnchanged = intrinsicConstructors.get(value);
6985
+ if (intrinsicUnchanged !== void 0) return !intrinsicUnchanged();
6801
6986
  if (isLiveCapability(value)) return true;
6802
6987
  if (functionProperties.has(value) || prototypes.has(value)) return true;
6803
6988
  return descriptorObjects.has(value) && Object.values(Object.getOwnPropertyDescriptors(value)).some(
@@ -7446,7 +7631,7 @@ function validateGenericValue(value, path, depth, state) {
7446
7631
  if (typeof value === "object" && value !== null && hasGuestObjectState(value)) {
7447
7632
  fail("invalidState", path, "guest function properties, prototype links and custom descriptors cannot be restored");
7448
7633
  }
7449
- if (state.dataPropertiesOnly && types3.isProxy(value)) {
7634
+ if (state.dataPropertiesOnly && types4.isProxy(value)) {
7450
7635
  fail("invalidType", path, "proxy objects are not snapshot data");
7451
7636
  }
7452
7637
  if (depth > state.limits.maxDepth)
@@ -8380,6 +8565,7 @@ function assertSnapshotInactive(snapshot) {
8380
8565
 
8381
8566
  // packages/safe-js/src/interp/iteration.ts
8382
8567
  function getSandboxIterator(value) {
8568
+ if (isGuestHostObject(value)) return getHostObjectIterator(value);
8383
8569
  if (isFloat32Array(value)) {
8384
8570
  return syncIterator(Float32Array.prototype.values.call(value));
8385
8571
  }
@@ -9504,6 +9690,7 @@ function createSandboxClosure(input) {
9504
9690
  if (input.sandbox === true) {
9505
9691
  Object.defineProperty(closure, "sandbox", { value: true });
9506
9692
  }
9693
+ if (input.generator === true) Object.defineProperty(closure, "generator", { value: true });
9507
9694
  if (input.length !== void 0) {
9508
9695
  Object.defineProperty(closure, "length", { value: input.length });
9509
9696
  }
@@ -9536,7 +9723,13 @@ function createSandboxClosure(input) {
9536
9723
  return Object.freeze(closure);
9537
9724
  }
9538
9725
  function ownEnumerableSandboxEntries(value) {
9539
- if (isGuestHostObject(value)) return getHostObjectKeys(value).map((key) => [key, getHostObjectMember(value, key)]);
9726
+ if (isGuestHostObject(value)) {
9727
+ const entries = [];
9728
+ for (const key of getHostObjectKeys(value)) {
9729
+ if (hasHostObjectMember(value, key, true)) entries.push([key, getHostObjectMember(value, key)]);
9730
+ }
9731
+ return entries;
9732
+ }
9540
9733
  if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
9541
9734
  if (isGuestClosure(value)) return Object.entries(value.properties ?? {});
9542
9735
  if (isSandboxClosure(value) || isSandboxGenerator(value) || isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxRegex(value)) return [];
@@ -9694,7 +9887,7 @@ function measureSandboxData(values, options = {}) {
9694
9887
  return;
9695
9888
  }
9696
9889
  if (isGuestHostObject(value)) {
9697
- for (const key of getHostObjectKeys(value)) usage += key.length + 1;
9890
+ usage += measureHostObjectData(value);
9698
9891
  return;
9699
9892
  }
9700
9893
  const prototype = getSandboxPrototype(value);
@@ -9791,7 +9984,7 @@ function measureSandboxData(values, options = {}) {
9791
9984
  function reconcileCompiledValues(budget, values, compilation, parent, escaping = []) {
9792
9985
  while (parent?.closed) parent = parent.parent;
9793
9986
  const included = /* @__PURE__ */ new Set();
9794
- const usage = measureSandboxData(values, { compileTickets: included });
9987
+ const usage = measureSandboxData([...values, ...budget.retainedValues()], { compileTickets: included });
9795
9988
  const kept = /* @__PURE__ */ new Set();
9796
9989
  if (parent !== void 0) measureSandboxData(escaping, { compileTickets: kept });
9797
9990
  const transferred = /* @__PURE__ */ new Set();
@@ -22935,6 +23128,86 @@ function hoistVarDeclarations(node, scope) {
22935
23128
  }
22936
23129
  }
22937
23130
 
23131
+ // packages/safe-js/src/interp/string-coercion.ts
23132
+ function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
23133
+ if (value === null || typeof value !== "object") {
23134
+ if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
23135
+ return budget.allocateString(String(value));
23136
+ }
23137
+ return stringifyObject(value, budget, context, joining);
23138
+ }
23139
+ async function stringifyObject(value, budget, context, joining) {
23140
+ const leaveCall = budget.enterCall();
23141
+ try {
23142
+ budget.visitNode();
23143
+ for (const name of ["toString", "valueOf"]) {
23144
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
23145
+ let result;
23146
+ if (descriptor === void 0) {
23147
+ if (name === "valueOf") continue;
23148
+ result = await defaultToString(value, budget, context, joining);
23149
+ } else {
23150
+ const hook = ownDataValue(value, name);
23151
+ if (!isSandboxClosure(hook)) continue;
23152
+ if (context?.invokeClosure === void 0) {
23153
+ throw new TypeError("String hooks require a sandbox call context.");
23154
+ }
23155
+ result = await context.invokeClosure(hook, [], value);
23156
+ }
23157
+ if (result === null || typeof result !== "object") {
23158
+ return sandboxString(result, budget, context, joining);
23159
+ }
23160
+ }
23161
+ throw new TypeError("Cannot convert object to primitive value");
23162
+ } finally {
23163
+ leaveCall();
23164
+ }
23165
+ }
23166
+ async function defaultToString(value, budget, context, joining) {
23167
+ if (isSandboxDate(value)) return budget.allocateString(dateString(value));
23168
+ if (Array.isArray(value) || isFloat32Array(value)) {
23169
+ if (Object.hasOwn(value, "join")) {
23170
+ const join = ownDataValue(value, "join");
23171
+ if (!isSandboxClosure(join))
23172
+ return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
23173
+ if (context?.invokeClosure === void 0) {
23174
+ throw new TypeError("String hooks require a sandbox call context.");
23175
+ }
23176
+ return context.invokeClosure(join, [], value);
23177
+ }
23178
+ if (joining.has(value)) return "";
23179
+ joining.add(value);
23180
+ try {
23181
+ const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
23182
+ let text = "";
23183
+ for (let index = 0; index < length; index++) {
23184
+ budget.visitNode();
23185
+ const element = ownDataValue(value, String(index));
23186
+ const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
23187
+ text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
23188
+ }
23189
+ return text;
23190
+ } finally {
23191
+ joining.delete(value);
23192
+ }
23193
+ }
23194
+ if (sandboxErrorTypes.has(value)) {
23195
+ const nameValue = ownDataValue(value, "name");
23196
+ const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
23197
+ const messageValue = ownDataValue(value, "message");
23198
+ const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
23199
+ return name === "" ? message : message === "" ? name : `${name}: ${message}`;
23200
+ }
23201
+ return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
23202
+ }
23203
+ function ownDataValue(value, name) {
23204
+ const descriptor = Object.getOwnPropertyDescriptor(value, name);
23205
+ if (descriptor !== void 0 && !Object.hasOwn(descriptor, "value")) {
23206
+ throw new TypeError("String conversion requires sandbox data properties.");
23207
+ }
23208
+ return descriptor?.value;
23209
+ }
23210
+
22938
23211
  // packages/safe-js/src/interp/methods/array.ts
22939
23212
  var activeArrayCallbacks = /* @__PURE__ */ new WeakMap();
22940
23213
  var arrayMethodNames = /* @__PURE__ */ new Set([
@@ -25628,6 +25901,9 @@ async function evaluateObjectExpression(node, context) {
25628
25901
  return value;
25629
25902
  }
25630
25903
  if (isObjectPrototypeSetterProperty(property, key.value)) {
25904
+ if (value.value === null || typeof value.value === "object") {
25905
+ setSandboxPrototype(object, value.value, context.budget);
25906
+ }
25631
25907
  continue;
25632
25908
  }
25633
25909
  defineSandboxProperty(object, String(key.value), value.value);
@@ -25749,7 +26025,11 @@ async function evaluateBinaryExpression(node, context) {
25749
26025
  if (right.kind !== "normal") {
25750
26026
  return right;
25751
26027
  }
25752
- const value = applyBinaryOperator(node, left.value, right.value, context);
26028
+ const value = node.operator === "in" && isGuestHostObject(right.value) ? hasHostObjectMember(right.value, await sandboxString(left.value, context.budget, {
26029
+ stack: context.callStack,
26030
+ thisValue: void 0,
26031
+ invokeClosure: (closure, args, thisValue) => invokeSandboxClosure(closure, args, context, context.callStack, void 0, thisValue)
26032
+ })) : applyBinaryOperator(node, left.value, right.value, context);
25753
26033
  return {
25754
26034
  kind: "normal",
25755
26035
  hasValue: true,
@@ -26432,7 +26712,7 @@ function forInKeys(object, budget) {
26432
26712
  const keys = [];
26433
26713
  const seen = /* @__PURE__ */ new Set();
26434
26714
  let depth = 0;
26435
- for (let current = object; current !== null; current = getSandboxPrototype(current)) {
26715
+ for (let current = object; current !== null; current = getSandboxPrototype(current, budget)) {
26436
26716
  if (depth > 0) budget.visitNode();
26437
26717
  assertSandboxDataDepth(depth++);
26438
26718
  const properties = isGuestClosure(current) ? materializeFunctionProperties(current) : isSandboxClosure(current) ? current.properties ?? {} : current;
@@ -26446,9 +26726,9 @@ function forInKeys(object, budget) {
26446
26726
  return keys;
26447
26727
  }
26448
26728
  function hasForInProperty(object, key, budget) {
26449
- if (isGuestHostObject(object)) return getHostObjectKeys(object).includes(key);
26729
+ if (isGuestHostObject(object)) return hasHostObjectMember(object, key, true);
26450
26730
  let depth = 0;
26451
- for (let current = object; current !== null; current = getSandboxPrototype(current)) {
26731
+ for (let current = object; current !== null; current = getSandboxPrototype(current, budget)) {
26452
26732
  if (depth > 0) budget.visitNode();
26453
26733
  assertSandboxDataDepth(depth++);
26454
26734
  const properties = isGuestClosure(current) ? materializeFunctionProperties(current) : isSandboxClosure(current) ? current.properties ?? {} : current;
@@ -27449,7 +27729,7 @@ function applyBinaryOperator(node, left, right, context) {
27449
27729
  throw new TypeError("Function has a non-object prototype in instanceof check.");
27450
27730
  }
27451
27731
  let depth = 0;
27452
- for (let current = getSandboxPrototype(left); current !== null; current = getSandboxPrototype(current)) {
27732
+ for (let current = getSandboxPrototype(left, context.budget); current !== null; current = getSandboxPrototype(current, context.budget)) {
27453
27733
  context.budget.visitNode();
27454
27734
  assertSandboxDataDepth(depth++);
27455
27735
  if (current === prototype) return true;
@@ -27663,7 +27943,7 @@ function getMemberValue(target, property, context) {
27663
27943
  return getPropertyValue(current, property, context);
27664
27944
  }
27665
27945
  if (Object.hasOwn(current, String(property))) return current[String(property)];
27666
- current = getSandboxPrototype(current);
27946
+ current = getSandboxPrototype(current, context.budget);
27667
27947
  if (current !== null) {
27668
27948
  context.budget.visitNode();
27669
27949
  assertSandboxDataDepth(++depth);
@@ -27713,7 +27993,7 @@ function setSandboxProperty(target, property, value, budget) {
27713
27993
  } else {
27714
27994
  if (typeof prototypeOwner === "object" && prototypeOwner !== null) {
27715
27995
  let depth = 0;
27716
- for (let prototype = getSandboxPrototype(prototypeOwner); prototype !== null; prototype = getSandboxPrototype(prototype)) {
27996
+ for (let prototype = getSandboxPrototype(prototypeOwner, budget); prototype !== null; prototype = getSandboxPrototype(prototype, budget)) {
27717
27997
  budget.visitNode();
27718
27998
  assertSandboxDataDepth(depth++);
27719
27999
  const properties = isSandboxClosure(prototype) ? prototype.properties : prototype;
@@ -27907,6 +28187,13 @@ async function evaluateObjectSpread(node, context) {
27907
28187
  value: []
27908
28188
  };
27909
28189
  }
28190
+ if (isGuestHostObject(value.value)) {
28191
+ const entries = [];
28192
+ for (const key of getHostObjectKeys(value.value)) {
28193
+ if (hasHostObjectMember(value.value, key, true)) entries.push([key, getHostObjectMember(value.value, key)]);
28194
+ }
28195
+ return { ok: true, value: entries };
28196
+ }
27910
28197
  if (isSandboxClosure(value.value) && !isGuestClosure(value.value) || isSandboxPromise(value.value)) {
27911
28198
  throw new TypeError(
27912
28199
  `Cannot spread ${describeObjectSpreadValue(value.value)} into object literal.`
@@ -28089,6 +28376,7 @@ function createInterpretedClosure(node, context, evaluateNode2) {
28089
28376
  function createGeneratorClosure(node, context, evaluateNode2) {
28090
28377
  return createSandboxClosure({
28091
28378
  guest: true,
28379
+ generator: true,
28092
28380
  sandbox: true,
28093
28381
  length: getFunctionLength(node.params),
28094
28382
  ...node.id === void 0 ? {} : { name: node.id.name },
@@ -29355,7 +29643,7 @@ function createReplayableRandom(options = {}) {
29355
29643
 
29356
29644
  // packages/safe-js/src/realm.ts
29357
29645
  import { AsyncLocalStorage as AsyncLocalStorage6 } from "node:async_hooks";
29358
- import { types as types4 } from "node:util";
29646
+ import { types as types5 } from "node:util";
29359
29647
 
29360
29648
  // packages/safe-js/src/interp/globals/console-json.ts
29361
29649
  function createConsoleJsonGlobals(options) {
@@ -29506,7 +29794,7 @@ async function stringifyValue(value, state, indent) {
29506
29794
  return stringifyArray(value, state, indent);
29507
29795
  }
29508
29796
  if (isStringifyObject(value)) {
29509
- return stringifyObject(value, state, indent);
29797
+ return stringifyObject2(value, state, indent);
29510
29798
  }
29511
29799
  return void 0;
29512
29800
  }
@@ -29532,7 +29820,7 @@ ${indent}]`;
29532
29820
  leaveStringifyObject(value, state);
29533
29821
  }
29534
29822
  }
29535
- async function stringifyObject(value, state, indent) {
29823
+ async function stringifyObject2(value, state, indent) {
29536
29824
  enterStringifyObject(value, state);
29537
29825
  try {
29538
29826
  const nextIndent = indent + state.gap;
@@ -29747,90 +30035,138 @@ function assertStructuredCloneable(value, seen) {
29747
30035
  }
29748
30036
  }
29749
30037
 
29750
- // packages/safe-js/src/interp/string-coercion.ts
29751
- function sandboxString(value, budget, context, joining = /* @__PURE__ */ new Set()) {
29752
- if (value === null || typeof value !== "object") {
29753
- if (typeof value === "function") throw new TypeError("Expected a sandbox value.");
29754
- return budget.allocateString(String(value));
29755
- }
29756
- return stringifyObject2(value, budget, context, joining);
29757
- }
29758
- async function stringifyObject2(value, budget, context, joining) {
29759
- const leaveCall = budget.enterCall();
29760
- try {
29761
- budget.visitNode();
29762
- for (const name of ["toString", "valueOf"]) {
29763
- const descriptor = Object.getOwnPropertyDescriptor(value, name);
29764
- let result;
29765
- if (descriptor === void 0) {
29766
- if (name === "valueOf") continue;
29767
- result = await defaultToString(value, budget, context, joining);
29768
- } else {
29769
- const hook = ownDataValue(value, name);
29770
- if (!isSandboxClosure(hook)) continue;
29771
- if (context?.invokeClosure === void 0) {
29772
- throw new TypeError("String hooks require a sandbox call context.");
29773
- }
29774
- result = await context.invokeClosure(hook, [], value);
30038
+ // packages/safe-js/src/interp/globals/object.ts
30039
+ function createObjectGlobal(methods, budget) {
30040
+ const construct = ([value]) => {
30041
+ if (value === null || value === void 0) {
30042
+ budget.chargeDataUsage(1);
30043
+ return /* @__PURE__ */ Object.create(null);
30044
+ }
30045
+ if (typeof value !== "object") throw new TypeError("Object primitive boxing is not supported.");
30046
+ return value;
30047
+ };
30048
+ const constructor = createSandboxClosure({
30049
+ guest: true,
30050
+ sandbox: true,
30051
+ name: "Object",
30052
+ length: 1,
30053
+ call: construct,
30054
+ construct
30055
+ });
30056
+ const properties = materializeFunctionProperties(constructor);
30057
+ const prototype = properties.prototype;
30058
+ Object.defineProperty(properties, "prototype", { writable: false });
30059
+ for (const [name, method] of Object.entries(methods)) {
30060
+ Object.defineProperty(properties, name, { value: method, writable: true, configurable: true });
30061
+ }
30062
+ const prototypeMethods = {
30063
+ toString: createSandboxClosure({
30064
+ sandbox: true,
30065
+ name: "toString",
30066
+ length: 0,
30067
+ call: (_args, context) => budget.allocateString(`[object ${typeTag(context?.thisValue)}]`)
30068
+ }),
30069
+ valueOf: createSandboxClosure({
30070
+ sandbox: true,
30071
+ name: "valueOf",
30072
+ length: 0,
30073
+ call: (_args, context) => {
30074
+ const value = requireReceiver(context?.thisValue);
30075
+ if (typeof value !== "object")
30076
+ throw new TypeError("Object primitive boxing is not supported.");
30077
+ return value;
29775
30078
  }
29776
- if (result === null || typeof result !== "object") {
29777
- return sandboxString(result, budget, context, joining);
30079
+ }),
30080
+ hasOwnProperty: createSandboxClosure({
30081
+ sandbox: true,
30082
+ name: "hasOwnProperty",
30083
+ length: 1,
30084
+ call: async ([key], context) => hasOwnSandboxProperty(
30085
+ requireReceiver(context?.thisValue),
30086
+ await sandboxString(key, budget, context),
30087
+ false
30088
+ )
30089
+ }),
30090
+ propertyIsEnumerable: createSandboxClosure({
30091
+ sandbox: true,
30092
+ name: "propertyIsEnumerable",
30093
+ length: 1,
30094
+ call: async ([key], context) => hasOwnSandboxProperty(
30095
+ requireReceiver(context?.thisValue),
30096
+ await sandboxString(key, budget, context),
30097
+ true
30098
+ )
30099
+ }),
30100
+ isPrototypeOf: createSandboxClosure({
30101
+ sandbox: true,
30102
+ name: "isPrototypeOf",
30103
+ length: 1,
30104
+ call: ([value], context) => {
30105
+ if (typeof value !== "object" || value === null) return false;
30106
+ const receiver = requireReceiver(context?.thisValue);
30107
+ let depth = 0;
30108
+ for (let current = getSandboxPrototype(value, budget); current !== null; current = getSandboxPrototype(current, budget)) {
30109
+ budget.visitNode();
30110
+ assertSandboxDataDepth(depth++);
30111
+ if (current === receiver) return true;
30112
+ }
30113
+ return false;
29778
30114
  }
29779
- }
29780
- throw new TypeError("Cannot convert object to primitive value");
29781
- } finally {
29782
- leaveCall();
30115
+ })
30116
+ };
30117
+ for (const [name, method] of Object.entries(prototypeMethods)) {
30118
+ Object.defineProperty(prototype, name, { value: method, writable: true, configurable: true });
29783
30119
  }
30120
+ markDescriptorObject(prototype);
30121
+ installObjectPrototype(budget, prototype, constructor);
30122
+ return constructor;
29784
30123
  }
29785
- async function defaultToString(value, budget, context, joining) {
29786
- if (isSandboxDate(value)) return budget.allocateString(dateString(value));
29787
- if (Array.isArray(value) || isFloat32Array(value)) {
29788
- if (Object.hasOwn(value, "join")) {
29789
- const join = ownDataValue(value, "join");
29790
- if (!isSandboxClosure(join))
29791
- return isFloat32Array(value) ? "[object Float32Array]" : "[object Array]";
29792
- if (context?.invokeClosure === void 0) {
29793
- throw new TypeError("String hooks require a sandbox call context.");
29794
- }
29795
- return context.invokeClosure(join, [], value);
29796
- }
29797
- if (joining.has(value)) return "";
29798
- joining.add(value);
29799
- try {
29800
- const length = isFloat32Array(value) ? float32Storage(value).length : value.length;
29801
- let text = "";
29802
- for (let index = 0; index < length; index++) {
29803
- budget.visitNode();
29804
- const element = ownDataValue(value, String(index));
29805
- const part = element === null || element === void 0 ? "" : await sandboxString(element, budget, context, joining);
29806
- text = budget.allocateString(text + (index === 0 ? "" : ",") + part);
29807
- }
29808
- return text;
29809
- } finally {
29810
- joining.delete(value);
29811
- }
29812
- }
29813
- if (sandboxErrorTypes.has(value)) {
29814
- const nameValue = ownDataValue(value, "name");
29815
- const name = nameValue === void 0 ? "Error" : await sandboxString(nameValue, budget, context, joining);
29816
- const messageValue = ownDataValue(value, "message");
29817
- const message = messageValue === void 0 ? "" : await sandboxString(messageValue, budget, context, joining);
29818
- return name === "" ? message : message === "" ? name : `${name}: ${message}`;
29819
- }
29820
- return isSandboxPromise(value) ? "[object Promise]" : "[object Object]";
30124
+ function requireReceiver(value) {
30125
+ if (value === null || value === void 0)
30126
+ throw new TypeError("Object method requires a non-null receiver.");
30127
+ return value;
29821
30128
  }
29822
- function ownDataValue(value, name) {
29823
- const descriptor = Object.getOwnPropertyDescriptor(value, name);
29824
- if (descriptor !== void 0 && !Object.hasOwn(descriptor, "value")) {
29825
- throw new TypeError("String conversion requires sandbox data properties.");
29826
- }
29827
- return descriptor?.value;
30129
+ function hasOwnSandboxProperty(value, key, enumerable) {
30130
+ requireReceiver(value);
30131
+ if (isGuestHostObject(value)) return hasHostObjectMember(value, key, enumerable);
30132
+ let properties;
30133
+ if (isGuestClosure(value)) properties = materializeFunctionProperties(value);
30134
+ else if (isSandboxClosure(value)) {
30135
+ if (key === "length" || key === "name") return !enumerable;
30136
+ properties = value.properties ?? /* @__PURE__ */ Object.create(null);
30137
+ } else if (isSandboxMap(value) || isSandboxSet(value) || isSandboxPromise(value) || isSandboxGenerator(value))
30138
+ return false;
30139
+ else if (isSandboxRegex(value)) return key === "lastIndex" && !enumerable;
30140
+ else properties = Object(value);
30141
+ const descriptor = Object.getOwnPropertyDescriptor(properties, key);
30142
+ return descriptor !== void 0 && (!enumerable || descriptor.enumerable === true);
30143
+ }
30144
+ function typeTag(value) {
30145
+ if (value === void 0) return "Undefined";
30146
+ if (value === null) return "Null";
30147
+ if (typeof value === "string") return "String";
30148
+ if (typeof value === "number") return "Number";
30149
+ if (typeof value === "boolean") return "Boolean";
30150
+ if (isSandboxClosure(value)) {
30151
+ while (value.boundTarget !== void 0) value = value.boundTarget;
30152
+ return value.generator ? "GeneratorFunction" : value.async ? "AsyncFunction" : "Function";
30153
+ }
30154
+ if (Array.isArray(value)) return "Array";
30155
+ if (isSandboxDate(value)) return "Date";
30156
+ if (isSandboxErrorConstructorInstance(value, "Error")) return "Error";
30157
+ if (isSandboxRegex(value)) return "RegExp";
30158
+ if (isSandboxMap(value)) return "Map";
30159
+ if (isSandboxSet(value)) return "Set";
30160
+ if (isSandboxPromise(value)) return "Promise";
30161
+ if (isSandboxGenerator(value)) return "Generator";
30162
+ if (isFloat32Array(value)) return "Float32Array";
30163
+ return "Object";
29828
30164
  }
29829
30165
 
29830
30166
  // packages/safe-js/src/interp/globals/object-array.ts
29831
30167
  function createObjectArrayGlobals(options) {
29832
30168
  return {
29833
- Object: {
30169
+ Object: createObjectGlobal({
29834
30170
  keys: createSandboxClosure({
29835
30171
  sandbox: true,
29836
30172
  call: ([value]) => budgetSandboxValue2(getOwnEnumerableKeys(value), options.budget),
@@ -29848,7 +30184,11 @@ function createObjectArrayGlobals(options) {
29848
30184
  }),
29849
30185
  hasOwn: createSandboxClosure({
29850
30186
  sandbox: true,
29851
- call: ([value, key]) => Reflect.apply(Object.hasOwn, Object, [isSandboxClosure(value) ? objectProperties(value) : value, key]),
30187
+ call: ([value, key], context) => {
30188
+ if (value === null || value === void 0) throw new TypeError("Cannot convert undefined or null to object.");
30189
+ const name = sandboxString(key, options.budget, context);
30190
+ return typeof name === "string" ? hasOwnSandboxProperty(value, name, false) : name.then((property) => hasOwnSandboxProperty(value, property, false));
30191
+ },
29852
30192
  name: "hasOwn"
29853
30193
  }),
29854
30194
  getOwnPropertyDescriptor: createSandboxClosure({
@@ -29889,7 +30229,7 @@ function createObjectArrayGlobals(options) {
29889
30229
  call: ([value]) => {
29890
30230
  if (isSandboxDate(value)) return getDatePrototype(value, options.budget, options.compileOwner);
29891
30231
  objectProperties(value);
29892
- return getSandboxPrototype(value);
30232
+ return getSandboxPrototype(value, options.budget);
29893
30233
  },
29894
30234
  name: "getPrototypeOf"
29895
30235
  }),
@@ -29947,6 +30287,7 @@ function createObjectArrayGlobals(options) {
29947
30287
  freeze: createSandboxClosure({
29948
30288
  sandbox: true,
29949
30289
  call: ([value]) => {
30290
+ if (isGuestHostObject(value)) throw new TypeError("Live host objects cannot be frozen.");
29950
30291
  if (typeof value === "object" && value !== null) {
29951
30292
  Object.freeze(isGuestClosure(value) ? materializeFunctionProperties(value) : value);
29952
30293
  }
@@ -29964,7 +30305,7 @@ function createObjectArrayGlobals(options) {
29964
30305
  call: ([target, ...sources]) => assignSandboxValues(target, sources, options.budget),
29965
30306
  name: "assign"
29966
30307
  })
29967
- },
30308
+ }, options.budget),
29968
30309
  Array: createSandboxClosure({
29969
30310
  sandbox: true,
29970
30311
  call: (args) => createArrayFromConstructorArgs(args, options.budget),
@@ -30161,6 +30502,21 @@ function isAssignableSandboxTarget(value) {
30161
30502
  async function arrayFromSandboxValues(args, budget) {
30162
30503
  const [items, mapFn, thisValue] = args;
30163
30504
  const iterator = getSandboxIterator(items);
30505
+ if (isGuestHostObject(items) && iterator !== void 0) {
30506
+ if (mapFn !== void 0 && !isSandboxClosure(mapFn))
30507
+ throw new TypeError("Array.from mapping callback must be a function.");
30508
+ const values2 = [];
30509
+ while (true) {
30510
+ const next = await iterator.next();
30511
+ if (next.done) break;
30512
+ budget.allocateArrayLength(values2.length + 1);
30513
+ const value = mapFn === void 0 ? next.value : await mapFn.call([next.value, values2.length], { stack: [], thisValue });
30514
+ if (isSandboxPromise(value) && value.synchronousPrefix !== void 0)
30515
+ await value.synchronousPrefix;
30516
+ values2.push(value);
30517
+ }
30518
+ return allocateProducedSandboxValue(values2, budget);
30519
+ }
30164
30520
  const values = iterator === void 0 ? Reflect.apply(Array.from, Array, [items]) : await collectIteratorValues(iterator);
30165
30521
  if (mapFn === void 0 || !isSandboxClosure(mapFn)) {
30166
30522
  if (mapFn !== void 0) {
@@ -30419,7 +30775,7 @@ var RealmState = class {
30419
30775
  throw new TypeError("Realm limits must be positive safe integers with supported names.");
30420
30776
  this.limits[name] = Number(value);
30421
30777
  }
30422
- if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types4.isProxy(options.extensions)))
30778
+ if (options.extensions !== void 0 && (!Array.isArray(options.extensions) || types5.isProxy(options.extensions)))
30423
30779
  throw new TypeError("Extensions must be a registration array.");
30424
30780
  const registrations = options.extensions ?? [];
30425
30781
  const extensions = [];
@@ -30491,6 +30847,7 @@ var RealmState = class {
30491
30847
  this.budget.setRetainedValues(this, this.retainedRoots);
30492
30848
  this.tracker.onFatalRejection((error) => this.poison(error));
30493
30849
  } catch (error) {
30850
+ releaseObjectPrototype(this.budget);
30494
30851
  this.compilation.dispose();
30495
30852
  this.lease.release();
30496
30853
  throw error;
@@ -30638,7 +30995,7 @@ var RealmState = class {
30638
30995
  return this.phase.run(phase, () => {
30639
30996
  try {
30640
30997
  const result = call();
30641
- if (types4.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
30998
+ if (types5.isPromise(result) || phase.pending.size > 0 || phase.failure !== void 0) {
30642
30999
  return Promise.resolve(result).then(
30643
31000
  async (value) => {
30644
31001
  await Promise.allSettled(phase.pending);
@@ -30693,17 +31050,26 @@ var RealmState = class {
30693
31050
  owner: this,
30694
31051
  assertActive: this.assertOpen,
30695
31052
  chargeWork: this.chargeWork,
30696
- read: (operation) => {
31053
+ checkLength: (length) => this.budget.allocateArrayLength(length),
31054
+ checkTemporaryDataSize: (size) => {
31055
+ const temporary = {};
31056
+ try {
31057
+ this.budget.setRetainedDataUsage(temporary, size);
31058
+ } finally {
31059
+ this.budget.setRetainedDataUsage(temporary, 0);
31060
+ }
31061
+ },
31062
+ read: (operation, validate) => {
30697
31063
  const value = this.invokeHost(operation, operation);
30698
- if (types4.isPromise(value)) {
31064
+ if (types5.isPromise(value)) {
30699
31065
  void Promise.resolve(value).catch(() => void 0);
30700
31066
  throw new TypeError("Live property getters must be synchronous.");
30701
31067
  }
30702
- return this.importValue(value);
31068
+ return this.importValue(validate === void 0 ? value : validate(value));
30703
31069
  },
30704
31070
  write: (operation, value) => {
30705
31071
  const result = this.invokeHost(operation, () => operation(this.exportValue(value)));
30706
- if (types4.isPromise(result)) {
31072
+ if (types5.isPromise(result)) {
30707
31073
  void Promise.resolve(result).catch(() => void 0);
30708
31074
  throw new TypeError("Live property setters must be synchronous.");
30709
31075
  }
@@ -30896,7 +31262,7 @@ var RealmState = class {
30896
31262
  }
30897
31263
  });
30898
31264
  const output = getExtensionSetup(extension)(context);
30899
- if (types4.isPromise(output)) {
31265
+ if (types5.isPromise(output)) {
30900
31266
  void Promise.resolve(output).catch(() => void 0);
30901
31267
  throw new TypeError("Extension setup must be synchronous.");
30902
31268
  }
@@ -31057,6 +31423,7 @@ var RealmState = class {
31057
31423
  for (const reference of this.guestReferences.keys()) revokeGuestReference(reference, this);
31058
31424
  this.guestReferences.clear();
31059
31425
  this.budget.setRetainedValues(this, void 0);
31426
+ releaseObjectPrototype(this.budget);
31060
31427
  this.disposal = (async () => {
31061
31428
  const errors = [];
31062
31429
  for (const cleanup of this.cleanups.splice(0).reverse()) {
@@ -31083,7 +31450,7 @@ var RealmState = class {
31083
31450
  };
31084
31451
  function readModules(input) {
31085
31452
  const entries = (value, label) => {
31086
- if (types4.isMap(value) && !types4.isProxy(value)) {
31453
+ if (types5.isMap(value) && !types5.isProxy(value)) {
31087
31454
  const result = [...Map.prototype.entries.call(value)];
31088
31455
  if (result.length > 4096 || result.some(([key]) => typeof key !== "string" || key.length === 0))
31089
31456
  throw new TypeError(`${label} requires bounded string keys.`);
@@ -32065,6 +32432,7 @@ function run(source, options = {}) {
32065
32432
  }
32066
32433
  });
32067
32434
  } finally {
32435
+ releaseObjectPrototype(budget);
32068
32436
  compilation.dispose();
32069
32437
  operation.release();
32070
32438
  }
@@ -32307,4 +32675,4 @@ export {
32307
32675
  FileSnapshotBackend,
32308
32676
  run
32309
32677
  };
32310
- //# sourceMappingURL=chunk-BWVASPJX.js.map
32678
+ //# sourceMappingURL=chunk-MO3YD4ID.js.map