as-labs 0.1.0 → 0.1.1

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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
- ## [Unreleased]
3
+ ## 2026-04-02 - 0.1.1
4
+
5
+ - Add wrapper around binaryen to allow branch hinting
6
+
7
+ ## 2026-04-02 - 0.1.0
4
8
 
5
9
  - Added support for branch hinting
@@ -0,0 +1,223 @@
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();
@@ -1,4 +1,4 @@
1
- import { decode } from "@webassemblyjs/wasm-parser";
1
+ import binaryen from "assemblyscript/lib/binaryen.js";
2
2
  import {
3
3
  CallExpression,
4
4
  FunctionDeclaration,
@@ -8,46 +8,20 @@ import {
8
8
  NodeKind,
9
9
  ParenthesizedExpression,
10
10
  SourceKind,
11
- getFunctionName,
12
11
  } from "assemblyscript/dist/assemblyscript.js";
13
12
  import type {
14
13
  Expression,
15
14
  Program,
16
15
  Source,
17
16
  } from "assemblyscript/dist/assemblyscript.js";
18
- import type binaryen from "assemblyscript/lib/binaryen.js";
19
17
  import { Transform } from "assemblyscript/dist/transform.js";
20
18
 
21
- const CUSTOM_SECTION_NAME = "metadata.code.branch_hint";
22
-
23
19
  type HintValue = 0 | 1;
24
20
 
25
21
  type HintRecord = {
26
22
  value: HintValue;
27
23
  };
28
24
 
29
- type ResolvedHint = {
30
- offset: number;
31
- value: HintValue;
32
- };
33
-
34
- type FunctionHintGroup = {
35
- functionIndex: number;
36
- hints: ResolvedHint[];
37
- };
38
-
39
- type SectionInfo = {
40
- id: number;
41
- start: number;
42
- payloadOffset: number;
43
- end: number;
44
- };
45
-
46
- type U32 = {
47
- value: number;
48
- nextOffset: number;
49
- };
50
-
51
25
  type BranchHintCall = {
52
26
  value: HintValue;
53
27
  expression: Expression;
@@ -58,12 +32,15 @@ type BinaryWithSourceMap = {
58
32
  sourceMap?: Uint8Array | string | null;
59
33
  };
60
34
 
61
- type BinaryEmitter = (...args: unknown[]) => BinaryWithSourceMap;
35
+ type BinaryEmitterResult = Uint8Array | BinaryWithSourceMap;
36
+ type BinaryEmitter = (...args: unknown[]) => BinaryEmitterResult;
62
37
 
63
38
  type ConditionalStatement = {
64
39
  condition: Expression;
65
40
  };
66
41
 
42
+ const ANNOTATION_NAME = "@metadata.code.branch_hint";
43
+
67
44
  export default class BranchHintTransform extends Transform {
68
45
  private functionHintsByDeclaration = new Map<
69
46
  FunctionDeclaration | MethodDeclaration,
@@ -94,13 +71,18 @@ export default class BranchHintTransform extends Transform {
94
71
 
95
72
  const originalEmitBinary = module.emitBinary.bind(module) as BinaryEmitter;
96
73
  module.emitBinary = ((...args: unknown[]) => {
97
- const result = originalEmitBinary(...args);
98
- result.binary = injectBranchHints(
99
- result.binary,
100
- module,
101
- this.functionHintsByInternalName,
102
- );
103
- return result;
74
+ const text = module.emitText();
75
+ const annotatedText = annotateModuleText(text, this.functionHintsByInternalName);
76
+ if (annotatedText === text) {
77
+ return originalEmitBinary(...args);
78
+ }
79
+
80
+ const annotatedModule = binaryen.parseText(annotatedText);
81
+ try {
82
+ return (annotatedModule.emitBinary as BinaryEmitter)(...args);
83
+ } finally {
84
+ annotatedModule.dispose();
85
+ }
104
86
  }) as typeof module.emitBinary;
105
87
  }
106
88
 
@@ -266,319 +248,71 @@ function unwrapHint(expression: Expression): BranchHintCall | null {
266
248
  return null;
267
249
  }
268
250
 
269
- function injectBranchHints(
270
- binary: Uint8Array,
271
- module: binaryen.Module,
251
+ function annotateModuleText(
252
+ text: string,
272
253
  functionHintsByInternalName: Map<string, HintRecord[]>,
273
- ): Uint8Array {
274
- const importedFunctionCount = countImportedFunctions(binary);
275
- const functionOrder: string[] = [];
276
- for (let i = 0, n = module.getNumFunctions(); i < n; i++) {
277
- const name = getFunctionName(module.getFunctionByIndex(i));
278
- functionOrder.push(name ?? "");
279
- }
280
-
281
- const conditionalOffsets = collectConditionalOffsets(binary);
282
- const functionHints: FunctionHintGroup[] = [];
283
-
284
- for (let definedIndex = 0; definedIndex < conditionalOffsets.length; definedIndex++) {
285
- const internalName = functionOrder[importedFunctionCount + definedIndex];
286
- const wanted = functionHintsByInternalName.get(internalName);
287
- if (!wanted || wanted.length === 0) continue;
288
-
289
- const available = conditionalOffsets[definedIndex] || [];
290
- const matched: ResolvedHint[] = [];
291
- const count = Math.min(wanted.length, available.length);
292
- for (let i = 0; i < count; i++) {
293
- matched.push({
294
- offset: available[i],
295
- value: wanted[i].value,
296
- });
297
- }
298
- if (matched.length === 0) continue;
299
-
300
- functionHints.push({
301
- functionIndex: importedFunctionCount + definedIndex,
302
- hints: matched,
303
- });
304
- }
305
-
306
- if (functionHints.length === 0) return binary;
307
-
308
- const payload = encodeBranchHintPayload(functionHints);
309
- const customSection = encodeCustomSection(CUSTOM_SECTION_NAME, payload);
310
- return insertCustomSectionBeforeCode(binary, customSection, CUSTOM_SECTION_NAME);
311
- }
312
-
313
- function countImportedFunctions(binary: Uint8Array): number {
314
- const sections = parseSections(binary);
315
- const importSection = sections.find((section) => section.id === 2);
316
- if (!importSection) return 0;
317
-
318
- let offset = importSection.payloadOffset;
319
- const end = importSection.end;
320
- const countInfo = readU32(binary, offset);
321
- offset = countInfo.nextOffset;
322
- let functionImports = 0;
323
-
324
- for (let i = 0; i < countInfo.value && offset < end; i++) {
325
- const moduleName = readName(binary, offset);
326
- offset = moduleName.nextOffset;
327
- const fieldName = readName(binary, offset);
328
- offset = fieldName.nextOffset;
329
- const kind = binary[offset++] as number;
330
-
331
- switch (kind) {
332
- case 0:
333
- functionImports++;
334
- offset = readU32(binary, offset).nextOffset;
335
- break;
336
- case 1:
337
- offset = skipTableType(binary, offset);
338
- break;
339
- case 2:
340
- offset = skipMemoryType(binary, offset);
341
- break;
342
- case 3:
343
- offset = skipGlobalType(binary, offset);
344
- break;
345
- case 4:
346
- offset = skipTagType(binary, offset);
347
- break;
348
- default:
349
- throw new Error(`Unsupported import kind ${kind}`);
350
- }
351
- }
352
-
353
- return functionImports;
354
- }
355
-
356
- function collectConditionalOffsets(binary: Uint8Array): number[][] {
357
- const ast = decode(binary, {
358
- dump: false,
359
- ignoreCodeSection: false,
360
- ignoreDataSection: true,
361
- });
362
-
363
- const functions: any[] = [];
364
- walk(ast, (node: any) => {
365
- if (node?.type === "Func") {
366
- functions.push(node);
367
- }
368
- });
369
-
370
- return functions.map((func) => {
371
- const bodySize = readU32(binary, func.loc.start.column as number);
372
- const localsOffset = bodySize.nextOffset;
373
- const offsets: number[] = [];
374
-
375
- walk(func.body, (node: any) => {
376
- if (!node || !node.loc) return;
377
- if (node.type === "IfInstruction") {
378
- offsets.push((node.loc.start.column as number) - localsOffset - 1);
379
- } else if (node.type === "Instr" && node.id === "br_if") {
380
- offsets.push((node.loc.start.column as number) - localsOffset);
254
+ ): string {
255
+ const lines = text.split("\n");
256
+ const annotated: string[] = [];
257
+ let currentFunctionName: string | null = null;
258
+ let currentHints: HintRecord[] | null = null;
259
+ let hintIndex = 0;
260
+ let depth = 0;
261
+ let functionDepth = 0;
262
+ let changed = false;
263
+
264
+ for (const line of lines) {
265
+ const trimmed = line.trimStart();
266
+
267
+ if (currentFunctionName == null) {
268
+ const funcName = matchFunctionName(trimmed);
269
+ if (funcName) {
270
+ currentFunctionName = funcName;
271
+ currentHints = functionHintsByInternalName.get(funcName.slice(1)) ?? null;
272
+ hintIndex = 0;
273
+ functionDepth = depth;
381
274
  }
382
- });
383
-
384
- return offsets.filter((offset) => offset >= 0);
385
- });
386
- }
387
-
388
- function walk(node: unknown, visit: (node: unknown) => void): void {
389
- if (!node || typeof node !== "object") return;
390
- if (Array.isArray(node)) {
391
- for (const item of node) walk(item, visit);
392
- return;
393
- }
394
-
395
- visit(node);
396
- for (const [key, value] of Object.entries(node)) {
397
- if (key === "loc") continue;
398
- walk(value, visit);
399
- }
400
- }
401
-
402
- function encodeBranchHintPayload(functionHints: FunctionHintGroup[]): Uint8Array {
403
- const bytes: number[] = [];
404
- writeU32(bytes, functionHints.length);
405
-
406
- for (const { functionIndex, hints } of functionHints) {
407
- writeU32(bytes, functionIndex);
408
- writeU32(bytes, hints.length);
409
- for (const hint of hints) {
410
- writeU32(bytes, hint.offset);
411
- writeU32(bytes, 1);
412
- writeU32(bytes, hint.value);
413
275
  }
414
- }
415
-
416
- return Uint8Array.from(bytes);
417
- }
418
-
419
- function encodeCustomSection(name: string, payload: Uint8Array): Uint8Array {
420
- const nameBytes = new TextEncoder().encode(name);
421
- const contents: number[] = [];
422
- writeU32(contents, nameBytes.length);
423
- contents.push(...nameBytes);
424
- contents.push(...payload);
425
-
426
- const section: number[] = [];
427
- section.push(0);
428
- writeU32(section, contents.length);
429
- section.push(...contents);
430
- return Uint8Array.from(section);
431
- }
432
-
433
- function insertCustomSectionBeforeCode(
434
- binary: Uint8Array,
435
- customSection: Uint8Array,
436
- sectionName: string,
437
- ): Uint8Array {
438
- const sections = parseSections(binary);
439
- const filtered = sections.filter((section) => {
440
- if (section.id !== 0) return true;
441
- return readCustomSectionName(binary, section) !== sectionName;
442
- });
443
-
444
- const codeSection = filtered.find((section) => section.id === 10);
445
- if (!codeSection) {
446
- throw new Error("WebAssembly module has no code section");
447
- }
448
-
449
- const output: number[] = [];
450
- output.push(...binary.slice(0, 8));
451
276
 
452
- for (const section of filtered) {
453
- if (section.start === codeSection.start) {
454
- output.push(...customSection);
277
+ if (currentHints && hintIndex < currentHints.length && isHintableInstruction(trimmed)) {
278
+ annotated.push(
279
+ `${line.slice(0, line.length - trimmed.length)}(${ANNOTATION_NAME} "${encodeHintValue(currentHints[hintIndex].value)}")`,
280
+ );
281
+ hintIndex++;
282
+ changed = true;
455
283
  }
456
- output.push(...binary.slice(section.start, section.end));
457
- }
458
284
 
459
- return Uint8Array.from(output);
460
- }
461
-
462
- function parseSections(binary: Uint8Array): SectionInfo[] {
463
- const sections: SectionInfo[] = [];
464
- let offset = 8;
465
-
466
- while (offset < binary.length) {
467
- const start = offset;
468
- const id = binary[offset++] as number;
469
- const size = readU32(binary, offset);
470
- offset = size.nextOffset;
471
- const payloadOffset = offset;
472
- const end = payloadOffset + size.value;
473
- sections.push({
474
- id,
475
- start,
476
- payloadOffset,
477
- end,
478
- });
479
- offset = end;
480
- }
481
-
482
- return sections;
483
- }
285
+ annotated.push(line);
286
+ depth += countParensDelta(line);
484
287
 
485
- function readCustomSectionName(binary: Uint8Array, section: SectionInfo): string {
486
- const name = readName(binary, section.payloadOffset);
487
- return name.value;
488
- }
489
-
490
- function readName(binary: Uint8Array, offset: number): { value: string; nextOffset: number } {
491
- const length = readU32(binary, offset);
492
- const start = length.nextOffset;
493
- const end = start + length.value;
494
- return {
495
- value: new TextDecoder().decode(binary.slice(start, end)),
496
- nextOffset: end,
497
- };
498
- }
499
-
500
- function readU32(binary: Uint8Array, offset: number): U32 {
501
- let value = 0;
502
- let shift = 0;
503
- let current = offset;
504
-
505
- while (true) {
506
- const byte = binary[current++] as number;
507
- value |= (byte & 0x7f) << shift;
508
- if ((byte & 0x80) === 0) {
509
- return { value: value >>> 0, nextOffset: current };
288
+ if (currentFunctionName != null && depth <= functionDepth) {
289
+ currentFunctionName = null;
290
+ currentHints = null;
291
+ hintIndex = 0;
510
292
  }
511
- shift += 7;
512
293
  }
513
- }
514
294
 
515
- function skipTableType(binary: Uint8Array, offset: number): number {
516
- offset = skipReferenceType(binary, offset);
517
- return skipLimits(binary, offset);
295
+ return changed ? annotated.join("\n") : text;
518
296
  }
519
297
 
520
- function skipMemoryType(binary: Uint8Array, offset: number): number {
521
- return skipLimits(binary, offset);
298
+ function matchFunctionName(line: string): string | null {
299
+ const match = line.match(/^\(func(?:\s+(\$[^\s()]+))?/);
300
+ return match?.[1] ?? null;
522
301
  }
523
302
 
524
- function skipGlobalType(binary: Uint8Array, offset: number): number {
525
- offset = skipValueType(binary, offset);
526
- return offset + 1;
303
+ function isHintableInstruction(line: string): boolean {
304
+ return line.startsWith("(if") || line.startsWith("(br_if ");
527
305
  }
528
306
 
529
- function skipTagType(binary: Uint8Array, offset: number): number {
530
- offset += 1;
531
- return readU32(binary, offset).nextOffset;
307
+ function encodeHintValue(value: HintValue): string {
308
+ return value === 1 ? "\\01" : "\\00";
532
309
  }
533
310
 
534
- function skipLimits(binary: Uint8Array, offset: number): number {
535
- const flags = binary[offset++] as number;
536
- offset = readU32(binary, offset).nextOffset;
537
- if (flags & 0x01) {
538
- offset = readU32(binary, offset).nextOffset;
539
- }
540
- if (flags & 0x04) {
541
- offset = readU32(binary, offset).nextOffset;
311
+ function countParensDelta(line: string): number {
312
+ let delta = 0;
313
+ for (const ch of line) {
314
+ if (ch === "(") delta++;
315
+ else if (ch === ")") delta--;
542
316
  }
543
- return offset;
544
- }
545
-
546
- function skipReferenceType(binary: Uint8Array, offset: number): number {
547
- const type = binary[offset] as number;
548
- if (type === 0x63 || type === 0x64) {
549
- return offset + 1;
550
- }
551
- return skipHeapType(binary, offset + 1);
552
- }
553
-
554
- function skipValueType(binary: Uint8Array, offset: number): number {
555
- const type = binary[offset] as number;
556
- if (
557
- type === 0x7f ||
558
- type === 0x7e ||
559
- type === 0x7d ||
560
- type === 0x7c ||
561
- type === 0x7b ||
562
- type === 0x70 ||
563
- type === 0x6f
564
- ) {
565
- return offset + 1;
566
- }
567
- return skipReferenceType(binary, offset);
568
- }
569
-
570
- function skipHeapType(binary: Uint8Array, offset: number): number {
571
- const type = binary[offset] as number;
572
- if (type <= 0x7f) return offset + 1;
573
- return readU32(binary, offset).nextOffset;
574
- }
575
-
576
- function writeU32(target: number[], value: number): void {
577
- let current = value >>> 0;
578
- do {
579
- let byte = current & 0x7f;
580
- current >>>= 7;
581
- if (current !== 0) byte |= 0x80;
582
- target.push(byte);
583
- } while (current !== 0);
317
+ return delta;
584
318
  }
@@ -1,5 +1,5 @@
1
+ import binaryen from "assemblyscript/lib/binaryen.js";
1
2
  import type { Program, Source } from "assemblyscript/dist/assemblyscript.js";
2
- import type binaryen from "assemblyscript/lib/binaryen.js";
3
3
  import { Transform } from "assemblyscript/dist/transform.js";
4
4
  export default class BranchHintTransform extends Transform {
5
5
  private functionHintsByDeclaration;
@@ -1,7 +1,7 @@
1
- import { decode } from "@webassemblyjs/wasm-parser";
2
- import { CallExpression, IdentifierExpression, ParenthesizedExpression, getFunctionName, } from "assemblyscript/dist/assemblyscript.js";
1
+ import binaryen from "assemblyscript/lib/binaryen.js";
2
+ import { CallExpression, IdentifierExpression, ParenthesizedExpression, } from "assemblyscript/dist/assemblyscript.js";
3
3
  import { Transform } from "assemblyscript/dist/transform.js";
4
- const CUSTOM_SECTION_NAME = "metadata.code.branch_hint";
4
+ const ANNOTATION_NAME = "@metadata.code.branch_hint";
5
5
  export default class BranchHintTransform extends Transform {
6
6
  functionHintsByDeclaration = new Map();
7
7
  functionHintsByInternalName = new Map();
@@ -29,9 +29,18 @@ export default class BranchHintTransform extends Transform {
29
29
  return;
30
30
  const originalEmitBinary = module.emitBinary.bind(module);
31
31
  module.emitBinary = ((...args) => {
32
- const result = originalEmitBinary(...args);
33
- result.binary = injectBranchHints(result.binary, module, this.functionHintsByInternalName);
34
- return result;
32
+ const text = module.emitText();
33
+ const annotatedText = annotateModuleText(text, this.functionHintsByInternalName);
34
+ if (annotatedText === text) {
35
+ return originalEmitBinary(...args);
36
+ }
37
+ const annotatedModule = binaryen.parseText(annotatedText);
38
+ try {
39
+ return annotatedModule.emitBinary(...args);
40
+ }
41
+ finally {
42
+ annotatedModule.dispose();
43
+ }
35
44
  });
36
45
  }
37
46
  visitNode(node, currentFunction) {
@@ -169,278 +178,59 @@ function unwrapHint(expression) {
169
178
  }
170
179
  return null;
171
180
  }
172
- function injectBranchHints(binary, module, functionHintsByInternalName) {
173
- const importedFunctionCount = countImportedFunctions(binary);
174
- const functionOrder = [];
175
- for (let i = 0, n = module.getNumFunctions(); i < n; i++) {
176
- const name = getFunctionName(module.getFunctionByIndex(i));
177
- functionOrder.push(name ?? "");
178
- }
179
- const conditionalOffsets = collectConditionalOffsets(binary);
180
- const functionHints = [];
181
- for (let definedIndex = 0; definedIndex < conditionalOffsets.length; definedIndex++) {
182
- const internalName = functionOrder[importedFunctionCount + definedIndex];
183
- const wanted = functionHintsByInternalName.get(internalName);
184
- if (!wanted || wanted.length === 0)
185
- continue;
186
- const available = conditionalOffsets[definedIndex] || [];
187
- const matched = [];
188
- const count = Math.min(wanted.length, available.length);
189
- for (let i = 0; i < count; i++) {
190
- matched.push({
191
- offset: available[i],
192
- value: wanted[i].value,
193
- });
194
- }
195
- if (matched.length === 0)
196
- continue;
197
- functionHints.push({
198
- functionIndex: importedFunctionCount + definedIndex,
199
- hints: matched,
200
- });
201
- }
202
- if (functionHints.length === 0)
203
- return binary;
204
- const payload = encodeBranchHintPayload(functionHints);
205
- const customSection = encodeCustomSection(CUSTOM_SECTION_NAME, payload);
206
- return insertCustomSectionBeforeCode(binary, customSection, CUSTOM_SECTION_NAME);
207
- }
208
- function countImportedFunctions(binary) {
209
- const sections = parseSections(binary);
210
- const importSection = sections.find((section) => section.id === 2);
211
- if (!importSection)
212
- return 0;
213
- let offset = importSection.payloadOffset;
214
- const end = importSection.end;
215
- const countInfo = readU32(binary, offset);
216
- offset = countInfo.nextOffset;
217
- let functionImports = 0;
218
- for (let i = 0; i < countInfo.value && offset < end; i++) {
219
- const moduleName = readName(binary, offset);
220
- offset = moduleName.nextOffset;
221
- const fieldName = readName(binary, offset);
222
- offset = fieldName.nextOffset;
223
- const kind = binary[offset++];
224
- switch (kind) {
225
- case 0:
226
- functionImports++;
227
- offset = readU32(binary, offset).nextOffset;
228
- break;
229
- case 1:
230
- offset = skipTableType(binary, offset);
231
- break;
232
- case 2:
233
- offset = skipMemoryType(binary, offset);
234
- break;
235
- case 3:
236
- offset = skipGlobalType(binary, offset);
237
- break;
238
- case 4:
239
- offset = skipTagType(binary, offset);
240
- break;
241
- default:
242
- throw new Error(`Unsupported import kind ${kind}`);
243
- }
244
- }
245
- return functionImports;
246
- }
247
- function collectConditionalOffsets(binary) {
248
- const ast = decode(binary, {
249
- dump: false,
250
- ignoreCodeSection: false,
251
- ignoreDataSection: true,
252
- });
253
- const functions = [];
254
- walk(ast, (node) => {
255
- if (node?.type === "Func") {
256
- functions.push(node);
257
- }
258
- });
259
- return functions.map((func) => {
260
- const bodySize = readU32(binary, func.loc.start.column);
261
- const localsOffset = bodySize.nextOffset;
262
- const offsets = [];
263
- walk(func.body, (node) => {
264
- if (!node || !node.loc)
265
- return;
266
- if (node.type === "IfInstruction") {
267
- offsets.push(node.loc.start.column - localsOffset - 1);
268
- }
269
- else if (node.type === "Instr" && node.id === "br_if") {
270
- offsets.push(node.loc.start.column - localsOffset);
181
+ function annotateModuleText(text, functionHintsByInternalName) {
182
+ const lines = text.split("\n");
183
+ const annotated = [];
184
+ let currentFunctionName = null;
185
+ let currentHints = null;
186
+ let hintIndex = 0;
187
+ let depth = 0;
188
+ let functionDepth = 0;
189
+ let changed = false;
190
+ for (const line of lines) {
191
+ const trimmed = line.trimStart();
192
+ if (currentFunctionName == null) {
193
+ const funcName = matchFunctionName(trimmed);
194
+ if (funcName) {
195
+ currentFunctionName = funcName;
196
+ currentHints = functionHintsByInternalName.get(funcName.slice(1)) ?? null;
197
+ hintIndex = 0;
198
+ functionDepth = depth;
271
199
  }
272
- });
273
- return offsets.filter((offset) => offset >= 0);
274
- });
275
- }
276
- function walk(node, visit) {
277
- if (!node || typeof node !== "object")
278
- return;
279
- if (Array.isArray(node)) {
280
- for (const item of node)
281
- walk(item, visit);
282
- return;
283
- }
284
- visit(node);
285
- for (const [key, value] of Object.entries(node)) {
286
- if (key === "loc")
287
- continue;
288
- walk(value, visit);
289
- }
290
- }
291
- function encodeBranchHintPayload(functionHints) {
292
- const bytes = [];
293
- writeU32(bytes, functionHints.length);
294
- for (const { functionIndex, hints } of functionHints) {
295
- writeU32(bytes, functionIndex);
296
- writeU32(bytes, hints.length);
297
- for (const hint of hints) {
298
- writeU32(bytes, hint.offset);
299
- writeU32(bytes, 1);
300
- writeU32(bytes, hint.value);
301
200
  }
302
- }
303
- return Uint8Array.from(bytes);
304
- }
305
- function encodeCustomSection(name, payload) {
306
- const nameBytes = new TextEncoder().encode(name);
307
- const contents = [];
308
- writeU32(contents, nameBytes.length);
309
- contents.push(...nameBytes);
310
- contents.push(...payload);
311
- const section = [];
312
- section.push(0);
313
- writeU32(section, contents.length);
314
- section.push(...contents);
315
- return Uint8Array.from(section);
316
- }
317
- function insertCustomSectionBeforeCode(binary, customSection, sectionName) {
318
- const sections = parseSections(binary);
319
- const filtered = sections.filter((section) => {
320
- if (section.id !== 0)
321
- return true;
322
- return readCustomSectionName(binary, section) !== sectionName;
323
- });
324
- const codeSection = filtered.find((section) => section.id === 10);
325
- if (!codeSection) {
326
- throw new Error("WebAssembly module has no code section");
327
- }
328
- const output = [];
329
- output.push(...binary.slice(0, 8));
330
- for (const section of filtered) {
331
- if (section.start === codeSection.start) {
332
- output.push(...customSection);
201
+ if (currentHints && hintIndex < currentHints.length && isHintableInstruction(trimmed)) {
202
+ annotated.push(`${line.slice(0, line.length - trimmed.length)}(${ANNOTATION_NAME} "${encodeHintValue(currentHints[hintIndex].value)}")`);
203
+ hintIndex++;
204
+ changed = true;
333
205
  }
334
- output.push(...binary.slice(section.start, section.end));
335
- }
336
- return Uint8Array.from(output);
337
- }
338
- function parseSections(binary) {
339
- const sections = [];
340
- let offset = 8;
341
- while (offset < binary.length) {
342
- const start = offset;
343
- const id = binary[offset++];
344
- const size = readU32(binary, offset);
345
- offset = size.nextOffset;
346
- const payloadOffset = offset;
347
- const end = payloadOffset + size.value;
348
- sections.push({
349
- id,
350
- start,
351
- payloadOffset,
352
- end,
353
- });
354
- offset = end;
355
- }
356
- return sections;
357
- }
358
- function readCustomSectionName(binary, section) {
359
- const name = readName(binary, section.payloadOffset);
360
- return name.value;
361
- }
362
- function readName(binary, offset) {
363
- const length = readU32(binary, offset);
364
- const start = length.nextOffset;
365
- const end = start + length.value;
366
- return {
367
- value: new TextDecoder().decode(binary.slice(start, end)),
368
- nextOffset: end,
369
- };
370
- }
371
- function readU32(binary, offset) {
372
- let value = 0;
373
- let shift = 0;
374
- let current = offset;
375
- while (true) {
376
- const byte = binary[current++];
377
- value |= (byte & 0x7f) << shift;
378
- if ((byte & 0x80) === 0) {
379
- return { value: value >>> 0, nextOffset: current };
206
+ annotated.push(line);
207
+ depth += countParensDelta(line);
208
+ if (currentFunctionName != null && depth <= functionDepth) {
209
+ currentFunctionName = null;
210
+ currentHints = null;
211
+ hintIndex = 0;
380
212
  }
381
- shift += 7;
382
213
  }
214
+ return changed ? annotated.join("\n") : text;
383
215
  }
384
- function skipTableType(binary, offset) {
385
- offset = skipReferenceType(binary, offset);
386
- return skipLimits(binary, offset);
387
- }
388
- function skipMemoryType(binary, offset) {
389
- return skipLimits(binary, offset);
390
- }
391
- function skipGlobalType(binary, offset) {
392
- offset = skipValueType(binary, offset);
393
- return offset + 1;
216
+ function matchFunctionName(line) {
217
+ const match = line.match(/^\(func(?:\s+(\$[^\s()]+))?/);
218
+ return match?.[1] ?? null;
394
219
  }
395
- function skipTagType(binary, offset) {
396
- offset += 1;
397
- return readU32(binary, offset).nextOffset;
220
+ function isHintableInstruction(line) {
221
+ return line.startsWith("(if") || line.startsWith("(br_if ");
398
222
  }
399
- function skipLimits(binary, offset) {
400
- const flags = binary[offset++];
401
- offset = readU32(binary, offset).nextOffset;
402
- if (flags & 0x01) {
403
- offset = readU32(binary, offset).nextOffset;
404
- }
405
- if (flags & 0x04) {
406
- offset = readU32(binary, offset).nextOffset;
407
- }
408
- return offset;
223
+ function encodeHintValue(value) {
224
+ return value === 1 ? "\\01" : "\\00";
409
225
  }
410
- function skipReferenceType(binary, offset) {
411
- const type = binary[offset];
412
- if (type === 0x63 || type === 0x64) {
413
- return offset + 1;
226
+ function countParensDelta(line) {
227
+ let delta = 0;
228
+ for (const ch of line) {
229
+ if (ch === "(")
230
+ delta++;
231
+ else if (ch === ")")
232
+ delta--;
414
233
  }
415
- return skipHeapType(binary, offset + 1);
416
- }
417
- function skipValueType(binary, offset) {
418
- const type = binary[offset];
419
- if (type === 0x7f ||
420
- type === 0x7e ||
421
- type === 0x7d ||
422
- type === 0x7c ||
423
- type === 0x7b ||
424
- type === 0x70 ||
425
- type === 0x6f) {
426
- return offset + 1;
427
- }
428
- return skipReferenceType(binary, offset);
429
- }
430
- function skipHeapType(binary, offset) {
431
- const type = binary[offset];
432
- if (type <= 0x7f)
433
- return offset + 1;
434
- return readU32(binary, offset).nextOffset;
435
- }
436
- function writeU32(target, value) {
437
- let current = value >>> 0;
438
- do {
439
- let byte = current & 0x7f;
440
- current >>>= 7;
441
- if (current !== 0)
442
- byte |= 0x80;
443
- target.push(byte);
444
- } while (current !== 0);
234
+ return delta;
445
235
  }
446
236
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../branch-hinting/transform/index.ts"],"names":[],"mappings":"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"}
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,kBAAkB,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAkB,CAAC;QAC3E,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,IAAe,EAAE,EAAE;YAC1C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC/B,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,2BAA2B,CAAC,CAAC;YACjF,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;gBAC3B,OAAO,kBAAkB,CAAC,GAAG,IAAI,CAAC,CAAC;YACrC,CAAC;YAED,MAAM,eAAe,GAAG,QAAQ,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAC1D,IAAI,CAAC;gBACH,OAAQ,eAAe,CAAC,UAA4B,CAAC,GAAG,IAAI,CAAC,CAAC;YAChE,CAAC;oBAAS,CAAC;gBACT,eAAe,CAAC,OAAO,EAAE,CAAC;YAC5B,CAAC;QACH,CAAC,CAA6B,CAAC;IACjC,CAAC;IAEO,SAAS,CACf,IAAsC,EACtC,eAA+D;QAE/D,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,KAAK,MAAM,IAAI,IAAI,IAAI;gBAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;YAC/D,OAAO;QACT,CAAC;QAED,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB;gBACE,IAAI,CAAC,iBAAiB,CAAC,IAA2B,EAAE,IAA2B,CAAC,CAAC;gBACjF,OAAO;YACT;gBACE,IAAI,CAAC,iBAAiB,CAAC,IAAyB,EAAE,IAAyB,CAAC,CAAC;gBAC7E,OAAO;YACT;gBACE,IAAI,CAAC,yBAAyB,CAC5B,IAAuC,EACvC,eAAe,EACf,CAAE,IAAY,CAAC,MAAM,EAAG,IAAY,CAAC,OAAO,CAAC,CAC9C,CAAC;gBACF,OAAO;YACT;gBACE,IAAI,CAAC,yBAAyB,CAC5B,IAAuC,EACvC,eAAe,EACf,CAAE,IAAY,CAAC,IAAI,CAAC,CACrB,CAAC;gBACF,OAAO;YACT;gBACE,IAAI,CAAC,yBAAyB,CAC5B,IAAuC,EACvC,eAAe,EACf,CAAE,IAAY,CAAC,IAAI,CAAC,CACrB,CAAC;gBACF,OAAO;YACT;gBACE,IAAI,CAAC,yBAAyB,CAC5B,IAAuC,EACvC,eAAe,EACf,CAAE,IAAY,CAAC,WAAW,EAAG,IAAY,CAAC,WAAW,EAAG,IAAY,CAAC,IAAI,CAAC,CAC3E,CAAC;gBACF,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBAC1D,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;gBACzD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACrD,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACrD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBAC1D,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBAC1D,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACrD,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;gBAC5D,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;gBAC3D,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBAC1D,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACpD,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACpD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACrD,OAAO;YACT,mCAA0B;YAC1B,oCAA2B;YAC3B,qCAA4B;YAC5B;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,OAAO,IAAK,IAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBACnF,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;gBACzD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;gBACtD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;gBACtD,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;gBACxD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;gBACxD,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;gBACpD,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,cAAc,EAAE,eAAe,CAAC,CAAC;gBAC9D,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,eAAe,EAAE,eAAe,CAAC,CAAC;gBAC/D,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,iBAAiB,EAAE,eAAe,CAAC,CAAC;gBACjE,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;gBACrD,OAAO;YACT;gBACE,IAAI,CAAC,SAAS,CAAE,IAAY,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;gBAC1D,OAAO;YACT;gBACE,OAAO;QACX,CAAC;IACH,CAAC;IAEO,iBAAiB,CACvB,IAA6C,EAC7C,WAAoD;QAEpD,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO;QACvB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;IACzC,CAAC;IAEO,yBAAyB,CAC/B,IAA0B,EAC1B,eAA+D,EAC/D,aAAsD;QAEtD,IAAI,CAAC,eAAe;YAAE,OAAO;QAE7B,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACxC,IAAI,IAAI,EAAE,CAAC;YACT,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;YACjC,IAAI,KAAK,GAAG,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACjE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,KAAK,GAAG,EAAE,CAAC;gBACX,IAAI,CAAC,0BAA0B,CAAC,GAAG,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;YAC9D,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QACpC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;QAClD,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,aAAa,EAAE,CAAC;YAClC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,eAAe,CAAC,CAAC;QACzC,CAAC;IACH,CAAC;CACF;AAED,SAAS,UAAU,CAAC,UAAsB;IACxC,IAAI,OAAO,GAAe,UAAU,CAAC;IACrC,OAAO,OAAO,YAAY,uBAAuB,EAAE,CAAC;QAClD,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC;IAC/B,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,YAAY,cAAc,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtD,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAClC,IAAI,CAAC,CAAC,MAAM,YAAY,oBAAoB,CAAC;QAAE,OAAO,IAAI,CAAC;IAC3D,IAAI,OAAO,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAE3C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,CAAC;IACD,IAAI,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IACnD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,kBAAkB,CACzB,IAAY,EACZ,2BAAsD;IAEtD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,mBAAmB,GAAkB,IAAI,CAAC;IAC9C,IAAI,YAAY,GAAwB,IAAI,CAAC;IAC7C,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;QAEjC,IAAI,mBAAmB,IAAI,IAAI,EAAE,CAAC;YAChC,MAAM,QAAQ,GAAG,iBAAiB,CAAC,OAAO,CAAC,CAAC;YAC5C,IAAI,QAAQ,EAAE,CAAC;gBACb,mBAAmB,GAAG,QAAQ,CAAC;gBAC/B,YAAY,GAAG,2BAA2B,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;gBAC1E,SAAS,GAAG,CAAC,CAAC;gBACd,aAAa,GAAG,KAAK,CAAC;YACxB,CAAC;QACH,CAAC;QAED,IAAI,YAAY,IAAI,SAAS,GAAG,YAAY,CAAC,MAAM,IAAI,qBAAqB,CAAC,OAAO,CAAC,EAAE,CAAC;YACtF,SAAS,CAAC,IAAI,CACZ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,eAAe,KAAK,eAAe,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CACzH,CAAC;YACF,SAAS,EAAE,CAAC;YACZ,OAAO,GAAG,IAAI,CAAC;QACjB,CAAC;QAED,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrB,KAAK,IAAI,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAEhC,IAAI,mBAAmB,IAAI,IAAI,IAAI,KAAK,IAAI,aAAa,EAAE,CAAC;YAC1D,mBAAmB,GAAG,IAAI,CAAC;YAC3B,YAAY,GAAG,IAAI,CAAC;YACpB,SAAS,GAAG,CAAC,CAAC;QAChB,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AAC/C,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAY;IACrC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;IACxD,OAAO,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;AAC5B,CAAC;AAED,SAAS,qBAAqB,CAAC,IAAY;IACzC,OAAO,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,eAAe,CAAC,KAAgB;IACvC,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;AACvC,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY;IACpC,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,EAAE,IAAI,IAAI,EAAE,CAAC;QACtB,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;aACnB,IAAI,EAAE,KAAK,GAAG;YAAE,KAAK,EAAE,CAAC;IAC/B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "as-labs",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Experimental AssemblyScript APIs and transforms",
5
5
  "type": "module",
6
6
  "main": "./dist/transform/index.js",
@@ -29,6 +29,7 @@
29
29
  ],
30
30
  "scripts": {
31
31
  "build": "tsc -p tsconfig.json",
32
+ "bench:branch-hinting": "node branch-hinting/bench/run.mjs",
32
33
  "test:unit": "vitest run test/branch-hints.test.js",
33
34
  "test:as": "ast test",
34
35
  "test": "npm run build && npm run test:unit && npm run test:as",