@poe-platform/safe-js 0.1.302 → 0.1.304

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) {
@@ -14131,28 +14159,11 @@ function callFunctionMethod(target, methodName, args, options, stack, context) {
14131
14159
  const thisValue = args[0];
14132
14160
  if (methodName === "bind") {
14133
14161
  const boundArgs = args.slice(1);
14162
+ const explicitPrototype = hasExplicitSandboxPrototype(target);
14163
+ const prototype = getSandboxPrototype(target, options.budget);
14134
14164
  const bind = (length, name) => {
14135
- const bound = createSandboxClosure({
14136
- guest: true,
14137
- sandbox: true,
14138
- name: `bound ${name}`,
14139
- length,
14140
- boundTarget: target,
14141
- retainedValues: () => [target, thisValue, ...boundArgs, bound.name],
14142
- call: (callArgs, context2) => options.callClosure(target, [...boundArgs, ...callArgs], context2?.stack ?? [], thisValue),
14143
- ...target.construct === void 0 ? {} : {
14144
- construct: (callArgs, context2) => options.callClosure(
14145
- target,
14146
- [...boundArgs, ...callArgs],
14147
- context2?.stack ?? [],
14148
- void 0,
14149
- true,
14150
- context2?.newTarget === bound ? target : context2?.newTarget
14151
- )
14152
- }
14153
- });
14154
- if (hasExplicitSandboxPrototype(target))
14155
- setSandboxPrototype(bound, getSandboxPrototype(target, options.budget), options.budget);
14165
+ const bound = createBoundFunction({ target, thisValue, args: boundArgs }, `bound ${name}`, length, options.callClosure);
14166
+ if (explicitPrototype) setSandboxPrototype(bound, prototype, options.budget);
14156
14167
  return bound;
14157
14168
  };
14158
14169
  if (context?.getProperty === void 0)
@@ -14161,15 +14172,20 @@ function callFunctionMethod(target, methodName, args, options, stack, context) {
14161
14172
  target.name ?? ""
14162
14173
  );
14163
14174
  return (async () => {
14164
- const properties = target.properties;
14165
- const defaultName = target.name;
14166
- const hasLength = !isGuestClosure(target) || target.properties === void 0 || Object.hasOwn(target.properties, "length");
14167
- const length = hasLength ? await context.getProperty(target, "length") : void 0;
14168
- const name = !isGuestClosure(target) && !Object.hasOwn(properties ?? {}, "name") ? defaultName : await context.getProperty(target, "name");
14169
- return bind(
14170
- typeof length === "number" && !Number.isNaN(length) ? Math.max(0, Math.trunc(length) - boundArgs.length) : 0,
14171
- typeof name === "string" ? name : ""
14172
- );
14175
+ const release = options.budget !== void 0 && explicitPrototype && prototype !== null ? retainValues(options.budget, () => [prototype]) : void 0;
14176
+ try {
14177
+ const properties = target.properties;
14178
+ const defaultName = target.name;
14179
+ const hasLength = !isGuestClosure(target) || target.properties === void 0 || Object.hasOwn(target.properties, "length");
14180
+ const length = hasLength ? await context.getProperty(target, "length") : void 0;
14181
+ const name = !isGuestClosure(target) && !Object.hasOwn(properties ?? {}, "name") ? defaultName : await context.getProperty(target, "name");
14182
+ return bind(
14183
+ typeof length === "number" && !Number.isNaN(length) ? Math.max(0, Math.trunc(length) - boundArgs.length) : 0,
14184
+ typeof name === "string" ? name : ""
14185
+ );
14186
+ } finally {
14187
+ release?.();
14188
+ }
14173
14189
  })();
14174
14190
  }
14175
14191
  if (methodName === "call") {
@@ -20275,6 +20291,18 @@ function captureGuestHeapNode(value, encode) {
20275
20291
  const state2 = captureObjectState(value, encode);
20276
20292
  return { kind: "intrinsic", id: intrinsic, ...state2 === void 0 ? {} : { state: state2 } };
20277
20293
  }
20294
+ const bound = boundFunctionStates.get(value);
20295
+ if (bound !== void 0 && isSandboxClosure(value)) {
20296
+ return {
20297
+ kind: "bound-function",
20298
+ target: encode(bound.target),
20299
+ thisValue: encode(bound.thisValue),
20300
+ args: bound.args.map(encode),
20301
+ length: encode(value.length),
20302
+ ...value.name === void 0 ? {} : { name: value.name },
20303
+ state: captureObjectState(value, encode)
20304
+ };
20305
+ }
20278
20306
  if (isSandboxMap(value)) return { kind: "map", entries: [...value.entries].map(([key, entry]) => [encode(key), encode(entry)]), ...serializeCollectionProperties(value, encode) };
20279
20307
  if (isSandboxSet(value)) return { kind: "set", values: [...value.values].map(encode), ...serializeCollectionProperties(value, encode) };
20280
20308
  if (isSandboxArrayIterator(value)) {
@@ -24395,7 +24423,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
24395
24423
  createRawJson(node.text);
24396
24424
  return true;
24397
24425
  }
24398
- if (!["intrinsic", "guest-function", "guest-class", "guest-generator", "scope-frame", "guest-object", "guest-array", "array-iterator", "map", "set"].includes(String(node.kind))) return false;
24426
+ 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;
24399
24427
  const reference = (value, kinds) => {
24400
24428
  const ref = record3(value);
24401
24429
  fields(ref, ["kind", "id"]);
@@ -24406,7 +24434,7 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
24406
24434
  };
24407
24435
  const callable = (value) => {
24408
24436
  if (absent(value)) return;
24409
- const target = reference(value, ["intrinsic", "guest-function", "guest-class"]);
24437
+ const target = reference(value, ["intrinsic", "bound-function", "guest-function", "guest-class"]);
24410
24438
  if (target.kind === "intrinsic" && intrinsicCatalogue().get(String(target.id)) !== true)
24411
24439
  throw new TypeError("Guest accessor reference is not callable.");
24412
24440
  };
@@ -24502,6 +24530,22 @@ function validateGuestHeapNode(raw, heap, maxArrayLength = 4294967295) {
24502
24530
  if (descriptor.kind !== "data" || descriptor.writable !== false || descriptor.enumerable !== false || descriptor.configurable !== false)
24503
24531
  throw new TypeError("Invalid class prototype descriptor.");
24504
24532
  reference(descriptor.value, ["object", "guest-object"]);
24533
+ } else if (node.kind === "bound-function") {
24534
+ fields(node, ["kind", "target", "thisValue", "args", "length", "state"], ["name"]);
24535
+ if (Object.hasOwn(node, "name") && typeof node.name !== "string") throw new TypeError("Invalid bound function name.");
24536
+ if (array(node.args).length > maxArrayLength) throw new TypeError("Bound arguments exceed allocation limit.");
24537
+ if (!absent(node.length) && !(typeof node.length === "number" && node.length >= 0) && !(record3(node.length).kind === "number" && record3(node.length).value === "Infinity"))
24538
+ throw new TypeError("Invalid bound function length.");
24539
+ const visited = /* @__PURE__ */ new Set([raw]);
24540
+ let current = node;
24541
+ while (current.kind === "bound-function") {
24542
+ assertSnapshotDataDepth(visited.size, "<bound-target>");
24543
+ callable(current.target);
24544
+ current = reference(current.target);
24545
+ if (visited.has(current)) throw new TypeError("Cyclic bound function target.");
24546
+ visited.add(current);
24547
+ }
24548
+ state(node.state);
24505
24549
  } else if (node.kind === "guest-function") {
24506
24550
  fields(node, ["kind", "astNodeId", "scope", "state"], ["name", "environment"]);
24507
24551
  if (integer(node.astNodeId) < 1) throw new TypeError("Invalid guest AST identity.");
@@ -41195,4 +41239,4 @@ export {
41195
41239
  FileSnapshotBackend,
41196
41240
  run
41197
41241
  };
41198
- //# sourceMappingURL=chunk-T2TQBEDG.js.map
41242
+ //# sourceMappingURL=chunk-I3JCUPXR.js.map