as-labs 0.1.1 → 0.1.2
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/CHANGELOG.md +8 -0
- package/README.md +0 -5
- package/branch-hinting/README.md +18 -0
- package/branch-hinting/assembly/index.ts +9 -0
- package/branch-hinting/index.ts +1 -9
- package/branch-hinting/transform/index.ts +32 -3
- package/dist/branch-hinting/transform/index.js +23 -3
- package/dist/branch-hinting/transform/index.js.map +1 -1
- package/package.json +6 -2
- package/branch-hinting/bench/run.mjs +0 -223
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 2026-04-03 - 0.1.2
|
|
4
|
+
|
|
5
|
+
- Fix branch hint annotation for CLI text output and text-only emission paths
|
|
6
|
+
- Restructure `branch-hinting` AssemblyScript sources under `branch-hinting/assembly`
|
|
7
|
+
- Add feature-specific README and AssemblyScript `tsconfig.json` files
|
|
8
|
+
- Replace the synthetic branch hint benchmark with real `asc`-compiled fixture variants
|
|
9
|
+
- Clean package publish contents and ignore generated benchmark artifacts
|
|
10
|
+
|
|
3
11
|
## 2026-04-02 - 0.1.1
|
|
4
12
|
|
|
5
13
|
- Add wrapper around binaryen to allow branch hinting
|
package/README.md
CHANGED
|
@@ -17,7 +17,6 @@
|
|
|
17
17
|
- [Debugging](#debugging)
|
|
18
18
|
- [Architecture](#architecture)
|
|
19
19
|
- [Contributing](#contributing)
|
|
20
|
-
- [Who uses it?](#who-uses-it)
|
|
21
20
|
- [License](#license)
|
|
22
21
|
- [Contact](#contact)
|
|
23
22
|
|
|
@@ -163,10 +162,6 @@ The package is intentionally experimental. Contributions should prefer:
|
|
|
163
162
|
- conservative root-transform behavior
|
|
164
163
|
- tests that validate final wasm output, not just AST rewrites
|
|
165
164
|
|
|
166
|
-
# Who uses it?
|
|
167
|
-
|
|
168
|
-
This package is early and experimental. If you are using it, that likely means you are testing proposal support or custom AssemblyScript workflows before they are ready for a more stable package.
|
|
169
|
-
|
|
170
165
|
## License
|
|
171
166
|
|
|
172
167
|
This project is distributed under an open source license. Work on this project is done by passion, but if you want to support it financially, you can do so by making a donation to the project's [GitHub Sponsors](https://github.com/sponsors/JairusSW) page.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# branch-hinting
|
|
2
|
+
|
|
3
|
+
AssemblyScript helpers and transform entrypoint for WebAssembly branch hinting.
|
|
4
|
+
|
|
5
|
+
## Imports
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
import { likely, unlikely } from "as-labs/branch-hinting";
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Transform
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
asc assembly/index.ts --transform as-labs/branch-hinting -o build/module.wasm
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
The transform emits the `metadata.code.branch_hint` custom section for direct
|
|
18
|
+
`likely(...)` and `unlikely(...)` statement conditions.
|
package/branch-hinting/index.ts
CHANGED
|
@@ -69,10 +69,32 @@ export default class BranchHintTransform extends Transform {
|
|
|
69
69
|
afterCompile(module: binaryen.Module): void {
|
|
70
70
|
if (this.functionHintsByInternalName.size === 0) return;
|
|
71
71
|
|
|
72
|
+
const originalEmitText = module.emitText.bind(module);
|
|
73
|
+
const originalEmitStackIR = (module as binaryen.Module & {
|
|
74
|
+
emitStackIR?: () => string;
|
|
75
|
+
}).emitStackIR?.bind(module);
|
|
72
76
|
const originalEmitBinary = module.emitBinary.bind(module) as BinaryEmitter;
|
|
77
|
+
const getAnnotatedText = (): string => {
|
|
78
|
+
const text = originalEmitText();
|
|
79
|
+
return annotateModuleText(text, this.functionHintsByInternalName);
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
module.emitText = (() => {
|
|
83
|
+
return getAnnotatedText();
|
|
84
|
+
}) as typeof module.emitText;
|
|
85
|
+
|
|
86
|
+
if (originalEmitStackIR) {
|
|
87
|
+
(module as binaryen.Module & {
|
|
88
|
+
emitStackIR?: () => string;
|
|
89
|
+
}).emitStackIR = () => {
|
|
90
|
+
const text = originalEmitStackIR();
|
|
91
|
+
return annotateModuleText(text, this.functionHintsByInternalName);
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
73
95
|
module.emitBinary = ((...args: unknown[]) => {
|
|
74
|
-
const
|
|
75
|
-
const
|
|
96
|
+
const annotatedText = getAnnotatedText();
|
|
97
|
+
const text = originalEmitText();
|
|
76
98
|
if (annotatedText === text) {
|
|
77
99
|
return originalEmitBinary(...args);
|
|
78
100
|
}
|
|
@@ -301,7 +323,14 @@ function matchFunctionName(line: string): string | null {
|
|
|
301
323
|
}
|
|
302
324
|
|
|
303
325
|
function isHintableInstruction(line: string): boolean {
|
|
304
|
-
return
|
|
326
|
+
return (
|
|
327
|
+
line.startsWith("(if") ||
|
|
328
|
+
line.startsWith("(br_if ") ||
|
|
329
|
+
line === "if" ||
|
|
330
|
+
line.startsWith("if ") ||
|
|
331
|
+
line === "br_if" ||
|
|
332
|
+
line.startsWith("br_if ")
|
|
333
|
+
);
|
|
305
334
|
}
|
|
306
335
|
|
|
307
336
|
function encodeHintValue(value: HintValue): string {
|
|
@@ -27,10 +27,25 @@ export default class BranchHintTransform extends Transform {
|
|
|
27
27
|
afterCompile(module) {
|
|
28
28
|
if (this.functionHintsByInternalName.size === 0)
|
|
29
29
|
return;
|
|
30
|
+
const originalEmitText = module.emitText.bind(module);
|
|
31
|
+
const originalEmitStackIR = module.emitStackIR?.bind(module);
|
|
30
32
|
const originalEmitBinary = module.emitBinary.bind(module);
|
|
33
|
+
const getAnnotatedText = () => {
|
|
34
|
+
const text = originalEmitText();
|
|
35
|
+
return annotateModuleText(text, this.functionHintsByInternalName);
|
|
36
|
+
};
|
|
37
|
+
module.emitText = (() => {
|
|
38
|
+
return getAnnotatedText();
|
|
39
|
+
});
|
|
40
|
+
if (originalEmitStackIR) {
|
|
41
|
+
module.emitStackIR = () => {
|
|
42
|
+
const text = originalEmitStackIR();
|
|
43
|
+
return annotateModuleText(text, this.functionHintsByInternalName);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
31
46
|
module.emitBinary = ((...args) => {
|
|
32
|
-
const
|
|
33
|
-
const
|
|
47
|
+
const annotatedText = getAnnotatedText();
|
|
48
|
+
const text = originalEmitText();
|
|
34
49
|
if (annotatedText === text) {
|
|
35
50
|
return originalEmitBinary(...args);
|
|
36
51
|
}
|
|
@@ -218,7 +233,12 @@ function matchFunctionName(line) {
|
|
|
218
233
|
return match?.[1] ?? null;
|
|
219
234
|
}
|
|
220
235
|
function isHintableInstruction(line) {
|
|
221
|
-
return line.startsWith("(if") ||
|
|
236
|
+
return (line.startsWith("(if") ||
|
|
237
|
+
line.startsWith("(br_if ") ||
|
|
238
|
+
line === "if" ||
|
|
239
|
+
line.startsWith("if ") ||
|
|
240
|
+
line === "br_if" ||
|
|
241
|
+
line.startsWith("br_if "));
|
|
222
242
|
}
|
|
223
243
|
function encodeHintValue(value) {
|
|
224
244
|
return value === 1 ? "\\01" : "\\00";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../branch-hinting/transform/index.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gCAAgC,CAAC;AACtD,OAAO,EACL,cAAc,EAEd,oBAAoB,EAIpB,uBAAuB,GAExB,MAAM,uCAAuC,CAAC;AAM/C,OAAO,EAAE,SAAS,EAAE,MAAM,kCAAkC,CAAC;AAyB7D,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAErD,MAAM,CAAC,OAAO,OAAO,mBAAoB,SAAQ,SAAS;IAChD,0BAA0B,GAAG,IAAI,GAAG,EAGzC,CAAC;IACI,2BAA2B,GAAG,IAAI,GAAG,EAAwB,CAAC;IAEtE,UAAU,CAAC,MAA6B;QACtC,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,IAAI,MAAM,CAAC,UAAU,+BAAuB;gBAAE,SAAS;YACvD,IAAI,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,OAAO,CAAC;gBAAE,SAAS;YACtD,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC1C,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;QACH,CAAC;IACH,CAAC;IAED,eAAe,CAAC,OAAgB;QAC9B,KAAK,MAAM,CAAC,WAAW,EAAE,KAAK,CAAC,IAAI,IAAI,CAAC,0BAA0B,EAAE,CAAC;YACnE,MAAM,OAAO,GAAG,OAAO,CAAC,qBAAqB,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YAC/D,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;gBAAE,SAAS;YACtE,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;QACpE,CAAC;IACH,CAAC;IAED,YAAY,CAAC,MAAuB;QAClC,IAAI,IAAI,CAAC,2BAA2B,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO;QAExD,MAAM,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../branch-hinting/transform/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "as-labs",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Experimental AssemblyScript APIs and transforms",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/transform/index.js",
|
|
@@ -19,10 +19,14 @@
|
|
|
19
19
|
"branch-hinting"
|
|
20
20
|
],
|
|
21
21
|
"files": [
|
|
22
|
-
"branch-hinting",
|
|
23
22
|
"dist",
|
|
24
23
|
"transform",
|
|
25
24
|
"index.ts",
|
|
25
|
+
"branch-hinting/index.ts",
|
|
26
|
+
"branch-hinting/package.json",
|
|
27
|
+
"branch-hinting/README.md",
|
|
28
|
+
"branch-hinting/assembly/index.ts",
|
|
29
|
+
"branch-hinting/transform",
|
|
26
30
|
"README.md",
|
|
27
31
|
"CHANGELOG.md",
|
|
28
32
|
"LICENSE"
|
|
@@ -1,223 +0,0 @@
|
|
|
1
|
-
import { execFileSync } from "node:child_process";
|
|
2
|
-
import process from "node:process";
|
|
3
|
-
import binaryen from "assemblyscript/lib/binaryen.js";
|
|
4
|
-
|
|
5
|
-
const ITERATIONS = 25_000_000;
|
|
6
|
-
const WARMUP_ROUNDS = 4;
|
|
7
|
-
const SAMPLE_ROUNDS = 9;
|
|
8
|
-
const HINT_SECTION_NAME = "metadata.code.branch_hint";
|
|
9
|
-
|
|
10
|
-
function runtimeSupport() {
|
|
11
|
-
const options = execFileSync(process.execPath, ["--v8-options"], {
|
|
12
|
-
encoding: "utf8",
|
|
13
|
-
});
|
|
14
|
-
const hasBranchHintFlag = options.includes("--experimental-wasm-branch-hinting");
|
|
15
|
-
const hasCompilationHintsFlag = options.includes("--experimental-wasm-compilation-hints");
|
|
16
|
-
const branchHintingDisabled = process.execArgv.includes("--no-experimental-wasm-branch-hinting");
|
|
17
|
-
const compilationHintsDisabled = process.execArgv.includes("--no-experimental-wasm-compilation-hints");
|
|
18
|
-
return {
|
|
19
|
-
hasBranchHintFlag,
|
|
20
|
-
hasCompilationHintsFlag,
|
|
21
|
-
branchHintingEnabled: hasBranchHintFlag && !branchHintingDisabled,
|
|
22
|
-
compilationHintsEnabled: hasCompilationHintsFlag && !compilationHintsDisabled,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
function makeModuleText(annotation = "") {
|
|
27
|
-
const annotationLine = annotation ? ` ${annotation}\n` : "";
|
|
28
|
-
return `(module
|
|
29
|
-
(func $run (export "run") (param $iters i32) (param $seed i32) (result i32)
|
|
30
|
-
(local $i i32)
|
|
31
|
-
(local $x i32)
|
|
32
|
-
(local $acc i32)
|
|
33
|
-
(local.set $x (local.get $seed))
|
|
34
|
-
(loop $loop
|
|
35
|
-
(local.set $x
|
|
36
|
-
(i32.add
|
|
37
|
-
(i32.mul
|
|
38
|
-
(local.get $x)
|
|
39
|
-
(i32.const 1103515245)
|
|
40
|
-
)
|
|
41
|
-
(i32.const 12345)
|
|
42
|
-
)
|
|
43
|
-
)
|
|
44
|
-
${annotationLine} (if
|
|
45
|
-
(i32.eqz
|
|
46
|
-
(i32.and
|
|
47
|
-
(local.get $x)
|
|
48
|
-
(i32.const 63)
|
|
49
|
-
)
|
|
50
|
-
)
|
|
51
|
-
(then
|
|
52
|
-
(local.set $acc
|
|
53
|
-
(i32.add
|
|
54
|
-
(local.get $acc)
|
|
55
|
-
(i32.shr_u
|
|
56
|
-
(local.get $x)
|
|
57
|
-
(i32.const 7)
|
|
58
|
-
)
|
|
59
|
-
)
|
|
60
|
-
)
|
|
61
|
-
)
|
|
62
|
-
(else
|
|
63
|
-
(local.set $acc
|
|
64
|
-
(i32.add
|
|
65
|
-
(local.get $acc)
|
|
66
|
-
(i32.and
|
|
67
|
-
(local.get $x)
|
|
68
|
-
(i32.const 1)
|
|
69
|
-
)
|
|
70
|
-
)
|
|
71
|
-
)
|
|
72
|
-
)
|
|
73
|
-
)
|
|
74
|
-
(local.set $i
|
|
75
|
-
(i32.add
|
|
76
|
-
(local.get $i)
|
|
77
|
-
(i32.const 1)
|
|
78
|
-
)
|
|
79
|
-
)
|
|
80
|
-
(br_if $loop
|
|
81
|
-
(i32.lt_u
|
|
82
|
-
(local.get $i)
|
|
83
|
-
(local.get $iters)
|
|
84
|
-
)
|
|
85
|
-
)
|
|
86
|
-
)
|
|
87
|
-
(i32.xor
|
|
88
|
-
(local.get $acc)
|
|
89
|
-
(local.get $x)
|
|
90
|
-
)
|
|
91
|
-
)
|
|
92
|
-
)`;
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function compileWat(text) {
|
|
96
|
-
const module = binaryen.parseText(text);
|
|
97
|
-
try {
|
|
98
|
-
return module.emitBinary();
|
|
99
|
-
} finally {
|
|
100
|
-
module.dispose();
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
function hasHintSection(wasm) {
|
|
105
|
-
return Buffer.from(wasm).includes(Buffer.from(HINT_SECTION_NAME));
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
async function instantiate(wasm) {
|
|
109
|
-
const { instance } = await WebAssembly.instantiate(wasm, {});
|
|
110
|
-
return instance.exports.run;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
function median(values) {
|
|
114
|
-
const sorted = [...values].sort((a, b) => a - b);
|
|
115
|
-
return sorted[(sorted.length / 2) | 0];
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
function percentDelta(base, value) {
|
|
119
|
-
return ((value - base) / base) * 100;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function benchmarkOne(fn, iterations, seed) {
|
|
123
|
-
const start = process.hrtime.bigint();
|
|
124
|
-
const result = fn(iterations, seed);
|
|
125
|
-
const elapsedMs = Number(process.hrtime.bigint() - start) / 1e6;
|
|
126
|
-
return { elapsedMs, result };
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
function formatMs(value) {
|
|
130
|
-
return `${value.toFixed(2)} ms`;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function formatPct(value) {
|
|
134
|
-
const sign = value >= 0 ? "+" : "";
|
|
135
|
-
return `${sign}${value.toFixed(2)}%`;
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
function summarize(name, samples, baseline) {
|
|
139
|
-
const med = median(samples);
|
|
140
|
-
const delta = baseline == null ? null : percentDelta(baseline, med);
|
|
141
|
-
return {
|
|
142
|
-
name,
|
|
143
|
-
medianMs: med,
|
|
144
|
-
minMs: Math.min(...samples),
|
|
145
|
-
maxMs: Math.max(...samples),
|
|
146
|
-
deltaPct: delta,
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
async function main() {
|
|
151
|
-
const support = runtimeSupport();
|
|
152
|
-
|
|
153
|
-
const baselineWasm = compileWat(makeModuleText());
|
|
154
|
-
const hintedWasm = compileWat(makeModuleText('(@metadata.code.branch_hint "\\00")'));
|
|
155
|
-
const wrongHintWasm = compileWat(makeModuleText('(@metadata.code.branch_hint "\\01")'));
|
|
156
|
-
|
|
157
|
-
if (hasHintSection(baselineWasm)) {
|
|
158
|
-
throw new Error("baseline module unexpectedly contains a branch-hint section");
|
|
159
|
-
}
|
|
160
|
-
if (!hasHintSection(hintedWasm)) {
|
|
161
|
-
throw new Error("hinted module is missing the branch-hint section");
|
|
162
|
-
}
|
|
163
|
-
if (!hasHintSection(wrongHintWasm)) {
|
|
164
|
-
throw new Error("wrong-hint module is missing the branch-hint section");
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
const variants = [
|
|
168
|
-
{ name: "baseline", run: await instantiate(baselineWasm), samples: [] },
|
|
169
|
-
{ name: "hinted-correct", run: await instantiate(hintedWasm), samples: [] },
|
|
170
|
-
{ name: "hinted-wrong", run: await instantiate(wrongHintWasm), samples: [] },
|
|
171
|
-
];
|
|
172
|
-
|
|
173
|
-
const referenceSeed = 1;
|
|
174
|
-
const referenceResult = variants[0].run(ITERATIONS, referenceSeed);
|
|
175
|
-
for (const variant of variants.slice(1)) {
|
|
176
|
-
const result = variant.run(ITERATIONS, referenceSeed);
|
|
177
|
-
if (result !== referenceResult) {
|
|
178
|
-
throw new Error(`result mismatch for ${variant.name}: expected ${referenceResult}, got ${result}`);
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
for (let round = 0; round < WARMUP_ROUNDS; round++) {
|
|
183
|
-
for (const variant of variants) {
|
|
184
|
-
variant.run(ITERATIONS, round + 1);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const rotated = [...variants];
|
|
189
|
-
for (let round = 0; round < SAMPLE_ROUNDS; round++) {
|
|
190
|
-
const seed = 0x12345678 ^ round;
|
|
191
|
-
const expected = variants[0].run(ITERATIONS, seed);
|
|
192
|
-
for (const variant of rotated) {
|
|
193
|
-
const { elapsedMs, result } = benchmarkOne(variant.run, ITERATIONS, seed);
|
|
194
|
-
if (result !== expected) {
|
|
195
|
-
throw new Error(`result mismatch during ${variant.name}: expected ${expected}, got ${result}`);
|
|
196
|
-
}
|
|
197
|
-
variant.samples.push(elapsedMs);
|
|
198
|
-
}
|
|
199
|
-
rotated.push(rotated.shift());
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
const baselineMedian = median(variants[0].samples);
|
|
203
|
-
const summaries = variants.map((variant, index) =>
|
|
204
|
-
summarize(variant.name, variant.samples, index === 0 ? null : baselineMedian),
|
|
205
|
-
);
|
|
206
|
-
|
|
207
|
-
console.log(`Node ${process.version}`);
|
|
208
|
-
console.log(`Runtime args: ${process.execArgv.join(" ") || "(none)"}`);
|
|
209
|
-
console.log(`Flags available: branch-hinting=${support.hasBranchHintFlag} compilation-hints=${support.hasCompilationHintsFlag}`);
|
|
210
|
-
console.log(`Flags active: branch-hinting=${support.branchHintingEnabled} compilation-hints=${support.compilationHintsEnabled}`);
|
|
211
|
-
console.log(`Hint section present: baseline=${hasHintSection(baselineWasm)} hinted=${hasHintSection(hintedWasm)} wrong=${hasHintSection(wrongHintWasm)}`);
|
|
212
|
-
console.log(`Iterations per sample: ${ITERATIONS.toLocaleString()}`);
|
|
213
|
-
console.log("");
|
|
214
|
-
|
|
215
|
-
for (const summary of summaries) {
|
|
216
|
-
const delta = summary.deltaPct == null ? "" : ` delta vs baseline: ${formatPct(summary.deltaPct)}`;
|
|
217
|
-
console.log(
|
|
218
|
-
`${summary.name.padEnd(15)} median ${formatMs(summary.medianMs)} min ${formatMs(summary.minMs)} max ${formatMs(summary.maxMs)}${delta}`,
|
|
219
|
-
);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
await main();
|