@poe-platform/safe-js 0.1.303 → 0.1.305

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.
@@ -14080,6 +14080,34 @@ function functionString(value) {
14080
14080
  return `function ${name}() { [native code] }`;
14081
14081
  }
14082
14082
 
14083
+ // packages/safe-js/src/interp/bound-function-state.ts
14084
+ var boundFunctionStates = /* @__PURE__ */ new WeakMap();
14085
+
14086
+ // packages/safe-js/src/interp/bound-function.ts
14087
+ function createBoundFunction(state, name, length, callClosure) {
14088
+ const bound = createSandboxClosure({
14089
+ guest: true,
14090
+ sandbox: true,
14091
+ name,
14092
+ length,
14093
+ boundTarget: state.target,
14094
+ retainedValues: () => [state.target, state.thisValue, ...state.args, bound.name],
14095
+ call: (args, context) => callClosure(state.target, [...state.args, ...args], context?.stack ?? [], state.thisValue),
14096
+ ...state.target.construct === void 0 ? {} : {
14097
+ construct: (args, context) => callClosure(
14098
+ state.target,
14099
+ [...state.args, ...args],
14100
+ context?.stack ?? [],
14101
+ void 0,
14102
+ true,
14103
+ context?.newTarget === bound ? state.target : context?.newTarget
14104
+ )
14105
+ }
14106
+ });
14107
+ boundFunctionStates.set(bound, state);
14108
+ return bound;
14109
+ }
14110
+
14083
14111
  // packages/safe-js/src/interp/methods/function.ts
14084
14112
  var functionMethodNames = /* @__PURE__ */ new Set(["apply", "bind", "call", "toString"]);
