@poe-platform/safe-js 0.1.720 → 0.1.722
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +50 -7
- package/dist/config-mutations/types.d.ts +3 -1
- package/dist/safe-js/chunks/{chunk-B2SQLK4O.js → chunk-3QQYJ4RQ.js} +3 -2
- package/dist/safe-js/chunks/chunk-3QQYJ4RQ.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-OP3H3ZDN.js → chunk-55RIIUGG.js} +23 -7
- package/dist/safe-js/chunks/chunk-55RIIUGG.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-NJM2Q74Z.js → chunk-7SBQ7WTV.js} +10 -11
- package/dist/safe-js/chunks/chunk-7SBQ7WTV.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-KP6I45ET.js → chunk-BNIEPGDU.js} +9885 -8523
- package/dist/safe-js/chunks/{chunk-KP6I45ET.js.map → chunk-BNIEPGDU.js.map} +4 -4
- package/dist/safe-js/chunks/{chunk-HYD4K4HN.js → chunk-D3GC5QPZ.js} +63 -1
- package/dist/safe-js/chunks/chunk-D3GC5QPZ.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-KK5NCR5R.js → chunk-EH5A2EQI.js} +501 -150
- package/dist/safe-js/chunks/chunk-EH5A2EQI.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-APKV5Y6T.js → chunk-FA5CQO6V.js} +2 -2
- package/dist/safe-js/chunks/{chunk-RML35GIF.js → chunk-GCOLKRMY.js} +4 -4
- package/dist/safe-js/chunks/{chunk-U6KZ2DQ2.js → chunk-K3ZRBAG5.js} +3 -3
- package/dist/safe-js/chunks/{chunk-BGJXQN4A.js → chunk-QL2ALAE6.js} +4 -4
- package/dist/safe-js/chunks/{chunk-IDQ67DY2.js → chunk-RYVHEOHM.js} +1131 -101
- package/dist/safe-js/chunks/chunk-RYVHEOHM.js.map +7 -0
- package/dist/safe-js/chunks/{chunk-A7CADQAD.js → chunk-S2GFVXSI.js} +3 -3
- package/dist/safe-js/chunks/{chunk-XMA6FOJU.js → chunk-WF7HYDJ4.js} +4 -5
- package/dist/safe-js/chunks/{chunk-XMA6FOJU.js.map → chunk-WF7HYDJ4.js.map} +2 -2
- package/dist/safe-js/chunks/{chunk-NEJ44T4Y.js → chunk-XHSOM5CG.js} +2 -2
- package/dist/safe-js/chunks/{cli-runtime-PO6DQDHP.js → cli-runtime-6QPGM3TX.js} +14 -14
- package/dist/safe-js/chunks/{dump-TRGFSCJ7.js → dump-TU6SYRFD.js} +4 -4
- package/dist/safe-js/chunks/{fs-4T5MZW5J.js → fs-HTZT32MQ.js} +4 -4
- package/dist/safe-js/chunks/harness-RYAMI444.js +10 -0
- package/dist/safe-js/chunks/mcp-DO2IRFGQ.js +11 -0
- package/dist/safe-js/chunks/migration-file-K7UH5ZG6.js +12 -0
- package/dist/safe-js/chunks/restore-7LRP4BM3.js +13 -0
- package/dist/safe-js/chunks/run-6SETM7SV.js +17 -0
- package/dist/safe-js/chunks/runtime-modules-MCQS2SHQ.js +10 -0
- package/dist/safe-js/cli.js +2 -2
- package/dist/safe-js/core.js +7 -7
- package/dist/safe-js/extensions.d.ts +3 -1
- package/dist/safe-js/index.js +14 -14
- package/dist/safe-js/interp/async.d.ts +4 -1
- package/dist/safe-js/interp/budget.d.ts +15 -6
- package/dist/safe-js/interp/collection-iterator.d.ts +1 -1
- package/dist/safe-js/interp/host-bridge.d.ts +1 -0
- package/dist/safe-js/interp/host-capabilities.d.ts +13 -4
- package/dist/safe-js/interp/interpreter.d.ts +5 -1
- package/dist/safe-js/interp/intl-numberformat.d.ts +2 -2
- package/dist/safe-js/interp/jobs.d.ts +8 -0
- package/dist/safe-js/interp/scope.d.ts +13 -3
- package/dist/safe-js/interp/typed-array.d.ts +5 -2
- package/dist/safe-js/interp/values.d.ts +1 -0
- package/dist/safe-js/modules/registry.d.ts +4 -1
- package/dist/safe-js/modules/source-graph.d.ts +19 -1
- package/dist/safe-js/parse/compact-spans.d.ts +18 -0
- package/dist/safe-js/parse/dynamic-source.d.ts +3 -1
- package/dist/safe-js/parse/function-source.d.ts +1 -1
- package/dist/safe-js/parse/parser.d.ts +8 -3
- package/dist/safe-js/parse/tokenizer.d.ts +4 -0
- package/dist/safe-js/realm.d.ts +17 -3
- package/dist/safe-js/restore.d.ts +1 -0
- package/dist/safe-js/run.d.ts +10 -0
- package/dist/safe-js/snapshot/guest-heap.d.ts +1 -0
- package/dist/toolcraft-design/prompts/primitives/note.d.ts +1 -1
- package/package.json +2 -2
- package/dist/safe-js/chunks/chunk-B2SQLK4O.js.map +0 -7
- package/dist/safe-js/chunks/chunk-HYD4K4HN.js.map +0 -7
- package/dist/safe-js/chunks/chunk-IDQ67DY2.js.map +0 -7
- package/dist/safe-js/chunks/chunk-KK5NCR5R.js.map +0 -7
- package/dist/safe-js/chunks/chunk-NJM2Q74Z.js.map +0 -7
- package/dist/safe-js/chunks/chunk-OP3H3ZDN.js.map +0 -7
- package/dist/safe-js/chunks/harness-DLEQ2Z3O.js +0 -10
- package/dist/safe-js/chunks/mcp-TNVEFJ6K.js +0 -11
- package/dist/safe-js/chunks/migration-file-IDIUFLKY.js +0 -12
- package/dist/safe-js/chunks/restore-P27AUZR2.js +0 -13
- package/dist/safe-js/chunks/run-KGAEHYMV.js +0 -17
- package/dist/safe-js/chunks/runtime-modules-KICK45EE.js +0 -10
- /package/dist/safe-js/chunks/{chunk-APKV5Y6T.js.map → chunk-FA5CQO6V.js.map} +0 -0
- /package/dist/safe-js/chunks/{chunk-RML35GIF.js.map → chunk-GCOLKRMY.js.map} +0 -0
- /package/dist/safe-js/chunks/{chunk-U6KZ2DQ2.js.map → chunk-K3ZRBAG5.js.map} +0 -0
- /package/dist/safe-js/chunks/{chunk-BGJXQN4A.js.map → chunk-QL2ALAE6.js.map} +0 -0
- /package/dist/safe-js/chunks/{chunk-A7CADQAD.js.map → chunk-S2GFVXSI.js.map} +0 -0
- /package/dist/safe-js/chunks/{chunk-NEJ44T4Y.js.map → chunk-XHSOM5CG.js.map} +0 -0
- /package/dist/safe-js/chunks/{cli-runtime-PO6DQDHP.js.map → cli-runtime-6QPGM3TX.js.map} +0 -0
- /package/dist/safe-js/chunks/{dump-TRGFSCJ7.js.map → dump-TU6SYRFD.js.map} +0 -0
- /package/dist/safe-js/chunks/{fs-4T5MZW5J.js.map → fs-HTZT32MQ.js.map} +0 -0
- /package/dist/safe-js/chunks/{harness-DLEQ2Z3O.js.map → harness-RYAMI444.js.map} +0 -0
- /package/dist/safe-js/chunks/{mcp-TNVEFJ6K.js.map → mcp-DO2IRFGQ.js.map} +0 -0
- /package/dist/safe-js/chunks/{migration-file-IDIUFLKY.js.map → migration-file-K7UH5ZG6.js.map} +0 -0
- /package/dist/safe-js/chunks/{restore-P27AUZR2.js.map → restore-7LRP4BM3.js.map} +0 -0
- /package/dist/safe-js/chunks/{run-KGAEHYMV.js.map → run-6SETM7SV.js.map} +0 -0
- /package/dist/safe-js/chunks/{runtime-modules-KICK45EE.js.map → runtime-modules-MCQS2SHQ.js.map} +0 -0
|
@@ -157,12 +157,11 @@ function releaseTemplateObjects(budget) {
|
|
|
157
157
|
}
|
|
158
158
|
|
|
159
159
|
// packages/safe-js/src/interp/budget.ts
|
|
160
|
-
var REGEX_STEP_LIMIT = 2e3;
|
|
161
160
|
var REGEX_COMPILE_LIMITS = Object.freeze({
|
|
162
|
-
sourceLength:
|
|
163
|
-
flagsLength:
|
|
164
|
-
depth:
|
|
165
|
-
allocations:
|
|
161
|
+
sourceLength: Infinity,
|
|
162
|
+
flagsLength: Infinity,
|
|
163
|
+
depth: Infinity,
|
|
164
|
+
allocations: Infinity
|
|
166
165
|
});
|
|
167
166
|
var DEADLINE_CHECK_INTERVAL = 1024;
|
|
168
167
|
var SandboxError = class extends Error {
|
|
@@ -204,6 +203,8 @@ var BudgetAccounting = class {
|
|
|
204
203
|
allChecksSuspended = 0;
|
|
205
204
|
deadlineChecksSuspended = 0;
|
|
206
205
|
visitsUntilDeadlineCheck = DEADLINE_CHECK_INTERVAL;
|
|
206
|
+
pendingDeadlines;
|
|
207
|
+
earliestPendingDeadline;
|
|
207
208
|
retainedDataSize = 0;
|
|
208
209
|
retainedData = /* @__PURE__ */ new Map();
|
|
209
210
|
retainedValueSources = /* @__PURE__ */ new Map();
|
|
@@ -214,6 +215,8 @@ var BudgetAccounting = class {
|
|
|
214
215
|
provisionalScopes = 0;
|
|
215
216
|
compileTickets = /* @__PURE__ */ new Map();
|
|
216
217
|
completedCompileTickets = /* @__PURE__ */ new Set();
|
|
218
|
+
reconciliationHolds = 0;
|
|
219
|
+
deferredCompileDiscards = /* @__PURE__ */ new Set();
|
|
217
220
|
realmViews;
|
|
218
221
|
constructor(options = {}) {
|
|
219
222
|
this.deadline = normalizeDeadline(options.deadline);
|
|
@@ -221,6 +224,12 @@ var BudgetAccounting = class {
|
|
|
221
224
|
maxSteps: normalizeLimit("maxSteps", options.maxSteps),
|
|
222
225
|
maxCallDepth: normalizeLimit("maxCallDepth", options.maxCallDepth),
|
|
223
226
|
stringLength: normalizeLimit("stringLength", options.stringLength),
|
|
227
|
+
...options.regexSourceLength === void 0 ? {} : {
|
|
228
|
+
regexSourceLength: normalizeRegexLimit("regexSourceLength", options.regexSourceLength)
|
|
229
|
+
},
|
|
230
|
+
...options.regexCompileAllocations === void 0 ? {} : {
|
|
231
|
+
regexCompileAllocations: normalizeRegexLimit("regexCompileAllocations", options.regexCompileAllocations)
|
|
232
|
+
},
|
|
224
233
|
arrayLength: normalizeLimit("arrayLength", options.arrayLength),
|
|
225
234
|
dataSize: normalizeLimit("dataSize", options.dataSize)
|
|
226
235
|
});
|
|
@@ -228,6 +237,8 @@ var BudgetAccounting = class {
|
|
|
228
237
|
};
|
|
229
238
|
var Budget = class _Budget {
|
|
230
239
|
accounting;
|
|
240
|
+
realmView = false;
|
|
241
|
+
realmLease = false;
|
|
231
242
|
constructor(options = {}) {
|
|
232
243
|
this.accounting = new BudgetAccounting(options);
|
|
233
244
|
}
|
|
@@ -267,13 +278,62 @@ var Budget = class _Budget {
|
|
|
267
278
|
set currentCallDepth(value) {
|
|
268
279
|
this.accounting.currentCallDepth = value;
|
|
269
280
|
}
|
|
281
|
+
// Pending host operations keep their elapsed deadline active during sampled
|
|
282
|
+
// synchronous work. Linked private records need no observable native hooks.
|
|
283
|
+
acquireDeadline(deadline, onExceeded) {
|
|
284
|
+
if (!Number.isFinite(deadline)) throw new TypeError("Deadline must be a finite timestamp.");
|
|
285
|
+
const accounting = this.accounting;
|
|
286
|
+
const pending = {
|
|
287
|
+
deadline,
|
|
288
|
+
onExceeded,
|
|
289
|
+
next: accounting.pendingDeadlines,
|
|
290
|
+
active: true
|
|
291
|
+
};
|
|
292
|
+
if (pending.next !== void 0) pending.next.previous = pending;
|
|
293
|
+
accounting.pendingDeadlines = pending;
|
|
294
|
+
if (accounting.earliestPendingDeadline === void 0 || pending.deadline < accounting.earliestPendingDeadline.deadline)
|
|
295
|
+
accounting.earliestPendingDeadline = pending;
|
|
296
|
+
return () => {
|
|
297
|
+
if (!pending.active) return;
|
|
298
|
+
pending.active = false;
|
|
299
|
+
if (pending.previous === void 0) accounting.pendingDeadlines = pending.next;
|
|
300
|
+
else pending.previous.next = pending.next;
|
|
301
|
+
if (pending.next !== void 0) pending.next.previous = pending.previous;
|
|
302
|
+
pending.previous = pending.next = void 0;
|
|
303
|
+
pending.onExceeded = void 0;
|
|
304
|
+
if (accounting.earliestPendingDeadline !== pending) return;
|
|
305
|
+
accounting.earliestPendingDeadline = void 0;
|
|
306
|
+
for (let next = accounting.pendingDeadlines; next !== void 0; next = next.next)
|
|
307
|
+
if (accounting.earliestPendingDeadline === void 0 || next.deadline < accounting.earliestPendingDeadline.deadline)
|
|
308
|
+
accounting.earliestPendingDeadline = next;
|
|
309
|
+
};
|
|
310
|
+
}
|
|
270
311
|
forkRealm() {
|
|
271
312
|
const view = new _Budget();
|
|
272
313
|
view.accounting = this.accounting;
|
|
314
|
+
view.realmView = true;
|
|
273
315
|
const views = this.accounting.realmViews ??= /* @__PURE__ */ new Set([new WeakRef(this)]);
|
|
274
316
|
views.add(new WeakRef(view));
|
|
275
317
|
return view;
|
|
276
318
|
}
|
|
319
|
+
acquireRealmOwner() {
|
|
320
|
+
if (this.realmLease) throw new SandboxError("reentry");
|
|
321
|
+
const lease = this.acquireCompileOwner(
|
|
322
|
+
!this.realmView,
|
|
323
|
+
this.realmView ? this.accounting.activeCompileOwner : void 0
|
|
324
|
+
);
|
|
325
|
+
this.realmLease = true;
|
|
326
|
+
let released = false;
|
|
327
|
+
return {
|
|
328
|
+
owner: lease.owner,
|
|
329
|
+
release: () => {
|
|
330
|
+
if (released) return;
|
|
331
|
+
released = true;
|
|
332
|
+
this.realmLease = false;
|
|
333
|
+
lease.release();
|
|
334
|
+
}
|
|
335
|
+
};
|
|
336
|
+
}
|
|
277
337
|
visitNode(units = 1) {
|
|
278
338
|
if (!Number.isSafeInteger(units) || units < 0) {
|
|
279
339
|
throw new Error("units must be a non-negative safe integer.");
|
|
@@ -290,14 +350,17 @@ var Budget = class _Budget {
|
|
|
290
350
|
}
|
|
291
351
|
}
|
|
292
352
|
allocateString(value) {
|
|
293
|
-
|
|
353
|
+
this.allocateStringLength(value.length);
|
|
354
|
+
return value;
|
|
355
|
+
}
|
|
356
|
+
allocateStringLength(length) {
|
|
357
|
+
if (this.accounting.allChecksSuspended === 0 && this.accounting.limits.stringLength !== void 0 && length > this.accounting.limits.stringLength) {
|
|
294
358
|
throw new SandboxError({
|
|
295
359
|
budget: "stringLength",
|
|
296
|
-
current:
|
|
360
|
+
current: length,
|
|
297
361
|
limit: this.accounting.limits.stringLength
|
|
298
362
|
});
|
|
299
363
|
}
|
|
300
|
-
return value;
|
|
301
364
|
}
|
|
302
365
|
allocateArrayLength(length) {
|
|
303
366
|
if (this.accounting.allChecksSuspended === 0 && this.accounting.limits.arrayLength !== void 0 && length > this.accounting.limits.arrayLength) {
|
|
@@ -312,7 +375,8 @@ var Budget = class _Budget {
|
|
|
312
375
|
this.allocateArrayLength(count);
|
|
313
376
|
}
|
|
314
377
|
reconcileDataUsage(usage) {
|
|
315
|
-
const
|
|
378
|
+
const measured = usage + this.accounting.retainedDataSize;
|
|
379
|
+
const total = this.reconciliationDeferred ? Math.max(measured, this.accounting.currentDataSize) : measured;
|
|
316
380
|
this.checkDataUsage(total);
|
|
317
381
|
this.accounting.currentDataSize = total;
|
|
318
382
|
this.accounting.peakDataSize = Math.max(this.accounting.peakDataSize, total);
|
|
@@ -334,6 +398,23 @@ var Budget = class _Budget {
|
|
|
334
398
|
if (values === void 0) this.accounting.retainedValueSources.delete(owner);
|
|
335
399
|
else this.accounting.retainedValueSources.set(owner, values);
|
|
336
400
|
}
|
|
401
|
+
get reconciliationDeferred() {
|
|
402
|
+
return this.accounting.reconciliationHolds > 0;
|
|
403
|
+
}
|
|
404
|
+
deferReconciliation() {
|
|
405
|
+
this.accounting.reconciliationHolds++;
|
|
406
|
+
const generation = this.accounting.compileGeneration;
|
|
407
|
+
let released = false;
|
|
408
|
+
return () => {
|
|
409
|
+
if (released) return;
|
|
410
|
+
released = true;
|
|
411
|
+
if (generation !== this.accounting.compileGeneration) return;
|
|
412
|
+
if (--this.accounting.reconciliationHolds !== 0) return;
|
|
413
|
+
for (const ticket of this.accounting.deferredCompileDiscards)
|
|
414
|
+
this.accounting.completedCompileTickets.add(ticket);
|
|
415
|
+
this.accounting.deferredCompileDiscards.clear();
|
|
416
|
+
};
|
|
417
|
+
}
|
|
337
418
|
*retainedValues() {
|
|
338
419
|
for (const values of this.accounting.retainedValueSources.values()) {
|
|
339
420
|
const retained = values();
|
|
@@ -374,6 +455,7 @@ var Budget = class _Budget {
|
|
|
374
455
|
if (ticket.owner.generation !== this.accounting.compileGeneration || !this.accounting.compileTickets.has(ticket)) {
|
|
375
456
|
throw new SandboxError("reentry");
|
|
376
457
|
}
|
|
458
|
+
if (this.reconciliationDeferred) usage = Math.max(usage, this.compileTicketUsage(ticket));
|
|
377
459
|
this.setRetainedDataUsage(ticket, usage);
|
|
378
460
|
this.accounting.compileTickets.set(ticket, usage);
|
|
379
461
|
}
|
|
@@ -381,6 +463,10 @@ var Budget = class _Budget {
|
|
|
381
463
|
if (ticket.owner.generation !== this.accounting.compileGeneration) return;
|
|
382
464
|
const usage = this.accounting.compileTickets.get(ticket);
|
|
383
465
|
if (usage === void 0) return;
|
|
466
|
+
if (this.reconciliationDeferred) {
|
|
467
|
+
this.accounting.deferredCompileDiscards.add(ticket);
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
384
470
|
this.accounting.compileTickets.delete(ticket);
|
|
385
471
|
this.accounting.completedCompileTickets.delete(ticket);
|
|
386
472
|
this.accounting.retainedData.delete(ticket);
|
|
@@ -388,6 +474,19 @@ var Budget = class _Budget {
|
|
|
388
474
|
this.accounting.currentDataSize -= usage;
|
|
389
475
|
}
|
|
390
476
|
reconcileCompileData(usage, included, transferred = included, retainedOwner, complete = false) {
|
|
477
|
+
if (this.reconciliationDeferred) {
|
|
478
|
+
if (retainedOwner !== void 0) this.setRetainedDataUsage(retainedOwner, usage);
|
|
479
|
+
else {
|
|
480
|
+
let includedUsage2 = 0;
|
|
481
|
+
for (const ticket of included) includedUsage2 += this.compileTicketUsage(ticket);
|
|
482
|
+
const measured2 = usage + this.accounting.retainedDataSize - includedUsage2;
|
|
483
|
+
const total2 = Math.max(measured2, this.accounting.currentDataSize);
|
|
484
|
+
this.checkDataUsage(total2);
|
|
485
|
+
this.accounting.currentDataSize = total2;
|
|
486
|
+
this.accounting.peakDataSize = Math.max(this.accounting.peakDataSize, total2);
|
|
487
|
+
}
|
|
488
|
+
return /* @__PURE__ */ new Set();
|
|
489
|
+
}
|
|
391
490
|
let includedUsage = 0;
|
|
392
491
|
let transferredUsage = 0;
|
|
393
492
|
let discardedUsage = 0;
|
|
@@ -451,8 +550,10 @@ var Budget = class _Budget {
|
|
|
451
550
|
released = true;
|
|
452
551
|
if (generation !== this.accounting.compileGeneration) return;
|
|
453
552
|
this.accounting.provisionalScopes -= 1;
|
|
454
|
-
if (!commit)
|
|
455
|
-
|
|
553
|
+
if (!commit) {
|
|
554
|
+
const restored = previous + this.accounting.retainedDataSize - previousRetained;
|
|
555
|
+
this.accounting.currentDataSize = this.reconciliationDeferred ? Math.max(restored, this.accounting.currentDataSize) : restored;
|
|
556
|
+
}
|
|
456
557
|
};
|
|
457
558
|
}
|
|
458
559
|
enterCall() {
|
|
@@ -474,6 +575,8 @@ var Budget = class _Budget {
|
|
|
474
575
|
this.accounting.provisionalScopes = 0;
|
|
475
576
|
this.accounting.compileTickets.clear();
|
|
476
577
|
this.accounting.completedCompileTickets.clear();
|
|
578
|
+
this.accounting.reconciliationHolds = 0;
|
|
579
|
+
this.accounting.deferredCompileDiscards.clear();
|
|
477
580
|
this.accounting.stepsUsed = 0;
|
|
478
581
|
this.accounting.peakCallDepth = 0;
|
|
479
582
|
this.accounting.currentCallDepth = 0;
|
|
@@ -509,18 +612,26 @@ var Budget = class _Budget {
|
|
|
509
612
|
};
|
|
510
613
|
}
|
|
511
614
|
checkDeadline() {
|
|
512
|
-
|
|
615
|
+
const pending = this.accounting.earliestPendingDeadline;
|
|
616
|
+
const deadline = this.accounting.deadline === void 0 ? pending?.deadline : Math.min(this.accounting.deadline, pending?.deadline ?? Infinity);
|
|
617
|
+
if (this.accounting.allChecksSuspended > 0 || this.accounting.deadlineChecksSuspended > 0 || deadline === void 0) {
|
|
513
618
|
return;
|
|
514
619
|
}
|
|
515
620
|
const now = Date.now();
|
|
516
|
-
if (now <=
|
|
621
|
+
if (now <= deadline) {
|
|
517
622
|
return;
|
|
518
623
|
}
|
|
519
|
-
|
|
624
|
+
const reason = new SandboxError({
|
|
520
625
|
budget: "deadline",
|
|
521
626
|
current: now,
|
|
522
|
-
limit:
|
|
627
|
+
limit: deadline
|
|
523
628
|
});
|
|
629
|
+
if (pending?.deadline === deadline) {
|
|
630
|
+
const notify = pending.onExceeded;
|
|
631
|
+
pending.onExceeded = void 0;
|
|
632
|
+
notify?.(reason);
|
|
633
|
+
}
|
|
634
|
+
throw reason;
|
|
524
635
|
}
|
|
525
636
|
checkDataUsage(usage) {
|
|
526
637
|
if (this.accounting.allChecksSuspended === 0 && this.accounting.limits.dataSize !== void 0 && usage > this.accounting.limits.dataSize) {
|
|
@@ -532,7 +643,7 @@ var Budget = class _Budget {
|
|
|
532
643
|
}
|
|
533
644
|
}
|
|
534
645
|
checkSampledDeadline(units) {
|
|
535
|
-
if (this.accounting.allChecksSuspended > 0 || this.accounting.deadlineChecksSuspended > 0 || this.accounting.deadline === void 0) {
|
|
646
|
+
if (this.accounting.allChecksSuspended > 0 || this.accounting.deadlineChecksSuspended > 0 || this.accounting.deadline === void 0 && this.accounting.earliestPendingDeadline === void 0) {
|
|
536
647
|
return;
|
|
537
648
|
}
|
|
538
649
|
this.accounting.visitsUntilDeadlineCheck -= units;
|
|
@@ -565,14 +676,6 @@ var Budget = class _Budget {
|
|
|
565
676
|
};
|
|
566
677
|
}
|
|
567
678
|
};
|
|
568
|
-
function allocateRegexSteps(steps) {
|
|
569
|
-
if (!Number.isInteger(steps) || steps < 0) {
|
|
570
|
-
throw new Error("steps must be a non-negative integer.");
|
|
571
|
-
}
|
|
572
|
-
if (steps > REGEX_STEP_LIMIT) {
|
|
573
|
-
throw new SandboxError({ budget: "steps", current: steps, limit: REGEX_STEP_LIMIT });
|
|
574
|
-
}
|
|
575
|
-
}
|
|
576
679
|
function normalizeDeadline(deadline) {
|
|
577
680
|
if (deadline === void 0) {
|
|
578
681
|
return void 0;
|
|
@@ -588,6 +691,12 @@ function normalizeLimit(name, value) {
|
|
|
588
691
|
}
|
|
589
692
|
return value;
|
|
590
693
|
}
|
|
694
|
+
function normalizeRegexLimit(name, value) {
|
|
695
|
+
if (value === void 0) return void 0;
|
|
696
|
+
if (!Number.isSafeInteger(value) || value < 1)
|
|
697
|
+
throw new RangeError(`${name} must be a positive safe integer.`);
|
|
698
|
+
return value;
|
|
699
|
+
}
|
|
591
700
|
|
|
592
701
|
// packages/safe-js/src/interp/regex/compile-guard.ts
|
|
593
702
|
var compiledData = /* @__PURE__ */ new WeakMap();
|
|
@@ -628,7 +737,7 @@ var RegexCompileGuard = class {
|
|
|
628
737
|
ticket;
|
|
629
738
|
retained = false;
|
|
630
739
|
checkLength(length, flags = false) {
|
|
631
|
-
const hard = flags ? REGEX_COMPILE_LIMITS.flagsLength : REGEX_COMPILE_LIMITS.sourceLength;
|
|
740
|
+
const hard = flags ? REGEX_COMPILE_LIMITS.flagsLength : this.scope?.owner?.budget.limits.regexSourceLength ?? REGEX_COMPILE_LIMITS.sourceLength;
|
|
632
741
|
const limit = Math.min(hard, this.scope?.owner?.budget.limits.stringLength ?? hard);
|
|
633
742
|
if (length > limit) throw new SandboxError({ budget: "stringLength", current: length, limit });
|
|
634
743
|
}
|
|
@@ -639,11 +748,12 @@ var RegexCompileGuard = class {
|
|
|
639
748
|
}
|
|
640
749
|
allocate(units) {
|
|
641
750
|
const next = this.allocations + units;
|
|
642
|
-
|
|
751
|
+
const limit = this.scope?.owner?.budget.limits.regexCompileAllocations ?? REGEX_COMPILE_LIMITS.allocations;
|
|
752
|
+
if (next > limit) {
|
|
643
753
|
throw new SandboxError({
|
|
644
754
|
budget: "dataSize",
|
|
645
755
|
current: next,
|
|
646
|
-
limit
|
|
756
|
+
limit
|
|
647
757
|
});
|
|
648
758
|
}
|
|
649
759
|
this.work(units);
|
|
@@ -956,6 +1066,753 @@ function findNumberEnd(value, startIndex) {
|
|
|
956
1066
|
return index;
|
|
957
1067
|
}
|
|
958
1068
|
|
|
1069
|
+
// packages/safe-js/src/parse/compact-spans.ts
|
|
1070
|
+
var positionOwners = /* @__PURE__ */ new WeakMap();
|
|
1071
|
+
var getOwner = WeakMap.prototype.get.bind(positionOwners);
|
|
1072
|
+
var setOwner = WeakMap.prototype.set.bind(positionOwners);
|
|
1073
|
+
var cacheSize = 514;
|
|
1074
|
+
var writableSpan = /* @__PURE__ */ Symbol("compiler span writability");
|
|
1075
|
+
var CompactSourcePositions = class {
|
|
1076
|
+
sourceLength;
|
|
1077
|
+
lines = [0];
|
|
1078
|
+
positions = /* @__PURE__ */ new Map();
|
|
1079
|
+
makeSpan;
|
|
1080
|
+
constructor(source) {
|
|
1081
|
+
this.sourceLength = source.length;
|
|
1082
|
+
for (let offset = 0; offset < source.length; offset++) {
|
|
1083
|
+
const code = source.charCodeAt(offset);
|
|
1084
|
+
if (code === 13 && source.charCodeAt(offset + 1) === 10) offset++;
|
|
1085
|
+
if (code === 10 || code === 13 || code === 8232 || code === 8233)
|
|
1086
|
+
this.lines.push(offset + 1);
|
|
1087
|
+
}
|
|
1088
|
+
const owner = this;
|
|
1089
|
+
class Span {
|
|
1090
|
+
#start;
|
|
1091
|
+
#end;
|
|
1092
|
+
constructor(start, end) {
|
|
1093
|
+
this.#start = start;
|
|
1094
|
+
this.#end = end;
|
|
1095
|
+
Object.defineProperties(this, descriptors);
|
|
1096
|
+
}
|
|
1097
|
+
get start() {
|
|
1098
|
+
return typeof this.#start === "number" ? owner.position(this.#start) : this.#start.assigned;
|
|
1099
|
+
}
|
|
1100
|
+
set start(value) {
|
|
1101
|
+
if (Object.isFrozen(this)) throw new TypeError("Cannot assign to a frozen source span.");
|
|
1102
|
+
this.#start = getOwner(value) === owner ? value.offset : { assigned: value };
|
|
1103
|
+
}
|
|
1104
|
+
get end() {
|
|
1105
|
+
return typeof this.#end === "number" ? owner.position(this.#end) : this.#end.assigned;
|
|
1106
|
+
}
|
|
1107
|
+
set end(value) {
|
|
1108
|
+
if (Object.isFrozen(this)) throw new TypeError("Cannot assign to a frozen source span.");
|
|
1109
|
+
this.#end = getOwner(value) === owner ? value.offset : { assigned: value };
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
const descriptors = {
|
|
1113
|
+
start: {
|
|
1114
|
+
...Object.getOwnPropertyDescriptor(Span.prototype, "start"),
|
|
1115
|
+
enumerable: true
|
|
1116
|
+
},
|
|
1117
|
+
end: {
|
|
1118
|
+
...Object.getOwnPropertyDescriptor(Span.prototype, "end"),
|
|
1119
|
+
enumerable: true
|
|
1120
|
+
},
|
|
1121
|
+
// Sealed accessor-only objects otherwise report as frozen. This private
|
|
1122
|
+
// data field preserves the distinction for the mutable endpoint setters.
|
|
1123
|
+
[writableSpan]: { value: true, writable: true, configurable: true }
|
|
1124
|
+
};
|
|
1125
|
+
delete Span.prototype.start;
|
|
1126
|
+
delete Span.prototype.end;
|
|
1127
|
+
this.makeSpan = (start, end) => new Span(start, end);
|
|
1128
|
+
}
|
|
1129
|
+
position(offset) {
|
|
1130
|
+
this.assertOffset(offset);
|
|
1131
|
+
const cached = this.positions.get(offset);
|
|
1132
|
+
if (cached !== void 0) return cached;
|
|
1133
|
+
let low = 0, high = this.lines.length;
|
|
1134
|
+
while (low + 1 < high) {
|
|
1135
|
+
const middle = low + Math.floor((high - low) / 2);
|
|
1136
|
+
if (this.lines[middle] <= offset) low = middle;
|
|
1137
|
+
else high = middle;
|
|
1138
|
+
}
|
|
1139
|
+
const position = Object.freeze({
|
|
1140
|
+
line: low + 1,
|
|
1141
|
+
column: offset - this.lines[low] + 1,
|
|
1142
|
+
offset
|
|
1143
|
+
});
|
|
1144
|
+
setOwner(position, this);
|
|
1145
|
+
if (this.positions.size === cacheSize)
|
|
1146
|
+
this.positions.delete(this.positions.keys().next().value);
|
|
1147
|
+
this.positions.set(offset, position);
|
|
1148
|
+
return position;
|
|
1149
|
+
}
|
|
1150
|
+
span(start, end) {
|
|
1151
|
+
this.assertOffset(start);
|
|
1152
|
+
this.assertOffset(end);
|
|
1153
|
+
return this.makeSpan(start, end);
|
|
1154
|
+
}
|
|
1155
|
+
compatiblePosition(position) {
|
|
1156
|
+
if (!Number.isSafeInteger(position.offset) || position.offset < 0 || position.offset > this.sourceLength)
|
|
1157
|
+
return void 0;
|
|
1158
|
+
const point = this.position(position.offset);
|
|
1159
|
+
return point.line === position.line && point.column === position.column ? point : void 0;
|
|
1160
|
+
}
|
|
1161
|
+
assertOffset(offset) {
|
|
1162
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset > this.sourceLength)
|
|
1163
|
+
throw new RangeError("Source coordinate offset is outside its source.");
|
|
1164
|
+
}
|
|
1165
|
+
};
|
|
1166
|
+
function compactDerivedPosition(base, position) {
|
|
1167
|
+
return getOwner(base)?.compatiblePosition(position);
|
|
1168
|
+
}
|
|
1169
|
+
function compactSourceSpan(start, end) {
|
|
1170
|
+
const owner = getOwner(start);
|
|
1171
|
+
return owner !== void 0 && getOwner(end) === owner ? owner.span(start.offset, end.offset) : void 0;
|
|
1172
|
+
}
|
|
1173
|
+
|
|
1174
|
+
// packages/safe-js/src/parse/function-source.ts
|
|
1175
|
+
var functionSources = /* @__PURE__ */ new WeakMap();
|
|
1176
|
+
var templateSources = /* @__PURE__ */ new WeakMap();
|
|
1177
|
+
var functionStrictness = /* @__PURE__ */ new WeakMap();
|
|
1178
|
+
var evalFunctionDeclarations = /* @__PURE__ */ new WeakSet();
|
|
1179
|
+
var dynamicSourceRecords = /* @__PURE__ */ new WeakSet();
|
|
1180
|
+
var dynamicNodeSources = /* @__PURE__ */ new WeakMap();
|
|
1181
|
+
var dynamicValueSources = /* @__PURE__ */ new WeakMap();
|
|
1182
|
+
|
|
1183
|
+
// packages/safe-js/src/parse/compact-module-ast.ts
|
|
1184
|
+
var chunkLength = 65536;
|
|
1185
|
+
var scalarMask = 268435455;
|
|
1186
|
+
var handles = /* @__PURE__ */ new WeakMap();
|
|
1187
|
+
var mutableRecord = /* @__PURE__ */ Symbol("compiler record writability");
|
|
1188
|
+
var recordToken = /* @__PURE__ */ Symbol("compiler traversal authority");
|
|
1189
|
+
var defineCompilerProperty = Reflect.defineProperty;
|
|
1190
|
+
var NativeRowMap = Map;
|
|
1191
|
+
var nativeIndexMap = {
|
|
1192
|
+
get: Function.prototype.call.bind(Map.prototype.get),
|
|
1193
|
+
has: Function.prototype.call.bind(Map.prototype.has),
|
|
1194
|
+
set: Function.prototype.call.bind(Map.prototype.set),
|
|
1195
|
+
delete: Function.prototype.call.bind(Map.prototype.delete),
|
|
1196
|
+
clear: Function.prototype.call.bind(Map.prototype.clear),
|
|
1197
|
+
keys: Function.prototype.call.bind(Map.prototype.keys),
|
|
1198
|
+
size: Function.prototype.call.bind(
|
|
1199
|
+
Object.getOwnPropertyDescriptor(Map.prototype, "size").get
|
|
1200
|
+
)
|
|
1201
|
+
};
|
|
1202
|
+
var CodeRecord = class {
|
|
1203
|
+
constructor(token, owner, row) {
|
|
1204
|
+
this.owner = owner;
|
|
1205
|
+
this.row = row;
|
|
1206
|
+
if (token !== recordToken) throw new TypeError("Foreign compiler traversal authority.");
|
|
1207
|
+
Object.freeze(this);
|
|
1208
|
+
}
|
|
1209
|
+
owner;
|
|
1210
|
+
row;
|
|
1211
|
+
#brand = true;
|
|
1212
|
+
static authentic(value) {
|
|
1213
|
+
return #brand in value && value.#brand;
|
|
1214
|
+
}
|
|
1215
|
+
};
|
|
1216
|
+
function record(value) {
|
|
1217
|
+
if (value === null || typeof value !== "object") return void 0;
|
|
1218
|
+
return CodeRecord.authentic(value) ? value : handles.get(value);
|
|
1219
|
+
}
|
|
1220
|
+
var CompactModuleAst = class {
|
|
1221
|
+
constructor(source) {
|
|
1222
|
+
this.source = source;
|
|
1223
|
+
this.positions = new CompactSourcePositions(source);
|
|
1224
|
+
this.maxWords = Math.min(scalarMask - 1, Math.max(1024, source.length * 24 + 1024));
|
|
1225
|
+
}
|
|
1226
|
+
source;
|
|
1227
|
+
chunks = [];
|
|
1228
|
+
shapes = [];
|
|
1229
|
+
shapeIDs = /* @__PURE__ */ new Map();
|
|
1230
|
+
strings = [];
|
|
1231
|
+
stringIDs = /* @__PURE__ */ new Map();
|
|
1232
|
+
numbers = [];
|
|
1233
|
+
cache = /* @__PURE__ */ new Map();
|
|
1234
|
+
boundaries = /* @__PURE__ */ new Set();
|
|
1235
|
+
persistentBoundaries = /* @__PURE__ */ new Set();
|
|
1236
|
+
overrides = /* @__PURE__ */ new WeakMap();
|
|
1237
|
+
finished = false;
|
|
1238
|
+
positions;
|
|
1239
|
+
maxWords;
|
|
1240
|
+
used = 0;
|
|
1241
|
+
bodies = 0;
|
|
1242
|
+
dynamicSource;
|
|
1243
|
+
statistics() {
|
|
1244
|
+
return {
|
|
1245
|
+
words: this.used,
|
|
1246
|
+
bufferBytes: this.chunks.reduce((sum, c) => sum + c.byteLength, 0),
|
|
1247
|
+
bodies: this.bodies,
|
|
1248
|
+
materializedRecords: this.cache.size,
|
|
1249
|
+
strings: this.strings.length
|
|
1250
|
+
};
|
|
1251
|
+
}
|
|
1252
|
+
finish() {
|
|
1253
|
+
this.finished = true;
|
|
1254
|
+
if (this.chunks.length) {
|
|
1255
|
+
const last = this.chunks.length - 1;
|
|
1256
|
+
this.chunks[last] = this.chunks[last].slice(0, (this.used - 1) % chunkLength + 1);
|
|
1257
|
+
}
|
|
1258
|
+
this.stringIDs.clear();
|
|
1259
|
+
this.shapeIDs.clear();
|
|
1260
|
+
this.persistentBoundaries.clear();
|
|
1261
|
+
}
|
|
1262
|
+
/** Retirement consumes unobserved parser arrays after syntax validation. */
|
|
1263
|
+
pack(root, body = true, retire = false, persistent = true) {
|
|
1264
|
+
if (this.finished) throw new TypeError("Compiler body storage is finished.");
|
|
1265
|
+
const seen = /* @__PURE__ */ new WeakMap();
|
|
1266
|
+
const pending = [];
|
|
1267
|
+
const encode = (value) => {
|
|
1268
|
+
if (value === null || typeof value !== "object") return this.scalar(value);
|
|
1269
|
+
const existing = record(value);
|
|
1270
|
+
if (existing?.owner === this) {
|
|
1271
|
+
if (retire && !this.overrides.has(value)) {
|
|
1272
|
+
this.cache.delete(existing.row);
|
|
1273
|
+
if (!this.persistentBoundaries.has(existing.row)) this.boundaries.delete(existing.row);
|
|
1274
|
+
}
|
|
1275
|
+
return existing.row + 1;
|
|
1276
|
+
}
|
|
1277
|
+
const previous = seen.get(value);
|
|
1278
|
+
if (previous !== void 0) return previous + 1;
|
|
1279
|
+
let kind, row, values = [];
|
|
1280
|
+
const array = Array.isArray(value);
|
|
1281
|
+
const keys = array ? [] : Object.keys(value).filter((key) => key !== "nodeId");
|
|
1282
|
+
if (array) {
|
|
1283
|
+
kind = 0;
|
|
1284
|
+
row = this.reserve(2 + value.length);
|
|
1285
|
+
values = value;
|
|
1286
|
+
this.write(row, kind);
|
|
1287
|
+
this.write(row + 1, value.length);
|
|
1288
|
+
} else if (keys.length === 2 && keys[0] === "start" && keys[1] === "end") {
|
|
1289
|
+
const span = value, start = span.start, end = span.end;
|
|
1290
|
+
const startPoint = this.positions.compatiblePosition(start);
|
|
1291
|
+
const endPoint = this.positions.compatiblePosition(end);
|
|
1292
|
+
if (startPoint && endPoint) {
|
|
1293
|
+
kind = 1;
|
|
1294
|
+
row = this.reserve(3);
|
|
1295
|
+
this.write(row, kind);
|
|
1296
|
+
this.write(row + 1, start.offset);
|
|
1297
|
+
this.write(row + 2, end.offset);
|
|
1298
|
+
} else {
|
|
1299
|
+
kind = 2;
|
|
1300
|
+
row = this.reserve(7);
|
|
1301
|
+
this.write(row, kind);
|
|
1302
|
+
[start.line, start.column, start.offset, end.line, end.column, end.offset].forEach(
|
|
1303
|
+
(n, i) => this.write(row + 1 + i, n)
|
|
1304
|
+
);
|
|
1305
|
+
}
|
|
1306
|
+
} else {
|
|
1307
|
+
values = keys.map((key2) => value[key2]);
|
|
1308
|
+
if ("nodeId" in value || typeof value.type === "string" && "span" in value) {
|
|
1309
|
+
keys.push("@id");
|
|
1310
|
+
values.push(value.nodeId);
|
|
1311
|
+
const metadata = functionSources.get(value);
|
|
1312
|
+
if (metadata) {
|
|
1313
|
+
if (metadata.text !== this.source)
|
|
1314
|
+
throw new TypeError("Foreign compiler function source.");
|
|
1315
|
+
keys.push("@start", "@end", "@strict");
|
|
1316
|
+
values.push(
|
|
1317
|
+
metadata.start,
|
|
1318
|
+
metadata.end,
|
|
1319
|
+
functionStrictness.get(value)
|
|
1320
|
+
);
|
|
1321
|
+
}
|
|
1322
|
+
const template = templateSources.get(value);
|
|
1323
|
+
if (template !== void 0) {
|
|
1324
|
+
if (template !== this.source) throw new TypeError("Foreign compiler template source.");
|
|
1325
|
+
keys.push("@template");
|
|
1326
|
+
values.push(true);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
const key = JSON.stringify(keys);
|
|
1330
|
+
let shape = this.shapeIDs.get(key);
|
|
1331
|
+
if (shape === void 0) {
|
|
1332
|
+
shape = this.shapes.length;
|
|
1333
|
+
this.shapes.push(this.shape(keys));
|
|
1334
|
+
this.shapeIDs.set(key, shape);
|
|
1335
|
+
}
|
|
1336
|
+
kind = shape + 3;
|
|
1337
|
+
row = this.reserve(1 + values.length);
|
|
1338
|
+
this.write(row, kind);
|
|
1339
|
+
}
|
|
1340
|
+
seen.set(value, row);
|
|
1341
|
+
if (value.type === "VariableDeclarator") {
|
|
1342
|
+
this.boundaries.add(row);
|
|
1343
|
+
this.persistentBoundaries.add(row);
|
|
1344
|
+
}
|
|
1345
|
+
if (kind === 0 || kind >= 3) {
|
|
1346
|
+
const type = value.type;
|
|
1347
|
+
const bodyIndex = [
|
|
1348
|
+
"FunctionDeclaration",
|
|
1349
|
+
"FunctionExpression",
|
|
1350
|
+
"ArrowFunctionExpression"
|
|
1351
|
+
].includes(String(type)) ? keys.indexOf("body") : -1;
|
|
1352
|
+
pending.push({
|
|
1353
|
+
row,
|
|
1354
|
+
kind,
|
|
1355
|
+
values,
|
|
1356
|
+
index: 0,
|
|
1357
|
+
bodyIndex: bodyIndex >= 0 ? bodyIndex : void 0
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
return row + 1;
|
|
1361
|
+
};
|
|
1362
|
+
const reference = encode(root);
|
|
1363
|
+
while (pending.length) {
|
|
1364
|
+
const frame = pending[pending.length - 1];
|
|
1365
|
+
if (frame.index === frame.values.length) {
|
|
1366
|
+
pending.pop();
|
|
1367
|
+
continue;
|
|
1368
|
+
}
|
|
1369
|
+
const index = frame.index++;
|
|
1370
|
+
const child = encode(frame.values[index]);
|
|
1371
|
+
if (retire && frame.kind === 0)
|
|
1372
|
+
defineCompilerProperty(frame.values, index, { value: void 0 });
|
|
1373
|
+
this.write(frame.row + (frame.kind === 0 ? 2 : 1) + index, child);
|
|
1374
|
+
if (index === frame.bodyIndex && child >>> 28 === 0) {
|
|
1375
|
+
this.boundaries.add(child - 1);
|
|
1376
|
+
this.persistentBoundaries.add(child - 1);
|
|
1377
|
+
}
|
|
1378
|
+
}
|
|
1379
|
+
this.boundaries.add(reference - 1);
|
|
1380
|
+
if (persistent) this.persistentBoundaries.add(reference - 1);
|
|
1381
|
+
if (body) this.bodies++;
|
|
1382
|
+
return this.decode(reference);
|
|
1383
|
+
}
|
|
1384
|
+
/** Install source metadata and index numeric rows without publishing every node. */
|
|
1385
|
+
dynamicNodes(root, source) {
|
|
1386
|
+
if (!this.finished) throw new TypeError("Unfinished compiler storage.");
|
|
1387
|
+
if (source.body !== this.source) throw new TypeError("Foreign compiler dynamic source text.");
|
|
1388
|
+
if (this.dynamicSource && this.dynamicSource !== source)
|
|
1389
|
+
throw new TypeError("Foreign compiler dynamic source owner.");
|
|
1390
|
+
this.dynamicSource = source;
|
|
1391
|
+
const rows = new NativeRowMap(), seen = /* @__PURE__ */ new Set(), pending = [root];
|
|
1392
|
+
while (pending.length) {
|
|
1393
|
+
const row = pending.pop();
|
|
1394
|
+
if (seen.has(row)) continue;
|
|
1395
|
+
seen.add(row);
|
|
1396
|
+
const kind = this.read(row);
|
|
1397
|
+
if (kind === 0) {
|
|
1398
|
+
for (let i = 0, n = this.read(row + 1); i < n; i++) {
|
|
1399
|
+
const ref = this.read(row + 2 + i);
|
|
1400
|
+
if (ref >>> 28 === 0) pending.push((ref & scalarMask) - 1);
|
|
1401
|
+
}
|
|
1402
|
+
} else if (kind >= 3) {
|
|
1403
|
+
const keys = this.shapes[kind - 3].keys;
|
|
1404
|
+
const idIndex = keys.indexOf("@id"), typeIndex = keys.indexOf("type");
|
|
1405
|
+
if (idIndex >= 0 && typeIndex >= 0) {
|
|
1406
|
+
const id = this.decode(this.read(row + 1 + idIndex));
|
|
1407
|
+
const type = this.decode(this.read(row + 1 + typeIndex));
|
|
1408
|
+
if (typeof id === "number" && type !== "Module") nativeIndexMap.set(rows, id, row);
|
|
1409
|
+
}
|
|
1410
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1411
|
+
if (keys[i].startsWith("@")) continue;
|
|
1412
|
+
const ref = this.read(row + 1 + i);
|
|
1413
|
+
if (ref >>> 28 === 0) pending.push((ref & scalarMask) - 1);
|
|
1414
|
+
}
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
for (const node of this.cache.values()) {
|
|
1418
|
+
const id = node.nodeId;
|
|
1419
|
+
if (typeof id === "number" && nativeIndexMap.has(rows, id))
|
|
1420
|
+
dynamicNodeSources.set(node, source);
|
|
1421
|
+
}
|
|
1422
|
+
return new CompactNodeIndex(recordToken, rows, (row) => this.object(row));
|
|
1423
|
+
}
|
|
1424
|
+
scalar(value) {
|
|
1425
|
+
if (value === void 0) return 268435456;
|
|
1426
|
+
if (value === null) return 536870912;
|
|
1427
|
+
if (typeof value === "boolean") return 805306368 + (value ? 1 : 0);
|
|
1428
|
+
if (typeof value === "string") {
|
|
1429
|
+
let id = this.stringIDs.get(value);
|
|
1430
|
+
if (id === void 0) {
|
|
1431
|
+
id = this.strings.length;
|
|
1432
|
+
this.strings.push(value);
|
|
1433
|
+
this.stringIDs.set(value, id);
|
|
1434
|
+
}
|
|
1435
|
+
return 1073741824 + id;
|
|
1436
|
+
}
|
|
1437
|
+
if (typeof value === "number") {
|
|
1438
|
+
if (Number.isInteger(value) && !Object.is(value, -0) && Math.abs(value) <= scalarMask)
|
|
1439
|
+
return (value < 0 ? 1610612736 : 1342177280) + Math.abs(value);
|
|
1440
|
+
const id = this.numbers.length;
|
|
1441
|
+
this.numbers.push(value);
|
|
1442
|
+
return 1879048192 + id;
|
|
1443
|
+
}
|
|
1444
|
+
throw new TypeError("Unsupported compiler scalar.");
|
|
1445
|
+
}
|
|
1446
|
+
reserve(length) {
|
|
1447
|
+
const row = this.used, next = row + length;
|
|
1448
|
+
if (next > this.maxWords)
|
|
1449
|
+
throw new SandboxError({
|
|
1450
|
+
budget: "dataSize",
|
|
1451
|
+
current: next,
|
|
1452
|
+
limit: this.maxWords
|
|
1453
|
+
});
|
|
1454
|
+
this.used = next;
|
|
1455
|
+
this.write(next - 1, 0);
|
|
1456
|
+
return row;
|
|
1457
|
+
}
|
|
1458
|
+
read(index) {
|
|
1459
|
+
return this.chunks[Math.floor(index / chunkLength)][index % chunkLength];
|
|
1460
|
+
}
|
|
1461
|
+
write(index, value) {
|
|
1462
|
+
const chunk = Math.floor(index / chunkLength);
|
|
1463
|
+
this.chunks[chunk] ??= new Uint32Array(chunkLength);
|
|
1464
|
+
this.chunks[chunk][index % chunkLength] = value;
|
|
1465
|
+
}
|
|
1466
|
+
decode(reference, raw = false) {
|
|
1467
|
+
const tag = reference >>> 28, payload = reference & scalarMask;
|
|
1468
|
+
switch (tag) {
|
|
1469
|
+
case 0:
|
|
1470
|
+
return raw ? new CodeRecord(recordToken, this, payload - 1) : this.object(payload - 1);
|
|
1471
|
+
case 1:
|
|
1472
|
+
return void 0;
|
|
1473
|
+
case 2:
|
|
1474
|
+
return null;
|
|
1475
|
+
case 3:
|
|
1476
|
+
return payload !== 0;
|
|
1477
|
+
case 4:
|
|
1478
|
+
return this.strings[payload];
|
|
1479
|
+
case 5:
|
|
1480
|
+
return payload;
|
|
1481
|
+
case 6:
|
|
1482
|
+
return -payload;
|
|
1483
|
+
case 7:
|
|
1484
|
+
return this.numbers[payload];
|
|
1485
|
+
default:
|
|
1486
|
+
throw new TypeError("Invalid compiler reference.");
|
|
1487
|
+
}
|
|
1488
|
+
}
|
|
1489
|
+
shape(keys) {
|
|
1490
|
+
const descriptors = {};
|
|
1491
|
+
const owner = this;
|
|
1492
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1493
|
+
const key = keys[i];
|
|
1494
|
+
if (key === "@id") {
|
|
1495
|
+
descriptors.nodeId = {
|
|
1496
|
+
value: void 0,
|
|
1497
|
+
writable: true,
|
|
1498
|
+
enumerable: false,
|
|
1499
|
+
configurable: true
|
|
1500
|
+
};
|
|
1501
|
+
continue;
|
|
1502
|
+
}
|
|
1503
|
+
if (key.startsWith("@")) continue;
|
|
1504
|
+
const name = key;
|
|
1505
|
+
descriptors[name] = {
|
|
1506
|
+
enumerable: key !== "@id",
|
|
1507
|
+
configurable: true,
|
|
1508
|
+
get() {
|
|
1509
|
+
const handle = handles.get(this);
|
|
1510
|
+
if (handle?.owner !== owner || owner.shapes[owner.read(handle.row) - 3]?.descriptors !== descriptors)
|
|
1511
|
+
throw new TypeError("Foreign compiler record receiver.");
|
|
1512
|
+
const assigned = owner.overrides.get(this);
|
|
1513
|
+
return assigned?.has(name) ? assigned.get(name) : owner.decode(owner.read(handle.row + 1 + i));
|
|
1514
|
+
},
|
|
1515
|
+
set(value) {
|
|
1516
|
+
const handle = handles.get(this);
|
|
1517
|
+
if (handle?.owner !== owner || owner.shapes[owner.read(handle.row) - 3]?.descriptors !== descriptors)
|
|
1518
|
+
throw new TypeError("Foreign compiler record receiver.");
|
|
1519
|
+
if (Object.isFrozen(this))
|
|
1520
|
+
throw new TypeError("Cannot assign to a frozen compiler record.");
|
|
1521
|
+
let assigned = owner.overrides.get(this);
|
|
1522
|
+
if (!assigned) {
|
|
1523
|
+
assigned = /* @__PURE__ */ new Map();
|
|
1524
|
+
owner.overrides.set(this, assigned);
|
|
1525
|
+
}
|
|
1526
|
+
assigned.set(name, value);
|
|
1527
|
+
}
|
|
1528
|
+
};
|
|
1529
|
+
}
|
|
1530
|
+
descriptors[mutableRecord] = {
|
|
1531
|
+
value: true,
|
|
1532
|
+
writable: true,
|
|
1533
|
+
configurable: true
|
|
1534
|
+
};
|
|
1535
|
+
function CompilerRecord() {
|
|
1536
|
+
Object.defineProperties(this, descriptors);
|
|
1537
|
+
}
|
|
1538
|
+
CompilerRecord.prototype = Object.prototype;
|
|
1539
|
+
return {
|
|
1540
|
+
keys,
|
|
1541
|
+
descriptors,
|
|
1542
|
+
create: () => Reflect.construct(CompilerRecord, [])
|
|
1543
|
+
};
|
|
1544
|
+
}
|
|
1545
|
+
attachMetadata(output, row, shape) {
|
|
1546
|
+
const metadata = (name) => {
|
|
1547
|
+
const index = shape.keys.indexOf(name);
|
|
1548
|
+
return index < 0 ? void 0 : this.decode(this.read(row + 1 + index));
|
|
1549
|
+
};
|
|
1550
|
+
const id = metadata("@id");
|
|
1551
|
+
if (id !== void 0 && this.dynamicSource && shape.keys.includes("type")) {
|
|
1552
|
+
const type = metadata("type");
|
|
1553
|
+
if (type !== "Module") dynamicNodeSources.set(output, this.dynamicSource);
|
|
1554
|
+
}
|
|
1555
|
+
if (id !== void 0)
|
|
1556
|
+
Object.defineProperty(output, "nodeId", {
|
|
1557
|
+
value: id,
|
|
1558
|
+
writable: true,
|
|
1559
|
+
enumerable: false,
|
|
1560
|
+
configurable: true
|
|
1561
|
+
});
|
|
1562
|
+
const start = metadata("@start");
|
|
1563
|
+
if (start !== void 0) {
|
|
1564
|
+
functionSources.set(output, {
|
|
1565
|
+
text: this.source,
|
|
1566
|
+
start,
|
|
1567
|
+
end: metadata("@end")
|
|
1568
|
+
});
|
|
1569
|
+
const strict = metadata("@strict");
|
|
1570
|
+
if (strict !== void 0)
|
|
1571
|
+
functionStrictness.set(
|
|
1572
|
+
output,
|
|
1573
|
+
strict
|
|
1574
|
+
);
|
|
1575
|
+
}
|
|
1576
|
+
if (metadata("@template") === true)
|
|
1577
|
+
templateSources.set(output, this.source);
|
|
1578
|
+
}
|
|
1579
|
+
object(row) {
|
|
1580
|
+
const cached = this.cache.get(row);
|
|
1581
|
+
if (cached !== void 0) return cached;
|
|
1582
|
+
const tasks = [];
|
|
1583
|
+
const make = (index) => {
|
|
1584
|
+
const cached2 = this.cache.get(index);
|
|
1585
|
+
if (cached2) return cached2;
|
|
1586
|
+
const kind = this.read(index);
|
|
1587
|
+
let output2;
|
|
1588
|
+
if (kind === 0) {
|
|
1589
|
+
const array = [];
|
|
1590
|
+
array.length = this.read(index + 1);
|
|
1591
|
+
output2 = array;
|
|
1592
|
+
tasks.push({ row: index, kind, output: output2 });
|
|
1593
|
+
} else if (kind === 1)
|
|
1594
|
+
output2 = this.positions.span(this.read(index + 1), this.read(index + 2));
|
|
1595
|
+
else if (kind === 2)
|
|
1596
|
+
output2 = {
|
|
1597
|
+
start: {
|
|
1598
|
+
line: this.read(index + 1),
|
|
1599
|
+
column: this.read(index + 2),
|
|
1600
|
+
offset: this.read(index + 3)
|
|
1601
|
+
},
|
|
1602
|
+
end: {
|
|
1603
|
+
line: this.read(index + 4),
|
|
1604
|
+
column: this.read(index + 5),
|
|
1605
|
+
offset: this.read(index + 6)
|
|
1606
|
+
}
|
|
1607
|
+
};
|
|
1608
|
+
else {
|
|
1609
|
+
const shape = this.shapes[kind - 3];
|
|
1610
|
+
if (this.boundaries.has(index)) {
|
|
1611
|
+
output2 = shape.create();
|
|
1612
|
+
handles.set(output2, new CodeRecord(recordToken, this, index));
|
|
1613
|
+
this.attachMetadata(output2, index, shape);
|
|
1614
|
+
} else {
|
|
1615
|
+
output2 = {};
|
|
1616
|
+
tasks.push({ row: index, kind, output: output2 });
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
this.cache.set(index, output2);
|
|
1620
|
+
if (!this.finished) handles.set(output2, new CodeRecord(recordToken, this, index));
|
|
1621
|
+
return output2;
|
|
1622
|
+
};
|
|
1623
|
+
const value = (ref) => ref >>> 28 === 0 ? make((ref & scalarMask) - 1) : this.decode(ref);
|
|
1624
|
+
const output = make(row);
|
|
1625
|
+
while (tasks.length) {
|
|
1626
|
+
const { row: index, kind, output: target } = tasks.pop();
|
|
1627
|
+
if (kind === 0) {
|
|
1628
|
+
const array = target;
|
|
1629
|
+
for (let i = 0; i < array.length; i++) array[i] = value(this.read(index + 2 + i));
|
|
1630
|
+
} else {
|
|
1631
|
+
const shape = this.shapes[kind - 3];
|
|
1632
|
+
for (let i = 0; i < shape.keys.length; i++) {
|
|
1633
|
+
const key = shape.keys[i];
|
|
1634
|
+
if (!key.startsWith("@"))
|
|
1635
|
+
Object.defineProperty(target, key, {
|
|
1636
|
+
value: value(this.read(index + 1 + i)),
|
|
1637
|
+
writable: true,
|
|
1638
|
+
enumerable: true,
|
|
1639
|
+
configurable: true
|
|
1640
|
+
});
|
|
1641
|
+
}
|
|
1642
|
+
this.attachMetadata(target, index, shape);
|
|
1643
|
+
}
|
|
1644
|
+
}
|
|
1645
|
+
return output;
|
|
1646
|
+
}
|
|
1647
|
+
// Compiler passes use these private-owner records, not the decoded AST cache.
|
|
1648
|
+
isArray(row) {
|
|
1649
|
+
return this.read(row) === 0;
|
|
1650
|
+
}
|
|
1651
|
+
*entries(row) {
|
|
1652
|
+
const kind = this.read(row), cached = this.cache.get(row);
|
|
1653
|
+
if (cached) {
|
|
1654
|
+
for (const key of Object.keys(cached)) yield [key, this.field(row, key)];
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1657
|
+
if (kind === 0) {
|
|
1658
|
+
for (let i = 0, n = this.read(row + 1); i < n; i++)
|
|
1659
|
+
yield [String(i), this.decode(this.read(row + 2 + i), true)];
|
|
1660
|
+
} else if (kind === 1) {
|
|
1661
|
+
yield ["start", this.positions.position(this.read(row + 1))];
|
|
1662
|
+
yield ["end", this.positions.position(this.read(row + 2))];
|
|
1663
|
+
} else if (kind === 2) {
|
|
1664
|
+
yield [
|
|
1665
|
+
"start",
|
|
1666
|
+
{
|
|
1667
|
+
line: this.read(row + 1),
|
|
1668
|
+
column: this.read(row + 2),
|
|
1669
|
+
offset: this.read(row + 3)
|
|
1670
|
+
}
|
|
1671
|
+
];
|
|
1672
|
+
yield [
|
|
1673
|
+
"end",
|
|
1674
|
+
{
|
|
1675
|
+
line: this.read(row + 4),
|
|
1676
|
+
column: this.read(row + 5),
|
|
1677
|
+
offset: this.read(row + 6)
|
|
1678
|
+
}
|
|
1679
|
+
];
|
|
1680
|
+
} else if (kind >= 3) {
|
|
1681
|
+
const keys = this.shapes[kind - 3].keys;
|
|
1682
|
+
for (let i = 0; i < keys.length; i++) {
|
|
1683
|
+
const key = keys[i];
|
|
1684
|
+
if (!key.startsWith("@")) yield [key, this.decode(this.read(row + 1 + i), true)];
|
|
1685
|
+
}
|
|
1686
|
+
}
|
|
1687
|
+
}
|
|
1688
|
+
field(row, key) {
|
|
1689
|
+
const kind = this.read(row), cached = this.cache.get(row);
|
|
1690
|
+
if (cached) {
|
|
1691
|
+
const descriptor = Object.getOwnPropertyDescriptor(cached, key);
|
|
1692
|
+
if (!descriptor) return void 0;
|
|
1693
|
+
if ("value" in descriptor) return descriptor.value;
|
|
1694
|
+
const assigned = this.overrides.get(cached);
|
|
1695
|
+
if (assigned?.has(key)) return assigned.get(key);
|
|
1696
|
+
if (kind < 3) return Reflect.get(cached, key);
|
|
1697
|
+
if (descriptor.get !== this.shapes[kind - 3].descriptors[key]?.get)
|
|
1698
|
+
return Reflect.get(cached, key);
|
|
1699
|
+
}
|
|
1700
|
+
if (kind < 3) return void 0;
|
|
1701
|
+
const keys = this.shapes[kind - 3].keys, index = keys.indexOf(key === "nodeId" ? "@id" : key);
|
|
1702
|
+
return index < 0 ? void 0 : this.decode(this.read(row + 1 + index), true);
|
|
1703
|
+
}
|
|
1704
|
+
assignId(row, id) {
|
|
1705
|
+
const keys = this.shapes[this.read(row) - 3].keys, index = keys.indexOf("@id");
|
|
1706
|
+
if (index < 0) throw new TypeError("Compiler record is not an AST node.");
|
|
1707
|
+
this.write(row + 1 + index, this.scalar(id));
|
|
1708
|
+
const cached = this.cache.get(row);
|
|
1709
|
+
if (cached)
|
|
1710
|
+
Object.defineProperty(cached, "nodeId", {
|
|
1711
|
+
value: id,
|
|
1712
|
+
writable: true,
|
|
1713
|
+
enumerable: false,
|
|
1714
|
+
configurable: true
|
|
1715
|
+
});
|
|
1716
|
+
}
|
|
1717
|
+
offsets(row) {
|
|
1718
|
+
const span = this.field(row, "span");
|
|
1719
|
+
if (!(span instanceof CodeRecord)) return void 0;
|
|
1720
|
+
const kind = this.read(span.row);
|
|
1721
|
+
return kind === 1 ? [this.read(span.row + 1), this.read(span.row + 2)] : kind === 2 ? [this.read(span.row + 3), this.read(span.row + 6)] : void 0;
|
|
1722
|
+
}
|
|
1723
|
+
};
|
|
1724
|
+
function compilerField(value, key) {
|
|
1725
|
+
const handle = record(value);
|
|
1726
|
+
return handle ? handle.owner.field(handle.row, key) : value !== null && typeof value === "object" ? value[key] : void 0;
|
|
1727
|
+
}
|
|
1728
|
+
function compilerIsArray(value) {
|
|
1729
|
+
const handle = record(value);
|
|
1730
|
+
return handle ? handle.owner.isArray(handle.row) : Array.isArray(value);
|
|
1731
|
+
}
|
|
1732
|
+
function* compilerEntries(value) {
|
|
1733
|
+
const handle = record(value);
|
|
1734
|
+
if (handle) yield* handle.owner.entries(handle.row);
|
|
1735
|
+
else yield* Object.entries(value);
|
|
1736
|
+
}
|
|
1737
|
+
function* compilerElements(value) {
|
|
1738
|
+
if (value === null || typeof value !== "object") return;
|
|
1739
|
+
if (Array.isArray(value)) {
|
|
1740
|
+
yield* value;
|
|
1741
|
+
return;
|
|
1742
|
+
}
|
|
1743
|
+
for (const [, child] of compilerEntries(value)) yield child;
|
|
1744
|
+
}
|
|
1745
|
+
function compilerAssignId(value, id) {
|
|
1746
|
+
const handle = record(value);
|
|
1747
|
+
if (handle) handle.owner.assignId(handle.row, id);
|
|
1748
|
+
else
|
|
1749
|
+
Object.defineProperty(value, "nodeId", {
|
|
1750
|
+
value: id,
|
|
1751
|
+
writable: true,
|
|
1752
|
+
enumerable: false,
|
|
1753
|
+
configurable: true
|
|
1754
|
+
});
|
|
1755
|
+
}
|
|
1756
|
+
function compilerOffsets(value) {
|
|
1757
|
+
const handle = record(value);
|
|
1758
|
+
if (handle) return handle.owner.offsets(handle.row);
|
|
1759
|
+
const span = compilerField(value, "span");
|
|
1760
|
+
return span ? [span.start.offset, span.end.offset] : void 0;
|
|
1761
|
+
}
|
|
1762
|
+
var CompactNodeIndex = class extends Map {
|
|
1763
|
+
#rows;
|
|
1764
|
+
#decode;
|
|
1765
|
+
constructor(token, rows, decode) {
|
|
1766
|
+
super();
|
|
1767
|
+
if (token !== recordToken) throw new TypeError("Foreign compiler index authority.");
|
|
1768
|
+
this.#rows = rows;
|
|
1769
|
+
this.#decode = decode;
|
|
1770
|
+
}
|
|
1771
|
+
get size() {
|
|
1772
|
+
return nativeIndexMap.size(this.#rows);
|
|
1773
|
+
}
|
|
1774
|
+
has(key) {
|
|
1775
|
+
return nativeIndexMap.has(this.#rows, key);
|
|
1776
|
+
}
|
|
1777
|
+
get(key) {
|
|
1778
|
+
if (nativeIndexMap.has(this, key)) return nativeIndexMap.get(this, key);
|
|
1779
|
+
const row = nativeIndexMap.get(this.#rows, key);
|
|
1780
|
+
return row === void 0 ? void 0 : this.#decode(row);
|
|
1781
|
+
}
|
|
1782
|
+
set(key, value) {
|
|
1783
|
+
if (!nativeIndexMap.has(this.#rows, key)) nativeIndexMap.set(this.#rows, key, -1);
|
|
1784
|
+
nativeIndexMap.set(this, key, value);
|
|
1785
|
+
return this;
|
|
1786
|
+
}
|
|
1787
|
+
delete(key) {
|
|
1788
|
+
nativeIndexMap.delete(this, key);
|
|
1789
|
+
return nativeIndexMap.delete(this.#rows, key);
|
|
1790
|
+
}
|
|
1791
|
+
clear() {
|
|
1792
|
+
nativeIndexMap.clear(this);
|
|
1793
|
+
nativeIndexMap.clear(this.#rows);
|
|
1794
|
+
}
|
|
1795
|
+
keys() {
|
|
1796
|
+
return nativeIndexMap.keys(this.#rows);
|
|
1797
|
+
}
|
|
1798
|
+
*values() {
|
|
1799
|
+
for (const key of this.keys()) yield this.get(key);
|
|
1800
|
+
}
|
|
1801
|
+
*entries() {
|
|
1802
|
+
for (const key of this.keys()) yield [key, this.get(key)];
|
|
1803
|
+
}
|
|
1804
|
+
[Symbol.iterator]() {
|
|
1805
|
+
return this.entries();
|
|
1806
|
+
}
|
|
1807
|
+
forEach(callback, thisArg) {
|
|
1808
|
+
for (const [key, value] of this) callback.call(thisArg, value, key, this);
|
|
1809
|
+
}
|
|
1810
|
+
};
|
|
1811
|
+
function compactDynamicNodes(root, source) {
|
|
1812
|
+
const handle = record(root);
|
|
1813
|
+
return handle?.owner.dynamicNodes(handle.row, source);
|
|
1814
|
+
}
|
|
1815
|
+
|
|
959
1816
|
// packages/safe-js/src/parse/bindings.ts
|
|
960
1817
|
function getFunctionLength(params) {
|
|
961
1818
|
const firstOptional = params.findIndex(
|
|
@@ -1051,66 +1908,169 @@ function* hoistedVarDeclarations(nodes) {
|
|
|
1051
1908
|
|
|
1052
1909
|
// packages/safe-js/src/parse/private-names.ts
|
|
1053
1910
|
function validatePrivateNames(root, inheritedNames) {
|
|
1054
|
-
const pending = [
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1911
|
+
const pending = [
|
|
1912
|
+
{
|
|
1913
|
+
value: root,
|
|
1914
|
+
scope: inheritedNames === void 0 ? void 0 : { names: new Set(inheritedNames) }
|
|
1915
|
+
}
|
|
1916
|
+
];
|
|
1058
1917
|
while (pending.length > 0) {
|
|
1059
1918
|
const { value, scope, declaration } = pending.pop();
|
|
1060
1919
|
if (value === null || typeof value !== "object") continue;
|
|
1061
|
-
if (
|
|
1062
|
-
for (const entry of value) pending.push({ value: entry, scope });
|
|
1920
|
+
if (compilerIsArray(value)) {
|
|
1921
|
+
for (const entry of compilerElements(value)) pending.push({ value: entry, scope });
|
|
1063
1922
|
continue;
|
|
1064
1923
|
}
|
|
1065
|
-
const
|
|
1066
|
-
if (
|
|
1067
|
-
|
|
1068
|
-
pending.push({ value: klass.superClass, scope });
|
|
1924
|
+
const type = compilerField(value, "type");
|
|
1925
|
+
if (type === "ClassDeclaration" || type === "ClassExpression") {
|
|
1926
|
+
pending.push({ value: compilerField(value, "superClass"), scope });
|
|
1069
1927
|
const inner = { names: /* @__PURE__ */ new Set(), parent: scope };
|
|
1070
1928
|
const declarations = /* @__PURE__ */ new Map();
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
const
|
|
1929
|
+
const body = compilerField(value, "body");
|
|
1930
|
+
for (const element of compilerElements(compilerField(body, "body"))) {
|
|
1931
|
+
const key = compilerField(element, "key");
|
|
1932
|
+
if (compilerField(element, "type") === "StaticBlock" || compilerField(key, "type") !== "PrivateIdentifier")
|
|
1933
|
+
continue;
|
|
1934
|
+
const name = compilerField(key, "name");
|
|
1074
1935
|
if (name === "constructor") throw new Error("Private name #constructor is forbidden.");
|
|
1075
|
-
const kind = element
|
|
1936
|
+
const kind = compilerField(element, "type") === "MethodDefinition" ? compilerField(element, "kind") : "field";
|
|
1937
|
+
const isStatic = compilerField(element, "static");
|
|
1076
1938
|
const previous = declarations.get(name);
|
|
1077
|
-
if (previous !== void 0 && !(previous.static ===
|
|
1939
|
+
if (previous !== void 0 && !(previous.static === isStatic && (previous.kind === "get" && kind === "set" || previous.kind === "set" && kind === "get")))
|
|
1078
1940
|
throw new Error(`Duplicate private name #${name}.`);
|
|
1079
|
-
declarations.set(name, {
|
|
1941
|
+
declarations.set(name, {
|
|
1942
|
+
kind: previous === void 0 ? kind : "pair",
|
|
1943
|
+
static: isStatic
|
|
1944
|
+
});
|
|
1080
1945
|
inner.names.add(name);
|
|
1081
1946
|
}
|
|
1082
|
-
pending.push({ value:
|
|
1947
|
+
pending.push({ value: body, scope: inner });
|
|
1083
1948
|
continue;
|
|
1084
1949
|
}
|
|
1085
|
-
if (
|
|
1950
|
+
if (type === "PrivateIdentifier") {
|
|
1086
1951
|
if (declaration) continue;
|
|
1952
|
+
const name = String(compilerField(value, "name"));
|
|
1087
1953
|
let owner = scope;
|
|
1088
|
-
while (owner !== void 0 && !owner.names.has(
|
|
1089
|
-
if (owner === void 0) throw new Error(`Undeclared private name #${
|
|
1954
|
+
while (owner !== void 0 && !owner.names.has(name)) owner = owner.parent;
|
|
1955
|
+
if (owner === void 0) throw new Error(`Undeclared private name #${name}.`);
|
|
1090
1956
|
continue;
|
|
1091
1957
|
}
|
|
1092
|
-
if (
|
|
1093
|
-
const property =
|
|
1094
|
-
if (property
|
|
1958
|
+
if (type === "MemberExpression") {
|
|
1959
|
+
const property = compilerField(value, "property");
|
|
1960
|
+
if (compilerField(property, "type") === "PrivateIdentifier" && compilerField(compilerField(value, "object"), "type") === "Super")
|
|
1095
1961
|
throw new Error("super cannot access a private name.");
|
|
1096
1962
|
}
|
|
1097
|
-
if (
|
|
1098
|
-
const argument =
|
|
1099
|
-
if (argument
|
|
1963
|
+
if (type === "UnaryExpression" && compilerField(value, "operator") === "delete") {
|
|
1964
|
+
const argument = compilerField(value, "argument");
|
|
1965
|
+
if (compilerField(argument, "type") === "MemberExpression" && compilerField(compilerField(argument, "property"), "type") === "PrivateIdentifier")
|
|
1100
1966
|
throw new Error("Private elements cannot be deleted.");
|
|
1101
1967
|
}
|
|
1102
|
-
for (const [key, child] of
|
|
1968
|
+
for (const [key, child] of compilerEntries(value)) {
|
|
1103
1969
|
if (key === "span") continue;
|
|
1104
1970
|
pending.push({
|
|
1105
1971
|
value: child,
|
|
1106
1972
|
scope,
|
|
1107
|
-
declaration: key === "key" && (
|
|
1973
|
+
declaration: key === "key" && (type === "MethodDefinition" || type === "PropertyDefinition")
|
|
1108
1974
|
});
|
|
1109
1975
|
}
|
|
1110
1976
|
}
|
|
1111
1977
|
}
|
|
1112
1978
|
|
|
1979
|
+
// packages/safe-js/src/parse/compact-tokens.ts
|
|
1980
|
+
var types = [
|
|
1981
|
+
"identifier",
|
|
1982
|
+
"private-identifier",
|
|
1983
|
+
"keyword",
|
|
1984
|
+
"escaped-keyword",
|
|
1985
|
+
"numeric",
|
|
1986
|
+
"regex",
|
|
1987
|
+
"string",
|
|
1988
|
+
"template",
|
|
1989
|
+
"punctuator",
|
|
1990
|
+
"eof"
|
|
1991
|
+
];
|
|
1992
|
+
var stride = 3;
|
|
1993
|
+
var legacyEscape = 256;
|
|
1994
|
+
var tokenCacheSize = 256;
|
|
1995
|
+
var CompactTokens = class {
|
|
1996
|
+
constructor(sourcePositions) {
|
|
1997
|
+
this.sourcePositions = sourcePositions;
|
|
1998
|
+
}
|
|
1999
|
+
sourcePositions;
|
|
2000
|
+
rows = new Uint32Array(1024 * stride);
|
|
2001
|
+
values = [];
|
|
2002
|
+
templates = /* @__PURE__ */ new Map();
|
|
2003
|
+
tokens = /* @__PURE__ */ new Map();
|
|
2004
|
+
last;
|
|
2005
|
+
// Only indexing, iteration, length, push and at are used by the lexer/parser.
|
|
2006
|
+
// Historical tokens are materialized on demand in a bounded cache.
|
|
2007
|
+
indexed = new Proxy([], {
|
|
2008
|
+
get: (target, key, receiver) => {
|
|
2009
|
+
if (key === "length") return this.values.length;
|
|
2010
|
+
if (key === "push") return this.push;
|
|
2011
|
+
const index = arrayIndex(key);
|
|
2012
|
+
return index === void 0 ? Reflect.get(target, key, receiver) : this.get(index);
|
|
2013
|
+
},
|
|
2014
|
+
set: () => {
|
|
2015
|
+
throw new TypeError("Compiler token rows cannot be reassigned.");
|
|
2016
|
+
}
|
|
2017
|
+
});
|
|
2018
|
+
finish() {
|
|
2019
|
+
this.rows = this.rows.slice(0, this.values.length * stride);
|
|
2020
|
+
if (this.last) {
|
|
2021
|
+
this.last.start = this.sourcePositions.position(this.last.start.offset);
|
|
2022
|
+
this.last.end = this.sourcePositions.position(this.last.end.offset);
|
|
2023
|
+
}
|
|
2024
|
+
return this.indexed;
|
|
2025
|
+
}
|
|
2026
|
+
push = (token) => {
|
|
2027
|
+
if (this.last !== void 0) {
|
|
2028
|
+
const previous = this.values.length - 1;
|
|
2029
|
+
if (this.last.legacyEscape) this.rows[previous * stride + 2] |= legacyEscape;
|
|
2030
|
+
if (this.last.templateExpressions !== void 0)
|
|
2031
|
+
this.templates.set(previous, this.last.templateExpressions);
|
|
2032
|
+
}
|
|
2033
|
+
const index = this.values.length;
|
|
2034
|
+
const base = index * stride;
|
|
2035
|
+
if (base + stride > this.rows.length) {
|
|
2036
|
+
const rows = new Uint32Array(this.rows.length * 2);
|
|
2037
|
+
rows.set(this.rows);
|
|
2038
|
+
this.rows = rows;
|
|
2039
|
+
}
|
|
2040
|
+
this.rows.set([token.start.offset, token.end.offset, types.indexOf(token.type)], base);
|
|
2041
|
+
this.values.push(token.value);
|
|
2042
|
+
this.last = token;
|
|
2043
|
+
return index + 1;
|
|
2044
|
+
};
|
|
2045
|
+
get(index) {
|
|
2046
|
+
if (index >= this.values.length) return void 0;
|
|
2047
|
+
if (index === this.values.length - 1) return this.last;
|
|
2048
|
+
const cached = this.tokens.get(index);
|
|
2049
|
+
if (cached !== void 0) return cached;
|
|
2050
|
+
const base = index * stride;
|
|
2051
|
+
const bits = this.rows[base + 2];
|
|
2052
|
+
const token = {
|
|
2053
|
+
type: types[bits & 255],
|
|
2054
|
+
value: this.values[index],
|
|
2055
|
+
start: this.sourcePositions.position(this.rows[base]),
|
|
2056
|
+
end: this.sourcePositions.position(this.rows[base + 1])
|
|
2057
|
+
};
|
|
2058
|
+
if (bits & legacyEscape) token.legacyEscape = true;
|
|
2059
|
+
const expressions = this.templates.get(index);
|
|
2060
|
+
if (expressions !== void 0) token.templateExpressions = expressions;
|
|
2061
|
+
if (this.tokens.size === tokenCacheSize) this.tokens.delete(this.tokens.keys().next().value);
|
|
2062
|
+
this.tokens.set(index, token);
|
|
2063
|
+
return token;
|
|
2064
|
+
}
|
|
2065
|
+
};
|
|
2066
|
+
function arrayIndex(key) {
|
|
2067
|
+
if (typeof key !== "string") return void 0;
|
|
2068
|
+
const index = Number(key);
|
|
2069
|
+
return Number.isSafeInteger(index) && index >= 0 && String(index) === key ? index : void 0;
|
|
2070
|
+
}
|
|
2071
|
+
|
|
1113
2072
|
// packages/safe-js/src/parse/tokenizer.ts
|
|
2073
|
+
var freezePosition = Object.freeze;
|
|
1114
2074
|
var KEYWORDS = /* @__PURE__ */ new Set([
|
|
1115
2075
|
"class",
|
|
1116
2076
|
"extends",
|
|
@@ -1218,26 +2178,33 @@ function tokenize(source, options = {}) {
|
|
|
1218
2178
|
const lexer = new Lexer(source, options);
|
|
1219
2179
|
return lexer.tokenize();
|
|
1220
2180
|
}
|
|
2181
|
+
function tokenizeCompact(source, options, positions) {
|
|
2182
|
+
const tokens = new CompactTokens(positions);
|
|
2183
|
+
new Lexer(source, { ...options, sharedPositions: true }, tokens.indexed).tokenize();
|
|
2184
|
+
return tokens.finish();
|
|
2185
|
+
}
|
|
1221
2186
|
function collectComments(source) {
|
|
1222
2187
|
const comments = [];
|
|
1223
2188
|
tokenize(source, { allowRegexLiterals: true, statementList: true, comments });
|
|
1224
2189
|
return comments;
|
|
1225
2190
|
}
|
|
1226
2191
|
var Lexer = class {
|
|
1227
|
-
constructor(source, options) {
|
|
2192
|
+
constructor(source, options, tokens = []) {
|
|
1228
2193
|
this.source = source;
|
|
1229
2194
|
this.options = options;
|
|
2195
|
+
this.tokens = tokens;
|
|
1230
2196
|
}
|
|
1231
2197
|
source;
|
|
1232
2198
|
options;
|
|
2199
|
+
tokens;
|
|
1233
2200
|
index = 0;
|
|
1234
2201
|
line = 1;
|
|
1235
2202
|
column = 1;
|
|
1236
|
-
tokens = [];
|
|
1237
2203
|
groupingState = { stack: [], classHeads: [], tokenCount: 0 };
|
|
1238
2204
|
lastClosedStatementBoundary = false;
|
|
1239
2205
|
legacyStringEscape = false;
|
|
1240
2206
|
lineHasToken = false;
|
|
2207
|
+
lastPosition;
|
|
1241
2208
|
tokenize() {
|
|
1242
2209
|
while (!this.isAtEnd()) {
|
|
1243
2210
|
this.skipTrivia();
|
|
@@ -2011,11 +2978,15 @@ var Lexer = class {
|
|
|
2011
2978
|
return this.index >= this.source.length;
|
|
2012
2979
|
}
|
|
2013
2980
|
position() {
|
|
2014
|
-
|
|
2981
|
+
if (this.options.sharedPositions && this.lastPosition?.offset === this.index)
|
|
2982
|
+
return this.lastPosition;
|
|
2983
|
+
const position = {
|
|
2015
2984
|
line: this.line,
|
|
2016
2985
|
column: this.column,
|
|
2017
2986
|
offset: this.index
|
|
2018
2987
|
};
|
|
2988
|
+
if (!this.options.sharedPositions) return position;
|
|
2989
|
+
return this.lastPosition = freezePosition(position);
|
|
2019
2990
|
}
|
|
2020
2991
|
advance() {
|
|
2021
2992
|
if (this.isAtEnd()) {
|
|
@@ -2316,15 +3287,39 @@ function compareBySourceOrder(left, right) {
|
|
|
2316
3287
|
function isAstNode(value) {
|
|
2317
3288
|
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string" && "span" in value && typeof value.span?.start.offset === "number" && typeof value.span?.end.offset === "number";
|
|
2318
3289
|
}
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2324
|
-
|
|
2325
|
-
|
|
2326
|
-
|
|
2327
|
-
|
|
3290
|
+
function assignCompactIds(root) {
|
|
3291
|
+
const stack = [root];
|
|
3292
|
+
let nextId = 0;
|
|
3293
|
+
const isNode = (value) => value !== null && typeof value === "object" && typeof compilerField(value, "type") === "string" && compilerOffsets(value) !== void 0;
|
|
3294
|
+
while (stack.length) {
|
|
3295
|
+
const node = stack.pop();
|
|
3296
|
+
if (!isNode(node) || compilerField(node, "nodeId") !== void 0) continue;
|
|
3297
|
+
compilerAssignId(node, nextId++);
|
|
3298
|
+
const type = compilerField(node, "type");
|
|
3299
|
+
const children = [];
|
|
3300
|
+
const add = (value) => {
|
|
3301
|
+
if (isNode(value)) children.push(value);
|
|
3302
|
+
else if (compilerIsArray(value)) {
|
|
3303
|
+
for (const child of compilerElements(value))
|
|
3304
|
+
if (isNode(child)) children.push(child);
|
|
3305
|
+
}
|
|
3306
|
+
};
|
|
3307
|
+
if (type === "UnaryExpression") add(compilerField(node, "argument"));
|
|
3308
|
+
else if (type === "ExpressionStatement")
|
|
3309
|
+
add(compilerField(node, "expression"));
|
|
3310
|
+
else if (type === "Module") add(compilerField(node, "body"));
|
|
3311
|
+
else {
|
|
3312
|
+
for (const [key, child] of compilerEntries(node))
|
|
3313
|
+
if (key !== "nodeId" && key !== "span" && key !== "type") add(child);
|
|
3314
|
+
children.sort((left, right) => {
|
|
3315
|
+
const a = compilerOffsets(left), b = compilerOffsets(right);
|
|
3316
|
+
return a[0] - b[0] || a[1] - b[1];
|
|
3317
|
+
});
|
|
3318
|
+
}
|
|
3319
|
+
for (let i = children.length - 1; i >= 0; i--) stack.push(children[i]);
|
|
3320
|
+
}
|
|
3321
|
+
return root;
|
|
3322
|
+
}
|
|
2328
3323
|
|
|
2329
3324
|
// packages/safe-js/src/parse/syntax-diagnostic.ts
|
|
2330
3325
|
var syntaxDiagnostics = /* @__PURE__ */ new WeakMap();
|
|
@@ -3121,6 +4116,7 @@ function allHexDigits(value) {
|
|
|
3121
4116
|
}
|
|
3122
4117
|
|
|
3123
4118
|
// packages/safe-js/src/parse/parser.ts
|
|
4119
|
+
var isFrozenPosition = Object.isFrozen;
|
|
3124
4120
|
var MAX_CONDITIONAL_EXPRESSION_DEPTH = 256;
|
|
3125
4121
|
var MAX_IF_STATEMENT_DEPTH = 2048;
|
|
3126
4122
|
var STRICT_BINDING_NAMES = /* @__PURE__ */ new Set(["eval", "arguments", "implements", "interface", "let", "package", "private", "protected", "public", "static", "yield"]);
|
|
@@ -3211,7 +4207,7 @@ function parseModule(source, filename = "<input>", owner) {
|
|
|
3211
4207
|
compilation.dispose();
|
|
3212
4208
|
}
|
|
3213
4209
|
}
|
|
3214
|
-
function parseSourceModule(source, filename = "<input>", owner) {
|
|
4210
|
+
function parseSourceModule(source, filename = "<input>", owner, options = {}) {
|
|
3215
4211
|
const compilation = new CompileScope(owner);
|
|
3216
4212
|
const syntax = { imports: [], exports: [], moduleRequests: [] };
|
|
3217
4213
|
let parser;
|
|
@@ -3220,8 +4216,10 @@ function parseSourceModule(source, filename = "<input>", owner) {
|
|
|
3220
4216
|
if (limit !== void 0 && source.length > limit)
|
|
3221
4217
|
throw new SandboxError({ budget: "stringLength", current: source.length, limit });
|
|
3222
4218
|
owner?.budget.visitNode(source.length);
|
|
4219
|
+
const tokenOptions = { allowRegexLiterals: true, statementList: true, compilation, sharedPositions: options.sharedPositions };
|
|
4220
|
+
const tokens = options.compactAst ? tokenizeCompact(source, tokenOptions, new CompactSourcePositions(source)) : tokenize(source, tokenOptions);
|
|
3223
4221
|
parser = new Parser(
|
|
3224
|
-
|
|
4222
|
+
tokens,
|
|
3225
4223
|
source,
|
|
3226
4224
|
compilation,
|
|
3227
4225
|
"top-level",
|
|
@@ -3235,7 +4233,10 @@ function parseSourceModule(source, filename = "<input>", owner) {
|
|
|
3235
4233
|
true,
|
|
3236
4234
|
syntax
|
|
3237
4235
|
);
|
|
3238
|
-
|
|
4236
|
+
if (options.compactAst) parser.enableCompactAst();
|
|
4237
|
+
const parsed = parser.parseModule();
|
|
4238
|
+
parser.finishAstStorage();
|
|
4239
|
+
const module = (options.compactAst ? assignCompactIds : assignIds)(parsed);
|
|
3239
4240
|
if (source.includes("#")) validatePrivateNames(module);
|
|
3240
4241
|
let hasTLA = false;
|
|
3241
4242
|
const pending = [module];
|
|
@@ -3243,9 +4244,10 @@ function parseSourceModule(source, filename = "<input>", owner) {
|
|
|
3243
4244
|
const node = pending.pop();
|
|
3244
4245
|
if (node === null || typeof node !== "object") continue;
|
|
3245
4246
|
owner?.budget.visitNode();
|
|
3246
|
-
|
|
3247
|
-
if ("
|
|
3248
|
-
|
|
4247
|
+
const type = compilerField(node, "type");
|
|
4248
|
+
if (["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"].includes(String(type))) continue;
|
|
4249
|
+
if (type !== void 0 && (type === "AwaitExpression" || compilerField(node, "await") === true || type === "VariableDeclaration" && compilerField(node, "disposal") === "async")) hasTLA = true;
|
|
4250
|
+
for (const child of compilerElements(node)) pending.push(child);
|
|
3249
4251
|
}
|
|
3250
4252
|
return { ...syntax, module, hasTLA, requests: [...new Set(syntax.moduleRequests.map((request) => request.specifier))] };
|
|
3251
4253
|
} catch (error) {
|
|
@@ -3259,7 +4261,7 @@ function parseSourceModule(source, filename = "<input>", owner) {
|
|
|
3259
4261
|
compilation.dispose();
|
|
3260
4262
|
}
|
|
3261
4263
|
}
|
|
3262
|
-
function parseExecutableModule(source, filename = "<input>", owner) {
|
|
4264
|
+
function parseExecutableModule(source, filename = "<input>", owner, importSpecifiers) {
|
|
3263
4265
|
const compilation = new CompileScope(owner);
|
|
3264
4266
|
try {
|
|
3265
4267
|
const result = assignIds(
|
|
@@ -3268,7 +4270,10 @@ function parseExecutableModule(source, filename = "<input>", owner) {
|
|
|
3268
4270
|
source,
|
|
3269
4271
|
compilation,
|
|
3270
4272
|
"top-level",
|
|
3271
|
-
{ ...ordinaryFunctionContext, newTarget: false, requireAsyncAwait: true }
|
|
4273
|
+
{ ...ordinaryFunctionContext, newTarget: false, requireAsyncAwait: true },
|
|
4274
|
+
true,
|
|
4275
|
+
void 0,
|
|
4276
|
+
new Set(importSpecifiers)
|
|
3272
4277
|
).parseModule()
|
|
3273
4278
|
);
|
|
3274
4279
|
throwIfImportMetaAssignment(result);
|
|
@@ -3286,7 +4291,7 @@ function parseExecutableModule(source, filename = "<input>", owner) {
|
|
|
3286
4291
|
compilation.dispose();
|
|
3287
4292
|
}
|
|
3288
4293
|
}
|
|
3289
|
-
function parseEvalScript(source, context = {}, owner) {
|
|
4294
|
+
function parseEvalScript(source, context = {}, owner, filename = "<eval>", options = {}) {
|
|
3290
4295
|
const compilation = new CompileScope(owner);
|
|
3291
4296
|
try {
|
|
3292
4297
|
const limit = owner?.budget.limits.stringLength;
|
|
@@ -3294,14 +4299,16 @@ function parseEvalScript(source, context = {}, owner) {
|
|
|
3294
4299
|
throw new SandboxError({ budget: "stringLength", current: source.length, limit });
|
|
3295
4300
|
if (owner !== void 0) for (let index = 0; index < source.length; index++) owner.budget.visitNode();
|
|
3296
4301
|
const grammar = { await: false, yield: false, strict: context.strict === true };
|
|
3297
|
-
const
|
|
4302
|
+
const tokenOptions = {
|
|
3298
4303
|
allowRegexLiterals: true,
|
|
3299
4304
|
statementList: true,
|
|
3300
4305
|
allowLegacyNumbers: true,
|
|
3301
4306
|
allowLegacyEscapes: true,
|
|
3302
4307
|
allowHtmlComments: true,
|
|
3303
4308
|
compilation
|
|
3304
|
-
}
|
|
4309
|
+
};
|
|
4310
|
+
const tokens = options.compactAst ? tokenizeCompact(source, tokenOptions, new CompactSourcePositions(source)) : tokenize(source, tokenOptions);
|
|
4311
|
+
const parser = new Parser(tokens, source, compilation, "normal", {
|
|
3305
4312
|
grammar,
|
|
3306
4313
|
newTarget: context.newTarget === true,
|
|
3307
4314
|
superProperty: context.superProperty === true,
|
|
@@ -3311,7 +4318,10 @@ function parseEvalScript(source, context = {}, owner) {
|
|
|
3311
4318
|
await: false,
|
|
3312
4319
|
strictAwait: true
|
|
3313
4320
|
}, false);
|
|
3314
|
-
|
|
4321
|
+
if (options.compactAst) parser.enableCompactAst();
|
|
4322
|
+
const parsed = parser.parseScript();
|
|
4323
|
+
parser.finishAstStorage();
|
|
4324
|
+
const node = (options.compactAst ? assignCompactIds : assignIds)(parsed);
|
|
3315
4325
|
if (source.includes("#")) validatePrivateNames(node, context.privateNames);
|
|
3316
4326
|
for (const statement of node.body) {
|
|
3317
4327
|
if (statement.type === "FunctionDeclaration") evalFunctionDeclarations.add(statement);
|
|
@@ -3319,7 +4329,7 @@ function parseEvalScript(source, context = {}, owner) {
|
|
|
3319
4329
|
return { node, strict: grammar.strict };
|
|
3320
4330
|
} catch (error) {
|
|
3321
4331
|
if (error instanceof SandboxError) throw error;
|
|
3322
|
-
throw createSyntaxDiagnostic(source,
|
|
4332
|
+
throw createSyntaxDiagnostic(source, filename, error);
|
|
3323
4333
|
} finally {
|
|
3324
4334
|
compilation.dispose();
|
|
3325
4335
|
}
|
|
@@ -3373,7 +4383,7 @@ var ordinaryFunctionContext = {
|
|
|
3373
4383
|
await: true
|
|
3374
4384
|
};
|
|
3375
4385
|
var Parser = class {
|
|
3376
|
-
constructor(tokens, source, compilation, functionContext = "top-level", lexicalContext = { ...ordinaryFunctionContext, newTarget: false }, allowImportMeta = true, moduleSyntax) {
|
|
4386
|
+
constructor(tokens, source, compilation, functionContext = "top-level", lexicalContext = { ...ordinaryFunctionContext, newTarget: false }, allowImportMeta = true, moduleSyntax, importSpecifiers) {
|
|
3377
4387
|
this.tokens = tokens;
|
|
3378
4388
|
this.source = source;
|
|
3379
4389
|
this.compilation = compilation;
|
|
@@ -3381,6 +4391,7 @@ var Parser = class {
|
|
|
3381
4391
|
this.lexicalContext = lexicalContext;
|
|
3382
4392
|
this.allowImportMeta = allowImportMeta;
|
|
3383
4393
|
this.moduleSyntax = moduleSyntax;
|
|
4394
|
+
this.importSpecifiers = importSpecifiers;
|
|
3384
4395
|
this.functionScopes.add(this.scopes[0]);
|
|
3385
4396
|
}
|
|
3386
4397
|
tokens;
|
|
@@ -3390,6 +4401,7 @@ var Parser = class {
|
|
|
3390
4401
|
lexicalContext;
|
|
3391
4402
|
allowImportMeta;
|
|
3392
4403
|
moduleSyntax;
|
|
4404
|
+
importSpecifiers;
|
|
3393
4405
|
index = 0;
|
|
3394
4406
|
allowIn = true;
|
|
3395
4407
|
breakableDepth = 0;
|
|
@@ -3404,6 +4416,14 @@ var Parser = class {
|
|
|
3404
4416
|
varNames = /* @__PURE__ */ new WeakMap();
|
|
3405
4417
|
sourceExportNames = /* @__PURE__ */ new Set();
|
|
3406
4418
|
sourceLocalExports = /* @__PURE__ */ new Map();
|
|
4419
|
+
astStorage;
|
|
4420
|
+
enableCompactAst() {
|
|
4421
|
+
if (this.astStorage) throw new TypeError("Compiler body storage is already enabled.");
|
|
4422
|
+
this.astStorage = new CompactModuleAst(this.source);
|
|
4423
|
+
}
|
|
4424
|
+
finishAstStorage() {
|
|
4425
|
+
this.astStorage?.finish();
|
|
4426
|
+
}
|
|
3407
4427
|
get position() {
|
|
3408
4428
|
return (this.tokens[this.index] ?? this.tokens[this.tokens.length - 1]).start;
|
|
3409
4429
|
}
|
|
@@ -3417,6 +4437,8 @@ var Parser = class {
|
|
|
3417
4437
|
start: node.span.start.offset,
|
|
3418
4438
|
end: node.span.end.offset
|
|
3419
4439
|
});
|
|
4440
|
+
if (this.astStorage && node.type !== "ClassDeclaration" && node.type !== "ClassExpression" && node.body.span.end.offset - node.body.span.start.offset >= 512)
|
|
4441
|
+
node.body = this.astStorage.pack(node.body, true, true);
|
|
3420
4442
|
return node;
|
|
3421
4443
|
}
|
|
3422
4444
|
parseDynamicParameters() {
|
|
@@ -3454,7 +4476,8 @@ var Parser = class {
|
|
|
3454
4476
|
}
|
|
3455
4477
|
if (this.isExportToken(token)) {
|
|
3456
4478
|
const statement2 = this.parseSourceExport();
|
|
3457
|
-
if (statement2 !== void 0)
|
|
4479
|
+
if (statement2 !== void 0)
|
|
4480
|
+
body.push(this.astStorage?.pack(statement2, false, true) ?? statement2);
|
|
3458
4481
|
continue;
|
|
3459
4482
|
}
|
|
3460
4483
|
}
|
|
@@ -3463,26 +4486,29 @@ var Parser = class {
|
|
|
3463
4486
|
while (statement.type !== "EmptyStatement" && this.consumePunctuator(";") !== void 0) {
|
|
3464
4487
|
continue;
|
|
3465
4488
|
}
|
|
4489
|
+
if (this.astStorage) body[body.length - 1] = this.astStorage.pack(statement, false, true);
|
|
3466
4490
|
}
|
|
3467
4491
|
for (const [name, identifier] of this.sourceLocalExports) {
|
|
3468
4492
|
if (!this.scopes[0].has(name) && !this.varNames.get(this.scopes[0])?.has(name))
|
|
3469
4493
|
throw new Error(`Export '${name}' is not defined at line ${identifier.span.start.line}, column ${identifier.span.start.column}.`);
|
|
3470
4494
|
}
|
|
3471
4495
|
const end = this.currentToken().end;
|
|
3472
|
-
|
|
4496
|
+
const module = {
|
|
3473
4497
|
type: "Module",
|
|
3474
4498
|
body,
|
|
3475
4499
|
span: createSpan2(body[0]?.span.start ?? end, body[body.length - 1]?.span.end ?? end)
|
|
3476
4500
|
};
|
|
4501
|
+
return this.astStorage?.pack(module, false, true) ?? module;
|
|
3477
4502
|
}
|
|
3478
4503
|
parseScript() {
|
|
3479
4504
|
const body = this.parseStatementList(void 0, true);
|
|
3480
4505
|
const end = this.currentToken().end;
|
|
3481
|
-
|
|
4506
|
+
const module = {
|
|
3482
4507
|
type: "Module",
|
|
3483
4508
|
body,
|
|
3484
4509
|
span: createSpan2(body[0]?.span.start ?? end, body[body.length - 1]?.span.end ?? end)
|
|
3485
4510
|
};
|
|
4511
|
+
return this.astStorage?.pack(module, false, true) ?? module;
|
|
3486
4512
|
}
|
|
3487
4513
|
parseExpressionOnly() {
|
|
3488
4514
|
const expression = this.parseExpression({ allowSequence: true }).node;
|
|
@@ -3765,6 +4791,8 @@ var Parser = class {
|
|
|
3765
4791
|
while (statement.type !== "EmptyStatement" && this.consumePunctuator(";") !== void 0) {
|
|
3766
4792
|
if (++semicolons > 1) directivePrologue = false;
|
|
3767
4793
|
}
|
|
4794
|
+
if (start === void 0 && this.astStorage)
|
|
4795
|
+
body[body.length - 1] = this.astStorage.pack(statement, false, true);
|
|
3768
4796
|
}
|
|
3769
4797
|
return body;
|
|
3770
4798
|
}
|
|
@@ -4457,7 +5485,7 @@ var Parser = class {
|
|
|
4457
5485
|
}
|
|
4458
5486
|
this.index += 1;
|
|
4459
5487
|
const source = createStringLiteral(sourceToken);
|
|
4460
|
-
assertBareImportSpecifier(source);
|
|
5488
|
+
if (!this.importSpecifiers?.has(source.value)) assertBareImportSpecifier(source);
|
|
4461
5489
|
return {
|
|
4462
5490
|
type: "ImportDeclaration",
|
|
4463
5491
|
specifiers,
|
|
@@ -7368,14 +8396,16 @@ function positionWithinRaw(base, raw, index) {
|
|
|
7368
8396
|
}
|
|
7369
8397
|
column += 1;
|
|
7370
8398
|
}
|
|
7371
|
-
|
|
8399
|
+
const position = { line, column, offset };
|
|
8400
|
+
return compactDerivedPosition(base, position) ?? position;
|
|
7372
8401
|
}
|
|
7373
8402
|
function rebasePosition(position, base) {
|
|
7374
|
-
|
|
8403
|
+
const rebased = {
|
|
7375
8404
|
line: base.line + position.line - 1,
|
|
7376
8405
|
column: position.line === 1 ? base.column + position.column - 1 : position.column,
|
|
7377
8406
|
offset: base.offset + position.offset
|
|
7378
8407
|
};
|
|
8408
|
+
return compactDerivedPosition(base, rebased) ?? rebased;
|
|
7379
8409
|
}
|
|
7380
8410
|
function isLiteralPropertyKey(token) {
|
|
7381
8411
|
return token.type === "numeric" || token.type === "string";
|
|
@@ -7395,9 +8425,9 @@ function assertAllowedIdentifierReference(token, strict) {
|
|
|
7395
8425
|
}
|
|
7396
8426
|
}
|
|
7397
8427
|
function createSpan2(start, end) {
|
|
7398
|
-
return {
|
|
7399
|
-
start: { ...start },
|
|
7400
|
-
end: { ...end }
|
|
8428
|
+
return compactSourceSpan(start, end) ?? {
|
|
8429
|
+
start: isFrozenPosition(start) ? start : { ...start },
|
|
8430
|
+
end: isFrozenPosition(end) ? end : { ...end }
|
|
7401
8431
|
};
|
|
7402
8432
|
}
|
|
7403
8433
|
function hasLineBreakBetween(left, right) {
|
|
@@ -7554,10 +8584,6 @@ var numericTypedArrayConstructors = {
|
|
|
7554
8584
|
};
|
|
7555
8585
|
|
|
7556
8586
|
export {
|
|
7557
|
-
getFunctionLength,
|
|
7558
|
-
boundIdentifiers,
|
|
7559
|
-
containsParameterExpression,
|
|
7560
|
-
hoistedVarDeclarations,
|
|
7561
8587
|
internalSymbols,
|
|
7562
8588
|
sandboxErrorNames,
|
|
7563
8589
|
sandboxErrorTypes,
|
|
@@ -7575,18 +8601,22 @@ export {
|
|
|
7575
8601
|
SandboxError,
|
|
7576
8602
|
isFatalSandboxError,
|
|
7577
8603
|
Budget,
|
|
7578
|
-
allocateRegexSteps,
|
|
7579
|
-
CompileScope,
|
|
7580
|
-
RegexCompileGuard,
|
|
7581
|
-
regexCompiledData,
|
|
7582
|
-
tokenize,
|
|
7583
|
-
collectComments,
|
|
7584
8604
|
functionSources,
|
|
7585
8605
|
functionStrictness,
|
|
7586
8606
|
evalFunctionDeclarations,
|
|
7587
8607
|
dynamicSourceRecords,
|
|
7588
8608
|
dynamicNodeSources,
|
|
7589
8609
|
dynamicValueSources,
|
|
8610
|
+
compactDynamicNodes,
|
|
8611
|
+
getFunctionLength,
|
|
8612
|
+
boundIdentifiers,
|
|
8613
|
+
containsParameterExpression,
|
|
8614
|
+
hoistedVarDeclarations,
|
|
8615
|
+
CompileScope,
|
|
8616
|
+
RegexCompileGuard,
|
|
8617
|
+
regexCompiledData,
|
|
8618
|
+
tokenize,
|
|
8619
|
+
collectComments,
|
|
7590
8620
|
splitSourceLines,
|
|
7591
8621
|
ParseError,
|
|
7592
8622
|
formatParseError,
|
|
@@ -7615,4 +8645,4 @@ export {
|
|
|
7615
8645
|
Float16Array2 as Float16Array,
|
|
7616
8646
|
numericTypedArrayConstructors
|
|
7617
8647
|
};
|
|
7618
|
-
//# sourceMappingURL=chunk-
|
|
8648
|
+
//# sourceMappingURL=chunk-RYVHEOHM.js.map
|