@poe-platform/safe-bash 0.1.434 → 0.1.436
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/dist/safe-bash/browser.js +350 -113
- package/dist/safe-bash/browser.js.map +3 -3
- package/dist/safe-bash/commands/stream-format/nl.js +1 -1
- package/dist/safe-bash/commands/stream-format/nl.js.map +1 -1
- package/dist/safe-bash/commands/structured/interpreter.js +10 -10
- package/dist/safe-bash/commands/structured/interpreter.js.map +1 -1
- package/dist/safe-bash/commands/structured/limits.d.ts +3 -1
- package/dist/safe-bash/commands/structured/limits.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/limits.js +16 -5
- package/dist/safe-bash/commands/structured/limits.js.map +1 -1
- package/dist/safe-bash/commands/structured/values.d.ts +5 -3
- package/dist/safe-bash/commands/structured/values.d.ts.map +1 -1
- package/dist/safe-bash/commands/structured/values.js +73 -21
- package/dist/safe-bash/commands/structured/values.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/awk-runtime.js +4 -4
- package/dist/safe-bash/commands/text-programs/awk-runtime.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/regex.d.ts +2 -1
- package/dist/safe-bash/commands/text-programs/regex.d.ts.map +1 -1
- package/dist/safe-bash/commands/text-programs/regex.js +230 -93
- package/dist/safe-bash/commands/text-programs/regex.js.map +1 -1
- package/dist/safe-bash/commands/text-programs/sed.js +1 -1
- package/dist/safe-bash/commands/text-programs/sed.js.map +1 -1
- package/dist/safe-bash/portable.js +439 -148
- package/dist/safe-bash/portable.js.map +3 -3
- package/dist/safe-bash/shell/arrays/state.d.ts +6 -1
- package/dist/safe-bash/shell/arrays/state.d.ts.map +1 -1
- package/dist/safe-bash/shell/arrays/state.js +30 -3
- package/dist/safe-bash/shell/arrays/state.js.map +1 -1
- package/dist/safe-bash/shell/cleanup.d.ts +1 -1
- package/dist/safe-bash/shell/cleanup.d.ts.map +1 -1
- package/dist/safe-bash/shell/cleanup.js +7 -3
- package/dist/safe-bash/shell/cleanup.js.map +1 -1
- package/dist/safe-bash/shell/getopts.d.ts +10 -1
- package/dist/safe-bash/shell/getopts.d.ts.map +1 -1
- package/dist/safe-bash/shell/getopts.js +55 -6
- package/dist/safe-bash/shell/getopts.js.map +1 -1
- package/dist/safe-bash/shell/runtime.d.ts.map +1 -1
- package/dist/safe-bash/shell/runtime.js +69 -27
- package/dist/safe-bash/shell/runtime.js.map +1 -1
- package/package.json +2 -2
|
@@ -9222,7 +9222,7 @@ var InvocationScope = class _InvocationScope {
|
|
|
9222
9222
|
failures;
|
|
9223
9223
|
parent;
|
|
9224
9224
|
#children = /* @__PURE__ */ new Set();
|
|
9225
|
-
#callbacks =
|
|
9225
|
+
#callbacks = /* @__PURE__ */ new Map();
|
|
9226
9226
|
#finalizers = [];
|
|
9227
9227
|
#work = /* @__PURE__ */ new Set();
|
|
9228
9228
|
#controller = new AbortController();
|
|
@@ -9249,7 +9249,11 @@ var InvocationScope = class _InvocationScope {
|
|
|
9249
9249
|
register(cleanup) {
|
|
9250
9250
|
this.assertOpen();
|
|
9251
9251
|
if (typeof cleanup !== "function") throw new TypeError("Cleanup must be callable");
|
|
9252
|
-
|
|
9252
|
+
const registration = /* @__PURE__ */ Symbol();
|
|
9253
|
+
this.#callbacks.set(registration, cleanup);
|
|
9254
|
+
return () => {
|
|
9255
|
+
this.#callbacks.delete(registration);
|
|
9256
|
+
};
|
|
9253
9257
|
}
|
|
9254
9258
|
run(operation2) {
|
|
9255
9259
|
this.assertOpen();
|
|
@@ -9282,9 +9286,11 @@ var InvocationScope = class _InvocationScope {
|
|
|
9282
9286
|
close() {
|
|
9283
9287
|
if (!this.#drain) {
|
|
9284
9288
|
this.#drain = Promise.resolve().then(async () => {
|
|
9289
|
+
const callbacks = [...this.#callbacks.values()];
|
|
9290
|
+
this.#callbacks.clear();
|
|
9285
9291
|
try {
|
|
9286
9292
|
await Promise.all([
|
|
9287
|
-
...
|
|
9293
|
+
...callbacks.map((cleanup) => this.cleanup(cleanup)),
|
|
9288
9294
|
...[...this.#children].map((child) => child.close()),
|
|
9289
9295
|
...this.#work
|
|
9290
9296
|
]);
|
|
@@ -9311,6 +9317,39 @@ function throwCleanupFailures(failures) {
|
|
|
9311
9317
|
|
|
9312
9318
|
// packages/safe-bash/src/shell/getopts.ts
|
|
9313
9319
|
init_platform();
|
|
9320
|
+
var ownedInputs = /* @__PURE__ */ new WeakMap();
|
|
9321
|
+
function getoptsInputAllocationSize(argumentsCount) {
|
|
9322
|
+
return { bytes: 256 + argumentsCount * 8, slots: argumentsCount + 2 };
|
|
9323
|
+
}
|
|
9324
|
+
async function createGetoptsInput(args, allocation, controls2) {
|
|
9325
|
+
const work = new ScanWork(controls2);
|
|
9326
|
+
if (!Array.isArray(args)) throw new GetoptsError("INVALID_INPUT", "Getopts requires an argument array");
|
|
9327
|
+
const length = args.length;
|
|
9328
|
+
if (length > work.maxArguments) throw new GetoptsError("ARGUMENT_LIMIT", "Getopts argument limit exceeded");
|
|
9329
|
+
const size = getoptsInputAllocationSize(length);
|
|
9330
|
+
const reservation = allocation?.reserve(size.bytes, size.slots);
|
|
9331
|
+
try {
|
|
9332
|
+
const snapshot = [];
|
|
9333
|
+
for (let index = 0; index < length; index++) {
|
|
9334
|
+
const waiting = work.step();
|
|
9335
|
+
if (waiting) await waiting;
|
|
9336
|
+
snapshot.push(args[index]);
|
|
9337
|
+
}
|
|
9338
|
+
await work.flush();
|
|
9339
|
+
if (args.length !== length) throw new GetoptsError("INVALID_INPUT", "Getopts argument extent changed during admission");
|
|
9340
|
+
const input3 = Object.freeze({ args: Object.freeze(snapshot) });
|
|
9341
|
+
reservation?.commit(input3);
|
|
9342
|
+
ownedInputs.set(input3, {});
|
|
9343
|
+
return input3;
|
|
9344
|
+
} catch (error) {
|
|
9345
|
+
try {
|
|
9346
|
+
reservation?.release();
|
|
9347
|
+
} catch (cleanup) {
|
|
9348
|
+
throw new AggregateError([error, cleanup], "Getopts input allocation and release failed");
|
|
9349
|
+
}
|
|
9350
|
+
throw error;
|
|
9351
|
+
}
|
|
9352
|
+
}
|
|
9314
9353
|
var GetoptsError = class extends Error {
|
|
9315
9354
|
constructor(code, message3) {
|
|
9316
9355
|
super(message3);
|
|
@@ -9375,6 +9414,9 @@ var ScanWork = class {
|
|
|
9375
9414
|
check() {
|
|
9376
9415
|
this.signal?.throwIfAborted();
|
|
9377
9416
|
}
|
|
9417
|
+
get inputBytes() {
|
|
9418
|
+
return this.bytes;
|
|
9419
|
+
}
|
|
9378
9420
|
step() {
|
|
9379
9421
|
this.check();
|
|
9380
9422
|
if (this.steps === this.maxSteps) throw new GetoptsError("STEP_LIMIT", "Getopts work step limit exceeded");
|
|
@@ -9431,19 +9473,25 @@ async function validateString(value2, work, optstring = false) {
|
|
|
9431
9473
|
else work.addBytes(3);
|
|
9432
9474
|
}
|
|
9433
9475
|
}
|
|
9434
|
-
async function scanGetopts(state, optstring,
|
|
9476
|
+
async function scanGetopts(state, optstring, input3, options3) {
|
|
9435
9477
|
if (!record2(options3) || typeof options3.reportErrors !== "boolean") throw new GetoptsError("INVALID_INPUT", "Getopts requires explicit diagnostic policy and work controls");
|
|
9436
9478
|
const work = new ScanWork(options3.work);
|
|
9437
9479
|
const original = cloneGetoptsState(state);
|
|
9480
|
+
const owned = ownedInputs.get(input3);
|
|
9481
|
+
const args = owned ? input3.args : input3;
|
|
9438
9482
|
if (!Array.isArray(args)) throw new GetoptsError("INVALID_INPUT", "Getopts requires an argument array");
|
|
9439
9483
|
if (args.length > work.maxArguments) throw new GetoptsError("ARGUMENT_LIMIT", "Getopts argument limit exceeded");
|
|
9440
9484
|
const starting = work.step();
|
|
9441
9485
|
if (starting) await starting;
|
|
9442
9486
|
await validateString(optstring, work, true);
|
|
9443
|
-
|
|
9444
|
-
|
|
9445
|
-
|
|
9446
|
-
|
|
9487
|
+
const specificationBytes = work.inputBytes;
|
|
9488
|
+
if (owned?.bytes !== void 0) work.addBytes(owned.bytes);
|
|
9489
|
+
else {
|
|
9490
|
+
for (let argument2 = 0; argument2 < args.length; argument2++) {
|
|
9491
|
+
const waiting = work.step();
|
|
9492
|
+
if (waiting) await waiting;
|
|
9493
|
+
await validateString(args[argument2], work);
|
|
9494
|
+
}
|
|
9447
9495
|
}
|
|
9448
9496
|
const silent = optstring.startsWith(":");
|
|
9449
9497
|
const specification = new Int8Array(128).fill(-1);
|
|
@@ -9459,6 +9507,7 @@ async function scanGetopts(state, optstring, args, options3) {
|
|
|
9459
9507
|
const waiting = work.step();
|
|
9460
9508
|
if (waiting) await waiting;
|
|
9461
9509
|
await work.flush();
|
|
9510
|
+
if (owned) owned.bytes = work.inputBytes - specificationBytes;
|
|
9462
9511
|
return { state: active === void 0 ? { index } : { index, active: { ...active } }, kind, status: kind === "end" ? 1 : 0, option: option2, optind: index, argument: argument2, diagnostic: diagnostic4 };
|
|
9463
9512
|
};
|
|
9464
9513
|
const end = () => {
|
|
@@ -10606,7 +10655,7 @@ var StateMonitor = class {
|
|
|
10606
10655
|
monitors.set(raw, this);
|
|
10607
10656
|
monitors.set(this.proxy, this);
|
|
10608
10657
|
if (session.monitors) session.monitors.add(this);
|
|
10609
|
-
else session.scope.register(async () => {
|
|
10658
|
+
else this.#retireCleanup = session.scope.register(async () => {
|
|
10610
10659
|
await session.scope.drainWork();
|
|
10611
10660
|
this.closeValues();
|
|
10612
10661
|
});
|
|
@@ -10625,18 +10674,46 @@ var StateMonitor = class {
|
|
|
10625
10674
|
#internalEnrollment;
|
|
10626
10675
|
#restorations;
|
|
10627
10676
|
#overlays;
|
|
10677
|
+
#retireCleanup;
|
|
10678
|
+
#positionalRevision = {};
|
|
10679
|
+
#getoptsInput;
|
|
10628
10680
|
closeValues() {
|
|
10629
10681
|
this.values.close();
|
|
10630
10682
|
this.positionals.close();
|
|
10683
|
+
this.invalidateGetoptsInput();
|
|
10684
|
+
this.#retireCleanup?.();
|
|
10685
|
+
this.#retireCleanup = void 0;
|
|
10686
|
+
}
|
|
10687
|
+
get positionalRevision() {
|
|
10688
|
+
return this.#positionalRevision;
|
|
10689
|
+
}
|
|
10690
|
+
get getoptsInput() {
|
|
10691
|
+
return this.#getoptsInput?.input;
|
|
10692
|
+
}
|
|
10693
|
+
retainGetoptsInput(revision, input3, allocation) {
|
|
10694
|
+
this.session.scope.assertOpen();
|
|
10695
|
+
if (revision !== this.#positionalRevision) return false;
|
|
10696
|
+
this.#getoptsInput?.allocation.close();
|
|
10697
|
+
this.#getoptsInput = { input: input3, allocation };
|
|
10698
|
+
return true;
|
|
10699
|
+
}
|
|
10700
|
+
invalidateGetoptsInput() {
|
|
10701
|
+
this.#getoptsInput?.allocation.close();
|
|
10702
|
+
this.#getoptsInput = void 0;
|
|
10703
|
+
this.#positionalRevision = {};
|
|
10631
10704
|
}
|
|
10632
10705
|
changedValue(target, field, key) {
|
|
10633
10706
|
if (field === "state") {
|
|
10634
10707
|
if (key === "variables") this.values.invalidate();
|
|
10635
|
-
if (key === "positional")
|
|
10708
|
+
if (key === "positional") {
|
|
10709
|
+
this.positionals.invalidate();
|
|
10710
|
+
this.invalidateGetoptsInput();
|
|
10711
|
+
}
|
|
10636
10712
|
} else if (field === "variables" && (this.raw.variables === target || this.raw.variables === this.#wrapped.get(target))) {
|
|
10637
10713
|
this.values.invalidate(String(key));
|
|
10638
10714
|
} else if (field === "positional" && (this.raw.positional === target || this.raw.positional === this.#wrapped.get(target))) {
|
|
10639
10715
|
this.positionals.invalidate();
|
|
10716
|
+
this.invalidateGetoptsInput();
|
|
10640
10717
|
}
|
|
10641
10718
|
}
|
|
10642
10719
|
internalOwner() {
|
|
@@ -12595,7 +12672,7 @@ var InvocationCancellationOwner = class {
|
|
|
12595
12672
|
this.finalized = new Promise((resolve) => {
|
|
12596
12673
|
this.#resolveFinalized = resolve;
|
|
12597
12674
|
});
|
|
12598
|
-
parent.register(async () => {
|
|
12675
|
+
this.#retireCleanup = parent.register(async () => {
|
|
12599
12676
|
this.requestClose();
|
|
12600
12677
|
await this.finalized;
|
|
12601
12678
|
});
|
|
@@ -12605,6 +12682,7 @@ var InvocationCancellationOwner = class {
|
|
|
12605
12682
|
#failures;
|
|
12606
12683
|
#outcomes;
|
|
12607
12684
|
#publicPromise;
|
|
12685
|
+
#retireCleanup;
|
|
12608
12686
|
#resolveFinalized;
|
|
12609
12687
|
#admissionOpen = true;
|
|
12610
12688
|
#boundary;
|
|
@@ -12681,6 +12759,7 @@ var InvocationCancellationOwner = class {
|
|
|
12681
12759
|
this.#outcomes.discard(this.#record);
|
|
12682
12760
|
this.#closeBoundary();
|
|
12683
12761
|
this.#resolveFinalized();
|
|
12762
|
+
this.#retireCleanup();
|
|
12684
12763
|
}
|
|
12685
12764
|
}
|
|
12686
12765
|
async #finishOnce(barrier, captured) {
|
|
@@ -12693,6 +12772,7 @@ var InvocationCancellationOwner = class {
|
|
|
12693
12772
|
return selection;
|
|
12694
12773
|
} finally {
|
|
12695
12774
|
this.#resolveFinalized();
|
|
12775
|
+
this.#retireCleanup();
|
|
12696
12776
|
}
|
|
12697
12777
|
}
|
|
12698
12778
|
#closeBoundary() {
|
|
@@ -14047,10 +14127,18 @@ var Runtime = class _Runtime {
|
|
|
14047
14127
|
if (--file.references === 0 && this.outputFiles.get(path) === file) this.outputFiles.delete(path);
|
|
14048
14128
|
};
|
|
14049
14129
|
let target2;
|
|
14130
|
+
let outputScope;
|
|
14050
14131
|
try {
|
|
14051
|
-
|
|
14132
|
+
outputScope = io[invocationScope].child();
|
|
14133
|
+
target2 = await openFileOutput({ fs: this.fs, signal: this.signal, registerCleanup: (cleanup) => {
|
|
14134
|
+
outputScope.register(cleanup);
|
|
14135
|
+
} }, path, append ? "a" : "w", random ? incremental : void 0);
|
|
14052
14136
|
} catch (error) {
|
|
14053
|
-
|
|
14137
|
+
try {
|
|
14138
|
+
await outputScope?.close();
|
|
14139
|
+
} finally {
|
|
14140
|
+
release();
|
|
14141
|
+
}
|
|
14054
14142
|
throw error;
|
|
14055
14143
|
}
|
|
14056
14144
|
outputs.add(async (completion) => {
|
|
@@ -14066,7 +14154,11 @@ var Runtime = class _Runtime {
|
|
|
14066
14154
|
}
|
|
14067
14155
|
}
|
|
14068
14156
|
} finally {
|
|
14069
|
-
|
|
14157
|
+
try {
|
|
14158
|
+
await outputScope?.close();
|
|
14159
|
+
} finally {
|
|
14160
|
+
release();
|
|
14161
|
+
}
|
|
14070
14162
|
}
|
|
14071
14163
|
});
|
|
14072
14164
|
const output2 = this.budget.sink(target2.sink, this.signal);
|
|
@@ -14307,7 +14399,9 @@ var Runtime = class _Runtime {
|
|
|
14307
14399
|
fs: this.fs,
|
|
14308
14400
|
signal: this.commandSignal,
|
|
14309
14401
|
executionScope: this.budget.executionScope,
|
|
14310
|
-
registerCleanup: (cleanup) =>
|
|
14402
|
+
registerCleanup: (cleanup) => {
|
|
14403
|
+
scope.register(cleanup);
|
|
14404
|
+
},
|
|
14311
14405
|
invoke: (name3, args, options3) => {
|
|
14312
14406
|
const invocation = this.invoke(name3, args, options3, context2, state, scope);
|
|
14313
14407
|
void invocation.catch(() => void 0);
|
|
@@ -14914,7 +15008,9 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
14914
15008
|
stdout: this.budget.sink(incoming.stdout, runtime.signal),
|
|
14915
15009
|
stderr: this.budget.sink(incoming.stderr, runtime.signal),
|
|
14916
15010
|
signal: this.commandSignal,
|
|
14917
|
-
registerCleanup: (cleanup) =>
|
|
15011
|
+
registerCleanup: (cleanup) => {
|
|
15012
|
+
scope.register(cleanup);
|
|
15013
|
+
},
|
|
14918
15014
|
invoke: (name2, args, options3) => {
|
|
14919
15015
|
const invocation = invocationOverride.current ? invocationOverride.current(name2, args, options3) : runtime.invoke(name2, args, options3, context2, child, scope);
|
|
14920
15016
|
void invocation.catch(() => void 0);
|
|
@@ -15492,26 +15588,49 @@ ${prefix3} line ${offset + line}: \`${source2.split("\n")[line - 1] ?? ""}'
|
|
|
15492
15588
|
}
|
|
15493
15589
|
const optstring = context2.args[offset];
|
|
15494
15590
|
const name2 = context2.args[offset + 1];
|
|
15495
|
-
const
|
|
15496
|
-
|
|
15497
|
-
|
|
15498
|
-
|
|
15499
|
-
|
|
15500
|
-
|
|
15501
|
-
|
|
15502
|
-
const
|
|
15503
|
-
|
|
15504
|
-
|
|
15591
|
+
const explicit = context2.args.length > offset + 2;
|
|
15592
|
+
const monitor = explicit ? void 0 : stateMonitor(state);
|
|
15593
|
+
const revision = monitor?.positionalRevision;
|
|
15594
|
+
const supplied = explicit ? context2.args.slice(offset + 2) : state.positional;
|
|
15595
|
+
if (supplied.length > fields2) this.budget.fail("maxExpansionFields");
|
|
15596
|
+
const maxBytes = saturatedProduct(bytes3, saturatedSum(supplied.length, 1));
|
|
15597
|
+
const maxSteps = saturatedSum(saturatedProduct(maxBytes, 2), saturatedSum(supplied.length, 2));
|
|
15598
|
+
const work = { maxArguments: fields2, maxBytes, maxSteps, yieldEvery: 128, signal: this.signal, checkpoint };
|
|
15599
|
+
let input3 = monitor?.getoptsInput;
|
|
15600
|
+
let allocation;
|
|
15505
15601
|
let result2;
|
|
15506
15602
|
try {
|
|
15507
|
-
|
|
15508
|
-
|
|
15509
|
-
|
|
15510
|
-
|
|
15511
|
-
|
|
15603
|
+
if (!input3 && monitor) {
|
|
15604
|
+
const size = getoptsInputAllocationSize(supplied.length);
|
|
15605
|
+
const arena = this.budget.values;
|
|
15606
|
+
const usage2 = arena.usage;
|
|
15607
|
+
if (size.bytes + 64 <= arena.maximumBytes - usage2.bytes && size.slots + 1 <= arena.maximumSlots - usage2.slots) {
|
|
15608
|
+
allocation = arena.scope();
|
|
15609
|
+
input3 = await createGetoptsInput(supplied, allocation, work);
|
|
15610
|
+
}
|
|
15611
|
+
}
|
|
15612
|
+
const args = input3?.args ?? supplied;
|
|
15613
|
+
if (!input3 || allocation) for (let index = 0; index < args.length; index++) {
|
|
15614
|
+
this.signal.throwIfAborted();
|
|
15615
|
+
admit2(args[index]);
|
|
15616
|
+
if ((index + 1) % 128 === 0) await checkpoint();
|
|
15617
|
+
}
|
|
15618
|
+
state.getopts ??= cloneGetoptsBinding(state);
|
|
15619
|
+
try {
|
|
15620
|
+
result2 = await scanGetopts(state.getopts.cursor, optstring, input3 ?? args, {
|
|
15621
|
+
reportErrors: state.variables.OPTERR === void 0 || state.variables.OPTERR === "" || decimalIndex(state.variables.OPTERR) !== 0,
|
|
15622
|
+
work
|
|
15623
|
+
});
|
|
15624
|
+
} catch (error) {
|
|
15625
|
+
this.signal.throwIfAborted();
|
|
15626
|
+
if (error instanceof GetoptsError && (error.code === "NON_ASCII_OPTION" || error.code === "INVALID_INPUT")) throw new CommandFailure(`getopts: ${error.message}`, 2);
|
|
15627
|
+
throw error;
|
|
15628
|
+
}
|
|
15512
15629
|
this.signal.throwIfAborted();
|
|
15513
|
-
if (
|
|
15514
|
-
|
|
15630
|
+
if (monitor && monitor.positionalRevision !== revision) throw new CommandFailure("getopts: positional arguments changed during validation", 2);
|
|
15631
|
+
if (allocation && monitor.retainGetoptsInput(revision, input3, allocation)) allocation = void 0;
|
|
15632
|
+
} finally {
|
|
15633
|
+
allocation?.close();
|
|
15515
15634
|
}
|
|
15516
15635
|
this.signal.throwIfAborted();
|
|
15517
15636
|
state.getopts.cursor = result2.state;
|
|
@@ -18832,10 +18951,32 @@ function extendedSource(source2) {
|
|
|
18832
18951
|
}
|
|
18833
18952
|
return result2;
|
|
18834
18953
|
}
|
|
18954
|
+
var NfaStorage = class {
|
|
18955
|
+
constructor(budget) {
|
|
18956
|
+
this.budget = budget;
|
|
18957
|
+
}
|
|
18958
|
+
budget;
|
|
18959
|
+
used = 0;
|
|
18960
|
+
reserve(bytes3) {
|
|
18961
|
+
this.budget.step(0);
|
|
18962
|
+
if (!Number.isSafeInteger(bytes3) || bytes3 < 0 || bytes3 > this.budget.maxBufferBytes - this.used) {
|
|
18963
|
+
throw new ProgramError("regular expression state buffer limit exceeded");
|
|
18964
|
+
}
|
|
18965
|
+
this.used += bytes3;
|
|
18966
|
+
}
|
|
18967
|
+
release(bytes3) {
|
|
18968
|
+
if (!Number.isSafeInteger(bytes3) || bytes3 < 0 || bytes3 > this.used) throw new ProgramError("invalid regular expression state accounting");
|
|
18969
|
+
this.used -= bytes3;
|
|
18970
|
+
}
|
|
18971
|
+
clear() {
|
|
18972
|
+
this.used = 0;
|
|
18973
|
+
}
|
|
18974
|
+
};
|
|
18835
18975
|
var Pattern = class {
|
|
18836
18976
|
groupCount;
|
|
18837
18977
|
code = [];
|
|
18838
18978
|
anchored;
|
|
18979
|
+
linear;
|
|
18839
18980
|
constructor(source2, extended = true, ignoreCase = false) {
|
|
18840
18981
|
if (source2.length > 8192) throw new ProgramError("regular expression exceeds 8192 bytes");
|
|
18841
18982
|
if (!extended) source2 = extendedSource(source2);
|
|
@@ -19002,92 +19143,188 @@ var Pattern = class {
|
|
|
19002
19143
|
};
|
|
19003
19144
|
compile2(root);
|
|
19004
19145
|
emit2({ kind: "match" });
|
|
19146
|
+
this.linear = this.code.every((instruction) => instruction.kind === "character" || instruction.kind === "begin" || instruction.kind === "end" || instruction.kind === "match");
|
|
19005
19147
|
}
|
|
19006
|
-
find(text3, budget, from = 0) {
|
|
19007
|
-
|
|
19008
|
-
|
|
19009
|
-
|
|
19010
|
-
|
|
19011
|
-
|
|
19012
|
-
|
|
19013
|
-
|
|
19014
|
-
|
|
19015
|
-
|
|
19016
|
-
|
|
19017
|
-
|
|
19018
|
-
|
|
19019
|
-
|
|
19020
|
-
|
|
19021
|
-
|
|
19022
|
-
return false;
|
|
19023
|
-
};
|
|
19024
|
-
for (let position = start; positions.size && position <= text3.length; position++) {
|
|
19025
|
-
budget.step();
|
|
19026
|
-
const pending = positions.get(position)?.reverse() ?? [];
|
|
19027
|
-
positions.delete(position);
|
|
19028
|
-
queued -= pending.length;
|
|
19029
|
-
const visited = /* @__PURE__ */ new Set();
|
|
19030
|
-
let stateBytes = 0;
|
|
19031
|
-
const enqueue = (destination2, thread) => {
|
|
19032
|
-
if (destination2 === position) pending.push(thread);
|
|
19033
|
-
else {
|
|
19034
|
-
const waiting = positions.get(destination2);
|
|
19035
|
-
if (waiting) waiting.push(thread);
|
|
19036
|
-
else positions.set(destination2, [thread]);
|
|
19037
|
-
queued++;
|
|
19038
|
-
}
|
|
19039
|
-
if ((queued + pending.length) * (32 + this.groupCount * 16) > budget.maxBufferBytes) throw new ProgramError("regular expression state buffer limit exceeded");
|
|
19040
|
-
};
|
|
19041
|
-
while (pending.length) {
|
|
19042
|
-
budget.step();
|
|
19043
|
-
const thread = pending.pop();
|
|
19044
|
-
const state = this.groupCount ? `${thread.pc}:${thread.captures.join(",")}` : thread.pc;
|
|
19045
|
-
if (visited.has(state)) continue;
|
|
19046
|
-
visited.add(state);
|
|
19047
|
-
stateBytes += typeof state === "string" ? state.length * 2 + 32 : 16;
|
|
19048
|
-
if (stateBytes > budget.maxBufferBytes) throw new ProgramError("regular expression state buffer limit exceeded");
|
|
19049
|
-
const instruction = this.code[thread.pc];
|
|
19148
|
+
async find(text3, budget, from = 0) {
|
|
19149
|
+
await budget.checkpoint();
|
|
19150
|
+
let units = 0;
|
|
19151
|
+
const work = (count2 = 1) => {
|
|
19152
|
+
budget.step(count2);
|
|
19153
|
+
units += count2;
|
|
19154
|
+
if (units < 64) return void 0;
|
|
19155
|
+
units %= 64;
|
|
19156
|
+
return budget.checkpoint();
|
|
19157
|
+
};
|
|
19158
|
+
if (this.linear) {
|
|
19159
|
+
for (let start = from; start <= text3.length && (!this.anchored || start === 0); start++) {
|
|
19160
|
+
let position = start;
|
|
19161
|
+
for (const instruction of this.code) {
|
|
19162
|
+
const paused = work(2);
|
|
19163
|
+
if (paused) await paused;
|
|
19050
19164
|
if (instruction.kind === "character") {
|
|
19051
|
-
if (position
|
|
19052
|
-
|
|
19053
|
-
|
|
19054
|
-
|
|
19055
|
-
if (
|
|
19056
|
-
|
|
19057
|
-
|
|
19058
|
-
|
|
19059
|
-
|
|
19060
|
-
|
|
19061
|
-
|
|
19062
|
-
|
|
19063
|
-
|
|
19165
|
+
if (position >= text3.length || !instruction.accepts(text3[position])) break;
|
|
19166
|
+
position++;
|
|
19167
|
+
} else if (instruction.kind === "begin" && position !== 0 || instruction.kind === "end" && position !== text3.length) break;
|
|
19168
|
+
else if (instruction.kind === "match") {
|
|
19169
|
+
if (position - start > budget.maxBufferBytes) throw new ProgramError("text buffer limit exceeded");
|
|
19170
|
+
const copied = work(position - start);
|
|
19171
|
+
if (copied) await copied;
|
|
19172
|
+
const match = { start, end: position, groups: [text3.slice(start, position)] };
|
|
19173
|
+
await budget.checkpoint();
|
|
19174
|
+
return match;
|
|
19175
|
+
}
|
|
19176
|
+
}
|
|
19177
|
+
}
|
|
19178
|
+
return void 0;
|
|
19179
|
+
}
|
|
19180
|
+
const storage = new NfaStorage(budget);
|
|
19181
|
+
const positionDigits = String(text3.length).length;
|
|
19182
|
+
const instructionDigits = String(this.code.length).length;
|
|
19183
|
+
try {
|
|
19184
|
+
for (let start = from; start <= text3.length && (!this.anchored || start === 0); start++) {
|
|
19185
|
+
storage.reserve(256);
|
|
19186
|
+
const positions = /* @__PURE__ */ new Map([[start, [{ pc: 0, captures: [], bytes: 64 }]]]);
|
|
19187
|
+
let bestEnd;
|
|
19188
|
+
let bestCaptures = [];
|
|
19189
|
+
let bestBytes = 0;
|
|
19190
|
+
try {
|
|
19191
|
+
for (let position = start; positions.size && position <= text3.length; position++) {
|
|
19192
|
+
const advanced = work();
|
|
19193
|
+
if (advanced) await advanced;
|
|
19194
|
+
const pending = positions.get(position);
|
|
19195
|
+
if (!pending) continue;
|
|
19196
|
+
const reversed2 = work(pending.length);
|
|
19197
|
+
if (reversed2) await reversed2;
|
|
19198
|
+
pending.reverse();
|
|
19199
|
+
positions.delete(position);
|
|
19200
|
+
const visited = /* @__PURE__ */ new Set();
|
|
19201
|
+
let stateBytes = 0;
|
|
19202
|
+
const enqueue = (destination2, pc, captures, saveSlot) => {
|
|
19203
|
+
const length = saveSlot === void 0 ? captures.length : Math.max(captures.length, saveSlot + 1);
|
|
19204
|
+
const bytes3 = 64 + length * 8;
|
|
19205
|
+
const waiting = destination2 === position ? pending : positions.get(destination2);
|
|
19206
|
+
storage.reserve(bytes3 + (waiting ? 0 : 64));
|
|
19207
|
+
const saved = saveSlot === void 0 ? captures : [...captures];
|
|
19208
|
+
if (saveSlot !== void 0) saved[saveSlot] = position;
|
|
19209
|
+
const thread = { pc, captures: saved, bytes: bytes3 };
|
|
19210
|
+
if (waiting) waiting.push(thread);
|
|
19211
|
+
else positions.set(destination2, [thread]);
|
|
19212
|
+
};
|
|
19213
|
+
while (pending.length) {
|
|
19214
|
+
const paused = work();
|
|
19215
|
+
if (paused) await paused;
|
|
19216
|
+
const thread = pending.pop();
|
|
19217
|
+
try {
|
|
19218
|
+
let state = thread.pc;
|
|
19219
|
+
let bytes3 = 32;
|
|
19220
|
+
if (this.groupCount) {
|
|
19221
|
+
const joinedLength = Math.max(0, thread.captures.length - 1) + thread.captures.length * positionDigits;
|
|
19222
|
+
const stateLength = instructionDigits + 1 + joinedLength;
|
|
19223
|
+
const serialized2 = work(stateLength);
|
|
19224
|
+
if (serialized2) await serialized2;
|
|
19225
|
+
const reserved2 = 32 + joinedLength * 2 + 64 + stateLength * 2;
|
|
19226
|
+
storage.reserve(reserved2);
|
|
19227
|
+
state = `${thread.pc}:${thread.captures.join(",")}`;
|
|
19228
|
+
bytes3 = 64 + state.length * 2;
|
|
19229
|
+
storage.release(reserved2 - bytes3);
|
|
19230
|
+
} else storage.reserve(bytes3);
|
|
19231
|
+
if (visited.has(state)) {
|
|
19232
|
+
storage.release(bytes3);
|
|
19233
|
+
continue;
|
|
19234
|
+
}
|
|
19235
|
+
visited.add(state);
|
|
19236
|
+
stateBytes += bytes3;
|
|
19237
|
+
const instruction = this.code[thread.pc];
|
|
19238
|
+
if (instruction.kind === "character") {
|
|
19239
|
+
if (position < text3.length && instruction.accepts(text3[position])) enqueue(position + 1, thread.pc + 1, thread.captures);
|
|
19240
|
+
} else if (instruction.kind === "backreference") {
|
|
19241
|
+
const begin = thread.captures[instruction.index * 2];
|
|
19242
|
+
const end = thread.captures[instruction.index * 2 + 1];
|
|
19243
|
+
if (begin === void 0 || end === void 0 || position + end - begin > text3.length) continue;
|
|
19244
|
+
let matches3 = true;
|
|
19245
|
+
for (let offset = 0; offset < end - begin; offset++) {
|
|
19246
|
+
const compared = work();
|
|
19247
|
+
if (compared) await compared;
|
|
19248
|
+
const expected = text3[begin + offset];
|
|
19249
|
+
const actual = text3[position + offset];
|
|
19250
|
+
if (instruction.ignoreCase ? expected.toLowerCase() !== actual.toLowerCase() : expected !== actual) {
|
|
19251
|
+
matches3 = false;
|
|
19252
|
+
break;
|
|
19253
|
+
}
|
|
19254
|
+
}
|
|
19255
|
+
if (matches3) enqueue(position + end - begin, thread.pc + 1, thread.captures);
|
|
19256
|
+
} else if (instruction.kind === "match") {
|
|
19257
|
+
let preferred2 = bestEnd === void 0 || position > bestEnd;
|
|
19258
|
+
if (position === bestEnd) for (let index = 1; index <= this.groupCount; index++) {
|
|
19259
|
+
const compared = work();
|
|
19260
|
+
if (compared) await compared;
|
|
19261
|
+
const begin = thread.captures[index * 2];
|
|
19262
|
+
const end = thread.captures[index * 2 + 1];
|
|
19263
|
+
const priorBegin = bestCaptures[index * 2];
|
|
19264
|
+
const priorEnd = bestCaptures[index * 2 + 1];
|
|
19265
|
+
const length = begin === void 0 || end === void 0 ? -1 : end - begin;
|
|
19266
|
+
const priorLength = priorBegin === void 0 || priorEnd === void 0 ? -1 : priorEnd - priorBegin;
|
|
19267
|
+
if (length !== priorLength) {
|
|
19268
|
+
preferred2 = length > priorLength;
|
|
19269
|
+
break;
|
|
19270
|
+
}
|
|
19271
|
+
}
|
|
19272
|
+
if (preferred2) {
|
|
19273
|
+
const retained = 32 + thread.captures.length * 8;
|
|
19274
|
+
storage.reserve(retained);
|
|
19275
|
+
bestEnd = position;
|
|
19276
|
+
bestCaptures = thread.captures;
|
|
19277
|
+
storage.release(bestBytes);
|
|
19278
|
+
bestBytes = retained;
|
|
19279
|
+
}
|
|
19280
|
+
} else if (instruction.kind === "split") {
|
|
19281
|
+
enqueue(position, instruction.second, thread.captures);
|
|
19282
|
+
enqueue(position, instruction.first, thread.captures);
|
|
19283
|
+
} else if (instruction.kind === "jump") enqueue(position, instruction.target, thread.captures);
|
|
19284
|
+
else if (instruction.kind === "save") {
|
|
19285
|
+
const copied = work(Math.max(thread.captures.length, instruction.slot + 1));
|
|
19286
|
+
if (copied) await copied;
|
|
19287
|
+
enqueue(position, thread.pc + 1, thread.captures, instruction.slot);
|
|
19288
|
+
} else if (instruction.kind === "begin" ? position === 0 : position === text3.length) enqueue(position, thread.pc + 1, thread.captures);
|
|
19289
|
+
} finally {
|
|
19290
|
+
storage.release(thread.bytes);
|
|
19064
19291
|
}
|
|
19065
19292
|
}
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
|
|
19072
|
-
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19293
|
+
visited.clear();
|
|
19294
|
+
storage.release(stateBytes + 64);
|
|
19295
|
+
}
|
|
19296
|
+
if (bestEnd !== void 0) {
|
|
19297
|
+
let characters = bestEnd - start;
|
|
19298
|
+
for (let index = 1; index <= this.groupCount; index++) {
|
|
19299
|
+
const counted = work();
|
|
19300
|
+
if (counted) await counted;
|
|
19301
|
+
const begin = bestCaptures[index * 2];
|
|
19302
|
+
const end = bestCaptures[index * 2 + 1];
|
|
19303
|
+
if (begin !== void 0 && end !== void 0) characters += end - begin;
|
|
19304
|
+
}
|
|
19305
|
+
const copied = work(characters);
|
|
19306
|
+
if (copied) await copied;
|
|
19307
|
+
storage.reserve(64 + (this.groupCount + 1) * 40 + characters * 2);
|
|
19308
|
+
const groups = [text3.slice(start, bestEnd)];
|
|
19309
|
+
for (let index = 1; index <= this.groupCount; index++) {
|
|
19310
|
+
const materialized = work();
|
|
19311
|
+
if (materialized) await materialized;
|
|
19312
|
+
const begin = bestCaptures[index * 2];
|
|
19313
|
+
const end = bestCaptures[index * 2 + 1];
|
|
19314
|
+
groups.push(begin === void 0 || end === void 0 ? void 0 : text3.slice(begin, end));
|
|
19077
19315
|
}
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
}
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
pending.push({ pc: thread.pc + 1, captures });
|
|
19085
|
-
} else if (instruction.kind === "begin" ? position === 0 : position === text3.length) pending.push({ pc: thread.pc + 1, captures: thread.captures });
|
|
19316
|
+
await budget.checkpoint();
|
|
19317
|
+
return { start, end: bestEnd, groups };
|
|
19318
|
+
}
|
|
19319
|
+
} finally {
|
|
19320
|
+
positions.clear();
|
|
19321
|
+
storage.clear();
|
|
19086
19322
|
}
|
|
19087
19323
|
}
|
|
19088
|
-
|
|
19324
|
+
return void 0;
|
|
19325
|
+
} finally {
|
|
19326
|
+
storage.clear();
|
|
19089
19327
|
}
|
|
19090
|
-
return void 0;
|
|
19091
19328
|
}
|
|
19092
19329
|
};
|
|
19093
19330
|
async function replacementLength(replacement, match, budget, available2) {
|
|
@@ -19149,7 +19386,7 @@ async function substitute(text3, pattern, replacement, budget, global, occurrenc
|
|
|
19149
19386
|
while (search <= text3.length) {
|
|
19150
19387
|
await budget.checkpoint();
|
|
19151
19388
|
budget.step();
|
|
19152
|
-
const match = pattern.find(text3, budget, search);
|
|
19389
|
+
const match = await pattern.find(text3, budget, search);
|
|
19153
19390
|
if (!match) break;
|
|
19154
19391
|
if (match.start === match.end && match.start === previousEnd) {
|
|
19155
19392
|
search = match.end + 1;
|
|
@@ -19482,7 +19719,7 @@ async function execute(program, context2, files, quiet, budget, separator, outpu
|
|
|
19482
19719
|
if (terminated) outputState.unterminatedFiles.delete(path);
|
|
19483
19720
|
else outputState.unterminatedFiles.add(path);
|
|
19484
19721
|
};
|
|
19485
|
-
const matches3 = async (address) => address.kind === "number" ? number4 === address.number : address.kind === "last" ? (await peekNext()).done === true : getPattern(address.pattern).find(pattern, budget) !== void 0;
|
|
19722
|
+
const matches3 = async (address) => address.kind === "number" ? number4 === address.number : address.kind === "last" ? (await peekNext()).done === true : await getPattern(address.pattern).find(pattern, budget) !== void 0;
|
|
19486
19723
|
for (let pc = 0; pc < program.length; ) {
|
|
19487
19724
|
budget.step();
|
|
19488
19725
|
await budget.checkpoint();
|
|
@@ -22920,7 +23157,7 @@ var AwkRuntime = class {
|
|
|
22920
23157
|
let search = 0;
|
|
22921
23158
|
while (search <= value2.length) {
|
|
22922
23159
|
await this.budget.checkpoint();
|
|
22923
|
-
const match = matcher.find(value2, this.budget, search);
|
|
23160
|
+
const match = await matcher.find(value2, this.budget, search);
|
|
22924
23161
|
if (!match) break;
|
|
22925
23162
|
if (match.start === match.end) {
|
|
22926
23163
|
search = match.end + 1;
|
|
@@ -23022,7 +23259,7 @@ var AwkRuntime = class {
|
|
|
23022
23259
|
case "string":
|
|
23023
23260
|
return string(expression.value);
|
|
23024
23261
|
case "regex":
|
|
23025
|
-
return numeric(expression.pattern.find(this.record, this.budget) ? 1 : 0);
|
|
23262
|
+
return numeric(await expression.pattern.find(this.record, this.budget) ? 1 : 0);
|
|
23026
23263
|
case "variable":
|
|
23027
23264
|
return this.get(expression.name);
|
|
23028
23265
|
case "field":
|
|
@@ -23064,7 +23301,7 @@ var AwkRuntime = class {
|
|
|
23064
23301
|
if (operator === "&&" && !truth(left)) return numeric(0);
|
|
23065
23302
|
if (operator === "||" && truth(left)) return numeric(1);
|
|
23066
23303
|
if (operator === "~" || operator === "!~") {
|
|
23067
|
-
const matched = (await this.regex(expression.right)).find(this.asText(left), this.budget) !== void 0;
|
|
23304
|
+
const matched = await (await this.regex(expression.right)).find(this.asText(left), this.budget) !== void 0;
|
|
23068
23305
|
return numeric((operator === "~" ? matched : !matched) ? 1 : 0);
|
|
23069
23306
|
}
|
|
23070
23307
|
const right = await this.scalarExpression(expression.right);
|
|
@@ -23206,7 +23443,7 @@ var AwkRuntime = class {
|
|
|
23206
23443
|
}
|
|
23207
23444
|
if (name2 === "match") {
|
|
23208
23445
|
const value2 = this.asText(await this.scalarExpression(args[0]));
|
|
23209
|
-
const matched = (await this.regex(args[1])).find(value2, this.budget);
|
|
23446
|
+
const matched = await (await this.regex(args[1])).find(value2, this.budget);
|
|
23210
23447
|
this.set("RSTART", numeric(matched ? matched.start + 1 : 0));
|
|
23211
23448
|
this.set("RLENGTH", numeric(matched ? matched.end - matched.start : -1));
|
|
23212
23449
|
return this.get("RSTART");
|
|
@@ -23684,6 +23921,7 @@ var Budget8 = class {
|
|
|
23684
23921
|
signal;
|
|
23685
23922
|
steps = 0;
|
|
23686
23923
|
nextYield = 1024;
|
|
23924
|
+
lastYield = monotonicNow();
|
|
23687
23925
|
inputBytes = 0;
|
|
23688
23926
|
outputBytes = 0;
|
|
23689
23927
|
results = 0;
|
|
@@ -23693,12 +23931,13 @@ var Budget8 = class {
|
|
|
23693
23931
|
this.steps += count2;
|
|
23694
23932
|
if (this.steps > this.limits.maxSteps) throw new JqLimitError("maxSteps");
|
|
23695
23933
|
}
|
|
23696
|
-
async tick() {
|
|
23697
|
-
this.step();
|
|
23698
|
-
if (this.steps >= this.nextYield) {
|
|
23699
|
-
this.nextYield = this.steps + 1024;
|
|
23934
|
+
async tick(count2 = 1) {
|
|
23935
|
+
this.step(count2);
|
|
23936
|
+
if (this.steps >= this.nextYield || monotonicNow() - this.lastYield >= 25) {
|
|
23700
23937
|
await yieldTurn(this.signal);
|
|
23701
23938
|
this.signal.throwIfAborted();
|
|
23939
|
+
this.nextYield = this.steps + 1024;
|
|
23940
|
+
this.lastYield = monotonicNow();
|
|
23702
23941
|
}
|
|
23703
23942
|
}
|
|
23704
23943
|
collection(size) {
|
|
@@ -23747,6 +23986,11 @@ function object() {
|
|
|
23747
23986
|
function objectKeys(value2) {
|
|
23748
23987
|
return keyOrders.get(value2)?.slice() ?? Object.keys(value2);
|
|
23749
23988
|
}
|
|
23989
|
+
function* objectKeyIterator(value2) {
|
|
23990
|
+
const keys = keyOrders.get(value2);
|
|
23991
|
+
if (keys) yield* keys;
|
|
23992
|
+
else for (const key in value2) if (Object.hasOwn(value2, key)) yield key;
|
|
23993
|
+
}
|
|
23750
23994
|
function objectSize(value2) {
|
|
23751
23995
|
return keyOrders.get(value2)?.length ?? Object.keys(value2).length;
|
|
23752
23996
|
}
|
|
@@ -24261,36 +24505,83 @@ function describe(value2, budget) {
|
|
|
24261
24505
|
const text3 = bytes3.length < 15 ? bytes3.toString() : `${bytes3.subarray(0, 11).toString()}...`;
|
|
24262
24506
|
return `${type(value2)} (${text3})`;
|
|
24263
24507
|
}
|
|
24264
|
-
function stringCompare(left, right) {
|
|
24265
|
-
|
|
24266
|
-
|
|
24267
|
-
|
|
24268
|
-
|
|
24508
|
+
async function stringCompare(left, right, budget) {
|
|
24509
|
+
await budget.tick(1 + Math.ceil(Math.min(left.length, right.length) / 32));
|
|
24510
|
+
let leftOffset = 0;
|
|
24511
|
+
let rightOffset = 0;
|
|
24512
|
+
let points = 0;
|
|
24513
|
+
while (leftOffset < left.length && rightOffset < right.length) {
|
|
24514
|
+
if (points++ % 32 === 0) await budget.tick(0);
|
|
24515
|
+
const leftPoint = left.codePointAt(leftOffset);
|
|
24516
|
+
const rightPoint = right.codePointAt(rightOffset);
|
|
24517
|
+
if (leftPoint !== rightPoint) return leftPoint < rightPoint ? -1 : 1;
|
|
24518
|
+
leftOffset += leftPoint > 65535 ? 2 : 1;
|
|
24519
|
+
rightOffset += rightPoint > 65535 ? 2 : 1;
|
|
24520
|
+
}
|
|
24521
|
+
return leftOffset < left.length ? 1 : rightOffset < right.length ? -1 : 0;
|
|
24522
|
+
}
|
|
24523
|
+
async function stableSort(items, budget, comparator) {
|
|
24524
|
+
await budget.tick(0);
|
|
24525
|
+
budget.collection(items.length);
|
|
24526
|
+
if (items.length < 2) return;
|
|
24527
|
+
await budget.tick(items.length);
|
|
24528
|
+
const scratch = new Array(items.length);
|
|
24529
|
+
let source2 = items;
|
|
24530
|
+
let target = scratch;
|
|
24531
|
+
for (let width = 1; width < items.length; width *= 2) {
|
|
24532
|
+
for (let start = 0; start < items.length; start += width * 2) {
|
|
24533
|
+
const middle = Math.min(start + width, items.length);
|
|
24534
|
+
const end = Math.min(start + width * 2, items.length);
|
|
24535
|
+
let left = start;
|
|
24536
|
+
let right = middle;
|
|
24537
|
+
for (let index = start; index < end; index++) {
|
|
24538
|
+
await budget.tick();
|
|
24539
|
+
if (left < middle && (right >= end || await comparator(source2[left], source2[right]) <= 0)) target[index] = source2[left++];
|
|
24540
|
+
else target[index] = source2[right++];
|
|
24541
|
+
}
|
|
24542
|
+
}
|
|
24543
|
+
const previous = source2;
|
|
24544
|
+
source2 = target;
|
|
24545
|
+
target = previous;
|
|
24546
|
+
}
|
|
24547
|
+
if (source2 !== items) for (let index = 0; index < items.length; index++) {
|
|
24548
|
+
await budget.tick();
|
|
24549
|
+
items[index] = source2[index];
|
|
24550
|
+
}
|
|
24551
|
+
}
|
|
24552
|
+
async function sortedKeys(value2, budget) {
|
|
24553
|
+
await budget.tick(0);
|
|
24554
|
+
const keys = [];
|
|
24555
|
+
for (const key of objectKeyIterator(value2)) {
|
|
24556
|
+
await budget.tick();
|
|
24557
|
+
budget.collection(keys.length + 1);
|
|
24558
|
+
keys.push(key);
|
|
24269
24559
|
}
|
|
24270
|
-
|
|
24560
|
+
await stableSort(keys, budget, (left, right) => stringCompare(left, right, budget));
|
|
24561
|
+
return keys;
|
|
24271
24562
|
}
|
|
24272
|
-
function compare2(left, right, budget) {
|
|
24273
|
-
budget.
|
|
24563
|
+
async function compare2(left, right, budget) {
|
|
24564
|
+
await budget.tick();
|
|
24274
24565
|
const rank2 = (value2) => value2 === null ? 0 : value2 === false ? 1 : value2 === true ? 2 : isNumber(value2) ? 3 : typeof value2 === "string" ? 4 : Array.isArray(value2) ? 5 : 6;
|
|
24275
24566
|
const difference = rank2(left) - rank2(right);
|
|
24276
24567
|
if (difference) return Math.sign(difference);
|
|
24277
24568
|
if (isNumber(left) && isNumber(right)) return compareNumbers(left, right, budget);
|
|
24569
|
+
if (typeof left === "string" && typeof right === "string") return stringCompare(left, right, budget);
|
|
24278
24570
|
if (left === right && !Array.isArray(left) && !isObject(left)) return 0;
|
|
24279
|
-
if (typeof left === "string" && typeof right === "string") return stringCompare(left, right);
|
|
24280
24571
|
if (Array.isArray(left) && Array.isArray(right)) {
|
|
24281
24572
|
for (let index = 0; index < Math.min(left.length, right.length); index++) {
|
|
24282
|
-
const result2 = compare2(left[index], right[index], budget);
|
|
24573
|
+
const result2 = await compare2(left[index], right[index], budget);
|
|
24283
24574
|
if (result2) return result2;
|
|
24284
24575
|
}
|
|
24285
24576
|
return Math.sign(left.length - right.length);
|
|
24286
24577
|
}
|
|
24287
24578
|
if (isObject(left) && isObject(right)) {
|
|
24288
|
-
const keys =
|
|
24289
|
-
const otherKeys =
|
|
24290
|
-
const keyDifference = compare2(keys, otherKeys, budget);
|
|
24579
|
+
const keys = await sortedKeys(left, budget);
|
|
24580
|
+
const otherKeys = await sortedKeys(right, budget);
|
|
24581
|
+
const keyDifference = await compare2(keys, otherKeys, budget);
|
|
24291
24582
|
if (keyDifference) return keyDifference;
|
|
24292
24583
|
for (const key of keys) {
|
|
24293
|
-
const result2 = compare2(left[key], right[key], budget);
|
|
24584
|
+
const result2 = await compare2(left[key], right[key], budget);
|
|
24294
24585
|
if (result2) return result2;
|
|
24295
24586
|
}
|
|
24296
24587
|
}
|
|
@@ -24367,12 +24658,12 @@ function contains(value2, sought, budget) {
|
|
|
24367
24658
|
if (isObject(value2) && isObject(sought)) return objectKeys(sought).every((key) => Object.hasOwn(value2, key) && contains(value2[key], sought[key], budget));
|
|
24368
24659
|
return type(value2) === type(sought) && equal(value2, sought, budget);
|
|
24369
24660
|
}
|
|
24370
|
-
function binary(operator, left, right, budget) {
|
|
24661
|
+
async function binary(operator, left, right, budget) {
|
|
24371
24662
|
budget.step();
|
|
24372
24663
|
if (["==", "!=", "<", "<=", ">", ">="].includes(operator)) {
|
|
24373
24664
|
if (operator === "==") return equal(left, right, budget);
|
|
24374
24665
|
if (operator === "!=") return !equal(left, right, budget);
|
|
24375
|
-
const order = compare2(left, right, budget);
|
|
24666
|
+
const order = await compare2(left, right, budget);
|
|
24376
24667
|
switch (operator) {
|
|
24377
24668
|
case "<":
|
|
24378
24669
|
return order < 0;
|
|
@@ -24409,7 +24700,7 @@ function binary(operator, left, right, budget) {
|
|
|
24409
24700
|
const result2 = copyObject(left);
|
|
24410
24701
|
for (const key of objectKeys(right)) {
|
|
24411
24702
|
const value2 = right[key];
|
|
24412
|
-
put(result2, key, Object.hasOwn(left, key) && isObject(left[key]) && isObject(value2) ? binary("*", left[key], value2, budget) : value2);
|
|
24703
|
+
put(result2, key, Object.hasOwn(left, key) && isObject(left[key]) && isObject(value2) ? await binary("*", left[key], value2, budget) : value2);
|
|
24413
24704
|
}
|
|
24414
24705
|
budget.collection(objectKeys(result2).length);
|
|
24415
24706
|
return result2;
|
|
@@ -24626,7 +24917,7 @@ var Interpreter = class _Interpreter {
|
|
|
24626
24917
|
}
|
|
24627
24918
|
for await (const right of this.run(ast.right, input3)) {
|
|
24628
24919
|
for await (const left of this.run(ast.left, input3)) {
|
|
24629
|
-
const result2 = binary(operator, left, right, this.budget);
|
|
24920
|
+
const result2 = await binary(operator, left, right, this.budget);
|
|
24630
24921
|
this.budget.value(result2);
|
|
24631
24922
|
yield result2;
|
|
24632
24923
|
}
|
|
@@ -24731,7 +25022,7 @@ var Interpreter = class _Interpreter {
|
|
|
24731
25022
|
for await (const path of this.paths(left, input3)) {
|
|
24732
25023
|
let previous = result3;
|
|
24733
25024
|
for (const key of path) previous = indexValue(previous, key);
|
|
24734
|
-
const assigned = operator === "=" ? value2 : operator === "//=" ? truth2(previous) ? previous : value2 : binary(operator.slice(0, -1), previous, value2, this.budget);
|
|
25025
|
+
const assigned = operator === "=" ? value2 : operator === "//=" ? truth2(previous) ? previous : value2 : await binary(operator.slice(0, -1), previous, value2, this.budget);
|
|
24735
25026
|
result3 = this.set(result3, path, assigned);
|
|
24736
25027
|
this.budget.value(result3);
|
|
24737
25028
|
}
|
|
@@ -24760,10 +25051,10 @@ var Interpreter = class _Interpreter {
|
|
|
24760
25051
|
this.budget.value(result2);
|
|
24761
25052
|
}
|
|
24762
25053
|
}
|
|
24763
|
-
deletions.
|
|
25054
|
+
await stableSort(deletions, this.budget, async (first, second) => -await compare2(first, second, this.budget));
|
|
24764
25055
|
let lastDeletion;
|
|
24765
25056
|
for (const path of deletions) {
|
|
24766
|
-
if (!lastDeletion || compare2(lastDeletion, path, this.budget) !== 0) result2 = this.set(result2, path, deleted);
|
|
25057
|
+
if (!lastDeletion || await compare2(lastDeletion, path, this.budget) !== 0) result2 = this.set(result2, path, deleted);
|
|
24767
25058
|
lastDeletion = path;
|
|
24768
25059
|
}
|
|
24769
25060
|
this.budget.value(result2);
|
|
@@ -24821,7 +25112,7 @@ var Interpreter = class _Interpreter {
|
|
|
24821
25112
|
}
|
|
24822
25113
|
if (name2 === "keys" || name2 === "keys_unsorted") {
|
|
24823
25114
|
if (Array.isArray(input3)) yield input3.map((_, index) => index);
|
|
24824
|
-
else if (isObject(input3)) yield name2 === "keys" ?
|
|
25115
|
+
else if (isObject(input3)) yield name2 === "keys" ? await sortedKeys(input3, budget) : objectKeys(input3);
|
|
24825
25116
|
else throw new JqError("keys requires an object or array");
|
|
24826
25117
|
return;
|
|
24827
25118
|
}
|
|
@@ -24873,12 +25164,12 @@ var Interpreter = class _Interpreter {
|
|
|
24873
25164
|
for (const [, item] of entries(input3, budget)) {
|
|
24874
25165
|
await budget.tick();
|
|
24875
25166
|
if (!first && separator !== null) {
|
|
24876
|
-
if (typeof separator !== "string") binary("+", result2, separator, budget);
|
|
25167
|
+
if (typeof separator !== "string") await binary("+", result2, separator, budget);
|
|
24877
25168
|
if (typeof separator !== "string") throw new JqError("join separator must be a string or null when used");
|
|
24878
25169
|
append(separator, separatorBytes);
|
|
24879
25170
|
}
|
|
24880
25171
|
first = false;
|
|
24881
|
-
if (isObject(item) || Array.isArray(item)) binary("+", result2, item, budget);
|
|
25172
|
+
if (isObject(item) || Array.isArray(item)) await binary("+", result2, item, budget);
|
|
24882
25173
|
const text3 = item === null ? "" : typeof item === "string" ? item : stringify(item, budget);
|
|
24883
25174
|
append(text3, budget.value(text3));
|
|
24884
25175
|
}
|
|
@@ -25016,7 +25307,7 @@ var Interpreter = class _Interpreter {
|
|
|
25016
25307
|
let result2 = null;
|
|
25017
25308
|
for (const item of input3) {
|
|
25018
25309
|
await budget.tick();
|
|
25019
|
-
result2 = binary("+", result2, item, budget);
|
|
25310
|
+
result2 = await binary("+", result2, item, budget);
|
|
25020
25311
|
budget.value(result2);
|
|
25021
25312
|
}
|
|
25022
25313
|
yield result2;
|
|
@@ -25031,7 +25322,7 @@ var Interpreter = class _Interpreter {
|
|
|
25031
25322
|
if (keyBytes2 > budget.limits.maxValueBytes) throw new JqLimitError("maxValueBytes");
|
|
25032
25323
|
keyed.push({ value: value2, key });
|
|
25033
25324
|
}
|
|
25034
|
-
keyed
|
|
25325
|
+
await stableSort(keyed, budget, (left, right) => compare2(left.key, right.key, budget));
|
|
25035
25326
|
if (name2 === "min" || name2 === "min_by" || name2 === "max" || name2 === "max_by") {
|
|
25036
25327
|
yield keyed[name2.startsWith("min") ? 0 : keyed.length - 1]?.value ?? null;
|
|
25037
25328
|
return;
|
|
@@ -32014,7 +32305,7 @@ function createNlCommand(limits) {
|
|
|
32014
32305
|
if (numbered) blanks = 0;
|
|
32015
32306
|
} else if (current === "t") numbered = record4.length > 0;
|
|
32016
32307
|
else if (current === "n") numbered = false;
|
|
32017
|
-
else numbered = current.find(bytes3.toString("latin1"), budget) !== void 0;
|
|
32308
|
+
else numbered = await current.find(bytes3.toString("latin1"), budget) !== void 0;
|
|
32018
32309
|
if (numbered) {
|
|
32019
32310
|
if (number4 < -(1n << 63n) || number4 >= 1n << 63n) throw new UsageError("line number overflow");
|
|
32020
32311
|
let label = number4.toString();
|