14085
14113
  function getFunctionMember(target, property, options) {
@@ -14134,25 +14162,7 @@ function callFunctionMethod(target, methodName, args, options, stack, context) {
14134
14162
  const explicitPrototype = hasExplicitSandboxPrototype(target);
14135
14163
  const prototype = getSandboxPrototype(target, options.budget);
14136
14164
  const bind = (length, name) => {
14137
- const bound = createSandboxClosure({
14138
- guest: true,
14139
- sandbox: true,
14140
- name: `bound ${name}`,
14141
- length,
14142
- boundTarget: target,
14143
- retainedValues: () => [target, thisValue, ...boundArgs, bound.name],
14144
- call: (callArgs, context2) => options.callClosure(target, [...boundArgs, ...callArgs], context2?.stack ?? [], thisValue),
14145
- ...target.construct === void 0 ? {} : {
14146
- construct: (callArgs, context2) => options.callClosure(
14147
- target,
14148
- [...boundArgs, ...callArgs],
14149
- context2?.stack ?? [],
14150
- void 0,
14151
- true,
14152
- context2?.newTarget === bound ? target : context2?.newTarget
14153
- )
14154
- }
14155
- });
14165
+ const bound = createBoundFunction({ target, thisValue, args: boundArgs }, `bound ${name}`, length, options.callClosure);
14156
14166
  if (explicitPrototype) setSandboxPrototype(bound, prototype, options.budget);
14157
14167
  return bound;
14158
14168
  };
@@ -14185,25 +14195,37 @@ function callFunctionMethod(target, methodName, args, options, stack, context) {
14185
14195
  if (applyArgs === null || applyArgs === void 0) {
14186
14196
  return options.callClosure(target, [], stack, thisValue);
14187
14197
  }
14188
- if (!Array.isArray(applyArgs)) {
14189
- throw new TypeError("Function#apply requires an array or nullish arguments value.");
14198
+ if (typeof applyArgs !== "object") {
14199
+ throw new TypeError("Function#apply requires an object or nullish arguments value.");
14190
14200
  }
14191
- if (context?.getProperty === void 0)
14201
+ if (context?.getProperty === void 0 && Array.isArray(applyArgs))
14192
14202
  return options.callClosure(target, applyArgs, stack, thisValue);
14193
14203
  return (async () => {
14204
+ const budget = options.budget ?? new Budget();
14205
+ const invocationContext = {
14206
+ ...context,
14207
+ stack,
14208
+ thisValue: context?.thisValue,
14209
+ invokeClosure: context?.invokeClosure ?? ((callee, values2, receiver) => Promise.resolve(options.callClosure(callee, values2, stack, receiver)))
14210
+ };
14211
+ const read = (value, key) => {
14212
+ if (context?.getProperty !== void 0) return context.getProperty(value, key);
14213
+ const descriptor = getSandboxPropertyDescriptor(value, key, budget);
14214
+ return descriptor === void 0 ? void 0 : readPropertyDescriptor(descriptor, value, invocationContext);
14215
+ };
14194
14216
  const values = [];
14195
- const length = applyArgs.length;
14196
- options.budget?.allocateArrayLength(length);
14197
- const retained = {};
14198
- options.budget?.setRetainedValues(retained, () => values);
14217
+ const release = retainValues(budget, () => [applyArgs, ...values]);
14199
14218
  try {
14219
+ const number = await sandboxNumber(await read(applyArgs, "length"), budget, invocationContext);
14220
+ const length = Number.isNaN(number) || number <= 0 ? 0 : Math.min(Math.trunc(number), Number.MAX_SAFE_INTEGER);
14221
+ budget.allocateArrayLength(length);
14200
14222
  for (let index = 0; index < length; index++) {
14201
- options.budget?.visitNode();
14202
- values.push(await context.getProperty(applyArgs, index));
14223
+ budget.visitNode();
14224
+ values.push(await read(applyArgs, String(index)));
14203
14225
  }
14204
14226
  return await options.callClosure(target, values, stack, thisValue);
14205
14227
  } finally {
14206
- options.budget?.setRetainedValues(retained, void 0);
14228
+ release();
14207
14229
  }
14208
14230
  })();
14209
14231
  }
@@ -20281,6 +20303,18 @@ function captureGuestHeapNode(value, encode) {
20281
20303
  const state2 = captureObjectState(value, encode);
20282
20304
  return { kind: "intrinsic", id: intrinsic, ...state2 === void 0 ? {} : { state: state2 } };
20283
20305
  }
20306
+ const bound = boundFunctionStates.get(value);
20307
+ if (bound !== void 0 && isSandboxClosure(value)) {
20308
+ return {
20309
+ kind: "bound-function",
20310
+ target: encode(bound.target),
20311
+ thisValue: encode(bound.thisValue),
20312
+ args: bound.args.map(encode),
20313
+ length: encode(value.length),
20314
+ ...value.name === void 0 ? {} : { name: value.name },
20315
+ state: captureObjectState(value, encode)
20316
+ };
20317
+ }
20284
20318
  if (isSandboxMap(value)) return { kind: "map", entries: [...value.entries].map(([key, entry]) => [encode(key), encode(entry)]), ...serializeCollectionProperties(value, encode) };
20285
20319
  if (isSandboxSet(value)) return { kind: "set", values: [...value.values].map(encode), ...serializeCollectionProperties(value, encode) };
20286
20320
  if (isSandboxArrayIterator(value)) {
@@ -24401,7 +24435,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
24401
24435
  createRawJson(node.text);
24402
24436
  return true;
24403
24437
  }
24404
- if (!["intrinsic", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "array-iterator", "map", "set"].includes(String(node.kind))) return false;
24438
+ if (!["intrinsic", "bound-function", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "array-iterator", "map", "set"].includes(String(node.kind))) return false;
24405
24439
  const reference = (value, kinds) => {
24406
24440
  const ref = record3(value);
24407
24441
  fields(ref, ["kind", "id"]);
@@ -24412,7 +24446,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
24412
24446
  };
24413
24447
  const callable = (value) => {
24414
24448
  if (absent(value)) return;
24415
- const target = reference(value, ["intrinsic", "guest-function", "guest-class"]);
24449
+ const target = reference(value, ["intrinsic", "bound-function", "guest-function", "guest-class"]);
24416
24450
  if (target.kind === "intrinsic" && intrinsicCatalogue().get(String(target.id)) !== true)
24417
24451
  throw new TypeError("Guest accessor reference is not callable.");
24418
24452
  };
@@ -24508,6 +24542,22 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
24508
24542
  if (descriptor.kind !== "data" || descriptor.writable !== false || descriptor.enumerable !== false || descriptor.configurable !== false)
24509
24543
  throw new TypeError("Invalid class prototype descriptor.");
24510
24544
  reference(descriptor.value, ["object", "guest-object"]);
24545
+ } else if (node.kind === "bound-function") {
24546
+ fields(node, ["kind", "target", "thisValue", "args", "length", "state"], ["name"]);
24547
+ if (Object.hasOwn(node, "name") && typeof node.name !== "string") throw new TypeError("Invalid bound function name.");
24548
+ if (array(node.args).length > maxArrayLength) throw new TypeError("Bound arguments exceed allocation limit.");
24549
+ if (!absent(node.length) && !(typeof node.length === "number" && node.length >= 0) && !(record3(node.length).kind === "number" && record3(node.length).value === "Infinity"))
24550
+ throw new TypeError("Invalid bound function length.");
24551
+ const visited = /* @__PURE__ */ new Set([raw]);
24552
+ let current = node;
24553
+ while (current.kind === "bound-function") {
24554
+ assertSnapshotDataDepth(visited.size, "<bound-target>");
24555
+ callable(current.target);
24556
+ current = reference(current.target);
24557
+ if (visited.has(current)) throw new TypeError("Cyclic bound function target.");
24558
+ visited.add(current);
24559
+ }
24560
+ state(node.state);
24511
24561
  } else if (node.kind === "guest-function") {
24512
24562
  fields(node, ["kind", "astNodeId", "scope", "state"], ["name", "environment"]);
24513
24563
  if (integer(node.astNodeId) < 1) throw new TypeError("Invalid guest AST identity.");
@@ -41201,4 +41251,4 @@ export {
41201
41251
  FileSnapshotBackend,
41202
41252
  run
41203
41253
  };
41204
- //# sourceMappingURL=chunk-S5C5SAU4.js.map
41254
+ //# sourceMappingURL=chunk-JIC2DHRN.js.map