From d0ad7618f3b076e3e8e7e91fb9a74012cd3d5aba Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Fri, 14 Feb 2025 17:30:22 +0800 Subject: [PATCH 01/14] wip --- .prettierignore | 2 +- as-test.config.js | 2 +- jest.config.ts | 2 +- package.json | 2 +- .../fixture/assertResultTest.expectInfo.json | 30 ------ .../__snapshots__/instrument.test.ts.snap | 3 - .../__snapshots__/precompile.test.ts.snap | 99 ------------------- {tests-as => tests/as}/comparison.test.ts | 2 +- {tests-as => tests/as}/expect.test.ts | 2 +- {tests-as => tests/as}/format.test.ts | 4 +- {tests-as => tests/as}/mock.test.ts | 2 +- {tests-as => tests/as}/mockBaseFunc.ts | 0 {tests-as => tests/as}/tsconfig.json | 0 .../fixture/assertResultTest.expectInfo.json | 30 ++++++ {tests-ts => tests/ts}/fixture/constructor.ts | 0 .../ts}/fixture/ifBlock.debugInfo.json | 0 .../ts}/fixture/traceParse.debugInfo.json | 0 .../ts}/fixture/traceParse.trace | 0 .../ts}/fixture/transformFunction.ts | 0 .../ts}/test/assertResult.test.ts | 12 +-- .../__snapshots__/instrument.test.ts.snap | 3 + .../__snapshots__/precompile.test.ts.snap | 3 + .../ts}/test/core/instrument.test.ts | 6 +- .../ts}/test/core/precompile.test.ts | 4 +- .../ts}/test/core/throwError.test.ts | 6 +- .../parser/__snapshots__/parser.test.ts.snap | 0 .../ts}/test/parser/parser.test.ts | 4 +- .../test/parser/singleFileAnalysis.test.ts | 4 +- .../parser/singleFunctionAnalysis.test.ts | 4 +- .../ts}/test/utils/import.test.ts | 2 +- .../ts}/test/utils/path.test.ts | 8 +- .../ts}/test/utils/utils.test.ts | 4 +- tsconfig.json | 2 +- 33 files changed, 73 insertions(+), 169 deletions(-) delete mode 100644 tests-ts/fixture/assertResultTest.expectInfo.json delete mode 100644 tests-ts/test/core/__snapshots__/instrument.test.ts.snap delete mode 100644 tests-ts/test/core/__snapshots__/precompile.test.ts.snap rename {tests-as => tests/as}/comparison.test.ts (98%) rename {tests-as => tests/as}/expect.test.ts (85%) rename {tests-as => tests/as}/format.test.ts (93%) rename {tests-as => tests/as}/mock.test.ts (99%) rename {tests-as => tests/as}/mockBaseFunc.ts (100%) rename {tests-as => tests/as}/tsconfig.json (100%) create mode 100644 tests/ts/fixture/assertResultTest.expectInfo.json rename {tests-ts => tests/ts}/fixture/constructor.ts (100%) rename {tests-ts => tests/ts}/fixture/ifBlock.debugInfo.json (100%) rename {tests-ts => tests/ts}/fixture/traceParse.debugInfo.json (100%) rename {tests-ts => tests/ts}/fixture/traceParse.trace (100%) rename {tests-ts => tests/ts}/fixture/transformFunction.ts (100%) rename {tests-ts => tests/ts}/test/assertResult.test.ts (81%) create mode 100644 tests/ts/test/core/__snapshots__/instrument.test.ts.snap create mode 100644 tests/ts/test/core/__snapshots__/precompile.test.ts.snap rename {tests-ts => tests/ts}/test/core/instrument.test.ts (86%) rename {tests-ts => tests/ts}/test/core/precompile.test.ts (78%) rename {tests-ts => tests/ts}/test/core/throwError.test.ts (84%) rename {tests-ts => tests/ts}/test/parser/__snapshots__/parser.test.ts.snap (100%) rename {tests-ts => tests/ts}/test/parser/parser.test.ts (93%) rename {tests-ts => tests/ts}/test/parser/singleFileAnalysis.test.ts (94%) rename {tests-ts => tests/ts}/test/parser/singleFunctionAnalysis.test.ts (94%) rename {tests-ts => tests/ts}/test/utils/import.test.ts (98%) rename {tests-ts => tests/ts}/test/utils/path.test.ts (85%) rename {tests-ts => tests/ts}/test/utils/utils.test.ts (94%) diff --git a/.prettierignore b/.prettierignore index ea8e289..e3b01c0 100644 --- a/.prettierignore +++ b/.prettierignore @@ -3,4 +3,4 @@ /dist /node_modules /transform/*.mjs -/tests-ts/fixture +/tests/ts/fixture diff --git a/as-test.config.js b/as-test.config.js index 79667db..7cc4f00 100644 --- a/as-test.config.js +++ b/as-test.config.js @@ -1,6 +1,6 @@ export default { /** file include in test */ - include: ["assembly", "tests-as"], + include: ["assembly", "tests/as"], /** optional: file exclude */ exclude: [], diff --git a/jest.config.ts b/jest.config.ts index 7d56253..159a73f 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,7 +1,7 @@ import type { JestConfigWithTsJest } from "ts-jest"; const config: JestConfigWithTsJest = { - roots: ["tests-ts"], + roots: ["tests/ts"], extensionsToTreatAsEsm: [".ts"], verbose: true, preset: "ts-jest/presets/default-esm", diff --git a/package.json b/package.json index ebbcb7a..64c429a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "scripts": { "build": "tsc --build ./transform/tsconfig.json && node ./build/esbuild.js", "test": "node bin/as-test.js && cross-env NODE_OPTIONS=--experimental-vm-modules jest", - "lint": "eslint src assembly tests-ts/test --max-warnings=0 && prettier -c .", + "lint": "eslint src assembly tests/ts/test --max-warnings=0 && prettier -c .", "lint:fix": "eslint src assembly --fix", "example": "node bin/as-test.js --config example/as-test.config.cjs ; node bin/as-test.js --config example/as-test.config.js" }, diff --git a/tests-ts/fixture/assertResultTest.expectInfo.json b/tests-ts/fixture/assertResultTest.expectInfo.json deleted file mode 100644 index a902e22..0000000 --- a/tests-ts/fixture/assertResultTest.expectInfo.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "0": "tests-as/comparison.test.ts:6:20", - "1": "tests-as/comparison.test.ts:10:20", - "10": "tests-as/comparison.test.ts:42:20", - "11": "tests-as/comparison.test.ts:48:47", - "12": "tests-as/comparison.test.ts:59:22", - "13": "tests-as/comparison.test.ts:68:22", - "14": "tests-as/comparison.test.ts:77:25", - "15": "tests-as/comparison.test.ts:86:25", - "16": "tests-as/comparison.test.ts:96:25", - "17": "tests-as/comparison.test.ts:104:25", - "18": "tests-as/comparison.test.ts:114:22", - "19": "tests-as/comparison.test.ts:121:25", - "2": "tests-as/comparison.test.ts:11:23", - "20": "tests-as/comparison.test.ts:129:25", - "21": "tests-as/comparison.test.ts:137:25", - "22": "tests-as/comparison.test.ts:146:22", - "23": "tests-as/comparison.test.ts:154:22", - "24": "tests-as/comparison.test.ts:155:39", - "25": "tests-as/comparison.test.ts:160:39", - "26": "tests-as/comparison.test.ts:161:36", - "27": "tests-as/comparison.test.ts:194:22", - "3": "tests-as/comparison.test.ts:15:27", - "4": "tests-as/comparison.test.ts:19:27", - "5": "tests-as/comparison.test.ts:26:20", - "6": "tests-as/comparison.test.ts:30:20", - "7": "tests-as/comparison.test.ts:31:23", - "8": "tests-as/comparison.test.ts:32:23", - "9": "tests-as/comparison.test.ts:33:23" -} diff --git a/tests-ts/test/core/__snapshots__/instrument.test.ts.snap b/tests-ts/test/core/__snapshots__/instrument.test.ts.snap deleted file mode 100644 index 1028ba6..0000000 --- a/tests-ts/test/core/__snapshots__/instrument.test.ts.snap +++ /dev/null @@ -1,3 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`Instrument 1`] = `"{"debugFiles":["~lib/rt/common.ts","~lib/rt/tlsf.ts","~lib/shared/typeinfo.ts","~lib/rt/itcms.ts","tests-ts/fixture/constructor.ts","~lib/shared/runtime.ts","~lib/util/number.ts","~lib/util/math.ts","~lib/util/string.ts","~lib/rt.ts","~lib/util/error.ts"],"debugInfos":{"tests-ts/fixture/constructor/Foo#constructor":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[],[],[[4,7,25],[4,8,24],[4,11,4],[4,11,16]]]}}}"`; diff --git a/tests-ts/test/core/__snapshots__/precompile.test.ts.snap b/tests-ts/test/core/__snapshots__/precompile.test.ts.snap deleted file mode 100644 index f0437c2..0000000 --- a/tests-ts/test/core/__snapshots__/precompile.test.ts.snap +++ /dev/null @@ -1,99 +0,0 @@ -// Jest Snapshot v1, https://goo.gl/fbAQLP - -exports[`listFunction transform 1`] = ` -Map { - "tests-ts/fixture/transformFunction.ts" => [ - { - "name": "tests-ts/fixture/transformFunction/Foo.bar", - "range": [ - 49, - 49, - ], - }, - { - "name": "tests-ts/fixture/transformFunction/Foo#constructor", - "range": [ - 45, - 45, - ], - }, - { - "name": "tests-ts/fixture/transformFunction/Foo#foo", - "range": [ - 42, - 42, - ], - }, - { - "name": "", - "range": [ - 33, - 33, - ], - }, - { - "name": "tests-ts/fixture/transformFunction/subscribe", - "range": [ - 28, - 28, - ], - }, - { - "name": "b", - "range": [ - 20, - 22, - ], - }, - { - "name": "tests-ts/fixture/transformFunction/a4", - "range": [ - 20, - 22, - ], - }, - { - "name": "", - "range": [ - 16, - 16, - ], - }, - { - "name": "", - "range": [ - 14, - 14, - ], - }, - { - "name": "", - "range": [ - 12, - 12, - ], - }, - { - "name": "", - "range": [ - 12, - 12, - ], - }, - { - "name": "", - "range": [ - 4, - 4, - ], - }, - { - "name": "", - "range": [ - 3, - 8, - ], - }, - ], -} -`; diff --git a/tests-as/comparison.test.ts b/tests/as/comparison.test.ts similarity index 98% rename from tests-as/comparison.test.ts rename to tests/as/comparison.test.ts index b4392a4..37a4cde 100644 --- a/tests-as/comparison.test.ts +++ b/tests/as/comparison.test.ts @@ -1,4 +1,4 @@ -import { describe, endTest, expect, test } from "../assembly"; +import { describe, endTest, expect, test } from "../../assembly"; describe("base type equal", () => { test("i32", () => { diff --git a/tests-as/expect.test.ts b/tests/as/expect.test.ts similarity index 85% rename from tests-as/expect.test.ts rename to tests/as/expect.test.ts index b3afe33..d3c7d64 100644 --- a/tests-as/expect.test.ts +++ b/tests/as/expect.test.ts @@ -1,4 +1,4 @@ -import { describe, endTest, expect, test } from "../assembly"; +import { describe, endTest, expect, test } from "../../assembly"; describe("expect", () => { test("< = >", () => { diff --git a/tests-as/format.test.ts b/tests/as/format.test.ts similarity index 93% rename from tests-as/format.test.ts rename to tests/as/format.test.ts index dc4aaec..e2eb156 100644 --- a/tests-as/format.test.ts +++ b/tests/as/format.test.ts @@ -1,5 +1,5 @@ -import { describe, endTest, expect, test } from "../assembly"; -import { toJson } from "../assembly/formatPrint"; +import { describe, endTest, expect, test } from "../../assembly"; +import { toJson } from "../../assembly/formatPrint"; class A {} diff --git a/tests-as/mock.test.ts b/tests/as/mock.test.ts similarity index 99% rename from tests-as/mock.test.ts rename to tests/as/mock.test.ts index 5260ee4..3fa8588 100644 --- a/tests-as/mock.test.ts +++ b/tests/as/mock.test.ts @@ -1,4 +1,4 @@ -import { describe, endTest, expect, mock, remock, test, unmock } from "../assembly"; +import { describe, endTest, expect, mock, remock, test, unmock } from "../../assembly"; import { add, callee, caller, incr, MockClass, call_incr } from "./mockBaseFunc"; const mockReturnValue: i32 = 123; diff --git a/tests-as/mockBaseFunc.ts b/tests/as/mockBaseFunc.ts similarity index 100% rename from tests-as/mockBaseFunc.ts rename to tests/as/mockBaseFunc.ts diff --git a/tests-as/tsconfig.json b/tests/as/tsconfig.json similarity index 100% rename from tests-as/tsconfig.json rename to tests/as/tsconfig.json diff --git a/tests/ts/fixture/assertResultTest.expectInfo.json b/tests/ts/fixture/assertResultTest.expectInfo.json new file mode 100644 index 0000000..c753990 --- /dev/null +++ b/tests/ts/fixture/assertResultTest.expectInfo.json @@ -0,0 +1,30 @@ +{ + "0": "tests/as/comparison.test.ts:6:20", + "1": "tests/as/comparison.test.ts:10:20", + "10": "tests/as/comparison.test.ts:42:20", + "11": "tests/as/comparison.test.ts:48:47", + "12": "tests/as/comparison.test.ts:59:22", + "13": "tests/as/comparison.test.ts:68:22", + "14": "tests/as/comparison.test.ts:77:25", + "15": "tests/as/comparison.test.ts:86:25", + "16": "tests/as/comparison.test.ts:96:25", + "17": "tests/as/comparison.test.ts:104:25", + "18": "tests/as/comparison.test.ts:114:22", + "19": "tests/as/comparison.test.ts:121:25", + "2": "tests/as/comparison.test.ts:11:23", + "20": "tests/as/comparison.test.ts:129:25", + "21": "tests/as/comparison.test.ts:137:25", + "22": "tests/as/comparison.test.ts:146:22", + "23": "tests/as/comparison.test.ts:154:22", + "24": "tests/as/comparison.test.ts:155:39", + "25": "tests/as/comparison.test.ts:160:39", + "26": "tests/as/comparison.test.ts:161:36", + "27": "tests/as/comparison.test.ts:194:22", + "3": "tests/as/comparison.test.ts:15:27", + "4": "tests/as/comparison.test.ts:19:27", + "5": "tests/as/comparison.test.ts:26:20", + "6": "tests/as/comparison.test.ts:30:20", + "7": "tests/as/comparison.test.ts:31:23", + "8": "tests/as/comparison.test.ts:32:23", + "9": "tests/as/comparison.test.ts:33:23" +} diff --git a/tests-ts/fixture/constructor.ts b/tests/ts/fixture/constructor.ts similarity index 100% rename from tests-ts/fixture/constructor.ts rename to tests/ts/fixture/constructor.ts diff --git a/tests-ts/fixture/ifBlock.debugInfo.json b/tests/ts/fixture/ifBlock.debugInfo.json similarity index 100% rename from tests-ts/fixture/ifBlock.debugInfo.json rename to tests/ts/fixture/ifBlock.debugInfo.json diff --git a/tests-ts/fixture/traceParse.debugInfo.json b/tests/ts/fixture/traceParse.debugInfo.json similarity index 100% rename from tests-ts/fixture/traceParse.debugInfo.json rename to tests/ts/fixture/traceParse.debugInfo.json diff --git a/tests-ts/fixture/traceParse.trace b/tests/ts/fixture/traceParse.trace similarity index 100% rename from tests-ts/fixture/traceParse.trace rename to tests/ts/fixture/traceParse.trace diff --git a/tests-ts/fixture/transformFunction.ts b/tests/ts/fixture/transformFunction.ts similarity index 100% rename from tests-ts/fixture/transformFunction.ts rename to tests/ts/fixture/transformFunction.ts diff --git a/tests-ts/test/assertResult.test.ts b/tests/ts/test/assertResult.test.ts similarity index 81% rename from tests-ts/test/assertResult.test.ts rename to tests/ts/test/assertResult.test.ts index 12e3986..edf0d67 100644 --- a/tests-ts/test/assertResult.test.ts +++ b/tests/ts/test/assertResult.test.ts @@ -1,7 +1,7 @@ import { join } from "node:path"; import { fileURLToPath, URL } from "node:url"; -import { IAssertResult } from "../../src/interface.js"; -import { AssertResult } from "../../src/assertResult.js"; +import { IAssertResult } from "../../../src/interface.js"; +import { AssertResult } from "../../../src/assertResult.js"; const __dirname = fileURLToPath(new URL(".", import.meta.url)); @@ -39,10 +39,10 @@ test("equal failed", async () => { await assertResult.merge(testcaseA, expectInfoFIlePath); const expectFailedInfo = new Map(); expectFailedInfo.set("A", [ - "tests-as/comparison.test.ts:10:20\tvalue: 100\texpect: = 200", - "tests-as/comparison.test.ts:15:27\tvalue: [10]\texpect: = [1]", - "tests-as/comparison.test.ts:59:22\tvalue: { 1 : 1.5, 2 : 2.5 }\texpect: = { 1: 1.5, 2 : 2.0 }", - `tests-as/comparison.test.ts:48:47\nvalue: \n\t${actualString}\nexpect: \n\t${expectString}`, + "tests/as/comparison.test.ts:10:20\tvalue: 100\texpect: = 200", + "tests/as/comparison.test.ts:15:27\tvalue: [10]\texpect: = [1]", + "tests/as/comparison.test.ts:59:22\tvalue: { 1 : 1.5, 2 : 2.5 }\texpect: = { 1: 1.5, 2 : 2.0 }", + `tests/as/comparison.test.ts:48:47\nvalue: \n\t${actualString}\nexpect: \n\t${expectString}`, ]); expect(assertResult.fail).toEqual(1); expect(assertResult.total).toEqual(28); diff --git a/tests/ts/test/core/__snapshots__/instrument.test.ts.snap b/tests/ts/test/core/__snapshots__/instrument.test.ts.snap new file mode 100644 index 0000000..01b7623 --- /dev/null +++ b/tests/ts/test/core/__snapshots__/instrument.test.ts.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Instrument 1`] = `"{"debugFiles":["~lib/rt/common.ts","~lib/rt/tlsf.ts","~lib/shared/typeinfo.ts","~lib/rt/itcms.ts","tests/ts/fixture/constructor.ts","~lib/shared/runtime.ts","~lib/util/number.ts","~lib/util/math.ts","~lib/util/string.ts","~lib/rt.ts","~lib/util/error.ts"],"debugInfos":null}"`; diff --git a/tests/ts/test/core/__snapshots__/precompile.test.ts.snap b/tests/ts/test/core/__snapshots__/precompile.test.ts.snap new file mode 100644 index 0000000..f7fd6fb --- /dev/null +++ b/tests/ts/test/core/__snapshots__/precompile.test.ts.snap @@ -0,0 +1,3 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`listFunction transform 1`] = `Map {}`; diff --git a/tests-ts/test/core/instrument.test.ts b/tests/ts/test/core/instrument.test.ts similarity index 86% rename from tests-ts/test/core/instrument.test.ts rename to tests/ts/test/core/instrument.test.ts index 2e2e5a9..217e931 100644 --- a/tests-ts/test/core/instrument.test.ts +++ b/tests/ts/test/core/instrument.test.ts @@ -2,8 +2,8 @@ import fs from "fs-extra"; import { join } from "node:path"; import { tmpdir } from "node:os"; import { fileURLToPath, URL } from "node:url"; -import { compile } from "../../../src/core/compile.js"; -import { instrument } from "../../../src/core/instrument.js"; +import { compile } from "../../../../src/core/compile.js"; +import { instrument } from "../../../../src/core/instrument.js"; const fixturePath = join(fileURLToPath(new URL(".", import.meta.url)), "..", "..", "fixture", "constructor.ts"); const outputDir = join(tmpdir(), "assemblyscript-unittest-framework"); @@ -11,7 +11,7 @@ const outputDir = join(tmpdir(), "assemblyscript-unittest-framework"); test("Instrument", async () => { await compile([fixturePath], outputDir, "--memoryBase 16 --exportTable"); const wasmPath = join(outputDir, "constructor.wasm"); - const sourceCodePath = "tests-ts/fixture/constructor.ts"; + const sourceCodePath = "tests/ts/fixture/constructor.ts"; const result = await instrument([wasmPath], [sourceCodePath]); expect(result.length).toEqual(1); const instrumentedWasm = join(outputDir, "constructor.instrumented.wasm"); diff --git a/tests-ts/test/core/precompile.test.ts b/tests/ts/test/core/precompile.test.ts similarity index 78% rename from tests-ts/test/core/precompile.test.ts rename to tests/ts/test/core/precompile.test.ts index 01d00e3..e5ab209 100644 --- a/tests-ts/test/core/precompile.test.ts +++ b/tests/ts/test/core/precompile.test.ts @@ -1,6 +1,6 @@ import { join } from "node:path"; import { fileURLToPath, URL } from "node:url"; -import { precompile } from "../../../src/core/precompile.js"; +import { precompile } from "../../../../src/core/precompile.js"; test("listFunction transform", async () => { const transformFunction = join( @@ -11,7 +11,7 @@ test("listFunction transform", async () => { "transform", "listFunctions.mjs" ); - const unittestPackages = await precompile(["tests-ts/fixture/transformFunction.ts"], [], [], transformFunction); + const unittestPackages = await precompile(["tests/ts/fixture/transformFunction.ts"], [], [], transformFunction); expect(unittestPackages.testCodePaths).toEqual([]); expect(unittestPackages.sourceFunctions).toMatchSnapshot(); }); diff --git a/tests-ts/test/core/throwError.test.ts b/tests/ts/test/core/throwError.test.ts similarity index 84% rename from tests-ts/test/core/throwError.test.ts rename to tests/ts/test/core/throwError.test.ts index 713aa62..cc9f4c5 100644 --- a/tests-ts/test/core/throwError.test.ts +++ b/tests/ts/test/core/throwError.test.ts @@ -15,9 +15,9 @@ jest.unstable_mockModule("assemblyscript/asc", () => ({ // eslint-disable-next-line node/no-unsupported-features/es-syntax const { main } = await import("assemblyscript/asc"); // eslint-disable-next-line node/no-unsupported-features/es-syntax -const { precompile } = await import("../../../src/core/precompile.js"); +const { precompile } = await import("../../../../src/core/precompile.js"); // eslint-disable-next-line node/no-unsupported-features/es-syntax -const { compile } = await import("../../../src/core/compile.js"); +const { compile } = await import("../../../../src/core/compile.js"); test("transform error", async () => { const transformFunction = join( @@ -30,7 +30,7 @@ test("transform error", async () => { ); expect(jest.isMockFunction(main)).toBeTruthy(); await expect(async () => { - await precompile(["tests-ts/fixture/transformFunction.ts"], [], [], transformFunction); + await precompile(["tests/ts/fixture/transformFunction.ts"], [], [], transformFunction); }).rejects.toThrow("mock asc.main() error"); }); diff --git a/tests-ts/test/parser/__snapshots__/parser.test.ts.snap b/tests/ts/test/parser/__snapshots__/parser.test.ts.snap similarity index 100% rename from tests-ts/test/parser/__snapshots__/parser.test.ts.snap rename to tests/ts/test/parser/__snapshots__/parser.test.ts.snap diff --git a/tests-ts/test/parser/parser.test.ts b/tests/ts/test/parser/parser.test.ts similarity index 93% rename from tests-ts/test/parser/parser.test.ts rename to tests/ts/test/parser/parser.test.ts index 87489c0..e277e8f 100644 --- a/tests-ts/test/parser/parser.test.ts +++ b/tests/ts/test/parser/parser.test.ts @@ -2,14 +2,14 @@ import { join } from "node:path"; // eslint-disable-next-line node/no-extraneous-import import { jest } from "@jest/globals"; import { fileURLToPath, URL } from "node:url"; -import { SourceFunctionInfo } from "../../../src/interface.js"; +import { SourceFunctionInfo } from "../../../../src/interface.js"; jest.unstable_mockModule("node:fs/promises", () => ({ readFile: jest.fn(() => "\n".repeat(50)), })); // eslint-disable-next-line node/no-unsupported-features/es-syntax -const { Parser } = await import("../../../src/parser/index.js"); +const { Parser } = await import("../../../../src/parser/index.js"); // eslint-disable-next-line node/no-unsupported-features/es-syntax const { readFile } = await import("node:fs/promises"); const dirname = fileURLToPath(new URL(".", import.meta.url)); diff --git a/tests-ts/test/parser/singleFileAnalysis.test.ts b/tests/ts/test/parser/singleFileAnalysis.test.ts similarity index 94% rename from tests-ts/test/parser/singleFileAnalysis.test.ts rename to tests/ts/test/parser/singleFileAnalysis.test.ts index 2609ca7..c2cdf77 100644 --- a/tests-ts/test/parser/singleFileAnalysis.test.ts +++ b/tests/ts/test/parser/singleFileAnalysis.test.ts @@ -1,5 +1,5 @@ -import { FunctionCoverageResult, Rate } from "../../../src/interface.js"; -import { SingleFileCoverageAnalysis } from "../../../src/parser/singleFileAnalysis.js"; +import { FunctionCoverageResult, Rate } from "../../../../src/interface.js"; +import { SingleFileCoverageAnalysis } from "../../../../src/parser/singleFileAnalysis.js"; describe("singleFileAnalysis", () => { const source = "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n"; diff --git a/tests-ts/test/parser/singleFunctionAnalysis.test.ts b/tests/ts/test/parser/singleFunctionAnalysis.test.ts similarity index 94% rename from tests-ts/test/parser/singleFunctionAnalysis.test.ts rename to tests/ts/test/parser/singleFunctionAnalysis.test.ts index b55bfe6..3fd7e92 100644 --- a/tests-ts/test/parser/singleFunctionAnalysis.test.ts +++ b/tests/ts/test/parser/singleFunctionAnalysis.test.ts @@ -1,5 +1,5 @@ -import { CovInfo, FunctionCoverageResult } from "../../../src/interface.js"; -import { SingleFunctionCoverageAnalysis } from "../../../src/parser/singleFunctionAnalysis.js"; +import { CovInfo, FunctionCoverageResult } from "../../../../src/interface.js"; +import { SingleFunctionCoverageAnalysis } from "../../../../src/parser/singleFunctionAnalysis.js"; describe("singleFunctionAnalysis", () => { test("function with two if-else statement", () => { diff --git a/tests-ts/test/utils/import.test.ts b/tests/ts/test/utils/import.test.ts similarity index 98% rename from tests-ts/test/utils/import.test.ts rename to tests/ts/test/utils/import.test.ts index 85d9e94..9a87f5b 100644 --- a/tests-ts/test/utils/import.test.ts +++ b/tests/ts/test/utils/import.test.ts @@ -7,7 +7,7 @@ jest.unstable_mockModule("node:fs", () => ({ })); // eslint-disable-next-line node/no-unsupported-features/es-syntax -const { mockInstruFunc, covInstruFunc } = await import("../../../src/utils/import.js"); +const { mockInstruFunc, covInstruFunc } = await import("../../../../src/utils/import.js"); // eslint-disable-next-line node/no-unsupported-features/es-syntax const fs = await import("node:fs"); diff --git a/tests-ts/test/utils/path.test.ts b/tests/ts/test/utils/path.test.ts similarity index 85% rename from tests-ts/test/utils/path.test.ts rename to tests/ts/test/utils/path.test.ts index c44b863..6be4b38 100644 --- a/tests-ts/test/utils/path.test.ts +++ b/tests/ts/test/utils/path.test.ts @@ -1,5 +1,5 @@ import path from "node:path"; -import { findRoot, getIncludeFiles, splitCommand } from "../../../src/utils/pathResolver.js"; +import { findRoot, getIncludeFiles, splitCommand } from "../../../../src/utils/pathResolver.js"; describe("splitCommand", () => { test("normal", () => { @@ -20,7 +20,7 @@ describe("splitCommand", () => { }); test("findRoot", () => { - expect(findRoot(["tests-as/comparison.test.ts"])).toEqual("tests-as"); + expect(findRoot(["tests/as/comparison.test.ts"])).toEqual("tests/as"); expect(findRoot(["tests/A/a.test.ts", "tests/B/b.test.ts"])).toEqual("tests"); expect(() => findRoot([])).toThrowError("include length is zeros"); expect(findRoot(["a.test.ts", "b.test.ts"])).toEqual("."); @@ -34,7 +34,7 @@ test("getIncludeFiles", () => { path.normalize("src/core/instrument.ts"), path.normalize("src/core/precompile.ts"), ]); - expect(getIncludeFiles(["tests-ts/fixture/transformFunction.ts"], (s) => s.endsWith(".ts"))).toEqual([ - path.normalize("tests-ts/fixture/transformFunction.ts"), + expect(getIncludeFiles(["tests/ts/fixture/transformFunction.ts"], (s) => s.endsWith(".ts"))).toEqual([ + path.normalize("tests/ts/fixture/transformFunction.ts"), ]); }); diff --git a/tests-ts/test/utils/utils.test.ts b/tests/ts/test/utils/utils.test.ts similarity index 94% rename from tests-ts/test/utils/utils.test.ts rename to tests/ts/test/utils/utils.test.ts index 39a311f..b6ca030 100644 --- a/tests-ts/test/utils/utils.test.ts +++ b/tests/ts/test/utils/utils.test.ts @@ -1,8 +1,8 @@ import fs from "fs-extra"; import { join } from "node:path"; import { fileURLToPath, URL } from "node:url"; -import { DebugInfo, CovDebugInfo } from "../../../src/interface.js"; -import { isIncluded, json2map, checkFunctionName, checkGenerics } from "../../../src/utils/index.js"; +import { DebugInfo, CovDebugInfo } from "../../../../src/interface.js"; +import { isIncluded, json2map, checkFunctionName, checkGenerics } from "../../../../src/utils/index.js"; const __dirname = fileURLToPath(new URL(".", import.meta.url)); diff --git a/tsconfig.json b/tsconfig.json index 30f2c4a..f125d20 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -27,6 +27,6 @@ "noPropertyAccessFromIndexSignature": true, "skipLibCheck": true }, - "include": ["src/**/*.ts", "transform", "tests-ts/**/*.ts"], + "include": ["src/**/*.ts", "transform", "tests/ts/**/*.ts"], "exclude": ["assembly", "example"] } From 0c3bf7c24eee6bb7717a4f48ecefe62fc7530f68 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Fri, 14 Feb 2025 17:46:02 +0800 Subject: [PATCH 02/14] fix --- .../__snapshots__/instrument.test.ts.snap | 2 +- .../__snapshots__/precompile.test.ts.snap | 98 ++++++++++++++++++- tests/ts/test/core/precompile.test.ts | 1 + 3 files changed, 99 insertions(+), 2 deletions(-) diff --git a/tests/ts/test/core/__snapshots__/instrument.test.ts.snap b/tests/ts/test/core/__snapshots__/instrument.test.ts.snap index 01b7623..3765387 100644 --- a/tests/ts/test/core/__snapshots__/instrument.test.ts.snap +++ b/tests/ts/test/core/__snapshots__/instrument.test.ts.snap @@ -1,3 +1,3 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`Instrument 1`] = `"{"debugFiles":["~lib/rt/common.ts","~lib/rt/tlsf.ts","~lib/shared/typeinfo.ts","~lib/rt/itcms.ts","tests/ts/fixture/constructor.ts","~lib/shared/runtime.ts","~lib/util/number.ts","~lib/util/math.ts","~lib/util/string.ts","~lib/rt.ts","~lib/util/error.ts"],"debugInfos":null}"`; +exports[`Instrument 1`] = `"{"debugFiles":["~lib/rt/common.ts","~lib/rt/tlsf.ts","~lib/shared/typeinfo.ts","~lib/rt/itcms.ts","tests/ts/fixture/constructor.ts","~lib/shared/runtime.ts","~lib/util/number.ts","~lib/util/math.ts","~lib/util/string.ts","~lib/rt.ts","~lib/util/error.ts"],"debugInfos":{"tests/ts/fixture/constructor/Foo#constructor":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[],[],[[4,7,25],[4,8,24],[4,11,4],[4,11,16]]]}}}"`; diff --git a/tests/ts/test/core/__snapshots__/precompile.test.ts.snap b/tests/ts/test/core/__snapshots__/precompile.test.ts.snap index f7fd6fb..760ac1b 100644 --- a/tests/ts/test/core/__snapshots__/precompile.test.ts.snap +++ b/tests/ts/test/core/__snapshots__/precompile.test.ts.snap @@ -1,3 +1,99 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`listFunction transform 1`] = `Map {}`; +exports[`listFunction transform 1`] = ` +Map { + "tests/ts/fixture/transformFunction.ts" => [ + { + "name": "tests/ts/fixture/transformFunction/Foo.bar", + "range": [ + 49, + 49, + ], + }, + { + "name": "tests/ts/fixture/transformFunction/Foo#constructor", + "range": [ + 45, + 45, + ], + }, + { + "name": "tests/ts/fixture/transformFunction/Foo#foo", + "range": [ + 42, + 42, + ], + }, + { + "name": "", + "range": [ + 33, + 33, + ], + }, + { + "name": "tests/ts/fixture/transformFunction/subscribe", + "range": [ + 28, + 28, + ], + }, + { + "name": "b", + "range": [ + 20, + 22, + ], + }, + { + "name": "tests/ts/fixture/transformFunction/a4", + "range": [ + 20, + 22, + ], + }, + { + "name": "", + "range": [ + 16, + 16, + ], + }, + { + "name": "", + "range": [ + 14, + 14, + ], + }, + { + "name": "", + "range": [ + 12, + 12, + ], + }, + { + "name": "", + "range": [ + 12, + 12, + ], + }, + { + "name": "", + "range": [ + 4, + 4, + ], + }, + { + "name": "", + "range": [ + 3, + 8, + ], + }, + ], +} +`; diff --git a/tests/ts/test/core/precompile.test.ts b/tests/ts/test/core/precompile.test.ts index e5ab209..a9971b9 100644 --- a/tests/ts/test/core/precompile.test.ts +++ b/tests/ts/test/core/precompile.test.ts @@ -8,6 +8,7 @@ test("listFunction transform", async () => { "..", "..", "..", + "..", "transform", "listFunctions.mjs" ); From 3fbf515643f4fb267fb7c02b97abdd03c2584e5e Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 10:09:13 +0800 Subject: [PATCH 03/14] move src --- .clang-format | 140 ++++++ .clang-tidy | 180 +++++++ .gitignore | 15 +- .gitmodules | 6 + instrumentation/BasicBlockAnalysis.cpp | 32 ++ instrumentation/BasicBlockAnalysis.hpp | 47 ++ instrumentation/BasicBlockWalker.cpp | 146 ++++++ instrumentation/BasicBlockWalker.hpp | 174 +++++++ instrumentation/CMakeLists.txt | 39 ++ instrumentation/CovInstrumentationWalker.cpp | 113 +++++ instrumentation/CovInstrumentationWalker.hpp | 73 +++ instrumentation/CoverageInstru.cpp | 187 ++++++++ instrumentation/CoverageInstru.hpp | 124 +++++ instrumentation/InstrumentResponse.hpp | 19 + instrumentation/MockInstrumentationWalker.cpp | 102 ++++ instrumentation/MockInstrumentationWalker.hpp | 158 ++++++ instrumentation/main.cpp | 43 ++ package.json | 2 +- {build => scripts}/esbuild.js | 7 + third_party/binaryen | 1 + third_party/jsoncpp | 1 + transform/listFunctions.mjs | 453 ------------------ 22 files changed, 1603 insertions(+), 459 deletions(-) create mode 100644 .clang-format create mode 100644 .clang-tidy create mode 100644 .gitmodules create mode 100644 instrumentation/BasicBlockAnalysis.cpp create mode 100644 instrumentation/BasicBlockAnalysis.hpp create mode 100644 instrumentation/BasicBlockWalker.cpp create mode 100644 instrumentation/BasicBlockWalker.hpp create mode 100644 instrumentation/CMakeLists.txt create mode 100644 instrumentation/CovInstrumentationWalker.cpp create mode 100644 instrumentation/CovInstrumentationWalker.hpp create mode 100644 instrumentation/CoverageInstru.cpp create mode 100644 instrumentation/CoverageInstru.hpp create mode 100644 instrumentation/InstrumentResponse.hpp create mode 100644 instrumentation/MockInstrumentationWalker.cpp create mode 100644 instrumentation/MockInstrumentationWalker.hpp create mode 100644 instrumentation/main.cpp rename {build => scripts}/esbuild.js (70%) create mode 160000 third_party/binaryen create mode 160000 third_party/jsoncpp delete mode 100644 transform/listFunctions.mjs diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..c2e5bf7 --- /dev/null +++ b/.clang-format @@ -0,0 +1,140 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: true +AllowShortFunctionsOnASingleLine: None +AllowShortLambdasOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterCaseLabel: false + AfterClass: false + AfterControlStatement: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false + AfterObjCDeclaration: false + AfterStruct: false + AfterUnion: false + AfterExternBlock: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Attach +BreakBeforeInheritanceComma: false +BreakInheritanceList: BeforeColon +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: false +BreakConstructorInitializers: BeforeColon +BreakAfterJavaFieldAnnotations: false +BreakStringLiterals: true +ColumnLimit: 100 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: true +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Preserve +IncludeCategories: + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 1 + SortPriority: 0 + - Regex: '.*' + Priority: 3 + SortPriority: 0 + - Regex: '^(src|wasm-compiler)/' + Priority: 4 + SortPriority: 0 +IncludeIsMainRegex: '(Test)?$' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: false +IndentGotoLabels: true +IndentPPDirectives: None +IndentWidth: 2 +IndentWrappedFunctionNames: false +JavaScriptQuotes: Leave +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Auto +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: true +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: false +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatements +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Latest +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +... + diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..a99d78a --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,180 @@ +Checks: +'-*, + +bugprone-lambda-function-name, +bugprone-macro-parentheses, +bugprone-macro-repeated-side-effects, +bugprone-misplaced-widening-cast, +bugprone-move-forwarding-reference, +bugprone-multiple-statement-macro, +bugprone-parent-virtual-call, +bugprone-sizeof-container, +bugprone-sizeof-expression, +bugprone-string-integer-assignment, +bugprone-string-literal-with-embedded-nul, +bugprone-suspicious-memset-usage, +bugprone-suspicious-missing-comma, +bugprone-suspicious-semicolon, +bugprone-suspicious-string-compare, +bugprone-undelegated-constructor, +bugprone-unused-raii, +bugprone-unused-return-value, +bugprone-assert-side-effect, +bugprone-bool-pointer-implicit-conversion, +bugprone-copy-constructor-init, +bugprone-dangling-handle, +bugprone-fold-init-type, +bugprone-forward-declaration-namespace, +bugprone-forward-reference-overload, +bugprone-inaccurate-erase, +bugprone-incorrect-roundings, +bugprone-integer-division, +bugprone-misplaced-operator-in-strlen-in-alloc, +bugprone-string-constructor, +bugprone-suspicious-enum-usage, +bugprone-swapped-arguments, +bugprone-terminating-continue, +bugprone-throw-keyword-missing, +bugprone-too-small-loop-variable, +bugprone-undefined-memory-manipulation, +bugprone-use-after-move, +bugprone-unhandled-self-assignment, + +hicpp-multiway-paths-covered, + +clang-analyzer-core.builtin.NoRetmodernize-deprecated-headersurnFunctions, +clang-analyzer-core.CallAndMessage, +clang-analyzer-core.DivideZero, +clang-analyzer-core.DynamicTypePropagation, +clang-analyzer-core.NonnilStringConstants, +clang-analyzer-core.NonNullParamChecker, +clang-analyzer-core.NullDereference, +clang-analyzer-core.StackAddressEscape, +clang-analyzer-core.UndefinedBinaryOperatorResult, +clang-analyzer-core.uninitialized.ArraySubscript, +clang-analyzer-core.uninitializedmodernize-deprecated-headers.Assign, +clang-analyzer-core.uninitialized.Branch, +clang-analyzer-core.uninitialized.CapturedBlockVariable, +clang-analyzer-core.uninitialized.UndefReturn, +clang-analyzer-core.VLASize, + +clang-analyzer-cplusplus.NewDelete, +clang-analyzer-cplusplus.NewDeleteLeaks, +clang-analyzer-cplusplus.SelfAssignment, + +clang-analyzer-deadcode.DeadStores, + +clang-analyzer-optin.cplusplus.VirtualCall, +clang-analyzer-optin.performance.Padding, + +clang-analyzer-security.FloatLoopCounter, +clang-analyzer-security.insecureAmodernize-deprecated-headersPI.getpw, +clang-analyzer-security.insecureAPI.gets, +clang-analyzer-security.insecureAPI.mkstemp, +clang-analyzer-security.insecureAPI.mktemp, +clang-analyzer-security.insecureAPI.rand, +clang-analyzer-security.insecureAPI.strcpy, +clang-analyzer-security.insecuremodernize-deprecated-headersAPI.UncheckedReturn, +clang-analyzer-security.insecureAPI.vfork, + +clang-analyzer-unix.API, +clang-analyzer-unix.cstring.BadSizeArg, +clang-analyzer-unix.cstring.NullArg, +clang-analyzer-unix.Malloc, +clang-analyzer-unix.MallocSizeof, +clang-analyzer-unix.MismatchedDeallocator, +clang-analyzer-unix.StdCLibraryFunctions, +clang-analyzer-unix.Vfork, +clang-analyzer-valist.CopyToSelf, +clang-analyzer-valist.Uninitialized, +clang-analyzer-valist.Unterminated, +clang-analyzer-nullability.NullablePassedToNonnull, + +cert-dcl03-c, +cert-dcl21-cpp, +cert-dcl54-cpp, +cert-dcl58-cpp, +cert-err09-cpp, +cert-err34-c, +cert-err52-cpp, +cert-err58-cpp, +cert-err60-cpp, +cert-fio38-c, +cert-flp30-c, +cert-oop11-cpp, + +cppcoreguidelines-c-copy-assignment-signature, +cppcoreguidelines-explicit-virtual-functions, +cppcoreguidelines-interfaces-global-init, +cppcoreguidelines-narrowing-conversions, +cppcoreguidelines-pro-type-const-cast, +cppcoreguidelines-pro-type-cstyle-cast, +cppcoreguidelines-pro-type-member-init, +cppcoreguidelines-pro-type-static-cast-downcast, +cppcoreguidelines-slicing, +cppcoreguidelines-pro-type-vararg, +cppcoreguidelines-special-member-functions, +cppcoreguidelines-avoid-goto, +cppcoreguidelines-pro-type-reinterpret-cast, + +google-default-arguments, +google-explicit-constructor, +google-global-names-in-headers, +google-readability-casting, +google-readability-todo, +google-runtime-operator, +google-runtime-int, + +hicpp-exception-baseclass, +hicpp-move-const-arg, +hicpp-named-parameter, +hicpp-no-assembler, +hicpp-noexcept-move, +hicpp-signed-bitwise, +hicpp-use-nullptr, + + +misc-definitions-in-headers, +misc-misplaced-const, +misc-redundant-expression, +misc-unused-alias-decls, +misc-unused-parameters, +misc-unused-using-decls, +misc-unconventional-assign-operator, + + +readability-delete-null-pointer, +readability-implicit-bool-conversion, +readability-inconsistent-declaration-parameter-name, +readability-redundant-non-const-parameter, +readability-redundant-control-flow, +readability-redundant-declaration, +readability-redundant-function-ptr-dereference, +readability-redundant-member-init, +readability-redundant-smartptr-get, +readability-redundant-string-cstr, +readability-redundant-string-init, +readability-simplify-subscript-expr, +readability-static-accessed-through-instance, +readability-static-definition-in-anonymous-namespace, +readability-string-compare, +readability-uniqueptr-delete-release, +readability-uppercase-literal-suffix, +readability-braces-around-statements, +readability-non-const-parameter, +readability-isolate-declaration, + +modernize-loop-convert, +modernize-use-using, +modernize-use-nullptr, +modernize-use-noexcept, +modernize-deprecated-headers, +modernize-avoid-c-arrays, + +performance-move-const-arg +' + +WarningsAsErrors: '' +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: none \ No newline at end of file diff --git a/.gitignore b/.gitignore index bf46dff..6dc3da7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,10 @@ -node_modules -dist -coverage -coverage-ts -.vscode \ No newline at end of file +.vscode + +/node_modules +/dist + +/build* +/transform/listFunctions.mjs + +/coverage +/coverage-ts diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..0d05ad3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,6 @@ +[submodule "third_party/binaryen"] +path = third_party/binaryen +url = https://github.com/WebAssembly/binaryen.git +[submodule "third_party/jsoncpp"] +path = third_party/jsoncpp +url = https://github.com/open-source-parsers/jsoncpp.git diff --git a/instrumentation/BasicBlockAnalysis.cpp b/instrumentation/BasicBlockAnalysis.cpp new file mode 100644 index 0000000..9eedd0d --- /dev/null +++ b/instrumentation/BasicBlockAnalysis.cpp @@ -0,0 +1,32 @@ +#include "BasicBlockAnalysis.hpp" +#include +#include +#include +#include +#include + +namespace wasmInstrumentation { + +bool BasicBlockAnalysis::shouldIncludeFile(std::string_view fileName) const noexcept { + bool shouldInclude = false; + bool shouldExclude = false; + if (includes.size() == 0) { + shouldInclude = true; + } else { + for (const auto &include : includes) { + if (std::regex_match(fileName.begin(), fileName.end(), include)) { + shouldInclude = true; + break; + } + } + } + + for (const auto &exclude : this->excludes) { + if (std::regex_match(fileName.begin(), fileName.end(), exclude)) { + shouldExclude = true; + } + } + return (shouldInclude && (!shouldExclude)); +} + +} // namespace wasmInstrumentation diff --git a/instrumentation/BasicBlockAnalysis.hpp b/instrumentation/BasicBlockAnalysis.hpp new file mode 100644 index 0000000..be66685 --- /dev/null +++ b/instrumentation/BasicBlockAnalysis.hpp @@ -0,0 +1,47 @@ +#ifndef __ASC_COV_BASICBLOCK_ANALYSIS_HPP__ +#define __ASC_COV_BASICBLOCK_ANALYSIS_HPP__ + +#include +#include +#include +#include +#include +#include +#include + +namespace wasmInstrumentation { + +/// @brief Class for performing if file should be included. +/// +class BasicBlockAnalysis final { +public: + /// + /// @brief Add include file to debug info analysis + /// + /// @param include + inline void addInclude(const std::string &&include) noexcept { + includes.emplace_back(include); + } + + /// + /// @brief Add exclude file to debug info analysis + /// + /// @param exclude + inline void addExclude(const std::string &&exclude) noexcept { + excludes.emplace_back(exclude); + } + + /// + /// @brief If the debug file should be included into debug info analysis + /// + /// @param fileName + /// @return Return true if the file should be included + bool shouldIncludeFile(std::string_view fileName) const noexcept; + +private: + std::vector includes; ///< functions should be processed + std::vector excludes; ///< functions should not be processed +}; +} // namespace wasmInstrumentation + +#endif diff --git a/instrumentation/BasicBlockWalker.cpp b/instrumentation/BasicBlockWalker.cpp new file mode 100644 index 0000000..8e90545 --- /dev/null +++ b/instrumentation/BasicBlockWalker.cpp @@ -0,0 +1,146 @@ +#include "BasicBlockWalker.hpp" +#include +#include "ir/branch-utils.h" + +namespace wasmInstrumentation { + +void BasicBlockWalker::basicBlockWalk() noexcept { + // Iterate DefinedFunctions, generate coverage infos + wasm::ModuleUtils::iterDefinedFunctions(*module, [this](wasm::Function *const func) noexcept { + if ((!func->debugLocations.empty()) && basicBlockAnalysis.shouldIncludeFile(func->name.str)) { + walkFunctionInModule(func, module); + } + }); +} + +void BasicBlockWalker::visitExpression(wasm::Expression *curr) noexcept { + if (currBasicBlock == nullptr) { + return; + } + // push information + wasm::Function *const currFun = getFunction(); + currBasicBlock->contents.exprs.push_back(curr); + const auto debugLocationIterator = currFun->debugLocations.find(curr); + if (debugLocationIterator != currFun->debugLocations.cend()) { + const auto &debugLocation = debugLocationIterator->second; + currBasicBlock->contents.debugLocations.insert(debugLocation); + } +} + +void BasicBlockWalker::unlinkEmptyBlock() noexcept { + const auto lambda = [](std::unique_ptr &block) { + if (block->contents.exprs.empty() && block->out.size() == 1) { + const auto outBlock = block->out[0]; + outBlock->in.erase(std::find(outBlock->in.begin(), outBlock->in.end(), block.get())); + for (auto &inBlock : block->in) { + inBlock->out.erase(std::find(inBlock->out.begin(), inBlock->out.end(), block.get())); + inBlock->out.push_back(outBlock); + outBlock->in.push_back(inBlock); + } + block->in.clear(); + block->out.clear(); + return true; + } + return false; + }; + basicBlocks.erase(std::remove_if(basicBlocks.begin(), basicBlocks.end(), lambda), + basicBlocks.end()); +} + +void BasicBlockWalker::doWalkFunction(wasm::Function *const func) noexcept { + wasm::CFGWalker, + BasicBlockInfo>::doWalkFunction(func); + unlinkEmptyBlock(); + // LCOV_EXCL_START + if (basicBlocks.size() > UINT32_MAX) { + std::cerr << "Error: BasicBlocks length exceeds UINT32_MAX\n"; + ::exit(EXIT_FAILURE); + } + // LCOV_EXCL_STOP + for (size_t i = 0; i < basicBlocks.size(); i++) { + basicBlocks[i]->contents.basicBlockIndex = static_cast(i); + } + + FunctionAnalysisResult analysisResult; + analysisResult.functionIndex = functionIndex; + functionIndex++; + for (const auto &basicBlock : basicBlocks) { + const wasm::Index currBasicBlockIndex = basicBlock->contents.basicBlockIndex; + // Generate Branch coverage info + if (basicBlock->out.size() > 1U) { + for (const auto &out : basicBlock->out) { + analysisResult.branchInfo.emplace_back(currBasicBlockIndex, out->contents.basicBlockIndex); + } + } + // Generate Line coverage info + analysisResult.basicBlocks.push_back(basicBlock->contents); + + // Generate CovInstrument position + if (exit != nullptr && currBasicBlockIndex == exit->contents.basicBlockIndex) { + // For exit basicBlock, we instrument at the end of function + setCovInstrumentPosition(func->body, {currBasicBlockIndex, false}); + continue; + } + wasm::Expression *expr = nullptr; + bool pre = false; + if (basicBlock->contents.exprs.empty()) { + for (const auto &inBlock : basicBlock->in) { + assert(!inBlock->contents.exprs.empty()); + setCovInstrumentPosition(inBlock->contents.exprs.back(), {currBasicBlockIndex, false}); + } + } else { + wasm::Expression *const lastExpression = basicBlock->contents.exprs.back(); + if (lastExpression->is() || lastExpression->is() || + lastExpression->is()) { + if (basicBlock->contents.exprs.size() == 1U) { + expr = lastExpression; + pre = true; + } else { + expr = basicBlock->contents.exprs[basicBlock->contents.exprs.size() - 2]; + } + } else if (lastExpression->is() && basicBlock->contents.exprs.size() > 1U) { + // Special treatment for for-loop-continue case. + expr = basicBlock->contents.exprs[basicBlock->contents.exprs.size() - 2]; + } else { + expr = lastExpression; + } + + setCovInstrumentPosition(expr, {currBasicBlockIndex, pre}); + } + } + this->results[func->name.str] = std::move(analysisResult); +} + +wasm::Index +BasicBlockWalker::getFunctionIndexByName(const std::string_view &funcName) const noexcept { + const auto functionResultIterator = results.find(funcName); + if (functionResultIterator != results.cend()) { + return functionResultIterator->second.functionIndex; + } + return static_cast(-1); +} + +void BasicBlockWalker::setCovInstrumentPosition(wasm::Expression *const expr, + const InstrumentPosition &position) noexcept { + auto positions = covInstrumentPosition.find(expr); + if (positions != covInstrumentPosition.end()) { + positions->second.emplace_back(position); + } else { + covInstrumentPosition.emplace(expr, std::vector{position}); + } +} + +const std::vector * +BasicBlockWalker::getCovInstrumentPosition(wasm::Expression *const expr) const noexcept { + const auto iterator = covInstrumentPosition.find(expr); + if (iterator != covInstrumentPosition.cend()) { + return &(iterator->second); + } + return nullptr; +} + +BasicBlockAnalysis BasicBlockWalker::getBasicBlockAnalysis() const noexcept { + return basicBlockAnalysis; +} + +} // namespace wasmInstrumentation diff --git a/instrumentation/BasicBlockWalker.hpp b/instrumentation/BasicBlockWalker.hpp new file mode 100644 index 0000000..d79b122 --- /dev/null +++ b/instrumentation/BasicBlockWalker.hpp @@ -0,0 +1,174 @@ +#ifndef __ASC_COV_BASICBLOCK_WALKER_HPP__ +#define __ASC_COV_BASICBLOCK_WALKER_HPP__ +#include +#include +#include +#include +#include +#include +#include "BasicBlockAnalysis.hpp" +#include "cfg/cfg-traversal.h" +#include "ir/module-utils.h" +#include "support/index.h" +#include "wasm.h" +namespace wasmInstrumentation { + +struct InstrumentPosition { + wasm::Index basicBlockIndex; + bool pre; // pre = true means instrument before expression +}; + +/// +///@brief information about debugLocation in a basic block +/// +class BasicBlockInfo final { +public: + /// + /// @brief Copy constructor for BasicBlockInfo + /// + /// @param src + BasicBlockInfo(const BasicBlockInfo &src) noexcept + : exprs(src.exprs), debugLocations(src.debugLocations), basicBlockIndex(src.basicBlockIndex) { + } + + /// + /// @brief Move constructor for BasicBlockInfo + /// + /// @param src + BasicBlockInfo(BasicBlockInfo &&src) noexcept + : exprs(std::move(src.exprs)), debugLocations(std::move(src.debugLocations)), + basicBlockIndex(src.basicBlockIndex) { + } + + /// + /// @brief Destructors for BasicBlockInfo + /// + ~BasicBlockInfo() noexcept { + basicBlockIndex = static_cast(-1); + } + + /// + /// @brief Default constructor for BasicBlockInfo + /// + BasicBlockInfo() noexcept : basicBlockIndex(static_cast(-1)) { + } + + /// + /// @brief Copy equal operator function + /// + BasicBlockInfo &operator=(const BasicBlockInfo &src) noexcept { + this->exprs = src.exprs; + this->debugLocations = src.debugLocations; + this->basicBlockIndex = src.basicBlockIndex; + return *this; + } + + /// + /// @brief moves equal operator function + /// + BasicBlockInfo &operator=(BasicBlockInfo &&src) noexcept { + this->exprs = std::move(src.exprs); + this->debugLocations = std::move(src.debugLocations); + this->basicBlockIndex = src.basicBlockIndex; + src.basicBlockIndex = static_cast(-1); + return *this; + } + std::vector exprs; ///< expressions + std::set debugLocations; ///< debug infos + wasm::Index basicBlockIndex; ///< basic block ID +}; + +/// @brief Class for the analysis result of each function of analysis +class FunctionAnalysisResult final { +public: + /// @brief Default constructor of FunctionAnalysisResult + FunctionAnalysisResult() noexcept : functionIndex(static_cast(-1)) { + } + std::vector basicBlocks; ///< basicBlocks in this function + std::vector> branchInfo; ///< function branch info + wasm::Index functionIndex; ///< function Index +}; + +/// +///@brief Basic block walker with basic block information +/// +class BasicBlockWalker final + : public wasm::WalkerPass, BasicBlockInfo>> { +public: + /// + /// @brief Constructor for BasicBlockWalker + /// + /// @param _module + /// @param _reportFunName + BasicBlockWalker(wasm::Module *const _module, BasicBlockAnalysis &_basicBlockAnalysis) noexcept + : module(_module), basicBlockAnalysis(_basicBlockAnalysis) { + } + BasicBlockWalker(const BasicBlockWalker &src) = delete; + BasicBlockWalker(BasicBlockWalker &&src) = delete; + BasicBlockWalker &operator=(const BasicBlockWalker &) = delete; + BasicBlockWalker &operator=(BasicBlockWalker &&) = delete; + + /// + /// @brief Destructor for BasicBlockWalker + /// + ~BasicBlockWalker() noexcept override = default; + + /// + ///@brief Inherit from CFGWalker for expression visitor + /// + ///@param curr Current expression + void visitExpression(wasm::Expression *const curr) noexcept; + + /// + ///@brief Inherit from CFGWalker for function visitor + /// + ///@param func Current function + void doWalkFunction(wasm::Function *const func) noexcept; + + /// + /// @brief Search function id by function Name + /// + /// @param name + /// @return Function ID + wasm::Index getFunctionIndexByName(const std::string_view &funcName) const noexcept; + + /// + /// @brief Query coverage instrument position by expression reference + /// + /// @param expr + /// + const std::vector * + getCovInstrumentPosition(wasm::Expression *const expr) const noexcept; + + BasicBlockAnalysis getBasicBlockAnalysis() const noexcept; + + /// + /// @brief basicBlock walk + /// + void basicBlockWalk() noexcept; + + inline const std::unordered_map & + getResults() const noexcept { + return results; + } + +private: + wasm::Module *const module; ///< working wasm module + wasm::Index functionIndex = 0U; ///< function Index + const BasicBlockAnalysis &basicBlockAnalysis; ///< include analysis + std::unordered_map> covInstrumentPosition; + std::unordered_map results; ///< analysis results + /// + /// @brief traverse CFG to set the instrumentation position + /// + void setCovInstrumentPosition(wasm::Expression *const expr, + const InstrumentPosition &position) noexcept; + /// + /// @brief remove empty block that do not belong to any branch + /// + void unlinkEmptyBlock() noexcept; +}; +} // namespace wasmInstrumentation + +#endif diff --git a/instrumentation/CMakeLists.txt b/instrumentation/CMakeLists.txt new file mode 100644 index 0000000..8635298 --- /dev/null +++ b/instrumentation/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.5) +project(instrumentation VERSION 0.1.0) + +set(CMAKE_CXX_STANDARD 23) + +set(JSONCPP_WITH_TESTS OFF) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/jsoncpp) + +set(BUILD_TESTS 0) +set(BUILD_STATIC_LIBS ON) +set(BUILD_SHARED_LIBS OFF) +set(BUILD_OBJECT_LIBS OFF) +add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/binaryen) + +aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src sources) + +add_executable(wasm-instrumentation ${sources}) + +target_link_libraries(wasm-instrumentation binaryen jsoncpp_static) +target_include_directories(wasm-instrumentation SYSTEM PRIVATE ${CMAKE_CURRENT_LIST_DIR}/thirdparty/binaryen/src ${CMAKE_CURRENT_LIST_DIR}/thirdparty/jsoncpp/include) + +if(EMSCRIPTEN) + target_link_libraries(wasm-instrumentation "-sSINGLE_FILE") + target_link_libraries(wasm-instrumentation "-sFORCE_FILESYSTEM") + target_link_libraries(wasm-instrumentation "-sALLOW_MEMORY_GROWTH") + + # target_link_libraries(wasm-instrumentation "-sINITIAL_MEMORY=33554432") + target_link_libraries(wasm-instrumentation "-sNODERAWFS=1") + target_link_libraries(wasm-instrumentation "-sENVIRONMENT=node") + target_link_libraries(wasm-instrumentation "-sSTACK_SIZE=4mb") + target_link_libraries(wasm-instrumentation "-sMODULARIZE=1") + target_link_libraries(wasm-instrumentation "-sEXPORT_NAME=initInstrumenter") + target_link_libraries(wasm-instrumentation "-sEXPORT_ES6=1") + target_link_libraries(wasm-instrumentation "-sEXPORTED_RUNTIME_METHODS=allocateUTF8") + target_link_libraries(wasm-instrumentation "-sEXPORTED_FUNCTIONS=_malloc,_free") +else() +endif() + +add_executable(wasm-instrumentation main.cpp ${sources}) diff --git a/instrumentation/CovInstrumentationWalker.cpp b/instrumentation/CovInstrumentationWalker.cpp new file mode 100644 index 0000000..24fdf7c --- /dev/null +++ b/instrumentation/CovInstrumentationWalker.cpp @@ -0,0 +1,113 @@ +#include "CovInstrumentationWalker.hpp" + +namespace wasmInstrumentation { +void CovInstrumentationWalker::introduceReportFun() noexcept { + bool needImport = true; + wasm::ModuleUtils::iterDefinedFunctions( + *module, [this, &needImport](const BinaryenFunctionRef &func) noexcept { + if (func->name == wasm::IString(this->reportFunName)) { + // escape already declared function + // LCOV_EXCL_START + needImport = false; + // LCOV_EXCL_STOP + } + }); + wasm::ModuleUtils::iterImportedFunctions( + *module, [this, &needImport](const BinaryenFunctionRef &func) noexcept { + if (func->name == wasm::IString(this->reportFunName)) { + // escape already imported function + // LCOV_EXCL_START + needImport = false; + // LCOV_EXCL_STOP + } + }); + if (needImport) { + wasm::Builder builder(*module); + std::array iii_{BinaryenTypeInt32(), BinaryenTypeInt32(), + BinaryenTypeInt32()}; + const BinaryenType iii = BinaryenTypeCreate(iii_.data(), iii_.size()); + BinaryenAddFunctionImport(module, reportFunName, "covInstrument", "traceExpression", iii, + wasm::Type::none); + } +} + +void CovInstrumentationWalker::visitFunction(wasm::Function *const curr) noexcept { + using Parent = wasm::PostWalker>; + Parent::visitFunction(curr); + + const wasm::Index functionIndex = basicBlockWalker.getFunctionIndexByName(curr->name.str); + // function in instruction + if (functionIndex != static_cast(-1)) { + const std::array callInReportArgs = { + moduleBuilder.makeConst(functionIndex), + moduleBuilder.makeConst(static_cast(-1)), moduleBuilder.makeConst(1U)}; + wasm::Call *const callIn = + moduleBuilder.makeCall(this->reportFunName, callInReportArgs, wasm::Type::none); + + wasm::Block *const newBody = moduleBuilder.makeBlock(); + newBody->list.push_back(callIn); + newBody->list.push_back(curr->body); + newBody->finalize(curr->body->type); + curr->body = newBody; + } +} + +void CovInstrumentationWalker::visitExpression(wasm::Expression *curr) noexcept { + BinaryenFunctionRef func = getFunction(); + const std::vector *positionIterator = + basicBlockWalker.getCovInstrumentPosition(curr); + if (positionIterator != nullptr) { + for (const InstrumentPosition &position : *positionIterator) { + wasm::Block *replacement = moduleBuilder.makeBlock(); + const wasm::Index functionIndex = basicBlockWalker.getFunctionIndexByName(func->name.str); + const std::array reportArgs = { + moduleBuilder.makeConst(functionIndex), moduleBuilder.makeConst(position.basicBlockIndex), + moduleBuilder.makeConst(0U)}; + wasm::Expression *report = + moduleBuilder.makeCall(reportFunName, reportArgs, wasm::Type::none); + wasm::Expression **replacePtr = getCurrentPointer(); + if (position.pre) { + replacement->list.push_back(report); + replacement->list.push_back(*replacePtr); + } else { + replacement->list.push_back(*replacePtr); + replacement->list.push_back(report); + } + replacement->finalize(curr->type); + *replacePtr = replacement; + } + } + + if (curr->is()) { + // function out instrumentation + wasm::Call *const call = curr->cast(); + const wasm::Index targetFunctionIndex = + basicBlockWalker.getFunctionIndexByName(call->target.str); + if (targetFunctionIndex != static_cast(-1)) { + wasm::Block *replacement = moduleBuilder.makeBlock(); + const std::array callOutReportArgs = { + moduleBuilder.makeConst(targetFunctionIndex), + moduleBuilder.makeConst(static_cast(-1)), moduleBuilder.makeConst(2U)}; + wasm::Expression *callOut = + moduleBuilder.makeCall(reportFunName, callOutReportArgs, wasm::Type::none); + wasm::Expression **replacePtr = getCurrentPointer(); + replacement->list.push_back(*replacePtr); + replacement->list.push_back(callOut); + replacement->finalize(curr->type); + *replacePtr = replacement; + } + } +} + +void CovInstrumentationWalker::covWalk() noexcept { + introduceReportFun(); + wasm::ModuleUtils::iterDefinedFunctions( + *module, [this](const BinaryenFunctionRef &func) noexcept { + if (basicBlockWalker.getBasicBlockAnalysis().shouldIncludeFile(func->name.str)) { + walkFunctionInModule(func, this->module); + } + }); +} + +} // namespace wasmInstrumentation diff --git a/instrumentation/CovInstrumentationWalker.hpp b/instrumentation/CovInstrumentationWalker.hpp new file mode 100644 index 0000000..e6e9345 --- /dev/null +++ b/instrumentation/CovInstrumentationWalker.hpp @@ -0,0 +1,73 @@ +#ifndef __ASC_COV_INSTRUMENTATION_WALKER_HPP__ +#define __ASC_COV_INSTRUMENTATION_WALKER_HPP__ +#include +#include +#include +#include +#include "BasicBlockWalker.hpp" +#include "binaryen-c.h" +#include "ir/module-utils.h" +#include "support/index.h" +#include "wasm-builder.h" +#include "wasm-traversal.h" +#include "wasm-type.h" +#include "wasm.h" +namespace wasmInstrumentation { +/// +/// @brief Post walker for instrumentation purpose +/// +class CovInstrumentationWalker final + : public wasm::PostWalker> { +public: + /// + /// @brief Constructor for CovInstrumentationWalker + /// + /// @param _module + /// @param _reportFunName + /// @param _basicBlockWalker + CovInstrumentationWalker(wasm::Module *const _module, char const *const _reportFunName, + BasicBlockWalker &_basicBlockWalker) noexcept + : module(_module), reportFunName(_reportFunName), moduleBuilder(wasm::Builder(*_module)), + basicBlockWalker(_basicBlockWalker) { + } + CovInstrumentationWalker(const CovInstrumentationWalker &src) = delete; + CovInstrumentationWalker(CovInstrumentationWalker &&src) = delete; + CovInstrumentationWalker &operator=(const CovInstrumentationWalker &) = delete; + CovInstrumentationWalker &operator=(CovInstrumentationWalker &&) = delete; + + /// + /// @brief Destructor for CovInstrumentationWalker + /// + ~CovInstrumentationWalker() noexcept = default; + /// + /// @brief walk function + /// + /// @param curr current function reference + void visitFunction(wasm::Function *const curr) noexcept; + + /// + /// @brief walk expression + /// + /// @param curr current expression reference + void visitExpression(wasm::Expression *const curr) noexcept; + + /// + /// @brief walk module + /// + void covWalk() noexcept; + +private: + wasm::Module *const module; ///< working wasm module + char const *const reportFunName; ///< trace report function name + wasm::Builder moduleBuilder; ///< module build for create wasm reference + const BasicBlockWalker &basicBlockWalker; ///< basic block walker for instrument + /// + /// @brief introduce the trace report function, if customer does not config report function, use a + /// default one + /// + void introduceReportFun() noexcept; +}; +} // namespace wasmInstrumentation + +#endif diff --git a/instrumentation/CoverageInstru.cpp b/instrumentation/CoverageInstru.cpp new file mode 100644 index 0000000..d56d496 --- /dev/null +++ b/instrumentation/CoverageInstru.cpp @@ -0,0 +1,187 @@ +#include "CoverageInstru.hpp" +namespace wasmInstrumentation { + +void CoverageInstru::innerAnalysis(BasicBlockAnalysis &basicBlockAnalysis) const noexcept { + if (config->skipLib) { + basicBlockAnalysis.addExclude("~lib/.+"); + } + Json::Reader jsonReader; + Json::Value includesJsonValue; + Json::Value excludesJsonValue; + if (!config->includes.empty()) { + jsonReader.parse(std::string(config->includes), includesJsonValue); + if (includesJsonValue.isArray()) { + const uint32_t includesJsonSize = includesJsonValue.size(); + for (uint32_t i = 0U; i < includesJsonSize; ++i) { + basicBlockAnalysis.addInclude(includesJsonValue[i].asString()); + } + } + } + if (!config->excludes.empty()) { + jsonReader.parse(std::string(config->excludes), excludesJsonValue); + if (excludesJsonValue.isArray()) { + const uint32_t excludeJsonSize = excludesJsonValue.size(); + for (uint32_t i = 0U; i < excludeJsonSize; ++i) { + basicBlockAnalysis.addExclude(excludesJsonValue[i].asString()); + } + } + } +} + +InstrumentationResponse CoverageInstru::instrument() const noexcept { + if (config->fileName.empty() || config->reportFunction.empty() || config->sourceMap.empty() || + config->targetName.empty() || config->expectInfoOutputFilePath.empty() || + config->debugInfoOutputFilePath.empty()) { + std::cout << *config << std::endl; + return InstrumentationResponse::CONFIG_ERROR; // config error + } + std::filesystem::path filePath(config->fileName); + std::filesystem::path targetFilePath(config->targetName); + std::filesystem::path debugInfoPath(config->debugInfoOutputFilePath); + std::filesystem::path sourceMapPath(config->sourceMap); + if ((!std::filesystem::exists(filePath)) || + (!std::filesystem::exists(debugInfoPath.parent_path())) || + (!std::filesystem::exists(sourceMapPath)) || + (!std::filesystem::exists(targetFilePath.parent_path()))) { + std::cout << *config << std::endl; + return InstrumentationResponse::CONFIG_FILEPATH_ERROR; // config file path error + } + + wasm::Module module; + wasm::ModuleReader reader; + + reader.read(std::string(config->fileName), module, std::string(config->sourceMap)); + BasicBlockAnalysis basicBlockAnalysis = BasicBlockAnalysis(); + innerAnalysis(basicBlockAnalysis); + BasicBlockWalker basicBlockWalker = BasicBlockWalker(&module, basicBlockAnalysis); + basicBlockWalker.basicBlockWalk(); + const std::unordered_map &results = + basicBlockWalker.getResults(); + Json::Value json; + Json::Value debugInfoJson; + Json::Value debugFileJson; + for (auto &[function, result] : results) { + Json::Value innerJson; + innerJson["index"] = result.functionIndex; + Json::Value branchInfoArray(Json::ValueType::arrayValue); + for (const auto &branchInfo : result.branchInfo) { + Json::Value inner_array; + inner_array.append(branchInfo.first); + inner_array.append(branchInfo.second); + branchInfoArray.append(std::move(inner_array)); + } + innerJson["branchInfo"] = branchInfoArray; + Json::Value debugLineJson; + for (const auto &basicBlock : result.basicBlocks) { + if (basicBlock.basicBlockIndex != static_cast(-1)) { + Json::Value debugLineItemJsonArray(Json::ValueType::arrayValue); + for (const auto &debugLine : basicBlock.debugLocations) { + Json::Value debugInfo; + debugInfo.append(debugLine.fileIndex); + debugInfo.append(debugLine.lineNumber); + debugInfo.append(debugLine.columnNumber); + debugLineItemJsonArray.append(std::move(debugInfo)); + } + debugLineJson[basicBlock.basicBlockIndex] = debugLineItemJsonArray; + } + } + innerJson["lineInfo"] = debugLineJson; + debugInfoJson[function.data()] = innerJson; + } + for (const std::string &debugInfoFileName : module.debugInfoFileNames) { + debugFileJson.append(debugInfoFileName); + } + json["debugInfos"] = debugInfoJson; + json["debugFiles"] = debugFileJson; + std::ofstream jsonWriteStream(config->debugInfoOutputFilePath.data(), std::ios::trunc); + Json::StreamWriterBuilder jsonBuilder; + jsonBuilder["indentation"] = ""; + std::unique_ptr jsonWriter(jsonBuilder.newStreamWriter()); + if (jsonWriter->write(json, &jsonWriteStream) != 0) { + // Hard to control IO error + // LCOV_EXCL_START + return InstrumentationResponse::DEBUG_INFO_GENERATION_ERROR; // debug info json write failed + // LCOV_EXCL_STOP + } + jsonWriteStream.close(); + if (jsonWriteStream.fail() || jsonWriteStream.bad()) { + // Hard to control IO error + // LCOV_EXCL_START + return InstrumentationResponse::DEBUG_INFO_GENERATION_ERROR; // debug info json write failed + // LCOV_EXCL_STOP + } + CovInstrumentationWalker covWalker(&module, config->reportFunction.data(), basicBlockWalker); + covWalker.covWalk(); + + MockInstrumentationWalker mockWalker(&module); + mockWalker.mockWalk(); + + const BinaryenModuleAllocateAndWriteResult result = + BinaryenModuleAllocateAndWrite(&module, nullptr); + std::ofstream wasmFileStream(this->config->targetName.data(), std::ios::trunc | std::ios::binary); + wasmFileStream.write(static_cast(result.binary), + static_cast(result.binaryBytes)); + wasmFileStream.close(); + free(result.binary); + free(result.sourceMap); + if (wasmFileStream.fail() || wasmFileStream.bad()) { + // Hard to control IO error + // LCOV_EXCL_START + return InstrumentationResponse::FILE_GENERATION_ERROR; // debug info json write failed + // LCOV_EXCL_STOP + } + + Json::Value expectInfosJson; + for (const auto &[key, value] : mockWalker.getExpectInfos()) { + // Mock test will verified with wasm-testing-framework project, escape this + // LCOV_EXCL_START + expectInfosJson[std::to_string(key)] = value; + // LCOV_EXCL_STOP + } + std::ofstream expectInfosJsonWriteStream(config->expectInfoOutputFilePath.data(), + std::ios::trunc); + Json::StreamWriterBuilder expectInfosJsonBuilder; + expectInfosJsonBuilder["indentation"] = ""; + std::unique_ptr expectInfosJsonWriter(jsonBuilder.newStreamWriter()); + if (expectInfosJsonWriter->write(expectInfosJson, &expectInfosJsonWriteStream) != 0) { + // Hard to control IO error + // LCOV_EXCL_START + return InstrumentationResponse::EXPECT_INFO_GENERATION_ERROR; // expectation info generation + // failed + // LCOV_EXCL_STOP + } + expectInfosJsonWriteStream.close(); + if (expectInfosJsonWriteStream.fail() || expectInfosJsonWriteStream.bad()) { + // Hard to control IO error + // LCOV_EXCL_START + return InstrumentationResponse::EXPECT_INFO_GENERATION_ERROR; // expectation info generation + // failed + // LCOV_EXCL_STOP + } + return InstrumentationResponse::NORMAL; +} + +#if defined(__EMSCRIPTEN__) +extern "C" EMSCRIPTEN_KEEPALIVE wasmInstrumentation::InstrumentationResponse +wasm_instrument(char const *const fileName, char const *const targetName, + char const *const reportFunction, char const *const sourceMap, + char const *const expectInfoOutputFilePath, + char const *const debugInfoOutputFilePath, char const *const includes, + char const *const excludes, bool skipLib) noexcept { + + wasmInstrumentation::InstrumentationConfig config; + config.fileName = fileName; + config.targetName = targetName; + config.reportFunction = reportFunction; + config.sourceMap = sourceMap; + config.expectInfoOutputFilePath = expectInfoOutputFilePath; + config.debugInfoOutputFilePath = debugInfoOutputFilePath; + config.includes = includes; + config.excludes = excludes; + config.skipLib = skipLib; + wasmInstrumentation::CoverageInstru instrumentor(&config); + return instrumentor.instrument(); +} +#endif + +} // namespace wasmInstrumentation diff --git a/instrumentation/CoverageInstru.hpp b/instrumentation/CoverageInstru.hpp new file mode 100644 index 0000000..80e8240 --- /dev/null +++ b/instrumentation/CoverageInstru.hpp @@ -0,0 +1,124 @@ +#ifndef __ASC_COV_COVERAGE_INSTRU_HPP__ +#define __ASC_COV_COVERAGE_INSTRU_HPP__ +#include "json/json.h" +#include "json/value.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "BasicBlockAnalysis.hpp" +#include "BasicBlockWalker.hpp" +#include "CovInstrumentationWalker.hpp" +#include "InstrumentResponse.hpp" +#include "MockInstrumentationWalker.hpp" +#include "binaryen-c.h" +#include "support/index.h" +#include "wasm-io.h" +#include "wasm.h" + +namespace wasmInstrumentation { +/// +/// @brief Customer input configuration for instrumentation +/// +class InstrumentationConfig final { +public: + /// + /// @brief Default constructor for InstrumentationConfig + /// + InstrumentationConfig() noexcept = default; + std::string_view fileName; ///< input file name + std::string_view targetName; ///< target file name + std::string_view reportFunction; ///< trace report function name + std::string_view sourceMap; ///< input source map file name + std::string_view debugInfoOutputFilePath; ///< debug info output file name + std::string_view includes; ///< function include filter + std::string_view excludes; ///< function exclude filter + std::string_view expectInfoOutputFilePath; ///< exception info output file name + bool skipLib = true; ///< if skip lib functions + + /// + ///@brief Print information of InstrumentationConfig to output stream + /// + ///@param out target output stream + ///@param instance + ///@return processed output stream + friend std::ostream &operator<<(std::ostream &out, + const InstrumentationConfig &instance) noexcept { + out << "filename: " << instance.fileName << ", targetName: " << instance.targetName + << ", sourceMap: " << instance.sourceMap << ", reportFunction:" << instance.reportFunction + << ", includes: " << instance.includes << ", excludes: " << instance.excludes + << ", expectInfoOutputFilePath: " << instance.expectInfoOutputFilePath + << ", skipLib: " << std::boolalpha << instance.skipLib << std::endl; + return out; + } +}; + +/// +/// @brief Main instrumentation class +/// +class CoverageInstru final { + +public: + /// + ///@brief Constructor for coverage instrumentation + /// + ///@param cfg configuration from customer + explicit CoverageInstru(InstrumentationConfig const *const cfg) noexcept : config(cfg) { + } + CoverageInstru(const CoverageInstru &src) = delete; // disable copy construct + CoverageInstru(CoverageInstru &&src) = delete; // disable move construct + CoverageInstru &operator=(const CoverageInstru &) = delete; + CoverageInstru &operator=(CoverageInstru &&) = delete; + /// + ///@brief Destructor for CoverageInstru + /// + ~CoverageInstru() noexcept = default; + + /// + ///@brief Common public API for instrument process + /// + ///@return InstrumentationResponse + InstrumentationResponse instrument() const noexcept; + +private: + InstrumentationConfig const *const config; ///< customer configuration for instrumentation + /// + ///@brief Do preparation and analysis module + /// + void innerAnalysis(BasicBlockAnalysis &basicBlockAnalysis) const noexcept; +}; +} // namespace wasmInstrumentation + +// export wasm API +#if defined(__EMSCRIPTEN__) +#include +/// +///@brief Common public API for instrument process +/// +///@param fileName +///@param targetName +///@param reportFunction +///@param sourceMap +///@param expectInfoOutputFilePath +///@param debugInfoOutputFilePath +///@param includes +///@param excludes +///@param skipLib +///@return InstrumentationResponse +extern "C" EMSCRIPTEN_KEEPALIVE wasmInstrumentation::InstrumentationResponse +wasm_instrument(char const *const fileName, char const *const targetName, + char const *const reportFunction, char const *const sourceMap, + char const *const expectInfoOutputFilePath, + char const *const debugInfoOutputFilePath, char const *const includes = NULL, + char const *const excludes = NULL, bool skipLib = true) noexcept; +#endif +#endif diff --git a/instrumentation/InstrumentResponse.hpp b/instrumentation/InstrumentResponse.hpp new file mode 100644 index 0000000..868ed72 --- /dev/null +++ b/instrumentation/InstrumentResponse.hpp @@ -0,0 +1,19 @@ +#ifndef __ASC_INSTRUMENTATION_RESPONSE_HPP__ +#define __ASC_INSTRUMENTATION_RESPONSE_HPP__ +#include +namespace wasmInstrumentation { +/// +/// @brief Status class that returned by instrumentation flow +/// +enum class InstrumentationResponse : uint8_t { + NORMAL = 0U, ///< success + CONFIG_ERROR = 1U, ///< configuration error + CONFIG_FILEPATH_ERROR = 2U, ///< path check error for configuration + DEBUG_INFO_GENERATION_ERROR = 3U, ///< error during generate debug json info + FILE_GENERATION_ERROR = 4U, ///< instrumented file generation error + EXPECT_INFO_GENERATION_ERROR = 5U ///< expectation info generation error +}; + +} // namespace wasmInstrumentation + +#endif diff --git a/instrumentation/MockInstrumentationWalker.cpp b/instrumentation/MockInstrumentationWalker.cpp new file mode 100644 index 0000000..0ced2f0 --- /dev/null +++ b/instrumentation/MockInstrumentationWalker.cpp @@ -0,0 +1,102 @@ +#include "MockInstrumentationWalker.hpp" +#include +#include +#include +// mock test will be tested with wasm-testing-framework project, escape this class +// LCOV_EXCL_START +namespace wasmInstrumentation { + +void MockInstrumentationWalker::visitCall(wasm::Call *const curr) noexcept { + /* generate expect infos */ + if (std::any_of(this->expectTestFuncNames.begin(), this->expectTestFuncNames.end(), + [&curr](std::string_view str) noexcept { + auto lastIndex = curr->target.str.find_last_of(">"); + if (lastIndex != std::string_view::npos) { + return curr->target.str.substr(lastIndex + 1) == str; + } + return false; + })) { + const std::unordered_map + &currDebugLocations = getFunction()->debugLocations; + + const auto currentDebugLocationIterator = currDebugLocations.find(curr); + if (currentDebugLocationIterator != currDebugLocations.cend()) { + wasm::Function::DebugLocation const &currDebugLocation = currentDebugLocationIterator->second; + const std::string &fileName = module->debugInfoFileNames[currDebugLocation.fileIndex]; + std::stringstream expectInfo; + expectInfo << fileName << ":" << currDebugLocation.lineNumber << ":" + << currDebugLocation.columnNumber; + expectInfos[expectIndex] = expectInfo.str(); + } + curr->operands.back() = moduleBuilder.makeConst(wasm::Literal(expectIndex)); + expectIndex++; + } + + /* Function Call Mock */ + const auto functionRefsIterator = funcRefs.find(curr->target.str); + if (functionRefsIterator != funcRefs.end()) { + const wasm::Index localIdx = wasm::Builder::addVar(getFunction(), wasm::Type::i32); + const auto &[tableName, originFuncIdx] = functionRefsIterator->second; + const std::array callArgs = {moduleBuilder.makeConst(originFuncIdx), + moduleBuilder.makeConst(true)}; + wasm::If *const mockReplacement = moduleBuilder.makeIf( + moduleBuilder.makeBinary( + wasm::BinaryOp::NeInt32, + moduleBuilder.makeLocalTee(localIdx, + moduleBuilder.makeCall(checkMock, callArgs, wasm::Type::i32), + wasm::Type::i32), + moduleBuilder.makeConst(-1)), + moduleBuilder.makeCallIndirect( + tableName, moduleBuilder.makeLocalGet(localIdx, wasm::Type::i32), curr->operands, + getModule()->getFunction(curr->target)->type), + curr); + replaceCurrent(mockReplacement); + } +} + +void MockInstrumentationWalker::visitCallIndirect(wasm::CallIndirect *const curr) noexcept { + if (funcRefs.size() == 0U) { + return; + } + const std::array args = {curr->target, moduleBuilder.makeConst(false)}; + curr->target = moduleBuilder.makeCall(checkMock, args, wasm::Type::i32); +} + +bool MockInstrumentationWalker::mockFunctionDuplicateImportedCheck() const noexcept { + bool checkRepeat = false; + wasm::ModuleUtils::iterDefinedFunctions( + *module, [&checkRepeat, this](const BinaryenFunctionRef &func) noexcept { + if (func->name.str == this->checkMock) { + checkRepeat = true; + } + }); + wasm::ModuleUtils::iterImportedFunctions( + *module, [&checkRepeat, this](const BinaryenFunctionRef &func) noexcept { + if (func->name.str == this->checkMock) { + checkRepeat = true; + } + }); + if (!checkRepeat) { + std::array ii_ = + std::array{BinaryenTypeInt32(), BinaryenTypeInt32()}; + const BinaryenType ii = BinaryenTypeCreate(ii_.data(), ii_.size()); + BinaryenAddFunctionImport(module, this->checkMock.data(), "mockInstrument", "checkMock", ii, + BinaryenTypeInt32()); + } + return checkRepeat; +} + +uint32_t MockInstrumentationWalker::mockWalk() noexcept { + if (mockFunctionDuplicateImportedCheck()) { + return 1U; // failed + } else { + wasm::ModuleUtils::iterDefinedFunctions(*module, [this](wasm::Function *const func) noexcept { + if (!std::regex_match(func->name.str.begin(), func->name.str.end(), functionFilter)) { + walkFunctionInModule(func, this->module); + } + }); + return 0U; + } +} +// LCOV_EXCL_STOP +} // namespace wasmInstrumentation diff --git a/instrumentation/MockInstrumentationWalker.hpp b/instrumentation/MockInstrumentationWalker.hpp new file mode 100644 index 0000000..aedf2e3 --- /dev/null +++ b/instrumentation/MockInstrumentationWalker.hpp @@ -0,0 +1,158 @@ +#ifndef __ASC_COV_MOCKINSTRUMENTATION_WALKER_HPP__ +#define __ASC_COV_MOCKINSTRUMENTATION_WALKER_HPP__ +#include +#include +#include +#include +#include +#include +#include +#include +#include "binaryen-c.h" +#include "ir/module-utils.h" +#include "wasm-builder.h" +#include "wasm-traversal.h" +#include "wasm.h" +namespace wasmInstrumentation { +/// +///@brief Mock instrumentation walker class +/// +// mock test will be tested with wasm-testing-framework project, escape this class +// LCOV_EXCL_START +class MockInstrumentationWalker final : public wasm::PostWalker { +public: + /// + /// @brief Constructor for MockInstrumentationWalker + /// + /// @param _module + /// @param _checkMock + explicit MockInstrumentationWalker( + wasm::Module *const _module, + const std::string _checkMock = "mockInstrument/checkMock") noexcept + : module(_module), checkMock(_checkMock), moduleBuilder(wasm::Builder(*_module)) { + for (const auto &elemSegment : _module->elementSegments) { + if (elemSegment->type.isFunction()) { + const auto &data = elemSegment->data; + const size_t dataSize = data.size(); + for (std::size_t i = 0; i < dataSize; ++i) { + const wasm::RefFunc *funcRef = data[i]->cast(); + std::string_view functionName = funcRef->func.str; + const std::string_view nameSuffix = "@varargs"; + if (functionName.size() >= nameSuffix.size() && + std::equal(nameSuffix.begin(), nameSuffix.end(), + functionName.end() - nameSuffix.size())) { + functionName.remove_suffix(nameSuffix.size()); + } + funcRefs[functionName] = + std::make_pair(elemSegment->table, static_cast(i + 1)); + } + } + } + } + + MockInstrumentationWalker(const MockInstrumentationWalker &src) = delete; + MockInstrumentationWalker(MockInstrumentationWalker &&src) = delete; + MockInstrumentationWalker &operator=(const MockInstrumentationWalker &) = delete; + MockInstrumentationWalker &operator=(MockInstrumentationWalker &&) = delete; + /// + /// @brief Destructor for MockInstrumentationWalker + /// + ~MockInstrumentationWalker() noexcept = default; + /// + /// @brief Get expect infos + /// + /// @return expect infos, if assert fail, return the expect infos with debug info + const std::unordered_map &getExpectInfos() const noexcept { + return expectInfos; + } + + /// + /// @brief Visit call instruction + /// + /// @param curr Current expression reference + void visitCall(wasm::Call *const curr) noexcept; + + static void doPreVisit(MockInstrumentationWalker *self, wasm::Expression **currp) { + wasm::Expression *curr = *currp; + auto &locs = self->getFunction()->debugLocations; + auto &expressionStack = self->expressionStack; + if (locs.find(curr) == locs.end()) { + // No debug location, see if we should inherit one. + if (wasm::Expression *previous = self->getPrevious()) { + auto it = locs.find(previous); + if (it != locs.end()) { + locs[curr] = it->second; + } + } + } + expressionStack.push_back(curr); + } + + static void doPostVisit(MockInstrumentationWalker *self, wasm::Expression **currp) { + auto &exprStack = self->expressionStack; + while (exprStack.back() != *currp) { + // pop all the child expressions and keep current expression in stack. + exprStack.pop_back(); + } + } + + static void scan(MockInstrumentationWalker *self, wasm::Expression **currp) { + self->pushTask(MockInstrumentationWalker::doPostVisit, currp); + + PostWalker::scan(self, currp); + + self->pushTask(MockInstrumentationWalker::doPreVisit, currp); + } + + wasm::Expression *replaceCurrent(wasm::Expression *expression) { + PostWalker::replaceCurrent(expression); + // also update the stack + expressionStack.back() = expression; + return expression; + } + + wasm::Expression *getPrevious() { + if (expressionStack.empty()) { + return nullptr; + } + assert(expressionStack.size() >= 1); + return expressionStack[expressionStack.size() - 1]; + } + + /// + /// @brief Visit call indirect instruction + /// + /// @param curr Current expression reference + void visitCallIndirect(wasm::CallIndirect *const curr) noexcept; + + /// + /// @brief Check mock function duplicated + /// + /// @brief bool, true when the mock function is duplicated imported + bool mockFunctionDuplicateImportedCheck() const noexcept; + + /// + /// @brief Main API for mock instrumentation + /// + uint32_t mockWalk() noexcept; + +private: + wasm::Module *const module; ///< working module + const std::string checkMock; ///< mock check string + const std::regex functionFilter = std::regex("~lib/.+"); + wasm::Builder moduleBuilder; ///< module builder + uint32_t expectIndex = 0U; ///< expectation index, auto increase + wasm::ExpressionStack expressionStack; + std::unordered_map> + funcRefs; ///< cache function references + std::unordered_map expectInfos; ///< cache expectation infos + const std::vector expectTestFuncNames{ + "#isNull", "#notNull", "#equal", + "#notEqual", "#greaterThan", "#greaterThanOrEqual", + "#lessThan", "#lessThanOrEqual", "#closeTo"}; ///< expectation functions list +}; + +} // namespace wasmInstrumentation + +#endif +// LCOV_EXCL_STOP diff --git a/instrumentation/main.cpp b/instrumentation/main.cpp new file mode 100644 index 0000000..36df7ad --- /dev/null +++ b/instrumentation/main.cpp @@ -0,0 +1,43 @@ +#include +#include +#include "CoverageInstru.hpp" + +int main(int argc, char **argv) { + wasmInstrumentation::InstrumentationConfig config; + if (argc != 13) { + // print help documentation + std::cout << "wasm-instrumentation is a tool that instrument wasm binary " + "for code covareage report \n"; + std::cout << "-----------------------------\n"; + std::cout << "-i input wasm file\n"; + std::cout << "-o output file\n"; + std::cout << "-r report function name\n"; + std::cout << "-d debugInfo output file\n"; + std::cout << "-m source map file\n"; + std::cout << "-e expect codeInfo output file\n"; + std::cout << "-----------------------------\n"; + return 0; + } + for (int i = 1; i < argc; i = i + 2) { + if (strcmp(argv[i], "-i") == 0) { + config.fileName = argv[i + 1]; + } + if (strcmp(argv[i], "-o") == 0) { + config.targetName = argv[i + 1]; + } + if (strcmp(argv[i], "-d") == 0) { + config.debugInfoOutputFilePath = argv[i + 1]; + } + if (strcmp(argv[i], "-r") == 0) { + config.reportFunction = argv[i + 1]; + } + if (strcmp(argv[i], "-m") == 0) { + config.sourceMap = argv[i + 1]; + } + if (strcmp(argv[i], "-e") == 0) { + config.expectInfoOutputFilePath = argv[i + 1]; + } + } + wasmInstrumentation::CoverageInstru instrumenter(&config); + instrumenter.instrument(); +} diff --git a/package.json b/package.json index 64c429a..acd0134 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ }, "prettier": "@schleifner/prettier-config", "scripts": { - "build": "tsc --build ./transform/tsconfig.json && node ./build/esbuild.js", + "build": "tsc --build ./transform/tsconfig.json && node ./scripts/esbuild.js", "test": "node bin/as-test.js && cross-env NODE_OPTIONS=--experimental-vm-modules jest", "lint": "eslint src assembly tests/ts/test --max-warnings=0 && prettier -c .", "lint:fix": "eslint src assembly --fix", diff --git a/build/esbuild.js b/scripts/esbuild.js similarity index 70% rename from build/esbuild.js rename to scripts/esbuild.js index 0d74f12..5f3ab83 100644 --- a/build/esbuild.js +++ b/scripts/esbuild.js @@ -1,11 +1,18 @@ import { resolve } from "path"; import * as esbuild from "esbuild"; import { fileURLToPath, URL } from "url"; +import child_process from "node:child_process"; +import { promisify } from "node:util"; import pkg from "@sprout2000/esbuild-copy-plugin"; const { copyPlugin } = pkg; +const exec = promisify(child_process.exec); const __dirname = fileURLToPath(new URL(".", import.meta.url)); +await exec("tsc --build ./transform/tsconfig.json"); + +await exec("cmake -B build instrumentation -S instrumentation"); + await esbuild.build({ entryPoints: ["src/index.ts"], bundle: true, diff --git a/third_party/binaryen b/third_party/binaryen new file mode 160000 index 0000000..d9fa84a --- /dev/null +++ b/third_party/binaryen @@ -0,0 +1 @@ +Subproject commit d9fa84a038baaf0b25fb4822a00083f617b9c657 diff --git a/third_party/jsoncpp b/third_party/jsoncpp new file mode 160000 index 0000000..ba00447 --- /dev/null +++ b/third_party/jsoncpp @@ -0,0 +1 @@ +Subproject commit ba004477a6f260dedbe6ef6470b3760192e8d232 diff --git a/transform/listFunctions.mjs b/transform/listFunctions.mjs deleted file mode 100644 index 85bc832..0000000 --- a/transform/listFunctions.mjs +++ /dev/null @@ -1,453 +0,0 @@ -var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { - if (kind === "m") throw new TypeError("Private method is not writable"); - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); - return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; -}; -var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { - if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); -}; -var _SourceFunctionTransform_elementsByDeclaration; -import { Transform } from "assemblyscript/transform"; -class SourceFunctionTransform extends Transform { - constructor() { - super(...arguments); - this.functionInfos = []; - _SourceFunctionTransform_elementsByDeclaration.set(this, new Map()); - } - afterInitialize(program) { - __classPrivateFieldSet(this, _SourceFunctionTransform_elementsByDeclaration, program.elementsByDeclaration, "f"); - // There will be two sources with SourceKind.UserEntry, ~lib/rt/index-incremental.ts should be filtered - const entrySource = program.sources.find((source) => source.sourceKind === 1 /* SourceKind.UserEntry */ && !source.normalizedPath.startsWith("~lib/")); - this.visitNode(entrySource); - global.functionInfos = this.functionInfos.reverse(); - } - visitNode(node) { - switch (node.kind) { - case 0 /* NodeKind.Source */: { - this.visitSource(node); - break; - } - // types - case 1 /* NodeKind.NamedType */: - case 2 /* NodeKind.FunctionType */: - case 3 /* NodeKind.TypeName */: - case 4 /* NodeKind.TypeParameter */: { - break; - } - case 5 /* NodeKind.Parameter */: { - this.visitParameterNode(node); - break; - } - // Expressions - case 6 /* NodeKind.Identifier */: - case 13 /* NodeKind.False */: - case 16 /* NodeKind.Literal */: - case 18 /* NodeKind.Null */: - case 19 /* NodeKind.Omitted */: - case 23 /* NodeKind.Super */: - case 24 /* NodeKind.This */: - case 25 /* NodeKind.True */: - case 26 /* NodeKind.Constructor */: - case 29 /* NodeKind.Compiled */: { - break; - } - case 7 /* NodeKind.Assertion */: { - this.visitAssertionExpression(node); - break; - } - case 8 /* NodeKind.Binary */: { - this.visitBinaryExpression(node); - break; - } - case 9 /* NodeKind.Call */: { - this.visitCallExpression(node); - break; - } - case 10 /* NodeKind.Class */: { - this.visitClassExpression(node); - break; - } - case 11 /* NodeKind.Comma */: { - this.visitCommaExpression(node); - break; - } - case 12 /* NodeKind.ElementAccess */: { - this.visitElementAccessExpression(node); - break; - } - case 14 /* NodeKind.Function */: { - this.visitFunctionExpression(node); - break; - } - case 15 /* NodeKind.InstanceOf */: { - this.visitInstanceOfExpression(node); - break; - } - case 17 /* NodeKind.New */: { - this.visitNewExpression(node); - break; - } - case 20 /* NodeKind.Parenthesized */: { - this.visitParenthesizedExpression(node); - break; - } - case 21 /* NodeKind.PropertyAccess */: { - this.visitPropertyAccessExpression(node); - break; - } - case 22 /* NodeKind.Ternary */: { - this.visitTernaryExpression(node); - break; - } - case 27 /* NodeKind.UnaryPostfix */: { - this.visitUnaryPostfixExpression(node); - break; - } - case 28 /* NodeKind.UnaryPrefix */: { - this.visitUnaryPrefixExpression(node); - break; - } - // statements: - case 31 /* NodeKind.Break */: - case 34 /* NodeKind.Empty */: - case 35 /* NodeKind.Export */: - case 36 /* NodeKind.ExportDefault */: - case 37 /* NodeKind.ExportImport */: - case 32 /* NodeKind.Continue */: - case 42 /* NodeKind.Import */: - case 50 /* NodeKind.Module */: { - break; - } - case 30 /* NodeKind.Block */: { - this.visitBlockStatement(node); - break; - } - case 33 /* NodeKind.Do */: { - this.visitDoStatement(node); - break; - } - case 38 /* NodeKind.Expression */: { - this.visitExpressionStatement(node); - break; - } - case 39 /* NodeKind.For */: { - this.visitForStatement(node); - break; - } - case 40 /* NodeKind.ForOf */: { - this.visitForOfStatement(node); - break; - } - case 41 /* NodeKind.If */: { - this.visitIfStatement(node); - break; - } - case 43 /* NodeKind.Return */: { - this.visitReturnStatement(node); - break; - } - case 44 /* NodeKind.Switch */: { - this.visitSwitchStatement(node); - break; - } - case 45 /* NodeKind.Throw */: { - this.visitThrowStatement(node); - break; - } - case 46 /* NodeKind.Try */: { - this.visitTryStatement(node); - break; - } - case 47 /* NodeKind.Variable */: { - this.visitVariableStatement(node); - break; - } - case 48 /* NodeKind.Void */: { - this.visitVoidStatement(node); - break; - } - case 49 /* NodeKind.While */: { - this.visitWhileStatement(node); - break; - } - // declaration statements - case 56 /* NodeKind.ImportDeclaration */: - case 60 /* NodeKind.TypeDeclaration */: { - break; - } - case 51 /* NodeKind.ClassDeclaration */: { - this.visitClassDeclaration(node); - break; - } - case 52 /* NodeKind.EnumDeclaration */: { - this.visitEnumDeclaration(node); - break; - } - case 53 /* NodeKind.EnumValueDeclaration */: { - this.visitEnumValueDeclaration(node); - break; - } - case 54 /* NodeKind.FieldDeclaration */: { - this.visitFieldDeclaration(node); - break; - } - case 55 /* NodeKind.FunctionDeclaration */: { - this.visitFunctionDeclaration(node); - break; - } - case 57 /* NodeKind.InterfaceDeclaration */: { - this.visitInterfaceDeclaration(node); - break; - } - case 58 /* NodeKind.MethodDeclaration */: { - this.visitMethodDeclaration(node); - break; - } - case 59 /* NodeKind.NamespaceDeclaration */: { - this.visitNamespaceDeclaration(node); - break; - } - case 61 /* NodeKind.VariableDeclaration */: { - this.visitVariableDeclaration(node); - break; - } - // special - case 63 /* NodeKind.ExportMember */: - case 65 /* NodeKind.IndexSignature */: - case 66 /* NodeKind.Comment */: - case 62 /* NodeKind.Decorator */: { - break; - } - case 64 /* NodeKind.SwitchCase */: { - this.visitSwitchCase(node); - break; - } - } - } - visitSource(node) { - for (const statement of node.statements) { - this.visitNode(statement); - } - } - visitParameterNode(node) { - if (node.initializer) { - this.visitNode(node.initializer); - } - } - visitAssertionExpression(node) { - this.visitNode(node.expression); - } - visitBinaryExpression(node) { - this.visitNode(node.left); - this.visitNode(node.right); - } - visitCallExpression(node) { - this.visitNode(node.expression); - for (const arg of node.args) { - this.visitNode(arg); - } - } - visitClassExpression(node) { - this.visitClassDeclaration(node.declaration); - } - visitCommaExpression(node) { - for (const expr of node.expressions) { - this.visitNode(expr); - } - } - visitElementAccessExpression(node) { - this.visitNode(node.expression); - this.visitNode(node.elementExpression); - } - visitFunctionExpression(node) { - this.visitFunctionDeclaration(node.declaration); - } - visitInstanceOfExpression(node) { - this.visitNode(node.expression); - } - visitNewExpression(node) { - for (const arg of node.args) { - this.visitNode(arg); - } - } - visitParenthesizedExpression(node) { - this.visitNode(node.expression); - } - visitPropertyAccessExpression(node) { - this.visitNode(node.expression); - } - visitTernaryExpression(node) { - this.visitNode(node.condition); - this.visitNode(node.ifThen); - this.visitNode(node.ifElse); - } - visitUnaryPostfixExpression(node) { - this.visitNode(node.operand); - } - visitUnaryPrefixExpression(node) { - this.visitNode(node.operand); - } - visitBlockStatement(node) { - for (const statement of node.statements) { - this.visitNode(statement); - } - } - visitDoStatement(node) { - this.visitNode(node.body); - this.visitNode(node.condition); - } - visitExpressionStatement(node) { - this.visitNode(node.expression); - } - visitForStatement(node) { - if (node.initializer) { - this.visitNode(node.initializer); - } - if (node.condition) { - this.visitNode(node.condition); - } - if (node.incrementor) { - this.visitNode(node.incrementor); - } - this.visitNode(node.body); - } - visitForOfStatement(node) { - this.visitNode(node.variable); - this.visitNode(node.iterable); - this.visitNode(node.body); - } - visitIfStatement(node) { - this.visitNode(node.condition); - this.visitNode(node.ifTrue); - if (node.ifFalse) { - this.visitNode(node.ifFalse); - } - } - visitReturnStatement(node) { - if (node.value) { - this.visitNode(node.value); - } - } - visitSwitchStatement(node) { - this.visitNode(node.condition); - for (const switchCase of node.cases) { - this.visitSwitchCase(switchCase); - } - } - visitThrowStatement(node) { - this.visitNode(node.value); - } - visitTryStatement(node) { - for (const stat of node.bodyStatements) { - this.visitNode(stat); - } - if (node.catchStatements) { - for (const stat of node.catchStatements) { - this.visitNode(stat); - } - } - if (node.finallyStatements) { - for (const stat of node.finallyStatements) { - this.visitNode(stat); - } - } - } - visitVariableStatement(node) { - for (const declaration of node.declarations) { - this.visitVariableDeclaration(declaration); - } - } - visitVoidStatement(node) { - this.visitNode(node.expression); - } - visitWhileStatement(node) { - this.visitNode(node.condition); - this.visitNode(node.body); - } - visitClassDeclaration(node) { - for (const member of node.members) { - this.visitNode(member); - } - } - visitEnumDeclaration(node) { - for (const value of node.values) { - this.visitEnumValueDeclaration(value); - } - } - visitEnumValueDeclaration(node) { - if (node.initializer) { - this.visitNode(node.initializer); - } - } - visitFieldDeclaration(node) { - if (node.initializer) { - this.visitNode(node.initializer); - } - } - visitFunctionDeclaration(node) { - var _a, _b; - if (!(node.flags & (32768 /* CommonFlags.Ambient */ | 128 /* CommonFlags.Abstract */))) { - let startLine, endLine; - // startLine is the first Line of Function.body, same as endLine - if (node.body) { - if (node.body.kind === 30 /* NodeKind.Block */ && node.body.statements.length > 0) { - const bodyStatement = node.body.statements; - const startStat = bodyStatement[0]; - startLine = startStat.range.source.lineAt(startStat.range.start); - const endStat = bodyStatement.at(-1); - endLine = endStat.range.source.lineAt(endStat.range.end); - } - else { - if (node.flags & 524288 /* CommonFlags.Constructor */) { - // do not count constructor without any statements - return; - } - const LineRange = node.body.range; - startLine = LineRange.source.lineAt(LineRange.start); - endLine = LineRange.source.lineAt(LineRange.end); - } - } - else { - const LineRange = node.range; - startLine = LineRange.source.lineAt(LineRange.start); - endLine = LineRange.source.lineAt(LineRange.end); - } - this.functionInfos.push({ - name: (_b = (_a = __classPrivateFieldGet(this, _SourceFunctionTransform_elementsByDeclaration, "f").get(node)) === null || _a === void 0 ? void 0 : _a.internalName) !== null && _b !== void 0 ? _b : node.name.text, - range: [startLine, endLine], - }); - } - if (node.body) { - this.visitNode(node.body); - } - } - visitInterfaceDeclaration(node) { - this.visitClassDeclaration(node); - } - visitMethodDeclaration(node) { - this.visitFunctionDeclaration(node); - } - visitNamespaceDeclaration(node) { - for (const member of node.members) { - this.visitNode(member); - } - } - visitVariableDeclaration(node) { - if (node.initializer) { - this.visitNode(node.initializer); - } - } - visitSwitchCase(node) { - if (node.label) { - this.visitNode(node.label); - } - for (const stat of node.statements) { - this.visitNode(stat); - } - } -} -_SourceFunctionTransform_elementsByDeclaration = new WeakMap(); -export default SourceFunctionTransform; From 4eac3bc75eaf7426922409b07493d6fc2b97d5d7 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 17:09:28 +0800 Subject: [PATCH 04/14] wip --- CMakeLists.txt | 21 +++++++++++++++++++++ instrumentation/CMakeLists.txt | 20 ++------------------ package.json | 2 +- scripts/esbuild.js | 16 +++++++++++----- third_party/binaryen | 2 +- third_party/jsoncpp | 2 +- 6 files changed, 37 insertions(+), 26 deletions(-) create mode 100644 CMakeLists.txt diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..346a742 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.15) +project(instrumentation) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) +endif() + +set(JSONCPP_WITH_TESTS OFF) +set(BUILD_STATIC_LIBS ON) +set(BUILD_SHARED_LIBS OFF) +set(BUILD_OBJECT_LIBS OFF) +add_subdirectory(third_party/jsoncpp) + +set(BUILD_TESTS OFF) +set(BUILD_STATIC_LIB ON) +add_subdirectory(third_party/binaryen) + +add_subdirectory(instrumentation) diff --git a/instrumentation/CMakeLists.txt b/instrumentation/CMakeLists.txt index 8635298..94c669b 100644 --- a/instrumentation/CMakeLists.txt +++ b/instrumentation/CMakeLists.txt @@ -1,23 +1,9 @@ -cmake_minimum_required(VERSION 3.5) -project(instrumentation VERSION 0.1.0) - -set(CMAKE_CXX_STANDARD 23) - -set(JSONCPP_WITH_TESTS OFF) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/jsoncpp) - -set(BUILD_TESTS 0) -set(BUILD_STATIC_LIBS ON) -set(BUILD_SHARED_LIBS OFF) -set(BUILD_OBJECT_LIBS OFF) -add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../third_party/binaryen) - -aux_source_directory(${CMAKE_CURRENT_LIST_DIR}/src sources) +aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} sources) add_executable(wasm-instrumentation ${sources}) target_link_libraries(wasm-instrumentation binaryen jsoncpp_static) -target_include_directories(wasm-instrumentation SYSTEM PRIVATE ${CMAKE_CURRENT_LIST_DIR}/thirdparty/binaryen/src ${CMAKE_CURRENT_LIST_DIR}/thirdparty/jsoncpp/include) +target_include_directories(wasm-instrumentation SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/third_party/binaryen/src ${PROJECT_SOURCE_DIR}/third_party/jsoncpp/include) if(EMSCRIPTEN) target_link_libraries(wasm-instrumentation "-sSINGLE_FILE") @@ -35,5 +21,3 @@ if(EMSCRIPTEN) target_link_libraries(wasm-instrumentation "-sEXPORTED_FUNCTIONS=_malloc,_free") else() endif() - -add_executable(wasm-instrumentation main.cpp ${sources}) diff --git a/package.json b/package.json index acd0134..5a66655 100644 --- a/package.json +++ b/package.json @@ -73,8 +73,8 @@ "assembly/**/*", "bin/**/*", "dist/**/*", + "build/bin/wasm-instrumentation.js", "docs/**/*", - "example/**/*", "transform/**/*", "LICENSE", "README.md" diff --git a/scripts/esbuild.js b/scripts/esbuild.js index 5f3ab83..0535db2 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -1,17 +1,23 @@ import { resolve } from "path"; import * as esbuild from "esbuild"; import { fileURLToPath, URL } from "url"; -import child_process from "node:child_process"; -import { promisify } from "node:util"; +import { execSync } from "node:child_process"; import pkg from "@sprout2000/esbuild-copy-plugin"; const { copyPlugin } = pkg; -const exec = promisify(child_process.exec); const __dirname = fileURLToPath(new URL(".", import.meta.url)); -await exec("tsc --build ./transform/tsconfig.json"); +execSync("tsc --build ./transform/tsconfig.json"); -await exec("cmake -B build instrumentation -S instrumentation"); +function emsdkEnv() { + return { + env: "/Users/q540239/dev/emsdk:/Users/q540239/dev/emsdk/upstream/emscripten:" + process.env["PATH"], + ...process.env, + }; +} + +execSync("emcmake cmake -B build -S .", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); +execSync("cmake --build build --target wasm-instrumentation", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); await esbuild.build({ entryPoints: ["src/index.ts"], diff --git a/third_party/binaryen b/third_party/binaryen index d9fa84a..11dba9b 160000 --- a/third_party/binaryen +++ b/third_party/binaryen @@ -1 +1 @@ -Subproject commit d9fa84a038baaf0b25fb4822a00083f617b9c657 +Subproject commit 11dba9b1c2ad988500b329727f39f4d8786918c5 diff --git a/third_party/jsoncpp b/third_party/jsoncpp index ba00447..8190e06 160000 --- a/third_party/jsoncpp +++ b/third_party/jsoncpp @@ -1 +1 @@ -Subproject commit ba004477a6f260dedbe6ef6470b3760192e8d232 +Subproject commit 8190e061bc2d95da37479a638aa2c9e483e58ec6 From 3be4990772110d7403c665532d92e093793356a5 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 17:18:47 +0800 Subject: [PATCH 05/14] wip --- package-lock.json | 8 +------- package.json | 3 +-- scripts/esbuild.js | 1 + src/core/instrument.ts | 2 +- 4 files changed, 4 insertions(+), 10 deletions(-) diff --git a/package-lock.json b/package-lock.json index f3f0617..63d8ebc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,8 +17,7 @@ "fs-extra": "^11.1.1", "glob": "^10.2.6", "ignore": "^5.2.4", - "semver": "^7.5.3", - "wasm-instrumentation": "1.1.0" + "semver": "^7.5.3" }, "bin": { "as-test": "bin/as-test.js" @@ -9590,11 +9589,6 @@ "makeerror": "1.0.12" } }, - "node_modules/wasm-instrumentation": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/wasm-instrumentation/-/wasm-instrumentation-1.1.0.tgz", - "integrity": "sha512-yWgLKQUgMyh7+ms0FZYfXhPircmrIzCiKv/GQHuGXuoHM/OMvpnXEXvyKrZA56IPswY8lPeUt+Te5UkJas099A==" - }, "node_modules/watchpack": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", diff --git a/package.json b/package.json index 5a66655..2429dfe 100644 --- a/package.json +++ b/package.json @@ -27,8 +27,7 @@ "fs-extra": "^11.1.1", "glob": "^10.2.6", "ignore": "^5.2.4", - "semver": "^7.5.3", - "wasm-instrumentation": "1.1.0" + "semver": "^7.5.3" }, "peerDependencies": { "assemblyscript": ">=0.25.1" diff --git a/scripts/esbuild.js b/scripts/esbuild.js index 0535db2..d82b086 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -18,6 +18,7 @@ function emsdkEnv() { execSync("emcmake cmake -B build -S .", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); execSync("cmake --build build --target wasm-instrumentation", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); +execSync("tsc build/bin/wasm-instrumentation.js --declaration --allowJs --emitDeclarationOnly --outDir build/bin"); await esbuild.build({ entryPoints: ["src/index.ts"], diff --git a/src/core/instrument.ts b/src/core/instrument.ts index 68a7a03..755ada1 100644 --- a/src/core/instrument.ts +++ b/src/core/instrument.ts @@ -1,4 +1,4 @@ -import initInstrumenter from "wasm-instrumentation"; +import initInstrumenter from "../../build/bin/wasm-instrumentation.js"; import { InstrumentResult } from "../interface.js"; export async function instrument(sourceWasms: string[], sourceCodePaths: string[]): Promise { From 717d56faba9bbdb61aa90889a12563374153a4aa Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 17:51:25 +0800 Subject: [PATCH 06/14] wip --- CMakeLists.txt | 6 +- instrumentation/main.cpp | 43 ----- package.json | 2 +- scripts/esbuild.js | 12 +- src/core/instrument.ts | 2 +- tests/cpp/CMakeLists.txt | 54 +++++++ tests/cpp/check.py | 22 +++ tests/cpp/e2e.cpp | 60 +++++++ tests/cpp/fuzz.cpp | 34 ++++ tests/cpp/fuzz/assemblyscript.debug.wasm | Bin 0 -> 1782599 bytes tests/cpp/fuzz/assemblyscript.debug.wasm.map | 1 + tests/cpp/lit.cpp | 121 ++++++++++++++ tests/cpp/lit/build/do_while.wast.debug.json | 1 + tests/cpp/lit/build/do_while.wast.expect.json | 1 + .../lit/build/do_while.wast.instrumented.wasm | Bin 0 -> 183 bytes tests/cpp/lit/build/do_while.wast.out.wasm | Bin 0 -> 111 bytes .../cpp/lit/build/do_while.wast.out.wasm.map | 1 + tests/cpp/lit/build/do_while.wast.run.log | 11 ++ .../lit/build/do_while_break.wast.debug.json | 1 + .../lit/build/do_while_break.wast.expect.json | 1 + .../do_while_break.wast.instrumented.wasm | Bin 0 -> 223 bytes .../lit/build/do_while_break.wast.out.wasm | Bin 0 -> 124 bytes .../build/do_while_break.wast.out.wasm.map | 1 + .../cpp/lit/build/do_while_break.wast.run.log | 14 ++ .../build/do_while_continue.wast.debug.json | 1 + .../build/do_while_continue.wast.expect.json | 1 + .../do_while_continue.wast.instrumented.wasm | Bin 0 -> 220 bytes .../lit/build/do_while_continue.wast.out.wasm | Bin 0 -> 124 bytes .../build/do_while_continue.wast.out.wasm.map | 1 + .../lit/build/do_while_continue.wast.run.log | 11 ++ .../lit/build/do_while_once.wast.debug.json | 1 + .../lit/build/do_while_once.wast.expect.json | 1 + .../do_while_once.wast.instrumented.wasm | Bin 0 -> 273 bytes .../cpp/lit/build/do_while_once.wast.out.wasm | Bin 0 -> 141 bytes .../lit/build/do_while_once.wast.out.wasm.map | 1 + .../cpp/lit/build/do_while_once.wast.run.log | 9 ++ .../lit/build/exit_basicBlock.wast.debug.json | 1 + .../build/exit_basicBlock.wast.expect.json | 1 + .../exit_basicBlock.wast.instrumented.wasm | Bin 0 -> 207 bytes .../lit/build/exit_basicBlock.wast.out.wasm | Bin 0 -> 131 bytes .../build/exit_basicBlock.wast.out.wasm.map | 1 + .../lit/build/exit_basicBlock.wast.run.log | 5 + tests/cpp/lit/build/expect.test.debug.json | 1 + tests/cpp/lit/build/expect.test.expect.json | 1 + .../lit/build/expect.test.instrumented.wasm | Bin 0 -> 41011 bytes tests/cpp/lit/build/for_loop.wast.debug.json | 1 + tests/cpp/lit/build/for_loop.wast.expect.json | 1 + .../lit/build/for_loop.wast.instrumented.wasm | Bin 0 -> 210 bytes tests/cpp/lit/build/for_loop.wast.out.wasm | Bin 0 -> 130 bytes .../cpp/lit/build/for_loop.wast.out.wasm.map | 1 + tests/cpp/lit/build/for_loop.wast.run.log | 15 ++ .../lit/build/for_loop_break.wast.debug.json | 1 + .../lit/build/for_loop_break.wast.expect.json | 1 + .../for_loop_break.wast.instrumented.wasm | Bin 0 -> 244 bytes .../lit/build/for_loop_break.wast.out.wasm | Bin 0 -> 135 bytes .../build/for_loop_break.wast.out.wasm.map | 1 + .../cpp/lit/build/for_loop_break.wast.run.log | 25 +++ .../build/for_loop_continue.wast.debug.json | 1 + .../build/for_loop_continue.wast.expect.json | 1 + .../for_loop_continue.wast.instrumented.wasm | Bin 0 -> 244 bytes .../lit/build/for_loop_continue.wast.out.wasm | Bin 0 -> 138 bytes .../build/for_loop_continue.wast.out.wasm.map | 1 + .../lit/build/for_loop_continue.wast.run.log | 13 ++ .../lit/build/for_loop_return.wast.debug.json | 1 + .../build/for_loop_return.wast.expect.json | 1 + .../for_loop_return.wast.instrumented.wasm | Bin 0 -> 229 bytes .../lit/build/for_loop_return.wast.out.wasm | Bin 0 -> 133 bytes .../build/for_loop_return.wast.out.wasm.map | 1 + .../lit/build/for_loop_return.wast.run.log | 23 +++ tests/cpp/lit/build/if_else.wast.debug.json | 1 + tests/cpp/lit/build/if_else.wast.expect.json | 1 + .../lit/build/if_else.wast.instrumented.wasm | Bin 0 -> 175 bytes tests/cpp/lit/build/if_else.wast.out.wasm | Bin 0 -> 96 bytes tests/cpp/lit/build/if_else.wast.out.wasm.map | 1 + tests/cpp/lit/build/if_else.wast.run.log | 4 + .../lit/build/if_elseif_else.wast.debug.json | 1 + .../lit/build/if_elseif_else.wast.expect.json | 1 + .../if_elseif_else.wast.instrumented.wasm | Bin 0 -> 220 bytes .../lit/build/if_elseif_else.wast.out.wasm | Bin 0 -> 125 bytes .../build/if_elseif_else.wast.out.wasm.map | 1 + .../cpp/lit/build/if_elseif_else.wast.run.log | 5 + .../if_elseif_empty_else.wast.debug.json | 1 + .../if_elseif_empty_else.wast.expect.json | 1 + ...f_elseif_empty_else.wast.instrumented.wasm | Bin 0 -> 205 bytes .../build/if_elseif_empty_else.wast.out.wasm | Bin 0 -> 118 bytes .../if_elseif_empty_else.wast.out.wasm.map | 1 + .../build/if_elseif_empty_else.wast.run.log | 4 + .../lit/build/if_empty_else.wast.debug.json | 1 + .../lit/build/if_empty_else.wast.expect.json | 1 + .../if_empty_else.wast.instrumented.wasm | Bin 0 -> 162 bytes .../cpp/lit/build/if_empty_else.wast.out.wasm | Bin 0 -> 91 bytes .../lit/build/if_empty_else.wast.out.wasm.map | 1 + .../cpp/lit/build/if_empty_else.wast.run.log | 4 + .../build/if_multi_condition.wast.debug.json | 1 + .../build/if_multi_condition.wast.expect.json | 1 + .../if_multi_condition.wast.instrumented.wasm | Bin 0 -> 269 bytes .../build/if_multi_condition.wast.out.wasm | Bin 0 -> 124 bytes .../if_multi_condition.wast.out.wasm.map | 1 + .../lit/build/if_multi_condition.wast.run.log | 8 + .../lit/build/include_exclude.wast.debug.json | 1 + .../build/include_exclude.wast.expect.json | 1 + .../include_exclude.wast.instrumented.wasm | Bin 0 -> 206 bytes .../lit/build/include_exclude.wast.out.wasm | Bin 0 -> 142 bytes .../build/include_exclude.wast.out.wasm.map | 1 + .../lit/build/include_exclude.wast.run.log | 4 + .../cpp/lit/build/multi_func.wast.debug.json | 1 + .../cpp/lit/build/multi_func.wast.expect.json | 1 + .../build/multi_func.wast.instrumented.wasm | Bin 0 -> 327 bytes tests/cpp/lit/build/multi_func.wast.out.wasm | Bin 0 -> 309 bytes .../lit/build/multi_func.wast.out.wasm.map | 1 + tests/cpp/lit/build/multi_func.wast.run.log | 10 ++ .../lit/build/multi_if_else.wast.debug.json | 1 + .../lit/build/multi_if_else.wast.expect.json | 1 + .../multi_if_else.wast.instrumented.wasm | Bin 0 -> 236 bytes .../cpp/lit/build/multi_if_else.wast.out.wasm | Bin 0 -> 131 bytes .../lit/build/multi_if_else.wast.out.wasm.map | 1 + .../cpp/lit/build/multi_if_else.wast.run.log | 5 + .../cpp/lit/build/switch_case.wast.debug.json | 1 + .../lit/build/switch_case.wast.expect.json | 1 + .../build/switch_case.wast.instrumented.wasm | Bin 0 -> 295 bytes tests/cpp/lit/build/switch_case.wast.out.wasm | Bin 0 -> 277 bytes .../lit/build/switch_case.wast.out.wasm.map | 1 + tests/cpp/lit/build/switch_case.wast.run.log | 6 + .../switch_case_fallthrough.wast.debug.json | 1 + .../switch_case_fallthrough.wast.expect.json | 1 + ...ch_case_fallthrough.wast.instrumented.wasm | Bin 0 -> 277 bytes .../switch_case_fallthrough.wast.out.wasm | Bin 0 -> 301 bytes .../switch_case_fallthrough.wast.out.wasm.map | 1 + .../switch_case_fallthrough.wast.run.log | 6 + .../switch_case_rdefault.wast.debug.json | 1 + .../switch_case_rdefault.wast.expect.json | 1 + ...witch_case_rdefault.wast.instrumented.wasm | Bin 0 -> 301 bytes .../build/switch_case_rdefault.wast.out.wasm | Bin 0 -> 310 bytes .../switch_case_rdefault.wast.out.wasm.map | 1 + .../build/switch_case_rdefault.wast.run.log | 5 + tests/cpp/lit/build/while.wast.debug.json | 1 + tests/cpp/lit/build/while.wast.expect.json | 1 + .../lit/build/while.wast.instrumented.wasm | Bin 0 -> 207 bytes tests/cpp/lit/build/while.wast.out.wasm | Bin 0 -> 124 bytes tests/cpp/lit/build/while.wast.out.wasm.map | 1 + tests/cpp/lit/build/while.wast.run.log | 19 +++ .../cpp/lit/build/while_break.wast.debug.json | 1 + .../lit/build/while_break.wast.expect.json | 1 + .../build/while_break.wast.instrumented.wasm | Bin 0 -> 243 bytes tests/cpp/lit/build/while_break.wast.out.wasm | Bin 0 -> 134 bytes .../lit/build/while_break.wast.out.wasm.map | 1 + tests/cpp/lit/build/while_break.wast.run.log | 19 +++ .../lit/build/while_continue.wast.debug.json | 1 + .../lit/build/while_continue.wast.expect.json | 1 + .../while_continue.wast.instrumented.wasm | Bin 0 -> 234 bytes .../lit/build/while_continue.wast.out.wasm | Bin 0 -> 134 bytes .../build/while_continue.wast.out.wasm.map | 1 + .../cpp/lit/build/while_continue.wast.run.log | 14 ++ tests/cpp/lit/covInstrument/do_while.wast | 42 +++++ .../covInstrument/do_while.wast.debug.json | 70 ++++++++ .../lit/covInstrument/do_while.wast.run.log | 11 ++ .../cpp/lit/covInstrument/do_while_break.wast | 55 +++++++ .../do_while_break.wast.debug.json | 104 ++++++++++++ .../covInstrument/do_while_break.wast.run.log | 14 ++ .../lit/covInstrument/do_while_continue.wast | 55 +++++++ .../do_while_continue.wast.debug.json | 104 ++++++++++++ .../do_while_continue.wast.run.log | 11 ++ .../cpp/lit/covInstrument/do_while_once.wast | 79 +++++++++ .../do_while_once.wast.debug.json | 148 +++++++++++++++++ .../covInstrument/do_while_once.wast.run.log | 9 ++ .../lit/covInstrument/exit_basicBlock.wast | 30 ++++ .../exit_basicBlock.wast.debug.json | 70 ++++++++ .../exit_basicBlock.wast.run.log | 5 + tests/cpp/lit/covInstrument/for_loop.wast | 62 +++++++ .../covInstrument/for_loop.wast.debug.json | 92 +++++++++++ .../lit/covInstrument/for_loop.wast.run.log | 15 ++ .../cpp/lit/covInstrument/for_loop_break.wast | 66 ++++++++ .../for_loop_break.wast.debug.json | 116 ++++++++++++++ .../covInstrument/for_loop_break.wast.run.log | 25 +++ .../lit/covInstrument/for_loop_continue.wast | 71 ++++++++ .../for_loop_continue.wast.debug.json | 121 ++++++++++++++ .../for_loop_continue.wast.run.log | 13 ++ .../lit/covInstrument/for_loop_return.wast | 66 ++++++++ .../for_loop_return.wast.debug.json | 109 +++++++++++++ .../for_loop_return.wast.run.log | 23 +++ tests/cpp/lit/covInstrument/if_else.wast | 28 ++++ .../lit/covInstrument/if_else.wast.debug.json | 1 + .../lit/covInstrument/if_else.wast.run.log | 4 + .../cpp/lit/covInstrument/if_elseif_else.wast | 63 ++++++++ .../if_elseif_else.wast.debug.json | 1 + .../covInstrument/if_elseif_else.wast.run.log | 5 + .../covInstrument/if_elseif_empty_else.wast | 54 +++++++ .../if_elseif_empty_else.wast.debug.json | 1 + .../if_elseif_empty_else.wast.run.log | 4 + .../cpp/lit/covInstrument/if_empty_else.wast | 24 +++ .../if_empty_else.wast.debug.json | 1 + .../covInstrument/if_empty_else.wast.run.log | 4 + .../lit/covInstrument/if_multi_condition.wast | 57 +++++++ .../if_multi_condition.wast.debug.json | 121 ++++++++++++++ .../if_multi_condition.wast.run.log | 8 + .../lit/covInstrument/include_exclude.wast | 42 +++++ .../include_exclude.wast.debug.json | 1 + .../include_exclude.wast.run.log | 4 + tests/cpp/lit/covInstrument/multi_func.wast | 75 +++++++++ .../covInstrument/multi_func.wast.debug.json | 1 + .../lit/covInstrument/multi_func.wast.run.log | 10 ++ .../cpp/lit/covInstrument/multi_if_else.wast | 68 ++++++++ .../multi_if_else.wast.debug.json | 1 + .../covInstrument/multi_if_else.wast.run.log | 5 + tests/cpp/lit/covInstrument/switch_case.wast | 100 ++++++++++++ .../covInstrument/switch_case.wast.debug.json | 151 ++++++++++++++++++ .../covInstrument/switch_case.wast.run.log | 6 + .../switch_case_fallthrough.wast | 85 ++++++++++ .../switch_case_fallthrough.wast.debug.json | 139 ++++++++++++++++ .../switch_case_fallthrough.wast.run.log | 6 + .../covInstrument/switch_case_rdefault.wast | 107 +++++++++++++ .../switch_case_rdefault.wast.debug.json | 1 + .../switch_case_rdefault.wast.run.log | 5 + tests/cpp/lit/covInstrument/while.wast | 56 +++++++ .../lit/covInstrument/while.wast.debug.json | 87 ++++++++++ .../cpp/lit/covInstrument/while.wast.run.log | 19 +++ tests/cpp/lit/covInstrument/while_break.wast | 67 ++++++++ .../covInstrument/while_break.wast.debug.json | 116 ++++++++++++++ .../covInstrument/while_break.wast.run.log | 19 +++ .../cpp/lit/covInstrument/while_continue.wast | 67 ++++++++ .../while_continue.wast.debug.json | 114 +++++++++++++ .../covInstrument/while_continue.wast.run.log | 14 ++ .../expectInstrument/expect.test.expect.json | 1 + .../cpp/lit/expectInstrument/expect.test.wasm | Bin 0 -> 59010 bytes .../lit/expectInstrument/expect.test.wasm.map | 1 + tests/cpp/lit/run.cjs | 110 +++++++++++++ tests/cpp/main.cpp | 6 + tests/cpp/test-asc/asconfig.json | 15 ++ tests/cpp/test-asc/assembly/index.ts | 8 + tests/cpp/test-asc/package.json | 15 ++ tests/cpp/test-asc/run.cjs | 110 +++++++++++++ tests/cpp/utils/utils.cpp | 65 ++++++++ tests/cpp/utils/utils.h | 36 +++++ 233 files changed, 4313 insertions(+), 49 deletions(-) delete mode 100644 instrumentation/main.cpp create mode 100644 tests/cpp/CMakeLists.txt create mode 100644 tests/cpp/check.py create mode 100644 tests/cpp/e2e.cpp create mode 100644 tests/cpp/fuzz.cpp create mode 100644 tests/cpp/fuzz/assemblyscript.debug.wasm create mode 100644 tests/cpp/fuzz/assemblyscript.debug.wasm.map create mode 100644 tests/cpp/lit.cpp create mode 100644 tests/cpp/lit/build/do_while.wast.debug.json create mode 100644 tests/cpp/lit/build/do_while.wast.expect.json create mode 100644 tests/cpp/lit/build/do_while.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/do_while.wast.out.wasm create mode 100644 tests/cpp/lit/build/do_while.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/do_while.wast.run.log create mode 100644 tests/cpp/lit/build/do_while_break.wast.debug.json create mode 100644 tests/cpp/lit/build/do_while_break.wast.expect.json create mode 100644 tests/cpp/lit/build/do_while_break.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/do_while_break.wast.out.wasm create mode 100644 tests/cpp/lit/build/do_while_break.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/do_while_break.wast.run.log create mode 100644 tests/cpp/lit/build/do_while_continue.wast.debug.json create mode 100644 tests/cpp/lit/build/do_while_continue.wast.expect.json create mode 100644 tests/cpp/lit/build/do_while_continue.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/do_while_continue.wast.out.wasm create mode 100644 tests/cpp/lit/build/do_while_continue.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/do_while_continue.wast.run.log create mode 100644 tests/cpp/lit/build/do_while_once.wast.debug.json create mode 100644 tests/cpp/lit/build/do_while_once.wast.expect.json create mode 100644 tests/cpp/lit/build/do_while_once.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/do_while_once.wast.out.wasm create mode 100644 tests/cpp/lit/build/do_while_once.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/do_while_once.wast.run.log create mode 100644 tests/cpp/lit/build/exit_basicBlock.wast.debug.json create mode 100644 tests/cpp/lit/build/exit_basicBlock.wast.expect.json create mode 100644 tests/cpp/lit/build/exit_basicBlock.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/exit_basicBlock.wast.out.wasm create mode 100644 tests/cpp/lit/build/exit_basicBlock.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/exit_basicBlock.wast.run.log create mode 100644 tests/cpp/lit/build/expect.test.debug.json create mode 100644 tests/cpp/lit/build/expect.test.expect.json create mode 100644 tests/cpp/lit/build/expect.test.instrumented.wasm create mode 100644 tests/cpp/lit/build/for_loop.wast.debug.json create mode 100644 tests/cpp/lit/build/for_loop.wast.expect.json create mode 100644 tests/cpp/lit/build/for_loop.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/for_loop.wast.out.wasm create mode 100644 tests/cpp/lit/build/for_loop.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/for_loop.wast.run.log create mode 100644 tests/cpp/lit/build/for_loop_break.wast.debug.json create mode 100644 tests/cpp/lit/build/for_loop_break.wast.expect.json create mode 100644 tests/cpp/lit/build/for_loop_break.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/for_loop_break.wast.out.wasm create mode 100644 tests/cpp/lit/build/for_loop_break.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/for_loop_break.wast.run.log create mode 100644 tests/cpp/lit/build/for_loop_continue.wast.debug.json create mode 100644 tests/cpp/lit/build/for_loop_continue.wast.expect.json create mode 100644 tests/cpp/lit/build/for_loop_continue.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/for_loop_continue.wast.out.wasm create mode 100644 tests/cpp/lit/build/for_loop_continue.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/for_loop_continue.wast.run.log create mode 100644 tests/cpp/lit/build/for_loop_return.wast.debug.json create mode 100644 tests/cpp/lit/build/for_loop_return.wast.expect.json create mode 100644 tests/cpp/lit/build/for_loop_return.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/for_loop_return.wast.out.wasm create mode 100644 tests/cpp/lit/build/for_loop_return.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/for_loop_return.wast.run.log create mode 100644 tests/cpp/lit/build/if_else.wast.debug.json create mode 100644 tests/cpp/lit/build/if_else.wast.expect.json create mode 100644 tests/cpp/lit/build/if_else.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/if_else.wast.out.wasm create mode 100644 tests/cpp/lit/build/if_else.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/if_else.wast.run.log create mode 100644 tests/cpp/lit/build/if_elseif_else.wast.debug.json create mode 100644 tests/cpp/lit/build/if_elseif_else.wast.expect.json create mode 100644 tests/cpp/lit/build/if_elseif_else.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/if_elseif_else.wast.out.wasm create mode 100644 tests/cpp/lit/build/if_elseif_else.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/if_elseif_else.wast.run.log create mode 100644 tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json create mode 100644 tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json create mode 100644 tests/cpp/lit/build/if_elseif_empty_else.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/if_elseif_empty_else.wast.out.wasm create mode 100644 tests/cpp/lit/build/if_elseif_empty_else.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/if_elseif_empty_else.wast.run.log create mode 100644 tests/cpp/lit/build/if_empty_else.wast.debug.json create mode 100644 tests/cpp/lit/build/if_empty_else.wast.expect.json create mode 100644 tests/cpp/lit/build/if_empty_else.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/if_empty_else.wast.out.wasm create mode 100644 tests/cpp/lit/build/if_empty_else.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/if_empty_else.wast.run.log create mode 100644 tests/cpp/lit/build/if_multi_condition.wast.debug.json create mode 100644 tests/cpp/lit/build/if_multi_condition.wast.expect.json create mode 100644 tests/cpp/lit/build/if_multi_condition.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/if_multi_condition.wast.out.wasm create mode 100644 tests/cpp/lit/build/if_multi_condition.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/if_multi_condition.wast.run.log create mode 100644 tests/cpp/lit/build/include_exclude.wast.debug.json create mode 100644 tests/cpp/lit/build/include_exclude.wast.expect.json create mode 100644 tests/cpp/lit/build/include_exclude.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/include_exclude.wast.out.wasm create mode 100644 tests/cpp/lit/build/include_exclude.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/include_exclude.wast.run.log create mode 100644 tests/cpp/lit/build/multi_func.wast.debug.json create mode 100644 tests/cpp/lit/build/multi_func.wast.expect.json create mode 100644 tests/cpp/lit/build/multi_func.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/multi_func.wast.out.wasm create mode 100644 tests/cpp/lit/build/multi_func.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/multi_func.wast.run.log create mode 100644 tests/cpp/lit/build/multi_if_else.wast.debug.json create mode 100644 tests/cpp/lit/build/multi_if_else.wast.expect.json create mode 100644 tests/cpp/lit/build/multi_if_else.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/multi_if_else.wast.out.wasm create mode 100644 tests/cpp/lit/build/multi_if_else.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/multi_if_else.wast.run.log create mode 100644 tests/cpp/lit/build/switch_case.wast.debug.json create mode 100644 tests/cpp/lit/build/switch_case.wast.expect.json create mode 100644 tests/cpp/lit/build/switch_case.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/switch_case.wast.out.wasm create mode 100644 tests/cpp/lit/build/switch_case.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/switch_case.wast.run.log create mode 100644 tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json create mode 100644 tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json create mode 100644 tests/cpp/lit/build/switch_case_fallthrough.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/switch_case_fallthrough.wast.out.wasm create mode 100644 tests/cpp/lit/build/switch_case_fallthrough.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/switch_case_fallthrough.wast.run.log create mode 100644 tests/cpp/lit/build/switch_case_rdefault.wast.debug.json create mode 100644 tests/cpp/lit/build/switch_case_rdefault.wast.expect.json create mode 100644 tests/cpp/lit/build/switch_case_rdefault.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/switch_case_rdefault.wast.out.wasm create mode 100644 tests/cpp/lit/build/switch_case_rdefault.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/switch_case_rdefault.wast.run.log create mode 100644 tests/cpp/lit/build/while.wast.debug.json create mode 100644 tests/cpp/lit/build/while.wast.expect.json create mode 100644 tests/cpp/lit/build/while.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/while.wast.out.wasm create mode 100644 tests/cpp/lit/build/while.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/while.wast.run.log create mode 100644 tests/cpp/lit/build/while_break.wast.debug.json create mode 100644 tests/cpp/lit/build/while_break.wast.expect.json create mode 100644 tests/cpp/lit/build/while_break.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/while_break.wast.out.wasm create mode 100644 tests/cpp/lit/build/while_break.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/while_break.wast.run.log create mode 100644 tests/cpp/lit/build/while_continue.wast.debug.json create mode 100644 tests/cpp/lit/build/while_continue.wast.expect.json create mode 100644 tests/cpp/lit/build/while_continue.wast.instrumented.wasm create mode 100644 tests/cpp/lit/build/while_continue.wast.out.wasm create mode 100644 tests/cpp/lit/build/while_continue.wast.out.wasm.map create mode 100644 tests/cpp/lit/build/while_continue.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/do_while.wast create mode 100644 tests/cpp/lit/covInstrument/do_while.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/do_while.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/do_while_break.wast create mode 100644 tests/cpp/lit/covInstrument/do_while_break.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/do_while_break.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/do_while_continue.wast create mode 100644 tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/do_while_continue.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/do_while_once.wast create mode 100644 tests/cpp/lit/covInstrument/do_while_once.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/do_while_once.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/exit_basicBlock.wast create mode 100644 tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/exit_basicBlock.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/for_loop.wast create mode 100644 tests/cpp/lit/covInstrument/for_loop.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/for_loop.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/for_loop_break.wast create mode 100644 tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/for_loop_break.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/for_loop_continue.wast create mode 100644 tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/for_loop_continue.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/for_loop_return.wast create mode 100644 tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/for_loop_return.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/if_else.wast create mode 100644 tests/cpp/lit/covInstrument/if_else.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/if_else.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/if_elseif_else.wast create mode 100644 tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/if_elseif_else.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/if_elseif_empty_else.wast create mode 100644 tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/if_empty_else.wast create mode 100644 tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/if_empty_else.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/if_multi_condition.wast create mode 100644 tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/if_multi_condition.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/include_exclude.wast create mode 100644 tests/cpp/lit/covInstrument/include_exclude.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/include_exclude.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/multi_func.wast create mode 100644 tests/cpp/lit/covInstrument/multi_func.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/multi_func.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/multi_if_else.wast create mode 100644 tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/multi_if_else.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/switch_case.wast create mode 100644 tests/cpp/lit/covInstrument/switch_case.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/switch_case.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/switch_case_fallthrough.wast create mode 100644 tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/switch_case_rdefault.wast create mode 100644 tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/switch_case_rdefault.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/while.wast create mode 100644 tests/cpp/lit/covInstrument/while.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/while.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/while_break.wast create mode 100644 tests/cpp/lit/covInstrument/while_break.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/while_break.wast.run.log create mode 100644 tests/cpp/lit/covInstrument/while_continue.wast create mode 100644 tests/cpp/lit/covInstrument/while_continue.wast.debug.json create mode 100644 tests/cpp/lit/covInstrument/while_continue.wast.run.log create mode 100644 tests/cpp/lit/expectInstrument/expect.test.expect.json create mode 100644 tests/cpp/lit/expectInstrument/expect.test.wasm create mode 100644 tests/cpp/lit/expectInstrument/expect.test.wasm.map create mode 100644 tests/cpp/lit/run.cjs create mode 100644 tests/cpp/main.cpp create mode 100644 tests/cpp/test-asc/asconfig.json create mode 100644 tests/cpp/test-asc/assembly/index.ts create mode 100644 tests/cpp/test-asc/package.json create mode 100644 tests/cpp/test-asc/run.cjs create mode 100644 tests/cpp/utils/utils.cpp create mode 100644 tests/cpp/utils/utils.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 346a742..b06e399 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,8 +14,12 @@ set(BUILD_SHARED_LIBS OFF) set(BUILD_OBJECT_LIBS OFF) add_subdirectory(third_party/jsoncpp) -set(BUILD_TESTS OFF) +set(BUILD_TESTS OFF CACHE BOOL "force disable binaryen's deps" FORCE) set(BUILD_STATIC_LIB ON) add_subdirectory(third_party/binaryen) add_subdirectory(instrumentation) + +if(NOT EMSCRIPTEN) + add_subdirectory(tests/cpp) +endif() \ No newline at end of file diff --git a/instrumentation/main.cpp b/instrumentation/main.cpp deleted file mode 100644 index 36df7ad..0000000 --- a/instrumentation/main.cpp +++ /dev/null @@ -1,43 +0,0 @@ -#include -#include -#include "CoverageInstru.hpp" - -int main(int argc, char **argv) { - wasmInstrumentation::InstrumentationConfig config; - if (argc != 13) { - // print help documentation - std::cout << "wasm-instrumentation is a tool that instrument wasm binary " - "for code covareage report \n"; - std::cout << "-----------------------------\n"; - std::cout << "-i input wasm file\n"; - std::cout << "-o output file\n"; - std::cout << "-r report function name\n"; - std::cout << "-d debugInfo output file\n"; - std::cout << "-m source map file\n"; - std::cout << "-e expect codeInfo output file\n"; - std::cout << "-----------------------------\n"; - return 0; - } - for (int i = 1; i < argc; i = i + 2) { - if (strcmp(argv[i], "-i") == 0) { - config.fileName = argv[i + 1]; - } - if (strcmp(argv[i], "-o") == 0) { - config.targetName = argv[i + 1]; - } - if (strcmp(argv[i], "-d") == 0) { - config.debugInfoOutputFilePath = argv[i + 1]; - } - if (strcmp(argv[i], "-r") == 0) { - config.reportFunction = argv[i + 1]; - } - if (strcmp(argv[i], "-m") == 0) { - config.sourceMap = argv[i + 1]; - } - if (strcmp(argv[i], "-e") == 0) { - config.expectInfoOutputFilePath = argv[i + 1]; - } - } - wasmInstrumentation::CoverageInstru instrumenter(&config); - instrumenter.instrument(); -} diff --git a/package.json b/package.json index 2429dfe..a9d673c 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "assembly/**/*", "bin/**/*", "dist/**/*", - "build/bin/wasm-instrumentation.js", + "build_wasm/bin/wasm-instrumentation.js", "docs/**/*", "transform/**/*", "LICENSE", diff --git a/scripts/esbuild.js b/scripts/esbuild.js index d82b086..5b7e3c9 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -16,9 +16,15 @@ function emsdkEnv() { }; } -execSync("emcmake cmake -B build -S .", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); -execSync("cmake --build build --target wasm-instrumentation", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); -execSync("tsc build/bin/wasm-instrumentation.js --declaration --allowJs --emitDeclarationOnly --outDir build/bin"); +execSync("emcmake cmake -B build_wasm -S .", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); +execSync("cmake --build build_wasm --target wasm-instrumentation", { + encoding: "utf8", + stdio: "inherit", + env: emsdkEnv(), +}); +execSync( + "tsc build_wasm/bin/wasm-instrumentation.js --declaration --allowJs --emitDeclarationOnly --outDir build_wasm/bin" +); await esbuild.build({ entryPoints: ["src/index.ts"], diff --git a/src/core/instrument.ts b/src/core/instrument.ts index 755ada1..a622009 100644 --- a/src/core/instrument.ts +++ b/src/core/instrument.ts @@ -1,4 +1,4 @@ -import initInstrumenter from "../../build/bin/wasm-instrumentation.js"; +import initInstrumenter from "../../build_wasm/bin/wasm-instrumentation.js"; import { InstrumentResult } from "../interface.js"; export async function instrument(sourceWasms: string[], sourceCodePaths: string[]): Promise { diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt new file mode 100644 index 0000000..73679bf --- /dev/null +++ b/tests/cpp/CMakeLists.txt @@ -0,0 +1,54 @@ +find_package(GTest REQUIRED) +include(FetchContent) + +file(GLOB test_sources CONFIGURE_DEPENDS *.cpp ./utils/*.cpp) # innclude lit test by default + +add_executable( + wasm-instrumentation-test + ${test_sources} +) +target_link_libraries( + wasm-instrumentation-test + GTest::gtest_main + binaryen + jsoncpp_static +) +file(GLOB sources CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/instrumentation/*.cpp ${PROJECT_SOURCE_DIR}/instrumentation/*.hpp) +target_sources(wasm-instrumentation-test PUBLIC ${sources}) +target_include_directories(wasm-instrumentation-test PUBLIC ${PROJECT_SOURCE_DIR}/third_party/binaryen/src ${PROJECT_SOURCE_DIR}/third_party/jsoncpp/include) +include(GoogleTest) +gtest_discover_tests(wasm-instrumentation-test) + +if(ENABLE_E2E) + add_custom_target(npm-install ALL + COMMAND npm install + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test-asc + ) + add_custom_target(compile-asc ALL + DEPENDS npm-install + COMMAND npm run ascbuild + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test-asc + ) + add_dependencies(wasm-instrumentation-test copy-files) + add_custom_target(copy-files ALL + DEPENDS compile-asc + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${CMAKE_CURRENT_SOURCE_DIR}/test-asc/build + ${CMAKE_CURRENT_BINARY_DIR}/test-asc/build + ) +endif() + +if(CMAKE_COMPILER_IS_GNUCXX) + LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) + include(CodeCoverage) + APPEND_COVERAGE_COMPILER_FLAGS() + setup_target_for_coverage_gcovr_xml(NAME cov + EXECUTABLE wasm-instrumentation-test + DEPENDENCIES wasm-instrumentation-test + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/instrumentation") + + setup_target_for_coverage_gcovr_html(NAME cov_html + EXECUTABLE wasm-instrumentation-test + DEPENDENCIES wasm-instrumentation-test + BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/instrumentation") +endif() diff --git a/tests/cpp/check.py b/tests/cpp/check.py new file mode 100644 index 0000000..10ea7bf --- /dev/null +++ b/tests/cpp/check.py @@ -0,0 +1,22 @@ +import sys +import difflib + +if len(sys.argv) != 3: + print("Usage: python compare_files.py ") + sys.exit(1) + +file1_path = sys.argv[1] +file2_path = sys.argv[2] + +file1_lines = open(file1_path, "r").readlines() +file2_lines = open(file2_path, "r").readlines() + +diff_result = list(difflib.unified_diff(file1_lines, file2_lines)) + +for line in diff_result: + print(line) + +if diff_result: + sys.exit(1) +else: + sys.exit(0) diff --git a/tests/cpp/e2e.cpp b/tests/cpp/e2e.cpp new file mode 100644 index 0000000..3e0f53f --- /dev/null +++ b/tests/cpp/e2e.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include +#include +#include "../../instrumentation/CoverageInstru.hpp" +#include "../../instrumentation/InstrumentResponse.hpp" +#include "utils/utils.h" + +TEST(e2e, asc) { + const std::filesystem::path project_path = testUtils::getProjectPath(); + const std::filesystem::path build_path = project_path / "build"; + const std::filesystem::path wasmPath = + project_path / "test" / "test-asc" / "build" / "debug.wasm"; + const std::filesystem::path mapPath = + project_path / "test" / "test-asc" / "build" / "debug.wasm.map"; + const std::filesystem::path targetPath = wasmPath.parent_path() / "debug.wasm.instrumented.wasm"; + const std::filesystem::path targetDebugInfoPath = + wasmPath.parent_path() / "debug.wasm.debuginfo.json"; + const std::filesystem::path targetExpectInfoPath = + wasmPath.parent_path() / "debug.wasm.expectInfo.json"; + const char *reportName = "assembly/env/traceExpression"; + wasmInstrumentation::InstrumentationConfig config; + config.fileName = wasmPath.c_str(); + config.debugInfoOutputFilePath = targetDebugInfoPath.c_str(); + config.sourceMap = mapPath.c_str(); + config.targetName = targetPath.c_str(); + config.reportFunction = reportName; + config.expectInfoOutputFilePath = targetExpectInfoPath.c_str(); + wasmInstrumentation::CoverageInstru instrumentor(&config); + ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::NORMAL); +} +TEST(e2e, empty_config) { + wasmInstrumentation::InstrumentationConfig config; + wasmInstrumentation::CoverageInstru instrumentor(&config); + ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::CONFIG_ERROR); +} + +TEST(e2e, illegal_path_config) { + const std::filesystem::path project_path = testUtils::getProjectPath(); + const std::filesystem::path build_path = project_path / "build"; + const std::filesystem::path wasmPath = + project_path / "test" / "test-asc" / "build" / "debug.wasm"; + const std::filesystem::path mapPath = + project_path / "test" / "test-asc" / "build" / "debug.wasm.map"; + const std::filesystem::path targetPath = wasmPath.parent_path() / "debug.wasm.instrumented.wasm"; + const std::filesystem::path targetExpectInfoPath = + wasmPath.parent_path() / "debug.wasm.expectInfo.json"; + const char *reportName = "assembly/env/traceExpression"; + wasmInstrumentation::InstrumentationConfig config; + config.fileName = wasmPath.c_str(); + config.debugInfoOutputFilePath = "this path will not be existed"; + config.sourceMap = mapPath.c_str(); + config.targetName = targetPath.c_str(); + config.reportFunction = reportName; + config.expectInfoOutputFilePath = targetExpectInfoPath.c_str(); + wasmInstrumentation::CoverageInstru instrumentor(&config); + ASSERT_EQ(instrumentor.instrument(), + wasmInstrumentation::InstrumentationResponse::CONFIG_FILEPATH_ERROR); +} diff --git a/tests/cpp/fuzz.cpp b/tests/cpp/fuzz.cpp new file mode 100644 index 0000000..c59ff7f --- /dev/null +++ b/tests/cpp/fuzz.cpp @@ -0,0 +1,34 @@ +#include +#include +#include +#include +#include +#include +#include "../../instrumentation/CoverageInstru.hpp" +#include "../../instrumentation/InstrumentResponse.hpp" +#include "utils/utils.h" + +TEST(fuzz, asc) { + const std::filesystem::path project_path = testUtils::getProjectPath(); + const std::filesystem::path build_path = project_path / "build"; + const std::filesystem::path wasmPath = + project_path / "test" / "fuzz" / "assemblyscript.debug.wasm"; + const std::filesystem::path mapPath = + project_path / "test" / "fuzz" / "assemblyscript.debug.wasm.map"; + const std::filesystem::path targetPath = + build_path / "assemblyscript.debug.wasm.instrumented.wasm"; + const std::filesystem::path targetDebugInfoPath = + build_path / "assemblyscript.debug.wasm.debuginfo.json"; + const std::filesystem::path targetExpectInfoPath = + build_path / "assemblyscript.debug.wasm.expectinfo.json"; + const char *reportName = "assembly/env/traceExpression"; + wasmInstrumentation::InstrumentationConfig config; + config.fileName = wasmPath.c_str(); + config.debugInfoOutputFilePath = targetDebugInfoPath.c_str(); + config.sourceMap = mapPath.c_str(); + config.targetName = targetPath.c_str(); + config.expectInfoOutputFilePath = targetExpectInfoPath.c_str(); + config.reportFunction = reportName; + wasmInstrumentation::CoverageInstru instrumentor(&config); + ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::NORMAL); +} diff --git a/tests/cpp/fuzz/assemblyscript.debug.wasm b/tests/cpp/fuzz/assemblyscript.debug.wasm new file mode 100644 index 0000000000000000000000000000000000000000..183a0220af19c0effd6756b985ad4811d95ddfd3 GIT binary patch literal 1782599 zcmeFa37izw)jnLk&DJwagCHO-Rb7Qa86t^94M|?!N@X(7=Qy&7b)EUx3PB>rRY3k?;1(q zBm*L<-8h1VvA0O_ijj=aQX)(C4lk9;mr~_RjJ<1>AW>u~R~R~Y@9>f(;P$F9yc$I5 zrBugKu08^k_MkwN5{cztkflqh)+Lm=gz640MX=th5CLQF2=hllDRMB=B_e`K!vs_) z?9zidOcEo@mY@JNlxwFbC6s*0Rrnj!vVtW}mt3Egc87w)dUU z?1rWvw6JyD;`W&xt@|2rFMrFD{ILgiwsy3aa%@q;k!nAvG`mkp_SpSPb4$ff>+D!O zv$K?=UrG5?M@LJbg3|gY?EH(;@?|y5ZJ%ArF{q>l=m3rb=C=O*&(p{4=Cj1s-Lw5- z7aw1D;wHd!KDJWBPhQ;CR;ty2lIkeGymPiHzc+M zxUi#j(W1Ev+V^PfoG{DBqpdh`!OWJnX~WuG&(ttu#@wBMIiqbs%dFjIEcWT4O(Ncp(t9rSd~%Q zs?07UCNB89kFOi0$3f}-o;!5Mw95#ix5uPMehceLrnR=U&SbX@3ekr1@dO2F&l=s*MqWF;rDJxh-y^gx6X#;eXla|! z-U-`Rd5!7ic@_7zubGvKqHjZ9(R#1w)JPtTA&JEnEOE&~Bth<%7Pqyc`^G`o zVoaJo%WdPeA~+hyWAOVJ_4L4A2ku#OJ2CnCShTyS=^;1~>gC3DsL6}>+jAlOrhS%Q zDeasto6A!&Od34RCoX`0XdCN{F&)Uz7KwW$ChY4osqVr~O{{ge&Dwtuue|%iVl~OPiRt zQXLES8{gWpkf&;GFg=k_1{C#p^n$FbLO!ugJ7`g7>wdn?L!TLx+`Jf*q36)L{1*OP zh?q9_zx{Jrq9nTmD}mPVduacr$-xhzmr@4?i+1^ zfk9g~-9p=wDOIOt%^K6X&*Iq=+V@>BZf=`2N_V<;T`2gB%rk;$^T;cI) zqb0b-7fo8+8Q6_#30^I}=|Sg;1X#;A(u29s!I!JeH0|$mJ7>-@YCI>@lM;2NyF%!e z>+J({qHQ?O()C_(%QK|PgkEe)nyZ+(m&dG^2Ol%fX#pqFQuPvs7EPNwt99(Y`(hKa z$Y)yZmp&ECx<@wzf>iZBDSGy$ZJkl)DXo{^X|y5m<>;xCOegDapi6aO_-<;EuS-gD z#_sRS(T*z@WXRNx>+4D0jrklztD}uJdcneje2vs2POm_?P?_5SlN!2H^=67zq6!Qp zLz0Z?Q(t#S$sXWOr7MPZyHw|b{pQYOqie6!y(QUVdaa>$cgdeR>Ce87(W{8$j^1zK zfivgK_HhKO|8vXSPT!!=1`q+07j(|u_aI+41oa!&+CJ02UDEO=weGi|;~-v#^zsnQ z-h-AR-O0gh?nP~!U^XT!|2{&y2&X={pofGxJkRC;t>u{MVUA$NO;zhU))N*ut_41~+ z%zE3Q+l#Kkz@2q7eA2ZaDxOI#2m10&Z&^eIDJ+@?w2p0SB^9T& z&Sp*ZaMsG8s%f1qZ~$#`tqht$n<#e)_Fv#=e*}+WXg)|zptLV(QHlrb%?oB74Psmz*X9A?R$QnVB7R*U&(HzOq%Z8ARi`3Y~V@` zAsx@fg3Ru!&y$e8aMsQs{Inq|(?I)e2~&mY_3$j=oIZEI)&-0GM}FGc!YDhfvYPcc z2(StN=mm>0`Rmqb!_y|h-N!&E4lcUoa_v&arMt(sXCkh^vAk}HY+QJ61irxOd8s&e z3k9~|>A3bU66fx8z?bqhpgW%C9`KCrmWTIT)WD4xOYzA5OdDR0FVec=WT2Nu#o}!P zQEBM_+Bk1_3c7m_EZPt_rgf3uGqm|jxc1z4-$f-y(b|Jb_yXriK`z>;|8Siy*R%zT zJFxrK#_LAf57bG!|MEJuH;Vo)SI}vLRl025R_UEHqsE{t-S^<4Ee3c9d@a=TGg!v% z4~D?#&?|vr2#yQA)J*4lMu828o_Hi1>*VMboOpn3Zpn(TTP}=>>!6Y~U+;IO&yjUt zddqBIgS0!T{K^ZnuQpdsr4?DbJ0J2*YMD=KVP%PWF81?QlIk-F9Ubb~kPG@6qdQOz z(<=0_?m)S=1PcN_8CoscfuIw+ZGbkN=B%W?UYRss**>YnZ>D3&qgqt%Q>=tzbV~&e z-Pg?>d(v&-z}{DTo||7sw{6!}^7B?|y>E)=Cj=m}tZCZ0M4IpfZ$Jkn z;bP+lB?(VZQm{VZ3Qh;QK7MjR%n_JaD)P|PmapTqtym7_LT?NTuF$`U*B<5PWVVt) zt^J( XDFsh!Tp60}1=P9=i|o|B@ZoCI?#UKVpPf(u&9qO*h0OE zuo=|C)iJYFpq^m@Y(0~Qw#@GI-yJL&tEok3XwVwkapa6tysLEcpq2OYlvP&Z&3OLB zbyU6%*K2d-3dgqlZ~SZfONEnKTNdF4X<0u76&u?=bHS`lU@L8=HonyANt2@l-Grce zxPZb5J+up~!9jr@UvMc7+N9Egu6^6pju!o(Ann`2#9dzMVkNUHdWoJ;O3gZ;1;?&s z_T4z|lm-4dBk5fyN!6utgHLV*O#|*w!Nkkr*f89PbCK z_Az48^i8b6s;9Nho!N>Ol}RkQr3c&l7=u2x5t*f9MbANEca}-2mesy7&e8_yX#+x# zB_|gC-qzj-4#_S*C({#xaDbH-9bD!5&op#PeWz)tly7JG>(rw}F=7?qU2CONKE*>V zC_Q@9YWaAkv~;xW=dVrAEk3TPt&4Cl_JeHD{!c9(el|TYebT_=J4)3?mt$He{)f3G z)1nsQaRjIH3PJ*{*GJEEuPxOvx6^-Yskdg7i)!!)i0=?p?^@+xTlDZTXcgtC9{SCl zMUTqp*;Bg?x^K^gopblY4Tg!W2eh{Nj{LP8Fio3-$0_FrS+p)-@$NbMWca4(*3Q4S zcF_Ikw$@p48Rz5E+f@h}hYjtd7A&Ir_Jj6>(QU0Q9sXnTMMi^nYVRA|I9zD^d&@zK zCbYNBZEwYaHt*K7M1257HMX@LIG4`vyJ7ZCtgu&mD{bCeJG$c@s;6PnqHV$7nG=(Z za=b-@k~KV7T#y$SmggZD_47NcE;S=?s_zuBE2yA3nc8(hoDNXr(KIq<}0*H>ntbp6#T;HInTNQPuK~W{Rl?KU1D?^{^6+VU znHfq=s(9pNUK>G=FYnkrI4FGAO;Ebz0S#1II)FCL+g)$!vvdgLlXa#@~0LybXM zdh!L=*!{r~aDBa`D2AZZ>va#u(QV?>a)_z4ebRH8ce33Lr=H80 zQ_m)HvaS11JHMQ4Ltghbl9O$)(8;!zq5YF~60lP@O6mDp^ObEjN(@ft)er`ezUoRi z=)Ag&Lw5Gqu zVCS1r?L?*`BkNHd7m4 zYW1WAn-Ek_PH|CfVCoMF^!S1+K+qGbw z;Wo}or>(lre1{ShwD$)kszcmOVWh*+?i-^Hamyt7 z4usf7KE|Mr1)JkzEgdU*4w5eSPJ7F0-xz0UgY>wA-A1qc=tC>Nx5=|* zWzTx(2}nJj=AQdUibLKXg17bQm3^Z+WQ3|IP*qJB!XF}`P^1Cr)$s%Dp68|l5q9s@)=cI_Sr6MM43V5m0&m&Vf8#gl&d1l$=NE+ zQ=Hi-X1Mvxi`Kd51EmX+lwhw65+Fc?aLd3$MUf(Z5)CAJVtfHE<;m4mQ927N4R9(a zxixv&B$KsZeN+v|c7uwMc_`JDLf}(dxD_)oF(cSRTl7^@37MsosBE`1fl6X5jY*c4 zpz5i}rJ03|wNk;7N)T}?)}l)iDv9DErTkv3e{TwgB~D$gm=mEbkQmxR)yIMp!sl|k znz>CgsDE%t2}z{iql!L>g5^N}^tD*=r&ZutAwv zJQ4%ekfbU!3|sYZ4JpSOP-$u&n4=H@KpZ-uGHM4@iq<0w8gre|s1Y@cDE?477HK3( z0;zKP51z`>AT>fhxqa==hU|bc;qZ<_NwYzba8nqfU>E!kYf&{QCu+ca5tsmJ*xGZ~ zKu_oc{b6#dBovNu#0YcmRaM1cml*nvCBT?qgU&1xwW6OQ;bA|gCbD5fQ@(Bh8;K4# zq6E5N%bgI3pj|8o63`O-2OjEi{1=Th)>5OR)Gd@3j@E}`jnOa}1BuZZLL&z2gkx+W zilUz(l5*TX)ET9&MN=ZRFdug^Zd#bQ;|l0hVzyNHHGRR~(5>&Yn*AgiIxRaJ0!)EN$My>-kOjy@vO!|}q=SUntw zdmFZZACYooBB+dlYzVJK5|CDgw;?NogRVenZ1Oc|DQmSM|2)Sd{+b%2z8=P*!uW%U zkb=5MER2f~;^-UFiW8A8RVtuj^e5eb02HPFQI6$-Zv2lLMjX`QjdT8Q?*F(2aBNZX z#}lKwv985tf-OpJ&~sD?OXv|*&yVB)|ird%3u{68p?B}}>atFMVB@K+s<^u`~K zWvFtR8#q8UkxmdmqnxMpZTkEIUo3;fes!3QFly^+!gck?;&BZHNcAWaC|3oR2x`S# z(yxwYIi7$a5{n7uB&;fsjY60KX!7JiAE~XaWn+PXhIqItRu$bD2BJDp6r(wcg1r#L z^d0U+OHZ^4yqNMJ306XSE#|MPSQJxBFJ25{HQ~lyvP6WoW3s+NB@F-r)kwj|%)P_u>ie!_SsFP8W z?1aCn+HfuQCB4G6y=p0!|2L|7_3A|}hY8p!;O8v|IW2U;f20M~iGQ*!Eb;cu9f1}! zJGy`2K7C3naE}DNaV4Fg*wHRD9Zl;MiB^XehOUfW2`>s6>8h%af3voBsnKl2K|(~9 z5lO4R3bF6iAD2;)?~V8}BV`iFaj?KN9io&h(;U+R({z~9nT6wshA6s8gazmlMyeR& z+E{j`io#t?^Gu6OGu52VG|#liG*iRrO!G{OOf$8d&NR<7UB@X*^Gu6OvvEq#Gc7XB z)>BG>X|{pGOw+w6oMoD0T40)PuF)5AHJX@P0x7o5wq$Tagy=3$y=T4b8pnbVo(nWjf@ z3e!B(BGc@zC_Trt$TYhPrR15Wcja8B>D?$Sv}7EY4eKlqZld7tiZEQqP?SmHQl0|t zy^zOAF2gZN``|FHr6_5c6F93&ATPkeSphav@kHjyoFuFQd4Zxp=48ne$O{w+LMbLJ zjV88g|AbW5E@tC#$b&Rs1a4rI8XF_Ra}VShDV|koDa5k|PZZp8o*H-_V0kQ=2X!A} z=0V$+LOe8iO!8plQOJXkM;{M69&bF{c$@`PW35;XuEQjuGHJ_nEt7Ma+0x8M6Of*0 zL#eJ)l%f2osOJCIXrPCTRCyn49{qYyk&)^_X9xNv5M}Lk+A``UCY+`-cwm(`wFero zHH_4&EbBF6=X7V){1IcbLA*^gX8UGyQ;Rk?Gw$y6$0mFVp*&-p}+wrVlaA zGkuupBTOG<`WVy4nLfevNv2OReVXYrOrK@?9Mk8SzQFWFrn1#|iNh~5eTC_(OkZRA zI@33pzQy!yrtdI)m+5;<-)H&()5E!QS1>(->5)v2V!D#)(M*qF`Zm*dn7+sKeWo8W z{e>b1Oc%~;ZJ&ozsR(>s{n$@DI!_cFbYscdr| z=I~=oA7}am)2Ep}!?eKkC8n=3eU0hsOy6MoHq(_%k7N1?(@&Xx#`G(uhwFK4=r>9tIsVfsANH<+Hslj$0!7csqs>0L~};dxXxM~CoqdL+}8 zOpj)IBGXftp275Nrsps{k7<_aDyHW%UBh%O({)U*VtNhJo0zU=dNn>o}I~ z5*C5%6&x!HAQK-bkAOJBo~7sy;IF@elKB_@!$PGSPt>p4~w=(>Sp=^KSb zAbS(X3If^n5);VYEHQ!X28jt|a}pEC-Xbx9?5z?L$lfL~f$Z%P6Ug2nF@df-IhMYQ zAt#WQB`_zDmZdN!kd`GeCy1>1+ubm76o#$fM#R`EePafCC$oG znwGV+Adr`5H-+Ub zhP*)bZDA3}y~DB0y9@<^?0XUu$i6QH1ah(+$P|S|pzA}9r9WcG3uHf*asv5JIM(&4 zaDK*65XgPbvFsNNMS=X69P9duA^kN&K_K@H$Fkot6b16%ajffmhKy|KivsyWc+1#z zC`0BjhN3`zx#S%#c`GDOAb*799VvN7NuEG{rQ{tgdB;eeK>k?CJ5KVBmpp-dM)FRO zyb~o)Ab*nNoh*5$NS;9cRLMI{@=ljLf&3Ygcc$c>C3yn*vnB5whU~e*a-OgV6y#Dh zzlsxctA+D?hV%st1%a+L9LrqDP!z~rB#9Rbr$E;w97|uykQd1QgJVU3++`fgtYs(& zbY0G|^g4#TK(5TqTJDT~`a|H4J%y?6n*#3grLEv99YFGS@Q{1hO|s zOdxxs#00W8ajYniThFod%?vq#^ahCuq;nk03uJELSV5rcR*t1_6BdE&?ZP6Ey@O*# zf!v)^;4Ud3khxn52z1>eEcXhFK=wXi5y;*zF@fv@5);Ti$g!e8?jeq4@{%Z!dsq@5 zVJHaX9+kw$BvGL2agL>*V8{z(o|KqC<|&B@WS*9oK=v7qrJrRe2;`pQSmt?26zFLqVYHTaKl_W5^3+zvoy{AeZJ#@bn=JIf2Zf z94iQP9VRTx8S(0=oR0=eUa<#=Jq z2+Ii!d4cSS94iXsPvThD$-;Sxa0+Bk6;6TNX&lR(&QK7@ogs;5N}@p5SsY8B&5#$! zp2M-CK-akv6Ud#%u}qesAkejnW9iild4cTt94iXsFW^|$8iwqJ44I3BMIe7M$8wi2 zbY04j{RczlGKQi+el5pxmos#&V{lI`^Ky8Zy+RVNWGD!9T_uTEGvo!b*Kn*Tkh_*+ znSU}A1iIuTG<`iM<^<9=a4av7y^&)@f!s|T%dBT82z1@dvGfK>6v*W`)^!U*_EurJ zO;`l-w{t9a2Sesg$rI?hOA_y9C<^56k;Hq2Q=scUj-~Hs$O~j2;8;;0_aMhI4>1%3 zy7C-LKg^I9$UY)00@+6;CXjthVglL6IhKAx5(RQkaxC+dBnosrEs4)C6a{k6O5$_E zDbV#i$I>q_t&9mUt!1#WM35)f$VD%6Ue?UF@fwG9Lv1P zkbX<@1iIdq#CI5S0_k@pCXjhg3J7H1=U7o7_W{S!MJXVV{!n59>5n8PkolNnd4bF) z94iQPeaf-)XTlHK-V`MOMlCd7s!6cv7$iN_rfA) z(RqRFAvl??bdc*mmi-RL_q_E@^O33Co=m5g(oun%Bl+J;70g98a+4V`uC! zanI(|#A%T;bk^iOCr_W6nlfd= zL@08eR%Ghfabu^BojiK%jOqV5W$d&_Rx2_IZJsdWPpOG}jg73Tty6OL7#&$%n@}-P zbe9p4^K1L6w5ek!rv5T^3@ihcFVL1^BaK1E=shP-n;uzH+gp{GHhn6zg)Wf`YhyEJ z!2HHr5d;>_Z8x6oS3P6K;&uu?)30{MjF}7YF&q3c!n6JGn_wNCopWdG)3T^Fa&c|d ze*AL}VWaPi8H?~q0QbA}i`@4RzZejoF&8hY;$!mkmeQ94YQf~b9Q?u1Iz;f%8GKr( z)xZrnCD;UhKpApD0z8xfW77RhVl#z&kapU-!bJ|3C?7rhCK3f#0$I1L~3nY-WO z{oJ%qx#+YxEgjx>g+3eFi;D7(+Q`@PKj##wQc}JcS`Qw1Iet>hLgUM!eG%WQede6j zne$s`HMh=bIbiOB4&$q#4M>-|nqe2?Yc9w_IR4GhUM=c(bW&||TNWAL4(;8+KT9Cr zUXjG_d>Y8BXWzS4*{gj~%f78fx~VrR^1k~s5#MC$G!AJZBZ%J0nuj*A=AA7w=kuG! zhcQp{;`Ui>t$%9mpr3s-mNzxDw$m>XxW8*=9NyGx*4#z@lod_=AiCt^Pvhsd$p+gXmK^HVw&%*Hpp zjANR5wc|T*W9GKZZeOs7_>XO>ovqAo9M{wv5uH04Ul25oZ|YZ?h)-C}#;=bUnWnxa z8I$l+mo2kfjT4&sl%!8>X-DdbO#@3)TiYOLmSmpP)PPJ5OP`$F6jurK(%&gfy;Riw zjKZl+{gEP($qPF0b9?apSySk1Ri`yo&Bf=Y_FZ6{-c&nx(Vts7+F>o@jHc?ji^g_z zz?aT!iY>%9$y$xGnrg@%_zXg;aW+>urgdQ}eq^)NIH#$%9#qPH=QdT(T(I9lVn45` zW*_>!u<6sr7}=(34*!0dv5Ji%U&v`~cfa|Bckov?)f@mF`TJkzH`Od~zx8EY(3IGh z)c0B4SkqMdR!zuAh2mF4&oft>=bIOpYs?GHi_DA7%goEob>@}kRp!;^HRiSE_2v!c zP3C&@X7d*FR`U+?Zu1`VUh_Wle)9qILGvLqZ$4~3Vm@j zXFhMfV7_P;%$LlU&DYI0%s0)q%(u;V%y-TA%=gWY%umfP&9BU_&2P+a&F{=ZtmW1b z)=}0<>uBpZ>jdj$>on^O>rCrx>s;$RD{HN?R$FVV3$2T+ORP(+%dEB5<<>gu3hPSi zD(h4@n-HJS@39d3bU~@`&V-$)l1hlSe0yNgkU# zE_r-1lRP1LV)CTq$;nfarzTHJo}N4-d1msgqc~$c2)kK%Rbva$3E9S&(7Mb?A7-9_67DD z`$GF7`(pbN`%?QK_GR{3`*M4o-DO{4Uuj=uUu|DwUu*x9O4}69Of){4tG{KM>t11M>#84H{cRp~6&WFxN&d1It&Zo|2&gae- z&X>+t&ezU2&bQ8Y&i77w@F9Z_9emi}<%16&ykhVXgO411)Zmqaj~;x?;A00LH~9F$ z_2CQq)O~SR>ir?rhG`55C*r+;slM|Q*F{pH0~+JCh?=2Y!ci|&6W@Z;jKmEQh8qEm zaVZ|<;)(T6+@Qxdc7`D0*JVuyG;LXUm8BX<`hq9j!01K6?55@7??bsE zRX=CV78M`?3Z#s2Qmc`;H9`?+XaA#iLJa$5PlI$Q)rT}_j6=|^sF~IDvX?6bLr@Hs zKvNR9&=zadyJ*CRheFHji)&FUG#U~%{(y?p(Nr#)>X+J@8yHGO(ZE!+ZC>KeNMk&S z0;uo~Q8YX$x-1onLH1pdl(~P(*aQ0PNGu`JiTVNcQwtG_kRAv?4{kjU5k|8#yFc2? ztw@H(LLgiCP3)_7K583}DkCVD`1TPn1_^js#EIwqXz<+@gceAR-#Z)HYO^?Q0O z$0?RbDjh}xQic@;NAv(I7BeHss?;~Qw-%xEe)|9}*l z*}2GyAy$(L%|}k0>WHTLPk^t*QVE}{L8G%(b)m$g5vvx8KNhj-%vxBk)~rk5c*Lwj z7%2%HoS5v&R@{tQ^=8a!Fym%DsxuqrrNW)_hJ^R7H{$4*FnZkT1*S$YCCoajx7o{V zB*p|Yn!R@k?+w9dG>uNH4_LP_`xcW?x8w2O5dTVN5g1YzdtF;I9}B4T2AEWy1AnaHGBVgxntJribox^PyJ=J`Tgr zgL8ZSL7GL)DD`d(#tiMxbw?9VklTleIhNv{otF$J@)4F&WmZu}Rb?qO&4eL_S*y)z z^dUT!>ZvhnsGeGC0EqUY=hgVf@843*H5Miou%ME#zjkyJ)WHzVV~&svtB$1A`5o>p zx5aEHl2JF$jJmTS4EDA%7$_9!n&qN=RXV%Bex@3dvnZ3*gvll$GF}0o92+xe0 zjb_~Ene~W?XU5qxFt5TtVTCQ=vgQ`( z6{L~JvKRG5>3%4^r5S?z^fmjDge}Dt;Y4sn&wt{b9dI5lwG~PYLbn*!0E7mb1I&Ti zKjCWiogLQJ=2qq)cE+vA8RO^T{SfguGd#(2x-Y#!2K%NO@gMmzY=VvpO9ZPD)dY_l z63*gK&xN8(#VLrMG4WFvnG! zHQZ&j)MZGi17jWB&t-%OFuT=R4an+MI>VX0Wa7e#W7W}0f(j6<;vhEwZjTizVm9t> zq!OKpry__rgW|hmZ9)sV$I*yAXxUFS?vI5IjgjSoMmR-1uUQvOMP!+7j1NR1>P?!p z&>u9S4McDXy`6!jlb5>2xIGAk6F7yo2Vp*ZCX&F}^G;qqYLxvG;KoSI?gO3&BlDd; zBpSNSOW<%i{zNzwT^5GP=%3ve9YcGT2Go`cjccG-cw9rcK7z69^i3H~KS;|(>;X=H zT8P`A#K5su*zQj|CWBXEtnAonnTFFJ6>h*(#4)Vhw_pS0^h4Es=RwHl16%>%qO!bD z>k335+ByKv4)*&amFft{*RtU*TB^O3MH*ArU~lIP#0-CP#Oa?3JALD-75yzToM5xsQy*^N~~?T0g)ZfGrWjjnuxr7|SW_RcFEjU}*X;U6Z;y)Q0C_ z+bsjGXCz*T%(o01*5sybW%pSNhP6wZUp3MffqR~_1&Z+&$oPE&i31DL?LPJv^MMoE zgoAw{RZsgi%*fQE-WY@DVfU6qlVp~ryjIU|f=h`d^}mWPj3 z6Ekb)xN~Y9q+y}Lvg1jE5cDR=kX^x(VcBqV?e*YqFstWa@YkCSv{dx+FE%yt7_&8k zEkSI(vA`vWt#>J#S<@Il1@Dznx0{~zXrflugYmEy==SPB5WV zaB761lUN{Jy*htbEgtcN%RDgBMjHoq%SAp<6+7S`Ud~bq^VS<8pfHOq%x!Mr% zE@z%uU9urUqeHSB1-DAX7Iw?W;|J0fG?aJ=+iPl8;$^xNiLf^y_6p65l1S~Mbm`%u zyI`^t>J6P4)@$lV5qE1ymowN_0U+vCco+mV#V#jv39z@a2jU_K^K=;V z^gIWMnUXi97{}k>Di>NU3PoTJG_#RgW=Mlk+eNAeF+3r^m!5N9-r3!NnPsb)QKM&Z4oaqs~%N@ELV$37d=Tx34_ zARezV5+6kp%LkI~xDB~c-Bo6fjnfyN1mhe&&{-K4JUZ+dyYhvps-v&&0F{I*Y}F?! zslGf3KB>5rt+)0rZ>!O7n2|l3|G`KcF)$HwuD~17&XwUr#JMV*h&oq?6EWwSaH7h& zHk_z-{uxfxIM;;}wa)e7M4fX3j(nUO!-;z5rf{OcSszaHa_}q{EcsO=acq<==<-cQA41iSn4rE-SD;!szJ0__;H99W2@h|Z{@yoI7Q=T&2&Rh4>f1z+!W z&ihr^uBaREG>m093Eh4Z#Gvf-!&o|O-O##;FXPqVya-Fm@ZHeuFz4G z1=h$Wf-WPJBwR+|Y9s_BKvN$pcFMGS!S#j5it8bm1PYM2;U+E}=;BBeivK2r+2k(< zw;W=$G{uriuZ)_Zi&Ec*_IE|o92{z{Inq7WB1wEAp*X8L=j{|SSa2FI)016knZ;5w z7gHLxRp^%8P2-@8=BKu!{aib?QP^jOE~CZX!WE>2OJUlgnz6s~)E7%z2%E8`SnRQ? zcUlqNrVCSZNSLC;gj}puoJ-;Pjq%e$q3BXGLb9xH9LDEnr&7cb`f=)vV`@^zf+v{rA(efN4;lVN}Y+=xacVzYe6`^BX{#AKnDQT~coW z>7wOrU={EkAdTvGfi=MQfH>|<4@Vh;ygZqrm>a$AANXj{^q+p8(S3!IMB-Q>C5)ZVh}I zxDD_b;I_bLff%Ey=YS^gd7uS+0hk272(*C(paXmfI2iacaC_h@z@GtM1r7ne2HXMo zI&eqe8^EE!w}4H+w}Hce?*M-ed>6PA@I4@AuGIU$UjRP<{t|e2^|*$efh&L`fJXp- z1w0bC3-Bo5uE3SR-GD~}e+@haI1>0a@HfDBfWHO42mBrIec*opKLqX$`~)}(_!%$- z{2bT}`~o-{ctp*(hB3fnfMbEj1IGbR1nvPm4LBZnI&cE;4B+p9X9NELJQp|-xCS^0 zcsp=1@DAXfz&n9cfOi4^2)q|K6?h+T8ZZx>4tyB67w|FQpMZ}8{|tNr_!r>Q!2bk3 z1N;%36Tns#~Zd}6wz%{_X11|y|2)qS&5b!SGe*?eiJ+9&Z1E%|oYght2 z1b8s;NZ?Z7O5if!(ZDnf{1Xv4gaW4^a3}@NK;SS6oQ=S83Y>$$;S@LzffW?UB5(u+ zRv~aC1-cou=PC{RS; zYzlmaz&R8+bc=Bf=TcxL0_RcS7zDBuI2M6b6v!a3ngS;wa6Sc2LEr)koQl923Y?C> zg%mg&fr}`x27!wya47gQr4Q&C3JQFMz?BsE8iA`Q@ErnIQ($@DaShi{;BW-4rNEU4{F4G#A#fc9o<-n#3Vevb z4HWnYfg36CF#owCjALnF~0) zhG_OeqUno>=9%U$=JZR57MSKPrEu3jh!!v7^tD7Y>o|pJp^L*;5KUi2G|x19HH9p@O=h*N~-Is7ou{3ApQk1~CX>ElFmPY}&MNi_2m)2Ep} zLp1#?(E`)rbDZ)5(W1~7DV#45?RtsRUnZJ+mD67%nt7d5m=@olaMznevu|LGB3e)uG6wZ9XDPIyT zenm9@HPP%hL<`>%&3sR^D;=ZoAw;_lC7L~q!^?^059gE>M2k!dM{xR)OpoH+l|(Z~ zbNCnzAItPOrpGhQFg<~2;Y6bOlZX~i=9E*3=1$}A=|sEEB$_^(XyzQE*>gGlJfgWQ z(^W+Ct2zCAqQwiCuHp0xiKZ_mn!AK(<{zAL8PUR8qQ%QOy^Co63Zl6yiFRGZDc5ky zwVd)#qM7TMUeD<_5G~wDG`*hb%|!DXh-PyfzJ+M1H^$fU!7#3d=u!)pWOT|)p(>oBhR4%m1kpWlx)#F~8&2n|_wSH9Sh!%q64VHo|3C^AsEB89S*Cj2x@WXv6gNW z0dVaIS$x2Z>v{KfTbypHsN)R(Ntin5@tv`$q>UeTsiUo>I8w!#FV2r~+#Maa6)u@^ z>5+hlQEeKX>mbOWNdAw)fvt>z;V@=5QMwx599Z2P~pc>hqJ= ztvgU9Hn@pW(B(`>A}+|)Lrv;1NFCy+!ylb~NXXSwZYn|5Nk3Ip#j?S3Db*B}o(PU;)2h~^FJm|W4!wYxZ^zuE`rNHIxvSnaPA$E#9Mq*fUfG3xJ#0FB1$((%-DoM z-_#j=Y_1%qKE55_nS}%{L#N<;0#A%_I$&3vsw0$^O6$I!){0X*qk0@{a~+kd8h#48 zNS~@cQW_~#>DmImwV9vqM= zJ*d8l>r+^jqDu7jWcxjb)Es8ix_KiJ62(<1WiAz0`Y2TC>gYbmue6Z#VTShOL8uus z8xAkcFg%y;qw#4P-RJQ=s2RqCnxdqtGI$WJoIq8j_=4$5HKl@*qslpM(^a}^n#%u| z`|!7J1wqBi6;|G6vWfWCmrAN|b7kvtF0pONJu}_^+DG)b>B*WE)LR)wr7Hs~!zn{+ zuhyQY@4Gl!dvQH&=OMu?(;G%j!7SaB;pJH(Sn26_BSD9zxP3F`2m45kRn_{Qv|8$~ zWcLakrA@PmlZ~Fjej7Bw54+w^v02LJN9g9Lq}_Cq(tMQX9Ak8*;vZk0G*Krh5z{>p zf6D!n(w7gZTG>uinJEPsMKQPm_hXnQiu zRMYeb+B}w*;oIa+4cc&$KEh4^+s6A_DW_*cHBTy3P2Md~k)9AMHm7^RN}#e~u%f-W zqG84uufiJCFeH3I$W0g_??d2mT%6<4YRxN(G<&$q6BKHer7Op+sJ+VU@m%+l^j2jA zy~tKt>Nbx7#Qe$&6W)BIdV6EKs8UUCCyjD($fobQ!H>fR@nc1qh38?RZ_(qs2f z1$=9U7)%WURk1RKPFG56WB7I%N^aTiVu)+P;bk4MDN~lxX1AZ_Y^>Dtd$pLgCyf-& zfA{uhw||o-`L-H8^(5siL-eGnk~Z#AimS|fm6xf3yLr5Agy*wOZfMttlKkt)ZeFh8 znKoM9BHz$d>ep*7HK_C==DS2!{5`v<8KtGFf*arIsk$e+LsS`04|(ZO?cK^#1=SL# zE^gJ8p}Me9oucM6g~2ICjS+?8H#Y04ru_?+mUfTC#kR7*0Ivgm7mGdhW+h~ZCr&j` zHAppF8Ak7M^n{@=&?>GNs@XnoQuS6oU{M7s3@G1-Rb0MlTP6AS(JINe>lfo}?b*$z zwBr63dPs@*(PP0Z9}7--(vO~he63Zzpf}Y$?jo_F+GD6uWV+t({M45^QC}}xKhEow zBMItha8!AB`I3~?$9N97aaU3NdX)L*VC8Lz@+vEKv=*j9`aw?L{Gl@Ssm#V*Q1Lf; zZ7TDmk%pQ|DvmrQ;Ya&o_cOm1tvX6j=~HQH6AtYlY8_EmgkxM!*AtkMrd&yl1)Z++ zP$}B-zCD5J&@sA0Rk`t=aVP3b#XqGyX}V5QBL3#h^Lu-tS)SNAx_}Z}(TP-MSs(8b z*7nd>FM6#~w%N4BMU_?wmh&VNV)F@S`#4FT3 zzIi-PY7f??wNV2@)!!4(6q)67!$j9~b1DreDKzT;mW5H&RU=M~7PZbRd#agC_!0?m zo%UMZC1gMHJuGZhRXTw{>wl7flx} zw~C~$!dACp6OPL?*v0K#{F#eG+`>C>VL3R%2g&&ZA~-O6%y(cWnfUm)%6zIU^K_kw z$MXV5ZB4GvD2pmT)E+85q0*-?{|*toFqe&!T_dXS5LdYBChf9nn%)(He#{V1W%Qn; zObvQ9dXpClYU~c4{;C~H|DWjSQGKKOuqShfGN886<}=`su-=AkPN}MWs=W$T`lhv8 z{CeU~b3**rnx@=-a~j_ajAb<@l%{$lR=7H-sEBeweMPTi2FG16uIg0$YI#u0g_?I1 zpGsGbqSBRIoz71Oq`!#lZ{HZgu1-g9qUZp;@|DJ=dFuP>{Zn;#x&W^<;|Ve~uhWbp zUbQKns0~-qN~$k=yw?>CRMQmBay6UdqDogLobIMK#s4pRDl0LvG2Y2fKqaoOP4&V9 zcl1~t7Wo{$qhyBc%fkG|aAG}PkVO|FWv!cX3toUr6zV!u`sHr=t+k^K{QVa*uX7V` zs~tm$^w&aLS9hiUjf=nSxe|MHqlBafl=xeBO6=oP;&;jc6aOLV3<<05Rj9gIjf9|s zs<`4G-i@0mIl?#0P!6w9l`rL^52T4({!d?eORaj}q4ZSxC_R;3^jy^A)5Y$mF(o`2 zZ!NjRlZ!b!k4rM_#_WgXa?XAPhz9}fM}d)geAgv+collN$h2z(h0{k6b+4PUU&io` zmwXJT!iAHrU5uccSUN)p-!MZ>qQQxNjN5fuo@%j5aq!+V-P^rPZ#3~vg}2d^%7CH$f%H!33qX1&^hF@O6IuY8z?Xm)@MT~UNbktfJE8QBEWHy- z@5l}Y(mS&BPAI)2`!gWDBRd30@5t@|q<3U@1kyXQLxJ>;EWHy-@5l}V(mS&BPUwfg zo$80rbVU&&P^Z3>`Ze^3ry3; zb2`%;(*o0UhSG6pkjio>$F#sSeFB$ZnqyiJdI+VbPvl&t1vqLdCqbs^lQ@%Uj%k5u z`eaULnqyjEnm&condX=ln5IvqbhX}`T9v{Fp{nT%FudN(FB=-J8Fnp+-ZPh8hiZ8frAeX{gZ@ zKtqj&{xIyE#q@2a?=XFr>3dAy2em&SQY7*rk&lRc zOym#He=tI1cVtEJm_!K0FJbp_o^9!vIJ`6w>mnlE*z&5K&E)WokAf{8uW zO|5+YhMl6)-q#>iTlZ`4FylX6-Srcsz8fn_rq7g0ras!~afLt02jEmsDE|ret?Khi zdv{fKinq7$-KP@Q(a%=?P5YkMaHMPdM2qt6Chm(J@FWWr9*XB!O8rmynMzkW>!)Ex zxFwWkL)>^19X8BF6Xb@Jyu5VvG7*6H=1M@ zezMNQ>)c+ZNN)3t)E3NI=w&SoW_5a5ox!XFy{rR+SxdaEB|1xVOluv}J{=`>!jo{Iumci2QqUyGv~`ByCfDU%a8eKUM-Z*uX+ZMj@^_Iv$>C>jtfQc zJ(`2VOF~Ow%Zf)d`pkpA>m!FR_<|?Cm`X1f-o)QdBUcw-{+t0i^I`a<_Jlu<^tQng;Jg|sw{)ugkVSlFEt z&r?N;cuUdEDlR*7A8xIRZvd+b?`|6B`@|GQj4#D7{M^`o;LX#}_^rYi?evKwE0Qv- zUCr=%D`iI3Tg_&wdBl;{XtSAMj5!+LQEL9a5%jP4v|cD?jzR3O=9{YzZoavO;IH`Z z6C9-38f%Vi4y_<|`b{eQEu=!|akRCWatw5cr!_wMikgHm{l)G&>x*TQg#vEw!aqsP zEW}GAv6!N>LGI%BzIw`qA$vO1VQ-{w6}k!;2FZbsuf~NZnv=4|nd7=`4#vi6xO@s? zF5=3rP5^VMMo0;2WbJ0|hSOT^gYYVJM0nNtWWn8_DjJebC#+pb8+^4={*1%m zU!&PRqvPdH1VI(Op}0FqRXzusdX1KT_Z;X?U`i*ZkJDyZ7W4X+O*5Ju&6(vsKiHaRPHY~Ls=n;tBU9fSmmPMI^=nEv z!kT3M0fFzgL)pU)wkDgCH(>IcbUog6&z)6e{yG&-Mdo$R8yYe2wb;^>gjEwr8Gsko zCv&AWOBfa&wgKOL!*|hF@waEIS9?ZSg^x?e&Fa|1v=Z}B>yVYiGR=zX4in98+!U`MAUaRr-^Iql_tF69( zzN@W%I%S&^MEtkyzWvcdjUxE@pEbzr zZT88U1GDB z`;^KjHds5EJDq9nWd6q>bEnm43I2;Q>+YbtTcbSIqOrjmZVo@w9Bz&pWDa+E$*(bc z|0X`>yF-Vz?$K}dD0BPO)(++lt}?rg&RRpvA?vL@%^_aWDkN>saq^P`HlP=Vj2Zcx zb8kBH^ZNC$#g68V=FbTBWEaOIc#-v6b5C>R+9l%pE37H0+>KS{Z&Q)ZdH6!Z25Xo< zUSm#KV*L?9c3f=@HHVoyX3e2v)_+UWz>B+^JC6D7baIe8xR=eL=Frt+P8iz%p}qE6 zLz(^a7tHS6`w-5wehwqj90ObY-1>$2M{An7r#0Q2&Q__RDG6VwHK#Ryh}jH7cA7bD zgY`?doyIcrm-zP!coI#*)0)2{rX?8=E`VKDA!Pn4i?m$;=7?1!M^#MAE$X8V=D%fd$era27=-RDe&#?njDp~S0rWnYC%mE^mw{w(arICIG#OFF{4CoH3aqGBP*MaY| zdA=r!=!bPHjsaoPXAT=5PO1Za)>lbohZU+%RpS)uKCIX{CC{gbYI*mEdibWU+o{T} z6{>V)TBU_@0(BmQ&suml=~P*T%5fCd0y98Yoi=0lZKpR^l{7>* zLM2t~Pt~((B+%Z}MN`%il zlsLMZQ+oh>Ad=b~%xv4aK0kYUr;@jfc z2|TrIc3AYl!%GHn;VZ_5%hrIae`MpQetwU;jMSNl>l)?s+elp7h*!1l3ibHu3->7t zJbXaiiFe4TN_-)k9*%#PdOGAq3Q!Bu^hgsuAM*XT5wxP-uMcShgX3L0>93=6 zsw>nO_xYbns@LN~C84KKLCL4s%C`@@;9+1@z$ZiboZ5NNI-=5)SMi7nInSzZ_LPq- zU7|u2DyhPfSYc(`$h=JRK8@L7Sb{72^6Scg^fQI}!63Is;eKSO2IuZ=RhIPL|Weo?AIpZ2f=)eNYokqWXZC{=;0Lel0e=re<| zOwVepP_TlJ{AgJf3ijCco7RvDHT|0n+%r4%Os{{FQ7ZJVZ@4Q1`*y&z2&vU;L*o5LpHtQ#2WNMSy97phe4{8R(TBrI1lx6V(k%<&{kpV+1Gt>*;^xw8Y!;WRz) zyg*Yv&kHm`tm6p+0iM-q-sf4JCVrmPtLm%WXM3I)H(?oNf*(1d{oR~#C=?pk(MYw>ZB0B_KtXvA#WdPDX5x3;QYQW25&gcA z{%1z$p@>wBT120IZlK?o!uo?>dxHeLCmy9GIa(j1Cl&dZmckIp&m!P=>n+-YA<91n z^*@t~U-8Am0q(c7Lul>B)WSU#+|odSdqd&S658s}vjlht>-Q+AZm|}Yt#(uC$AmYM zn~b1jl77l5I(`s-#FDIh=z;VDc}i5maF2sVjb1H6zpGCDihl93N38R}i(l|N^g!h%^B`4sUs@wXOzaiQYxv!1X*GB@o6mT?TYhm3H=%&CCtaB zk}6c$W4kFC6%_JKhl3{G!9 z&~WJP7q#foY?{5*Bi-~UH|^T#5pLSF)1%k4XQxN5Y0Dn`MJ;+%n;z+=N4V*c?pJ{H zNH@KuKo=kM)&f1!O^_i|Qn;gx4R!-)suu?v!G$*};wgNf0TiEO zpldVb(HnQYe+O5E0qj#kIeSkht4-xsE$Z={A+w>nDA0$!zBxqcpeJNsrmE1_MwR3n z<0`4gYN-Ogn!3}p!i?NAWh(TPPd}wWR8Nzlfj*s4heGN=MOjfDtmvagePOIFhqVLv zlr6WkFH&hGB;&>M)dXvBpv_Q2=`*+0x%KpAC(Ir(#FJgT+Uj62krmEK- zr>v*_O*zX?^1TeDral!?2HHG*p$w#)Xw!yl1zl8HnK*Kzjqe1#ga zUjSmeX1@r;MVVayV!LL)1jKgDei?}En*9n8+co=DAl|^UUjyR0)_xsWU*8b7zr#g; z-2NWaPUEW4K7`1jL=GdeoXFusRuDOY$dN>jBJwSYNn7>Jy&-yGQEt*yo;18XX+(L_ z<{2bPjor#CfVr`K^Iam2G}L^n`b@i@awe6d?`%|B2bEm})j&{XjY`v~Qgo9CpDO5E z`lVV`omO43Ry3^|q~-H%cSBAI4z^ECM7o@ktx6~krQ*hS7n`j1MhmD+-;}1*(>JdC zYu-aEldI6?(e!L>q(QAs`4MHQ$p4Aq1iw34!(va6b)$GiOyw7-(Gx0^r9eT4PyADAI}YPuoe zIj-b-{v;(PpLd6#!?c*iv$G_kO(md~h|!jTq-${O;lF9=?JkreH89V zUwElEm+r#}*@x~f-2KYRWg;M*x$%Z4))pIBMBIqK6beU{R^yHs2&nhUrH+aT5ap{LCl4JKb!qSiWn-V8&X-DCO!@bR*^DCIgm% zi}1UP*G5&hyoYY7W7kZ)@Al9zqs|>jaTm9AvA^4?ri;oAmHQd-h!OhV|2Lxz)Lh_O z3e^}?&&sH=tj50T6ctxvU!m$Og{r)C>M$%&G8roQ!E!;lO3n}Ssm8Fo`FHR?>YJv@ z4yu0DZZ-F*cImB)UTstx^yNTzQYx2@qX~%%!`?@5hlG1>t$$5#RazbWsn2)o--*8?iA-pVzTgi8NQjrtMOALwpTVkADtr$Ph0&{ke(kQdT|xAD@p z^+MZuA=3+4UMT5>Y%ip?-6M^`UfT9v=x1JNh!@(y3+?EIhI%3ObmK^4n3wi*FSL^v z8t#RD;e~$bg?9Er=Z4fcXMkS<)WO>tFJ;1GX`?{Fk>qh2e~L0F2js%-1xRGZs(%uqUB=JMcYNk z#lbFa@8Zu~9OB{*F7D{!P#2qA9OmNBUEImV;V%Bd#b3I(vx_5K{FRHlFb)a-g)o%( zKkU5;yi~=NKi>Ct_gm#3aUOVxl*rxF%+1l1ws_Wa3ORlYq%Y zW46iS17wj+c2JNV0ogYZ6xjsX6kNa+L{U*xHWyS7{@+t|>sFn*ef#wT^#7aR=a)R} z`kvbB)^h5cQ&sa_`MV(eT^Rl@3V-i$bJ>))I7Ih`ze~d3rQz>=F0MuN?uS&doiJf4 zz|IDbLv(r^($6;VYJ40&KW4h}P_qr)D~dr1Vgw}%9a1)ZO|cP$rNSQn6F#UI~`0q~f-|#j#%Her4hp&mM(TpC{3dYyndJm$*spjjWp&Y-b9-h5b(dlsPjy+XvrxoTm%WkjdzeD}-fJ6(Cz zX=AN4i*mdTX-J12nKvhA@jW;-N@$Pr=01mB}SBQz5Has~)>4mE_oDc2L5*k5SF>Qtr>{30qq# zVpt)%rZTD+$Rct4!XTW;c!Pv~z9E0;!aIUw*g(HzNKLzBk76Y*E9TwM99Pv%%@>CO3HB(v|I3+Pi;g?*XN~2bT7}t+e-` z(%yqhdk-n?J+!p*X9;!F0PX_T!<;w|?v1BI4Zl=|mS*OUZ zutaAQt6p;6_mnRAlG5HwOM8o1Bsp&}xg>jwIVahBdFi~#3{y4BU*kRbi*h8}yn$jV z7z>CIFB%!Yf+@hSU^(!scnQ$~fW^1MFJ3o^axc@@8r+Tf=x*<`1KQ^+Jc z9ke5h>~v5|2HEN0RISfwLN}1kTG^Tz(Ldw_^Bsj>~wHC8Dpn|j%16S zCJXJ3_<@D?C-C!0GQ>^?KG|WXg94dhr-KH%z&;(|$SUrG3vgt$5kI)XzY~72`TG=p z&LjiubZ{2gU#A1C-DlzFGh}_84$day>vV7q*U_#XYunTy0bnVoQEsx z@$==*HRs~z{LVFBzz@#9ei1)-B;ZT8tR8}NH6e#uDvGW?R|duRO8ymdK#$@2XQ{F3GSmH6F)->dLTM(bDOmyFi0!7t5k z-^zcR-tlRK&M#HSLcxgZCZ)tU>vf{rU43~x3Ut?7<@&Hg_p^c1rI4k~zKr}eC>mih zCXP`d)N0p}cr zuyoH~Lw-}8LJn6VMt%?BJcLMZnp4Q*0>j8-o$JFIK7Tbun(5#IMI0wk39fg2*vP|U zmV+x5alSx#Y;b+p&F8NozpoeCpfxJm!z|D#{cOb)isONIm#~X;gN3G$B z*0_=)&vpu@_&AuL65iMGmfg#3>2ovDx+UQe*y`xqLw0 z7vUC1oSjg++Y7SBFAJAIB+_*Q2hFCmlhr#|@8onL^PYbA3GVn7^33&Mf>L z?s1H~9(R4b`Uv`2xcw0)FjSN$TpzDMf_{%v@bSOMW2@`?Nb4Kqx7aBZ{DSt|=K2Nr zeVzR7b#R9yj&7&~pLG2O_+6CCe~rACIJjF9Cpwh(Q?8FECG%g+Bshd-3ZGp>&dUGlgr6=F#TS5V?Wi1K^Z_0JHImN~eW5+_8I z$8)ZKrto;cq5B=R$9C7piRU(kN9xc(PJq;*b# zZhVXivfK5)h)CyBr1cKn(5U@hb^R}iNE;m7@_3&1c+K_C6CN8K-0t{g?Xk!8zl_vA zPpNHka1G@7+V6GOKVL+8*uhQ8U(p_Kxc*lV>2nn65vPDVbG6@_u73giK1+U^9o!>( zq4wMB`WK1>w>Y?r^sCxqpYX_^Ly;bJ=w4Fox8L=@CL%rN;J(g_w8sJ0$D?S7@wij? zy8m_UanSYgU|Ig`T>dlU{e)BahW`!i{g&(F6*G8jbqW{z7i*8VUH@X?vCS!5;$NaY z-f?}%jq{(TNKZP2zz?+FyRILINKZMqWcr)h;M(cG*Bvu-HM)KR? z6mWO5_B-PGxQ`7U&pU-HFcV*infOZo3ON&B>FsoIMe=5IJkCE8K+!%pEp z{r^+}UGKKE|DPhyBTnJJ{QuG(gVO$gAI4`@a?*x44D>_WxUZj7s}>EdqJ;bPK=nf1^EaPy4?? z{=%=9Te!i$LHpg2_HTe+Yl_#~E!^nesQpH#{ToH3K5pT+{%^I%n6&>};c=^5xXHgs zd)%4!ZxSAT-NNtu-)WDrY5#Y~rY4uqQ%?Qd!tedxYwvMs|M&0~gQmY*_=Eok?KeK{ z|3RcVz%BgI|D*PpkoNy5JO;XjKly*s9uw34pO9KB%IP+@@IU_lXunBm|9?cJL2lvC z{-3qS1*JLC zEp&H${6*d~(tslBD7VnV@$nb=%}fI#D(+rLdAGZTTO1#Mk@u`LAiQzYe#*PUE%bDJ z{6*fg(|{u7(Qcua27JrvZ^H?iEjY}D$H!mfy&w%JqKA2JAfn?3u#bChsRX_!gCMj4^yD3sR? zoV9Q~R+l@^4op{l7=e8h$LkqJ5MX6}?z46z%HeI)AVc6d8ON!gxf<1}`$rTw@hO)eN;_D92Eqp&Eu-GxQ0D{*Iwf zGUPK7vl%*vq0ch(Ifg#Z(76nKfuS!l^d*MQ zW9Z8aozKu$7`lL=3mN(&@UP4!cbR+u4m|14E>s+|7Pen z4Bf!cjST&kp_>@`9Yeoo=noA2k)b~^^gj&!nW4Wh^jC)d#?Z|SH8~7+rB%!?7HW<8VBO6F8j6;Uo?xb2x>=yEvT6;WQ4Xb9gt0GdP^d;Vcekb2x{? zxg5^pa6X4iI9$qMf6mzq;BX*^w{bX#!@(R5;czI2!#M2gvJu*k!~PuZ=5T(7#a+PR zLJk*kcn^n*IlPy{B^)m0@IDUj=WrQ^4{*4g!xbE^ z!wnp6d* zKF{G!4qxE#MGkjy_!5UNbNC8}yE%N7!`C?6!{O^3zQN&}9PZ_CABX!nJiy^W4&UPN zZ4Tez@LdiMarhpG?{oM8hle>l!r_M;9_8>DhfP^FBX#4jJBK|uyoJM_9QNX{H-~*V zyp_Yg9QNa|KZgT29LV8q91h}eFo#1p9LnJ^4u^9%g2Ry2n2ypzMR z9FF5~JckoFoXFuM4kvRsg~PizoXX)e4ySW?H-|GgoXO!V4rg;Xhr_uX&f{=ChYL7d z$l)Rm@8NJUhxc;0gu|sA-pAqn94_PV0S=dQxPrr#9IoPUHHQy!xQ4^E96rS1Iu6%! zxPils9B$(9VGbYRa5INnIDC}D$2feP!zVc0%HcK+pXBf<4xi@m84jQ2@Hq~*bGU=U z=Q-TT;R_tT$l)#yU*hm(4qxGLH;1os_!@_MIDDPMH#mHg!@V5t<8VKR2RJ;);aeQO z&EY#7zRTeu4&USOeGWh1@Gyr*IQ)>qqZ}UNu&IKtzZ`bwum^{?aM+W>UL5x3un&i~ za@d!{ejN7aZ~%t`IlPU-K^zX|a0rJ(IUL5}a1KXsIFiFr9Ny019UPA4a14icayXX5 zaU724Z~})DIh@4dWDcirco&CLIh@AfbPn(4a0Z7nIh@7eY!2seIG4kD9M0!(0f!4Y zT*To$94_YYUJjRVxRk^DIJ}?3WgI@h;c^aFaJZ7gRUEG7@IemOaJZJkhd5lv;d%}? zaJZ4fO&mVV;UgSw=5Py#k8=1JhmUjk1czHW+{WRP96rV2(;Pm-;jAstZ|Cq14o7o1hQm8K9LwQ2 z4##sify0R$PU3Jfhf_Gbi^HiLPUCPohj(*0gTt8|&f;)3hjTcb%i%l@=X1D#!-X6! z;_x007jt+ohf6qI%He$+-p}DO4jT+87@9IoSVJ%<}O z+{oc34j<<55e_$VxP`+t@{J2@Q7 z;W!S*b2x#+i5yPia59HeIJ}F)sT@w@a5{%~b2x*;nH%;BYyID>z)q;VKSSbNC>KYdBoX;X@p*<8VEP z8#vs^;U*3r=I{{?H*>g!!$&!MjKjw{e1gNR9B$+ANe-Xl@M#X8;qX}wpW|>lhdVfY zp2M9SzQEy&9PZ-qB@SQa@D&bsbNDKUuW`7C!`C@{gTpsD+{@uU4)=3-fWw0vzQy6& z9KOThyBr?k@I4OS=kNm#4|8~g!)LkK%m8kJGLXaDI2^>`U=D|HIF!R-91iDj1cxIz z9L3@79NxjIo!nI z!yG=s;bsoEaQG;Pk8!w+!xbE^=I}ud*KoL&!*v`!!Qqn(<~qWXUK~YvqrIQPZHNsn zY~Nj+QQ3%#7t^@QTb|rW<-AlBj83qeZ4tVw%VE9O+gn~eQiA8&g!62|1vcR#n{cU3xWXn}V-tR06Mke9ergi* zXE`LQaaM89_k?FB=6Qo^fFd818ld?mW-UrlI+_^}!8ZxkN9`GPgm>HL-l0r*bD43Wn3RWA7f;GgVVE(o!PsJ$DF^V|w7tPkzq)wkM zW2Pw1u^FLTI7anURb;}+b&uxbrqd|r=4YSg$9rr#ViO?ck}zG$0`khsgQi}SdfdZa zqk1JRUcK!Vu#Zi+^=!Lo*}O>wJ;(eIL|_wwHM90T+y1bn+scaG&n{p8vvZT9&+`$^ z&#~_nYlhedWbIJ-zBMYx>SQJr=DX?j^LQWZVj7xAQ8 z@QE@Kiaaj*J)09$j@aE6uiM>rGtW5Nn7U5h+|DKeszd4FNg-G_Z2sd>h|;6U8ay+N zp;4siD81NpdIjq)5pVMmEi+buXW8FswoRCm)Kll4t$SRNkE*)KJGL}zo}I(|Xp%#h z()*<%X;S+g2NS?%4@#qS&&hR5pD=@2ItMBPnNa~9V?LM_ADdatN$i+6{UYoGQSS1dM`LOw~ z%cfImfY{8#KDQo8Z;1?8kJX+pZUXPBePSmTy`6 zMWM@L5Q{TuYmFgNq&;+Pi;SPx7mYQ()!`pX>ZR+9si8e_ z)3Q853F}B>J6YDe6UKYo7$!wNhCP{8*>fwK-SikQmQT9_!^Gbf~rNZ5P zGFV;xeWMDN(`QR``4gBAHa64cPxfS7vKfmv-lnMW(7mGa6!}K6E)Z)nBCy?}?ykkU zMl=S>$t>a1KWsB8kEls8W6hSElRUO0c|2+e4H9JHY`dYl9vkSz27gF1r>?S^Ao{vR zMywwE<@9#_VTy#-nt&plF@56}@|CfUlkhDcGnTEBle5(Y9=AKo69!LyTsbDxWUHOg zHr2;$-t@^NkEfb%jM8gTxvlqKl$AOhRR>7JYL z30OU?Px`Fg($Afpi%eA#igSUzmY=8uz$(-BvvZ@`r`${a-~az_X#s3c#hbpZUv^TC zo6ck_Dyynn;ePbiZM?Rpw5vU}{b?QQ>QC?ZiNE`#UubCT^rJnPe+Is2T?e(v+< ze&LH>I`7Npf8~M;zxuU{zW$AiFA2W+_m^JQ`SL5Syz1&}zV+>Ezw;0O_)p*c-uM6c z2S5CmfBn&qfAViXz3$)t<7Yqr&;RL@88^T<8N>J-S7YK$3Okgpa1gL zzunyAbaT2pJ)B#do=z{Px6=pjdi8bsIsKgh&OqljXOJ`48R86ehB?EX5za_wlykdt zhcnt4-%670ya$m9yG;&{^ZGbslooIqRJb&PHdG^RV-Xv)S3= zJnB5=JnlTz&pOXJ+npWG^UhA^1?NR)m-CYIvV&)j=>LKVeLcL4 z*W0Tc`;=op9AT&fiuRUrysaGXD95|XaY#AdQ;zqQ;{)Y5tQ<#_<3r^*svO6ZqY3X2 ziNbbMjvmU$}v+pW+}&P z<(Q)!bCqMBa?Dqb1~-79P5>1qjEf~9FHi+X64wT9FHo;W6JTka%@$OZOZYaay+FRPb6Zlw+`R3{j4u$}vnihAYPiF!TN#}egOsvP$z$NkE&OgWY-#|q_GsT`}6<3Z(Eqa16M<00i(ryLuUW216BtQ?z_ z<5A^!OgSD`jwh63t8#2pjwhAlDdl)tIi69DXO-hQ<=CMd&nw4H<#<6kUQ~{kl;dUP z*sUC|DaRh=ctbh%D#t$M*smN1l;fasyrmp(E5|#^@h%+lg^o_!oLt*ft%eQ)hMBu< za(&4PsaP@>rvmS$#u?RJ1Lyah+68md-u>xL?Sn1iw?nWqL%6=Nb%C1CPf=#6#>xoM z;{!)JbozurLV#dP)(-J^B6Dhs+$*Xqd8DyVQ?Pg}tIdB`>UQQ}9BXvI=p}e1oWsWyR?99>Z$Xq58 zc%tr^+z%7FTl8u3K}A$$DjW24^n>1v{!8E2JJvyb_|Qjn<=j`olry?fsngIf;F&?_E_D`T#`eR)?WUui3n(e8My{ZF2OW2TC2-WlVk7TEJ8Z@~ zYLn0_;v{-eMSg5G@^-jk%QZX0_(3bPo~kFvk=LCP=A<5R(k*dP?>MPXoYXT;>J=y5 zYLU>l?Q&tlx66h8igLL@Q|1QDrMwyjszL|vnZZhAR?|S_--{lUk{wgFZzi`to6s}8 zZkVxXSq=OfgUpRVlXGKG<@KuTG{6PjWpt0|1BspnJq+v<@iro&{{$;iQ7S7^R>lk?~krC7iJ&wq2W90EfJ|#w;K;(8Y@kV1d}@q5naJ&9 zescSh+D ze28a4Tf(#qq7fdOItSa-5=;xd0mW1BhT0@NI~XSoSEPt(X-P$owXmWiRBnoi6Kljs zn_8lxqwKI5?{=Gn7YpO0(Ta3j6~(}6(H9+~a$^;})25cF=vX^!#v5moQr`GDX@Vj} z7401M+#-7$qtkhlGEomoVU3wAVaRrYe=3vjni|H7_^vYJO*_tbGwgT+6xSWAuY*C7 zCMFZSZwd?KjLfyfCuf44ShWtOg3l;EnFpJh0XO5`)J2>~1bYgrvLJO?z3*aSr8nC| z^mkLiSrpxOMHXSRrQ78CsEH$19JR^uf?Bh8sS;*Xfca$MFz$o7A+eK zMT~}-&;mQ51(~a22`vEs!n0cd<@}(!2Dz6o6Eu>~iyB6rRe)&4@axH448GnQ4$KH? z6{t0L8$s=noLo|(_*Ct?@r;7loPy!v1saILFrw$D@!4*xi{evpW@RFXONUjVKgg2)eO z1~DrI35u}CSgU2&zB1j2(SddoKGAX4AO)(p>hy+6Khsd< zSNc^~oL+zsz)yEAWYU-Ta9$($cq4ZZb!jqwD>MnDHk659ZD&$V?_yVzU2CiWTU@77 z)HQjtRH&vpS5uv5f*5lP!Kix5?6g6)m6j9wdnxC#}ic z0O={QG@(U&nntd-HY4QM4rB&513rZ1w=*Uu%%_Oj`yofix8ooK=KqVH7#g z!X#L_UD;p@{=J3`uw?1Hb#mbhyFFIca+`ibyy-Ua^6Y5Ze+`?qND8VEvDTochbfe3x<|sMlWC*r%G?iZK7PJ_b9sFI7Bunk z^Y!Qf#bv)3X+|qcE}9d-FZx8M`Q3(iO|hkEu$p2qY| zbLYgm%Ou~(bIkgfk}#`qs!(I_g5W_tNb0?KLEwQ2uvQ%J$%X~d(>4`E&(kFfk}Xyc zqa8b-7Ekb$b(2`0l+n;|L5Ny+r{m;`>JgAhYpPglT0&csP6M9{Org;5p!eGP9@@yZ z3(gg@7LU3$1J225s0gaSVOIE+SDy}DPyurvz7l5gn;NQRVhydpcD1_l^oE>Y)sXjd ze*Wsy3spIALRH?AnL$#wD^ml+OY*QK#b@)fb>BHSL*3>bkhuRn#UUP`Xz z(16M&dEDCK0WpoBkyE5G4y6R$ouIvJU3fTM!txC2NbOH1wM^42b)=v!A{J5ud!LT3>gg{lI2iuZ7)kn>ylIq!MwKY%gYt6cKP<(Uk; z)}znfP{0P)&lAs4s6ogYa30>yj9)_?1-&IKZ5Qfl6%nWqtOYM5KB$?)3s%LjBE4vn zvMk0f+dJdEWRrBWP%XA+yqBq8N#$nlskBp3dcQ=gB6Z+G6%AflLyX%r)>`7PXvq0) z2bo_f*g(R+35vcFSsZ)J|}^=+7CyGVFD5qu0^+q-up+T~(VFsYmP0eVZXi zh3cW0VS?zVW-wHstL&;KwS+`i^jkA**l$fzids8W;3UyXL<%eF@a3t|kPc?#7f85oo4coizQt zd4kgq<+hiaTV;>j(6{&5Bt895jQzHE#yen>bdnTfPsTearXL~K%k|7OJN>Y^Vs(+J zC<=gqifQSNq-kk)$!Y0TDz`Z?yw>crw8xA>v&3tO)6$yQw6q4Lk<-%M#ik{^_*=%b zghzzMv~(~&Ek$*qg1r$|9SbgT7WRbATZXrTfheUtNU4kWmRWO}tFSA#=c;g5uIDOr z(WJTR{R*eGScO)k7>~aq70RZ`XeC=XmB!Giw8ox_6 zOjYFRA!s^6wFr8<3w<^;BSz-rBDOG`ZE+{PaO_3*M zI$Fw$#EcMmG#hJ7T>}KQ9sO3s{-=c6;#D{32o5gmx60A9;$yZbUI@x{e#RTCGj1m2 zxVnb?`EDmauQS`@28|-Ke69hU@>$r=wDxPv488Gng*K4yw)WeA%{2VzgSGZ1)R}>e z)~3=;l0}160BzGCl4(uMVQXTVjD)C>^jD&IQ|juoiPfgIpD(5xY>r8j?!9n!gLl4r z4mG_;hx6K=@1E;>5Oq~~ch&h`R6vS3t*$;NJtH1j2M0;EJ-J&gqQiTnjyD{AP z7g;^o))Z?g^fuA%TF5Gm%`XW!^{x>cLt{Tma>JQ*l&75Z%U5bnD^K|G4pznE7k-pq zoT=p%=iL)3PUrB0#8s>&D`ac9UzDb!p~?mt?w^NJFFP6PkX)!kxoAIW3FR3JOE zf*!?=mid=i*m-qP*&$N)j)medDf~rYTVkiNy@hrfO~l!oOe9vYu3k5rT7p^aZimfy zJ#13SyCqKQsYnsCI>!xVS&4gMtw^snnQ|r7k~)GulrSgV8YlIQllqZvQwUlDZCFc! zmbIziA|VUFEyfV52>b7=PsgANg%DsIU^GH3Nhma7`5S|sWI}fF{H$je58@HKc<2}? zo=i71y{%}0gkxY91`w#-@ku!PWo-$^ZPZjQq%vfaZfqvTn-DrXSWw8)LZAl9;lsHO)(uE`? zUVkVJh2SG?CI)3K^oz8ug;dQO0FeobDuiEH9T(L>ZbrUYu_Rj&y?g4g7*Ke<0WDKD zJ`k0PnuKhdFG*}wQPuE_fTz9>seQzx6bXzMWt?_`o3!UXd_`fy?x$$R!%QR(H>6M_ z-zl`C+G5Sl`0b*z5ip^E518A)BlDV6Fz>DH2maJ0I5cd|oIj#1Knb1D0~RV(fUYEr zBz3FTwNNeOPEh$mpX}a@kfxm^tIv58?nDP)s zid^h)5H5l9ZB5~-3T=q(Dju#9;i?KAh07P(`kvpmcsQsA7QhU0}(!pfdP%5zs#G+6fBhT(sKw1i}# zZT}F=+4lGY?)5;BEJS%xd>vU_XXR%;n+o#?Bj;2biOAGZRYBdL&F_CJGLY>=PUKb- z5@iWOq9=*e&h*8@wXR*8+#)5`wYv?5oT-5vB#Z$VX>hiv2C{#aL_}h!kp>bY%18(O zN+BGdfgGLdCgs|gtecGdPom~$biEk4)xc^A$!537Z>jKHYT(L z;chg?LAXmJyBh6ZT=p^o`zLs#c1rj`l8T|UtxyD#y)4DqiK3$4k=YXy{Zej%OEGf8 zN+DPjlf=s>xDwMlzf{9_-B$4potQ~eRN+V@2%ZkZfdS%Ozz4XpX*$enSCFEBk z;ixWDun}R^6J#&EWq3Onh*BDkl)89=sWcl4^O5ykyl_6!vKMsGB-zVs*Qpk(WhW+j z=>*A3;9OQu{UzlssFN#ZN=Q`HA{yExDkG;V45Gz#m{^Go$rBp_p1}0H7Zy+8N-*7l zE1@yTyulJKscXRDL{fi}uQsqk%2*IpQnkqE{w=@2kIcd7o3k=P-M)YlTa8}w-I3#%3T+-Cnb0`L#K^WC zVnbx>d>5ue{d(dS5;Kjk9F$w3@ou4p+EJPT*I-XiCZ1w^fej^d11MPWNix}ByqmMa z(msM1Ta4OD-w8);3fv$zMid*PRqRMfr;2${#3nU*m0trM8VqudOctSlrGbTn(Ce)* zav)|gz|&xFF)fQT#SnDT1d>C(C~uT+u2{Zyu3(&7fm0=;#|mg^m7$}b7YbRNqmH~? z*kMNA)xsO6mAVviR9ewO^abNJ)ydm=hslArw;Hmk1aoPq`LU}(|6!Vc4_zt^4Ws%C zoGa>SF~uoPOeZQXmR)aMc;ZsBhM6|PGvseGxi#5vo{yW+Q1?h-md6H?HoN#n$}pF- zQVzt;D_+H**s?pDi+rkJF#J#*N+rz#w1F_9coVbKudsokT|g8?CAO0iYkDo7m=!h? z#q_8c-ln>UpmK*DT&UAEO6*M%3wSNL;}a@~Zqc%8o2A54RI6&7f&dk!+TyF&AHN8YDUq0ll0C3=?NE zl>4A6G$r>LW8^E96dI*zHyUL;hJ_qAnu#TLZB=L$%&89wA&smI)npXa4uDC#0Hb+vbK(frZgnuK9oNVmyDSvhTR5X zsZ6&>_%2QO9fLuyvT_BGFGX>v*i*ByATVQZE(pH7sti?cV;v0EBMMcYiegm|7h9|2 z=`H<5=TO;E+x5+08h`+&a}6zTPUjj2KW^t57eDFFHEH~0I@drn7GyiufXNIhI@iFM zD5&gQL-DFQ*WjQ-P~Eu(LojI7xuz9XP{b4?9?+H|gIji1(?Yuez) z>s;gEr)}q&w)i=vbImFEY1g@?9e!#%*VN+Y)Xp_fa0cx=*R;paX`O3M!%v6KHDG>& zy3RHAdF)}%7Ilffd#P zD)+WJijc_U>8Xuovek7u-GOObG!kBt!9(4h4K+OoY|M?6z?!{5dp=p;*FESZIbv>Xk0{4D)a;% z8g~>Vg{H)MLZ2`FL(Ul5E_DM&iLITofh0?lU1ysnkw{H>k}-tqJ>A}tmX#}DoEaA| z&MGcooXrJ{b3PIQ<8|SRTcTA|51>z|8@=d;ceA$8|0oVWU`xHZln8UKEy7%`81tl& zM(ZAD$Y*53)0kMV-G~FnE({5YL3+7gO%#mX7^#KS!*SOS=gM~G^IO^wP41<@%Ye{T$gaNtOU)&ZS|A)SC_)_>Vjob36%~@EI@L@R74G<^EMhra`UoDbc>dd^B5!9TL^x+h=A#aW{xV+ zN6?D`CIN4eSa*nl+j%O+jDy|ZOZbO=KA<2EUYm=6caNONLp1~DhhqvJLd`p!7Urkp2FI7r%y2wr11KbxU-5)0{qtbum z%743f&~4ep!`x^W4}Am0vy}gGyI^i zmf?qp&J8~#si#o02sum(EEt5f6LL8|3x;Je3kGEtRl1- zKTxckP?2N%1RMXrfiBLkx{8i&LeDOjAtQVvt|-aL&8tghi@u*nl6mYxdt`zYuVjNE z&<+qo8)eebKNXWIZXi&pbU-;VnJWmZIhw{?GIZ?Z*C4eTof=d&vDADB4#kxQDg`S+ zGF2R0Cl$U8I01E*-x`Uw)`>#7(}oohML>ykkzv>xHiut{157#G^|e$NI8VNugao36 zgGv=z{Q0MfB^9iEmG@L#Lz~bVQYS^9YfjW@3(4{(Sn@p-B4yT;;`Hj3ZC%je33bZr4lSXb_VgEuMmby(ucsAYaW*Gy4qI3#cC$M-J59<{x6tZ~e zy~^4XhSuI%+gslTLEaD9-r6vmyw_OXSR~fPNgFIum5_O7&YO>^)SLV357}nCm->8Cq;Qrkoauw~SCmnlcqK2qpjU>k3=c#B;xL zWv5Mc)_WvACu}Z0C*WpbDDENyu}8t6AMX_v1Jp6NBsqo;wQ$*|ZPlHow7Vn`pJ7zw zZ7pVy^%xmsiCBrJZMVRD#W-#IXf`};yA8};^10e4nQ;~6AoR3kaw9<*=W4}uu0|Cw z!o*#!CP^Dt(J5JReXHpmUf*hxbgNK|C$hNBm3oVi)a3f8OABm06^(9K(Hp&u4)5c9 zledfPt4KG`{k+G_@r1zMb#Ty8xSarMR=T9N2!Q3Ha5pb%jU>B>Lu9x>Vzrl zt!BdUd>@0}7rl(`wWY(6VSk`Yj2v$p6q0m3v&uXk`w3y+)I|Nw2&9ISNeYJ(ZUMku zM&M06^b)u+{8WKMwKr~i=;ek}a$N5n-QRo`*iz$8L?xIJhR~6ihD2mfg&H+81ioDq z20|vVugVvi9ZY@-L6BnzeW1PZUaS+BLO1r+2~d`f_cGW!DF!3KU9n=6^nN<)iRqhi z4mGEhxhI^k9pdWDs2$D;@(JzGI8B$48seFg*${?Mts~NYC2W>{I!n7*LQPj?u74(E z3F5Uf6@pmE%^7;WoOhv-1A|HmJ={YoiT3I2=?-}Y+ih$zCboPj2b~67m zrM%lw@FG&)axaB?InM07Qk>b@&6%B7Pk`C^_^uXtvlz3pr+Mr1-JIEh!Gye8WUsU} z-^baF*GjTL`xy&F4?RRIkOXD0KnJM1nB0rw9kfZjOmErV8SibIq?05T=#8xRj_CiA z1v-JNMcz!ZBYzFenruhDhsvjnI!M0tdb4)qZy(XQ|Ntx@y3HjtGviBDej(i;FVY*ioIS+HJ z`5EbmF(c6uTkUdg|Iigr6QUz=!DAAvd_cxtT^%WFuiC?!{@8sHc8J{RK7m8 zcgDNbCg~(8Mz;#DFYPL%)UU;Nk(6;BW`EK=cC_R?cFZ2HO%+n-p{65@VQZjwqpB)z z8u?8XN#|h>$L6ua(L8pr*gV!*C<7(1J3BW5%MtyVY8%~xTEbE z$juTy1vX166c{Zd2_)z}%jQAL(@4KI7ITq~NeS(i`)>Z#jr2MpjNK_L?}ee{L6sIA z!V0lHE5*oW2z?74WwAr-09n(bjwFdZi`Fe&W(xeghRDl%O&lPj>s_E%((4y_!BmkG z$W&3>`WxUlljSEZ79o2%*T(^C$`(3Xq++xU+p0g^(74{F*62v@5B8tQ~}-Z5X##sE)zOW zoMzC?Pd-rBVXH!lQlWKkWmdr3R(CnwZ#oxzCCMZ-Lkl0b>7 zAkv0tP9YjbHFTsx5vZw1t6D=+@)}_`g{>OY*E&OLoo(Ryu98P9qE^`2ASE-nAR$VQ zimI!OyuG(oX9zA5*7>b-J=IE6Oogha=-v9l6WPW}aVghUg`o1pH&#ffNFxLlCsx~c zqVa9&I&-^KF_QV>urM8hM|D|HJtb4Y5)bRWVmAejqM6eShH`ZEZnvo=E?>FB4x8~t z+oY5?CQiCjkwX2=$8%HQq+;Cpc!MEIIIX@a#+|QD;LayY?i|Wd)pe=gkE`&@Jgq+E zByi{Av#RXH5+}c@N#f-bpV9OVKch*~xNe9sZ-^&Y^t95W);&Z?MOOEUGJ5 zRN^fZ155nncs>|F*;+M zJD*&dJLfIK+rdCo#feC%izh~**;p&$+<9m)p}BK((IoDCs}sumlelv}MUwpqOaSOw z96wa8sTmSp)VosNA$e^M76;`;)+1vpP|%2iz+mc3|L09s{^U@H)9{Q0+F8lSNkl)rqUhZtcULgg@(k!0k5{!kMX8pHtWzgTsXV9Hyg5^8d2z8q z!n}DmdYMux)2FZYW>gfvUM1vZJ#kPB^Z zSTNZnoh0QkyTZH2m?0M>tDKoWb!tUi{Tu}VlZ>6@;RIFmOe&Dr`M~s;^ue>jsn4Jp zAxOVG+l)elS#0W45y@vdhMZ1bQj~!8NK6$y$4oe`OrBXGRnhn0UP4P19o2xcn9CTz;DBL;q-b z0q^b&t1#CR&gql?hhp{M>3R26$aBbUjd&tEG)0-)f;$IqVQ)jKE{$=5b#j^6@g?bj zIB9vDv;q_DM}O|XE*_RfyLf0fyLcE%D4rbk;hCzITspY2;zTYTT!D`)EeO>sj;pAt z+>?Ik;0pSZQo)^T>7|2Mne9slXNFS&f8FP&_i+3x;Sb5$1-N^;$h6%#lx7ji-$3b;vM&x z-E=}@c71HjKK#*)+4UzdW*>}?*)_(P?Nj!c-Jsa(5@U8FAG5cX9(An?BzXf;#%KY$S#d2Ue9{E#|>P52h8epjMnt* zRbQyWL{IN}O1Urdh6P{mdb$(8qg9ORC=pc*c_vHy1=fLv z$O6j<0||ga8N}!>*dtA&R3P$}mlY^^xQY;Zf)mW6nzG^D@N{*QDg}}k=t0?0i-xCL z)XfxdfnFsV9^#R(;h8tqSX`ioyYDE9Y)m6ElnDw^>2ZOc_(awE(D~tppaa?xcX8!p zvxgEB6%EBhs#0)I6~W@GyeLKJ_%s1wd4`aqtH7NQ7^3!)!MzniPtu|UA%3A9S|K!t zVqeDi+EmtVq$xFM)bbdJ7%ykxBq4F}@)PAqLvapN5UT7HP>v0p3_KT~h@L<&Jux=) z69|+E^Tw_nV*^L)&NDg_wUrkoB8vwNENUX2KM*6&p_d9Skds8)C@hs`bp<_5aFKtC zQS4LbxZ5RuI~K5?7}9u$;8GNu4wRY2?q6SMkDhg^-#+YF%o``p2Glp4cD{QBZ!`b2 zC=n|5z&H1L5sbdPf-#Ggz$i>|%*`^Fb#u#+$!bVvZ8ECh3Lb z5K=->o;~e+hp3$`mam`*mXygs4|fpy#1Hd$LYPb@80h1gWs_v$;L$h-3$5g3%$oK#YlTjf{|OfOi$^#Y!UESmi@D(Rk@W zL5P3J-z5P8o>ljrr^PX?7stLe!Nt^^Q3Oglh5x&q&<=RFxIVlKj6Tp#d>|uXULY_0 zK>cchTJeGK0wb~xItW!JEaL~M&Ju5XSp{X{LVLzXE0XRZ;$dO&(%4g*J$r~cyuR2y zLXU&x2`}@J@5PsYX~fp!=PI|-MxuGHa$C4RI6kiOWXko17nAEfY0LG>-wHofUIRRR zLJhE6jq0RnC_25;A$YZg>gi`_8)?e_gq-nNn_5E7_?#U!<88M|DQ`!d^t>WPa>jCX zKrh5~Kra^80d3$qppEzr|0nB!uxo{!2w%j|n|N!Q*8xSF)aa)7jR`uSmu(%;PBckT z9ndQ$K?fvymr)nUEkxHcNn8gcdXwoL_9m00n}>8jFIAv((M&AwbT3y2v=f6K4J~#s zQk8@GQz6K9G1HEzFMb?x4SgXMl$0I2n$-clWJV#S%dSKn(2Fr0(2L;dVPo(O6q`KMiz!iD$B#jkxKp&?Jztsc+EBl$D~OL$E4N)p-Uy{fEK9L zGii>K>!Lcap2AuWwx4bw5^pu2jD{EWhLks2@DId8Dla#^&W$ZK|A?=?u*Ew*KceJ8Z_=W0O+e>v7T>iWJSu zEftu*85h3oHH2^FztS^18|t=82;Xq!pR%qXfqBbc>G@m8Gsk&Ud;)cJ6*r1OFG26W zDGD9P)CXPZsyBVml@7t`+s)_@tiGF!E<%%U!3ox})Rprl$0)8Mi}rO=Y7ZVS`2nV= z_mH7Eg!N5TH+qxmFB4>a((mVzNo*^_?9QZ#D=db+RaM!pO3A!y8BoaqS_`l zg;87cQfGW8Z*n~bRM9Vp3taz~d_k*Dm~7}kZ!{s`8XaLJowJ9Stb7Z`*Zes^j`g$-;O>rZY9UXb(e{WA-sP9s_Bp8a3FY(_!erfVey$@Mi;Rf(H3e>g8A`5 zX?~1*bk(MWwjulMjaA}fS#Pn8Rm%@EQ*MGiRM|`OW5FAmBwjwj4w~K}J7|*l#_B)? zxI?|MYUxAeWgHH~J;jic5<6kcb66J9n57Om?6lp^* zx{H}s)LrDk7aknDN^}fxkYcn*>p)bXB^E5bN?5QQGHZ|ef?<6xPI^C1`hcX4ANg&! zcJUyfw~GhOfL%ODf>6Bho6D=cD_YcIy-T#%VU@DB`8g6NeHbSl{a9MeE*@IUE*@IU zE*@G8#j{!r64Qh?!pLIHkYaepPRQoxXw2rPiT1-M-%jtS7(-%v+hRMtX2cG6m$vy4 zLKOKpaKsB}b{;b)x6{M&uVz&eJIp9;^E30fZGMhbSUdJhlD>ELS;sGdd4ayH0xngO9;(wvBPG(o;E4v^@@{vD^eshD_5Cu zD}*d4wxM|R`c@V_(9*Ax9cbx~5qP}HjO)Tql>8CQ&V)~|L{Z>J3`A${VQ?@XcfemR zds$=~e-aH2L=Ghk4hB?;nJ#R3^szGUeR{h1y-%yvb$M|swn))-L9m|nP4)G_Pc-gu zyn)mk3>uc~+v21_aZ(>4UF30zLsV&z3SJ|+T+EI9aPyd0bH?op0VW2^%qY-DI5hXIL zQl2!$GEs7?H!7@p!aXp&WsE%HIgTJRQctWws(#d1SX!*_qLvoD)k7Ce+UoVmIu!}; z>Yy}A4+71Im}r!|j|`Odb&RY>jbPr~dc(qWe;7ux9cHj@l}xc`cu^NkdGjL0p7Nsm zIQ!sZYVC~B*F6X^5u7Q#RIazRh6LoP;srKf}~N>PyIk^M1{{#|D!7=Um`=NtTuFdzhh7@44qVT zq-Ld!dq?i6Cxd3+&_+=^=^{`&$qP)hzA7GKa3w8pNg+tTHKfw4hKGf&M5`MqQQUi> zfR$GPJ2GXPor1}iXPhYv(hQsBCm%RTvgf&Qwy9$=4`ocHBNgm^4D>*@pYlu_-WJ^VGNt{PXqgaZpsNp zXJ36rc*PSBGb2m70TC@&Cv0H-)5K-+uCh}MHytvJ$_twglIP$VN^C*s{YeKu;)%*M zy)j9Cc)k(`-RW`3Y`!9V8q+FZc=s(Lz+#g^($eX?DNmV`#GX+ZFMR7 zomqTD>WKnHFbZUKM;uVNz&}OS4bK5ZufLsXk4Tt)yY^Ip7vZ0%YiNflq8)Lb#wTh# z>fk=DT%p#;8Rd`>XihoRnln^{_C8M6T<*8Wf9U0Uo#-WKNbCsBJbI84LJ=;7KTIiE@5ju zMQ*L{;#=$S_SSkd8mg#y>eQ34wVp=2uemFByy-THZ>{gPy))hno1~K@VZkI=dl63_ zny0o@i#i&zEfmt&)nTM7gv}f+5ZYfg=Yk#Bt$ zFC6)LYmF|Nw6&g4=~O4&O-iefTc9(NKDdMwxCFVY6i0_r%mX_eDUOiLr4ffZT*|{{ zM*2sw@e?{=*(E*C1KYC}FC{ zuCx6V78^%M8!JsOqry~z`|8CRPQOa-*sF+N?I>cUv81JGpRWo`=^m}i(XPn%S(;!6 zyk%rsrP~b07-?-Y;x_IAa~ToHAB&mt2Zv@Pd9KJQ^0dO9g|Iv!taK_NgbnTWX!%xD zL@8Ms^0!K(b0AM62SBx!Vp~Nygm*0F+Xzz}U6$DQHX4&yQtS!o%j;rN3*+)p@YClR zL5T{cF>|@NC6i*fBtpFaJn}B$I}9Fq|7pSIlwb>0%_%ZuK{#gWw_?rlSVaV>occ3U zb;s*UV^8AH(N^-RWCASfMPBnxW`8+b}8f>noi7M z;?&Jtn_5CqHO~&4@#fnkoa>8|7AjJU6;=1dnVrSOnVow%v$Ny`n4OcWs9ODzE2>u4 zmrztKwG~zSl&UE%*NRk47X>e{-ldL^!gL5z{C)H}IqCj5X<3}~K%BHl$PRgOt*|(# zpKPzPbPrTlQy0dz$Q`6!#Id{T6}lT{zrMG7#dzn{&GXLpg45t?sU-=#^Fxw%Mt4%o zD{-2uY~DFhEw%0>@XlfiQ`t+kl$gIv66c-8lx2E{Qmv>6qHJGe`S#tU0F#xl(T4uVx^1= z>!~2IBoP-HQ*oD&aG|M4Iz|*N;#yk<>#-sg zJj-|wWhWwTQSdglWy- zyi%4eI!+PG7VSxvEjmF8s$YIE3#h|%LKyX^B!vh$ifr!p&011nb50Seus1ed*i^Qe zV4LuT9;S9PN&1K?iFh7S-pa-)_p9==JuS)>#jvuWFQBrej5gJa_c+5)QErbqVRlJ3 zxJ2A)hv17*c1T6pP{V8)IVnW8-xp8r^XDpsG@_W1rzC^Mh5a`>RC^Ya23Ah|E79r?M#mdGj0Lo(RinhM=Zb7zg@L ze}(8E8BUi*n9hzp64io2g}07WUf3L!k*LwLtG^5TPW)aJVg8`LRSJDT9}f^6hW81S zM1{q7HNG+_P`A_z&+z6MSl=&H&!U#tT5U-MJJ|;|HWuhzTj`^6(zZD1Nt<-D_mpTA z9+&j2DlP1EXh~I&zP8>K(H@Bh-B6E*Ix%!Pb$KOSdQ~n!FoGhGh6)8)rtOfDlNjbZAfZXniiiRI80q7f_*S zkEZjYJ(}IDmbZF9CpiK2fQ}I&Wc9Eb>sCjzn%he%i1ws{ye)3jrc|Q+;WWn)Z5<>T z#>(-da)$i?q?+PB9;uTw>Oy|dNER`Y7T+?w^4NQoq-Dm9MWZ?dUl77FQ7&mti<_MS zS@dv52BF*+2%m{dZJsSIwRw(9ZMN&jd~wSXDrPK<-q5=6AdFm7Lwj#}9~hD>+Itt$ z;s!JnTdbDS{2Tt)HM?#_rpB-9$7hS>_=25dnHMC#TxoI4<=+bRa^{&zt8$kKTDVLb=R@SB zWgv`F`;w#?*x+j}G+9lx?aHtX9qr)WpcUHm)|)Q!e$)0&M}f(EukD>--urCtthe7L z;Xt8Hs`L)pB)xN_Y~NDe;gnxp_Kg2_e8zvL_>BK9pYadA~4L;2cNdi=&vDMw+R4C9Ysgkv*6U5jQya-Pd9>T~~vpbZ?IFl!o z1iS!`MK&!@5z!%7ld)M-XBBl#od_rbX+|WFd27O~OsLzApP!L)U@Q88J~0LRyoqKV zEDuo!GKLZ?F5cpE3q}ZR4iw5Gp%;Wc5e-Si&~ms{8}Pwt(Y%~WR)i`tm0}9k*2_`b z7)^c~9@&WNA?{sSGn$cz6g(gS0q1SzNe>p%od>KSAQme; z8mKaT32oi35Gw*t37fd*#Qn(~DQlLV^b%_J@P-8W1)=p;t(IIvp9H~$N@5AoU3hbT z9Og_%i>YJ|H?NX;7v<(EnL`OGnPXBVgZV+JGe{-#fvu8BycD9T>cme9b)$nQDtoDt z>28y_N~VYHo$+q5NjgcY(T9~@Pa%Pjx9zpmoT-dUAu#`9tAv^R5C}JRmps4Mj?I0kwlfuJ292aJ1C7*$?Phok~vzIO6G8=lIaP7kv_IYJ5^@n zTuUzb_{ zh&(i%UM^yti!mdh5*}PZ}87IU&6cHM| zN@D!OAi;U^byjTVb-PeOtEua}55-)R5>a&}DP3GyRifBNU^K1w5>y&8y3X_U<{7F` zI(uHQg9+~p`2;?pLXgyY1E{+z0(~>BXdv%_mN&lCZE@0|IB9U4G$c+M8Yc~lkpdTn zLWA~Yy%+T5)>O9Pv5?+~IB8^@G%8NIU6DdwE!(2Q_`6tREA?;J|O>?;^}i+SU# zq6UOm*4q%8sh^Y=@AeqGf07+9Jw5om*!`Q*nh8~wwC3mGZIO1tX}aR~Pe45Fkb=R% zO0K1NBm$ZkCMv6eJ1m2nWiAn+%=7#GkUB)x;mre)-G8~p`%`dxfiW*Y$m!ixRrKP8 zsa5Rag=x3|@&AB}7baJEZ+^79VUa@#`RDX1Db0~mY6x%UoTPVB)rGdS*)boO2UF|K zt}1fse@2yNpAt^}PsNk+oR^5Cpmn0pfVcQIqC zMOyOjV!AX*oPQTHr0E^bkS0m5;l#hss=|bc(Hb5{cs3m#@lF(9XhxKn>dE-x7&8Xz z$T?NW`Q9}6cQjy-!ZSB4hBt$zXCn!3W|cg9X3&ff#J0{dqYz=Be{6uvk<9^CzdUv z4LrPfhJSUPq^_#lt5gY&X@26mCLB3iIWC1SvB~u(!MGBSI}oK0 zD(SC{A{hB11IRrN*5j-sO%{bJpkuq`DdmAZ9YG~I3ZgQAXAeAueS(gf)VcQvHSR%|$yhSwm8zfY4p%@~Z>L70w z3adg%`xI>$p<+;0I({u|SQc8@qUtC~x^bF&xtyhlPoJl+Rxwl3)>D+y>vdrTLPMd7 z+;qpO6f>F4xziL9q#DQ!EpyfBxDr#V%3zTQtz82>+E8)D>EHvk<*M|;D&+c=T`}sh z%wvFK0-&)PS_8lql_!R2K&JpT9r{tFcYo$GE7DIBHb>IJg5Ixky0&&5S3FEJ(bG`*^!El8*M zZT(ZO5~Oy1JKyVy!`rp=eaE{Z_ptTaqxC!pcMv3v=xVDz7kj&DTy4eosHb8+S2MRg@_%T1-wSgG3D)a?f0MSpr zEhcv(L7}HsIODg%a7fc|Ksc#W3BNLx1fsXDg=(Qcu`~Z^ONPr<%$Cg!m&4X@`EHm& z#^ix8LW+*Zq8VTez8@wkcj@We9M{Q;G1#m{sfQ;y4ZB%m(!;cTpEYHIbbp+*EKYg= zbJ0hCH?Cbg@W6KQpqRCbhrW*D$+af3S6!SbVeWxGLqp-*;M9bsLX!8YB*RN_eQuAt z#P-%J3f4AnspXA^z9&vv93vszQE8e<*-}c&?JzfcD{NBATNx*CQ1b4`GEBh-sw+VEDh z+L3y^e8iK%Eb(nj={mA7WCc5?;(UmmO(tii=CL-VqQeAJU_c3J%+G)3#aQIZ+0_*k9 zL_L~XSTFRnv^)5AYN;<_y*|zfXRv1HnwsF#QFh2nSwl#LoI+%c_aOB}MIdk2TNCz0 zgBp-kyTY*R^}3y|%~^F8|vcRKfG?i{)Io|~}m zxv3_CiWYUH6wBO{B&f7yRa@0oTV17Hc6EJH>wOBI&+gBA)ny8z$e0WcIO2>7iUTT& zh@uFJii(KLlL&%{h=73dzQ2eaJ0kWzC-Y>AR{zmdrRVM#R;*YNv0}wqD^?)zYp*In zi6GzQ*B63H?)mPUXnR4C$>Z0JRtjehw~T78 z=WaP3jX(^)(2hB@tQ=^{TwKwEW)Q^#H}zQ>y}xi%Uoa-Nv0XC2+z_2u0?BBI0p{zP zqhT>)fVrfax&s5urPZ?S^c&SA?)=n~E^|pvIvd$}?ORCIpdILT(r*t|%6}(T%3nSa zR^klcKp?p9zPs`t!a3y!gB04|+qpvfJLmyoh4$q`6xvr>h4v4P#$Mrg9Jc<0ku=`lD>UA$ z?;UEquPnMg#5pCVOiYL1OI^GINLy3GJVJEg2~{0VrX|Ly zNpZ%hpWw}yh-~I`zOtCqj>pS%aeZOBAS7tX`;~rtPl2DKG{n~vddTA3U8-hClsh6l zu~#;=3$6nvc1CjhKM6nF-FN#h-=rTV%q|_@jHUq5XOkAQI%^!pDKXB>Z$xZ&^F=#v zl24_dZ$8Cft^=fc_o|y%%EG;n$uCY>U zM$l%#x*3r|2=OUc@9Hp8>B&8N#m$ShpIA}o4=<0S<6dr~;}%D#yBhhQhKGqcL7r1X z#41eRAod<7y|I=Av$?jBZ~KMu3UY-fvbpq@TG8~FdeX7=q)*k7XyeC?{ET`Vx7LcL zKdvX;R!{m#J?Zv((sA{qJL*Y4ttZ`CPrA$O7BM~L?CwZ5oynEmeJ$|SEWb92ocolY zSv3ACA73)a2TbN-9-xc9eoqqv1Wgllo&5s04Kt`DuHw7it zu*aW~Opl)^u@ac8%_b0Gn*M5Dfgkp*fEkbKu@s`V8EA!BW%cHTtmc~)YTQ)7`+dJ` z((2k8OD_z;q1>MmS2U7#nW1^&F=JxnZL36oJ>~)es#)&mD5&1t>ZhU_y?8=)%mcD% z&cqqlTv=<39iwIi(jo%L|FQ` z9yVZ?5SKT@HIYxGCt0a9CNOs!u%sUd^|73U5Olv`C0m$GDTerQwtRx-`suPYFMHJ0 z_KNhBUZ04*&oT7LR+V5ug&|vQhirA0mKi%5vNg-iLq{31wad-Jj7_IP$RR^!iYT0&rPc^BL{-U0AuS+WR9DfLf!2^R72KVh;VQ?+J z|FOd0x*@k&9<&Mr?l-%`wiE`x99d!T>&HN0V20H-Z@uBnn1)HQ!oUn;m|YBGm=r4v z?&pF5pxZ3J+@ZqYK20pMKNbpuU+q+3aDP}ur|Dk}RTx}TyUlV< zd7I@;gA@i2jHEEQuTU7UPm*46dfEJe%%uP|VW z4pSI#v)cGOOyYSO4i?Gp~lVX|hr^7T7p1n6Re5DBRh`{NQ4u)F!g`5M#;)Q&5VFcNB_=a=Pt0 z-rxTB!24ZQyuXj{lX0CGX3z~th;lN0yXHxxuPl`)T=ko zZ>iz6dmZY^k!%N7PMl~d-a}Yh942e5XY**Bi~2_l1~6jt6N77y$~cEq|M+;}i!;b$ zvW)O0XFbIsV1BruUuBYiK}<b3kNV}~t z2c3Y!f-q(289nn^xI2z>@4w#A#d9*|^2DXZB1Vo(6b~3|X~@Soqc@y%f`&L_f3Vh6 zr9*}<$9*(W9~>Bw=-76#^kOWIZRe?CGE{5lD-MymT6>VK;5(}D?k3t-2>vVDKq^q) zW4DX2m`Q3DgB7>=n~B16IZl4Bwzv?)dwW}~*K(M6yrhyi;jrrXR7%kEuDt{j*UR^) z)RbN?EJ8)|UR8|e@$G#7N<~AaxYYaVBr!>GsgZgUS9yOOut|zb4FJ5QLMAi1Y~Sj! zAM?A~N!RQEn?jeo+&_mGxR6V4rS)akRwcu%t)|u%|L{DtvQFfI?r#N51=zP`M$2Zi{HKT$&ECcCkC+wjl5n zYB2nb3pH4DjQ|f;Vt44BGBq8+vsvcNF*JdL2#5D6x}7QGU}|rr_`&^&bJeVS+SuNQ zRyeFTy7p;%A7-3qWGBp#k#UaDR8KECVOZR}nQ8Y6150yQ_gsukCQ^!a?qqvmstAKg=sN}b4G}1S`2uIo zCr>uZ`m7{c*JmZ%H)8Nj<)#sspC+O_O=ha6rPmRQ?~G| zH%fAj!CLo?{KDHh`H$D-dmyiMvhl8Qe5zGqSvU|WP5;n5)IxkxC^cbn^0N}-+VnJQ zqV1H$h3O6BQlS%Lxx~ol3*3Dkx{Ci`u6V`IBY5|^T<;2YvZ=0_>gb*wKB{r$+@fCh zs3sQor_{rH*5#9uNX4vJOEY-uTXDeG*_b^IPWQvP60%Ucz+z2HqxQlA!r) zMfpV)oVZ=yz6RpQJVcsEFTjw>m7cAOGe)DTea)3u3*}q6!ur8=_IBL}<6$4sV?0(G zaKU&On|a*GRrAuD8#6?l@uPWZ%@5!yIvvkKyiS-yYuN>gc_@J~yi z8o!&z`&=VAG+S?{S0l{K)|X#G&y!wV!C2^U*G%*?Ot`nxD|))1P-)6q!gBM)*+K;EC&V@vqvk@*)+%|-ltd3SxWb`RDzjHS)N_Nerj3!na%!Q%gvWp zm>T<$F9NMP{cO4UPg%x_&-{x2#(MLhv1iDdG|Wi@u)fgl81FAGH(!}8mUycC4#(FQ z{awe`L)xA3?Jqa~CF>6yU-h$Zy6hfwaC1;R;__&t42Dct>{Swi-UW+Z{DW1N{&>E> zwA_4^TJW4lH2YMizj3+wKZ8A9spoMvP}z+oSW=ZR)_>e`^I!9O?)Kb6>m$h?SC$m6 zA7az36geYe$muuzlmma=9TOVbuHX^A*_guWTLdOs3Y!fW;bvf-+Uq}lxw$QgdmQvs zz#m@%(6o3<&vC~%9e)is6vFnrXecBYJYl){I-@i41x3d%jP*AyH;+lOO_rXUN-*SR zPbj|x^y>Bfy_cKEC)wVt@Q9<}efSVYkHsej*iyfE^(cLx*xKGDEVZkf)G!K-SOiH4 zd-wNQZf;MqeeA93eXOsQB#wvH=h$HpluB5lP&@r_ufOkd^Ry(}mxerHEDCP`7(4N+yld^A8%QJ#&_PBKx!lWt#T^3Dkij z_sG`>e|0lP=eHC6CoebOkz`Na89Gni1$2yhp@LDt?bs-u*r|^SDjpyk5d1jJ5 zb!UBlY6*DfLqXrOCst?b(vj_8glInfP%nfT5TueRRP8SNUaq?X+mba9b583NVM_)p zK;oDs!~$>%M!148_ii$0lnE?2QBj5hj^mT`EQ9~z0v?Pd1Rq8aWI8;&+tgvm6T5}!bY`S{kn_3Fjge7S?#p(XW5hG#&~tFw~A1ToBJ&A2)9 ziL5DvSa6>WIk2Z6mFX}jMC#I=JYG;1llBEs*wvCxev%$FStgKQNXGCxl`33-73AC6 z^nAj}6Up=t1*W~cHRyktmd=xdxPz$Bxt-t2XY|^8D_^PC-dj9kKf`q_l;|_cTeW3| zzUHg9%wWOI*KC>LK3=|d%M24OU$wLrohEG902^qNr??KDt9EVTy^N3vpp()Su(6&D@h4mrfw+ZBSBiILEXIT~*wXD#)H) zn7(6DWZcHxx;SPuEW$iS4Ux=Rmu4E)U=+_VY(gk(XUk`Z%huH`>khggT~-C{$+Fz2 zSQ@75FJ}on%3`93W>Bn4WE|IRhSyDwbUou}80_v}&v=95!_{aB&@5!*@8?EB zB>`~|su-6T>(j#JiApW`W=|hpsc93pRBDb$&tHsH=(#I_8QS6f26sW0JLzngZw|+w>-jxKs&I-y zx+P2mtcGYoOREl%6LZi$%*1`^4t*6p^z~KrIP6r>W5WYI3%A(J#=6fQYWvqbf)wVq zSTObmiWs)N^mIuwENn?6X{B#q=F_$lLnP@OL+~2`l7H4Gt%n&5qs_k#9HNso#UXeP z&BsP0OniDg!9}gp0=cmSDI+cp4N&_Y^IW zu$Z~UeQGsz2j0!6Rm-;1H&v4w>6`0GZ*fVbck`$t{MPyipFVhm-xiPX+kb}<&WA2U zvr399k#2-P*DE~|OK$r<7ru0;5N&S0xiy!!UzuLNj}DhCzD%1e?Ac) zGfeUVpK6%d7-koZt~nVecY){XV5orf%?&-E~+@Q=?8yS@Dm$f}^7O*WCA zw&ac$ve|cP9fS$*nq;qz(}FKKCcitZqJ(!%4vSZM`efLi%AO83_V)JY2RUP(F==)= z_8~FSj#pXl@&U|w6a-&r^zZv;YoZl?swI+-Is44T0!sj0q;neB{rTB=l z#B3Vr8KrX1)taEzWgT-aYDAzuXbzHkc*53$;}@3^GCClkh_MBm~_NRq?zDkW9Zbwzvnnk{}6} z1@~2(Kku3M-YLGArUgrE7V~~K8_b_sS^Qs&&Ce%32OU3-btp0MD)t%SVhvxGIGk^B%%HsM@*>xy~&yylmu>Q3iZ+=K^16J~z- z6!mLcVr+JmS+^4yxQ&#U1EfOWGYP%j4V(nJ0rr$me>Jwau1-Q`pv?IHBHAv7(9`?J z`q;^3t~ToB4;$kYu3+)*kF^zMEqoHiGH%j z=CYk*bLo5^`zaRPr<4t<_q>~JHpqAl`Z7YQDT_9?)iaW8KU;dg2nK#97);-f!PNTO zOt&R>JZt~(GMXGl#i9h-US?*|RmC47}M~P2!o^fyE{fWoOS!Ki=yf$q3$fi#m-&K=n^H2}}l0K{`cZcCHmI?;@ABm0_oWYbTe z%qv`yneXQxe!G4Xsvqvy%om39)_O~oIZ%ryRe^Wc?@6OmH z%PQMaHo3FX&^>@%WsHnjfWDY$1u~8=Zsk_%7ECoeNJDv$SxZ4nT6pWy6URiZXe^ih zvVbR+nXGD~B2%RXN1ALlSh+JURb**)v(p|;{BN5UcfLzkO(CE1}? z-Z|87sUPnd&ga=4_~eZkVJ*D}I{oJ^H}6TZ=lT(4=FON9eXg%AQX7w*=PftyOS0!x zXL0ttvU}?JNn>m?YHhJhRB*D* zzd{^tW`8AaALUUPls?;Y1xnP^tLFqKBxO7J=7*4|nuJR{yxJY`32X-i*m7UF_K_*nXEFL&dM}Z3Ps+G10_~i3n_E#nT zpvXi%&){E44alxee}SM^FI>98U5J0-(v6Akwbn=a{geF{bJS>NFCIM70Wrlg&hNS6 zB~lY4pUk-1<~C<9E^~ygA3s$O#!pz{uIH#PD00`s$UA6YUfZfb!fV-86{L6|Bt<}e zL%-|=V&g9`JF*wxg_<7@HI4?cl*3-@-lW-4g)f>|B$k!6`+victC{^xi4+Z_M;j&L zf9AL)R`!zYKS#N*pI`i2SlLUmzcs8(LlYIqUXs3HzW-l1Vl}h>64m^|82iWK->F8N zfkO80Ic7DpzgJflr9QIw{eAys9Il$#%OW^dE&E?NObNe#$o^}Ti(dBS;P(&N%L~~d z%Fg~ldfETB-27ZK`){B_gURCGaR)Ypk^Q&w%aYiXdMR`IA2cZcU7MPU91sa744x(Jlk5b*egYhs` z2$^fNYxC`Q`SP>bVxFJ~cStM%m3s%(B4;$q5*a19ci<`rYwjHg4GE$yS=b?CDE5-5 z$IbmRiyA^E(T&E9Xx(p8=!;1&RD5DKzsx$&J76G*#m#*Qf%`3;v@KO(2T0WFu~dI$ zYgTX#CKk?oyv#P?Vdl^xHK-@D{DymqToDIH)8DY9ZfJ7h zc;Ad`aZZ_f{%moK>~2TM}5gwmu+as)|Fp}(c;@Zs&PM*$zjEH zl70kaR_2#HL7-0nR@11RUf3&aBxd*woS^HK0bF0UqX9fgubI1sAq$Eq_oeLZs3Y@a zag|YnxC~M6JDyJ#+%_Nt9gv>ImDlWi^L+Vfn{{6Mu8@FUF{ZnhFT$3gt!* z8`0%-b6@nO*#c{H!Cx;taxQ-y^R64hqr-2Tmj&tN*#Vap&Pn=Y)1c7pP|t} za8uHe_%WTK9&9;7u~NM<+iUO)-K)ex(?DvJfUzDwXHC8FJXXi{lFjO0vdqSC%KS#g zb&4lO^b&2~U7hN_)o7|`vl2gMC4O|dEIvRSh^JG47jRgP7xapxU=g0vD#FCq{Y04R zQka^pijA3P3d^&n9lapO&KQ?KR03^hGP-9Ieh!?yUd9N#21g=McukR8Txpc z9R;(+B3d?Z#C^N<%K#%TZ)hYGe=qVDJ&~wTd2)yX5Fm+Lo)kb>dWSYamw;R;g1ApE zOy%2;_TOAgz{Au;y>~^ZVNXM#ptK_LJ0Uz`JScQh5#+-@dqjz64tGLKOjp&%B)ze- zbS`HSCHVk`r+1RJk;?0FxK!1qf9 zdq*%`+48QwT#W)WAqNoWiH$V~v{zIN`-=q}I*D;_XFS8zSn7=NyeVzQc;1pSV?6KZ z-p;t}mAE12W4gC9&hy9I+Zjg)=iZJk`*Uw+T((SRA-s)yJL80on(6X0y=8`AV7d}C z!_VB7nHAGq&gm|lWc%mo5ztcCz1UwJhVpLXZj}3!m-SbqKd8g#E^V)ZRa;oj5usG8eh*6SAU z>0dUBr)lfcUI!01t(fuL>5`6yiPKuTk>A3a9doLso6zj1U+d{=PZ4_8a-&(}PzRH> zR_98sn~Pd7Ar=vw#j?p_&Zw5RJ?S0Zqc-NN4Xy0rG6!CJ{b{V^jpE*@2F>A?nJdk< zXPkzqqMR!2zO}rs_Ou-lUB_-mYW3KSW`xS^$fKtv9=D9Qk3EGWBRTe7(%>EL25o&0 zwamgjOv=lsP~Ls&ZH_L1HnbPGPa)vpk;%kC2kEj+Lb($tHSXnjSyBz%P)r~z zLD;hzUfLoDy@PPl=DAPd&J{02lnk{+kjmj%>TrSw1&O-S+6<()U$+V=E-IBLI>xG6 ziDst`C%hW_$Y40;x@!c70GWSK>VC$_3w4%Yr&n-gBmKZ+5t$e^&7uynC>s~&j_T5} zKEN!`#N=b?sq+e7iW6^oLnVCaTiW^8tgl6)5%d+=BhwE~O8a71nO#+|vQh6xe7Jr; z;v<9aM|?ECA8{6f*cQt%3R$EOA0(V06Xmb@zYkw*8FAYQFP6`e|FS|f*?}Li^KWiM z9?dvb(^HpcZlh18m-zb=)`OVaYX9HP0@FsL6VMYuFZdF5&r}OL*hS7Rc9AlO?47M- z$_P*UN4~%N7Ya@8QEDont!i*5qKNyf?FHFKIr;u(cj&G(LSS5)d!RT9gOy#>tq9cd z6WVCx`YZTJnKw%_H}6w^(rP91>%B5F%?t{u0AWtm;x|GXaaK&WCWM`P4It5rm- z&7#51%E2Cfa;Ztm=A@E2*+7`b2Ooc2iqCyI>iBb?PI@&-xehwop@W71CMndRO-t!F zc}U!BZI+yo;85Fa7`w18JB|C441(P#MkV0pK{>lux&(R@9wg1lu7paa-7ACA)uUud z)9aeWxn@`Z$w1m>k+`qn=NkKZ>hI-T6M^=}0-Xb318zVN)f|?}fxbpuE-U-ZGAOq6 z5uPF~>nZ94qKM1axyv_4rX{b-HVLID5;yk$juzIx2up14mXtBj?R0mn9k!o-%5Gs2vYAgCJy_B;yFhW{6Ndlb&i3gbQZFOxzI4a5whrSEw-zy1fs-Pnb6=|7EWbGM zu?}5cYCu<{$QU$qcBO%9qE$;TwZlT+t_FP`EqJ^mEIX*)wL^;F;GW(oF(a`WHVO4# zoHu$#OI-JIMsA6L$(4+4}Tt zCe&_W91Js1=&*$;Qcalpj?TeS1X%9ov!;RcPX8&u#MEN@LRf=rtq=xW&p}kR3kw&0 za1vTODti8$HZl})b_0^@%C{2ZOo+(b)#k)&%``VwHXuYoOTD^gK2q+Zle6^656efnzstuIy|ad~5sB8V=Bocxr9? zo&I}YvU#L4%x)ADNm{E4S?lC-@vnV@BDOJm7cMZ-pqg>f9kBh0l50*(Gu~M6#%A6# z#sY_p#@#O>jk})(bR<}$2hb?CIaiTh1@jaVFk!IGamDPwY{kF{6BJhmST(QVBASB- zB61;epDOXKxlT|(DYuMUA_UX0TPN5G>keQELA+fI)ah;F=_@@U-qN&hmC8)~oEU_Q zYsI4e_nM?aJ&kC=JqIq}9a^U$F@B?hhV#TpyTEz;tYz@4+|g%hN(Y;O%3{EGW5=go zZWfhbz((Ctu&E!0iP-^V_?HeXzcgD;l^!OV`T=z)5X@xFYroxqACvW>o`Du(7Pt1? z$FjAHch=hT9?RA)+gWSRe=J-3*3Mcx?6GX^JGIu##uhJ^%X@Nocp@6m=U?e`eO6UWPS7GRf8Q$FA=gk6&gReq&>)wCt5m>*~qF>5i~snw*cp~eX(ZV%v5D&fS()G~{6*=F6e^9gb>ZbQ9@fmJ6;d2QCbK3cuCzPc)!I*Z{4!f1dm~ZTkSUF|DVvr* zgWkyy)IcSFT+3cPz`>`BL%xuY!4ZZWQDGxt`NKxyFx5fM(uJ*{DAd!~yL>*i0hamz zrF+V$ZTOOY?5G8RMj8}EmQ7h|Wvm!9O1%*7G;7*@3q`b(hCb6$K&$jMDvxyu~p^}kX*OY|;q!+JUT~SPOt1qCGIa0tP&Ej0Teyy^%ATX$s8)5g^mM)YOD;>g*)nu!~K7zi7(ak)?L{bW+&dE7WR0 zEx2h+(c_ZBhBGWcm80#_l^7FVv7(hUTMdkNkiDh~M7QhIL*RH4D`#);K$}9fjrhbiJ`8VP?cK6Q&>EJCwN>rJ+PTp_ere&zi;XT2Z(h4sp;^-9HVUm6tBU^@z*mzvX0Y?rO zw0*8_K9@_z0aSpY-?E4c_(UJl%kl1$=BW9Z$@D7YnZfI{WtK{EG!IJpCj=2RJie7W zS5FWzuaW+U7b;cAcR)3K#ZmD3ticP>Mz;`Li=*Qe*BOczD= zLkD7516w7c^e`X|_b!4?q!9Nkx&B-7bhi{u*4|ESm<5(uOLzLdcKIoPHC&>MubQ1> zJhnSxc+qPnY&~m)rryhn<{twi^ylZ&V+I(Z?`;+CMEgavf4|Z;7&=z`s91B}Cq$kZ z*I7;n#e=fUwA1ETh%h5wR7gMH?pm!jE{ew9iOi{aXFXXI0nB{@kjwb2F6NN1o{NpTx zPx^+Qv-LVWKs`N;2!WB;NkAm!Uyt=SzvlrqN(>tx*)!K`T|2CSDb2x`ch0fI31BX} zB+(8Z!17x~j_VZ(`F`fGfX~sJogJz+t8vP)vcKiLL-?+V1C|6kp7^olyM7lm`z3r= z?iX@R4VkozG%@1S~v8xJxvGI z8hB6mIPH{6;XnL+Z=FeigwV9ckNFr%srA|Pn z#V=?f_dGM9Kk7(Z2RNoqEV7)}DxMv!<0CPmaMG|_MAxh|GhvBLtR6Qv({#fGrCgNk zu|9t^IlON?aPn<7AhCBgY2z-_On=-{gdi%J$iy<%uFs#1e-m`Pkw*|NG}loomGZp~ z&&OVswT|$$c`s)xO-|U_TBr9=8wXMmAzyiTK23Ql9g($iZV4j!Fved_8gj zi;=TDuDN>1LN8bdvqp*F1PH?H9KLNnk<8sE=z~lt0c&RovpVIM>anvh6Og$JPVRHn z2vU4l)ssk7Z$VC1Za^N|Jr~)h2q1CJ&pY`klZ9(*j6{;2r<1$`uD0&#RiObp?srPD zTWv9olWKi$tOP>8RXj;QPpDiu18~1VE-ylZ5WLSqazTx5aaMKp;bbFf8GqxT=z3F> zH&c;6M9t=@d>`HGn9852dmU5xB@~_Emxo+d@WVqcEBV=X%ZwbgpR{FW z6+Z`VnOV)xr4(JmFR#3yYtt()>-c%{mKl67@~3Q>*@K^FZJ9x`=9#lCGjsg1a=6r{ zCt!N~?6+kGK|6oymYEIw{OOjNJ^A@2Mfc*Dm51D|iz$ozuwwiCa0g|HAJ*tbez?N& zIDWX$@_2q&oKKkE#9pw&|JXt6>*M^%ehW?k3t%R+(l4@H3hrk<*peh=xrJfZ@&)y^ za8R`Jc}D(<9r2?*aJkk>yhi;8UvPf53Mo2fdHzUH%SN3o8cbP%=DpF z78a2L9y_op-NARngh1(gC9DT<-DJyV>|J(*qOd$gcZ!+^@d6F0oqz^NfE?1%NPtDl zYQX`syhi8gi83^1%TP>TOo#lr-+!r7(cLv zaekgAhP5L9BN*27l<`rn5Z*}8A(8d)*P&GkR0e{xP&_hsFfutBhl%d)RlTsW`*mqH z{T-V9UFx!Es+1yXBOG#NZ5%J0Tuifc=`6;q!SC7pCj5Sk-zL8wH)EMDox^W?x}#P4 z#YsXYo4>xSztD;&=~pHn0r+%Fe_u5DNRz)M?N*VnLcSFeKF=Pc%{ZE3mEq&Ih75&(9gx+^k~JD7>BW;_jr6CeqQLO$lYI$M z>tI4gwEH3AfDxhaslbtlK=zkR674$XE_(#+4Hh;vYvMXQ98=#OEyb$^zcJaL^}^;& zQ@Nfv?_{&xTC??$uEP4}sEuA$FIa;f%g@>wZtW>vx6vQYMdbZ;M-d|SrG_dc>9-~o zl3~BhoD3|f@180GYxlZ(x_f`(dI$WFhrHdFhV&OU3Y>uLs2CDBaT*SAaT+8P-!o;* zex1z5X*iHT3=Xh*fCSztEcGh=3q&=Ie}VX(3i-V`+bg|Wvt%!8;ZwPL5iM0taS@&) ztg;fS(B+Cn*a)H37Ue$|7rJ$yuu$Gi?{w#;#V{inbvwCh<1&a583@5%nkUti?MY!H ztJ@dUp+H%2T3=QS$zx;A z`sDy~)?;|55`)<Nf(?j zxX%9CKuc`qu6EiWk#%%`Ps;W%F$Ifu9wy4}i`~*ylr{H`x$;xMKhk?;){d~|7{{S4 z>qtM&3%LaRkhk`>_6zJj-pX5gdl$F({Bm@>vT=Q9tcZAO&9VM9nwJh+t?FW^K7F87 z_$Qq6P$&Onl0QkiPNmHKTrAm|HJ{OFh@F~s++7~pKnPyTC4JD?q-?dn*p+IrrdLYf ztyv?Vcy$Ev4as8!vesHtt)*(Mmeo?$Y>dc%Z#MreF&f+IjBQFuf-l2|@XZ61Tl+HU zHPeTCCL2ZTLD?~bNu-=_I!ixD&iYScYUFZ^DKxD2FvGsw z$Xl9WrV1WcMTdhcaRzPQ+k=|P|JpHC&$m>KdK3}tf3%W+9oC=bzuBSrB0v^-HxKJC z9T|d^$p&dZP!Zl$GTt~*__o%);OHOi25xl>iTi5fQb#=MA{2;%jk_E<+aXU*6?gCf zA~@!Lo1PW@iDbwzD?^Goe12nYVrLnLHIBZsZt zF%RfC=~1k_R<|PSo8d-Z+*oiUF3(2QAD!T7pdd|ML|Y%Wz)^L|o$TtrTtMS0j6LXe zb#zVmG6&hNPOvS$2;zhBN%jmbWl8lp#t+)jaemOGOz?w|1AUlur8q!JS1MzLrebq( z8fTt~Elh$UaH8mU(Z=HKcHVj|aRqfWDEARM$mHGIA^ z9L~eN+&btM{*Q8D4kp+v^v1yK=q>WIH@QzutFLfeHH28{8kW`VtXjt(>A|zAspy!e zwxqx5LH)Qh;tb8jbcY~q<=+m1%PMBrCBb%VP$xh|W4Fd;RMqq<5PCrvF1= zmZLGx#b@LHs`QDaYm>9|O!Yy@|I+i+2Q~f@nH6*XQ3o~tLT3@XpI-P#C;v%e4Y&#geUu>Z;{4(?u3yvtOJ6evN8?H}v$Fd?3W5w(AGkNx)BHC7L@>m1XKfrK zLD_xD*YeuX`BK@<^g5SR9OPTwW0Dcw012PLLC!3gM%K#tQ*MBIS2{fFr8lxD0yjVn z6K_t(g~075-BmGb%xdlM2YgV6LJTF0+%SJq!00lZp7mBFOT4(xyjAZ>#GC=jh#jlKm%xo@Bq32O;uluzKat zC)t09v*6+KkSpA)xk)go$P{?2WZm-V^puCpZ)YiRazV}J9y?d+Eednt60j(zpPw7@ zVEY}v?>^M1BOW zF=fY;iRlo0spxG$+M516?74`A>b){9X`y;&EfbRo2jY||I_!1#?d|5wYg%UC*%aN( z*i_!kaPty>3|NLp_ z0I+e}OO<}P39P0}`nm;$Aj;s9-PUIILrnXdgWBMQlkd?usFeVfBpnP}J_iT=v6YL+ z#Wmch*KwuvjSF&qT-Z_P5WO7U8==T?3-eu=x=+-=+=C+pi7nJP4PN+|K0BK!S$nFd zzm0^T*Ddl*W=CJOvisM=%?qIra<93CCIdtILE8KRIy;egdEpRn2@2FlBba#{byq+C*}$)-}FkT!pN z?Q?pJ99yXlElfP+z#4mkjkB_BdI zJ%M>!O$K1Mg5r5eGb!jZV2_Rn47D7&bywwhWDr_#NeoT!MbIw^F)ow%t?9j%1!OiP zr<9m3SI~Z~dkb(u&YY0Mm|kz< zxN1T=_9^l1kwJ3iuO(-iT0`Z`2iO^6IrG6Ga^`QU66Jl6b@lHJsR$+bP$fZZK_hkZ*i*e+G=(?J+hkQ zTU3pQC)1;JCD6{;?zt|wLCxF3US)RIo9`2gkF3Njh`=7qd_I-=ndu5=TrT~!dgY4B zR{T&QDh6pm2^p6k4y!2Pp-5D86_sLunzUB)VoJf{#21Uog);^B%5QUw zcIZLC9pPv5zOJz~3NX&Q1rHiHOWPju7F{abE`7aFbqOj4MP8A%OY(qrpM$GN0JV~})5^<_DJs>b3@m^xf56hd-v-i+)=%xM_%iBsmLkk-F0 z0h}}y^2K1Y`JH@O{t(RX)F}n|V5}Sm5l7rU6FMcVqJ)#D^42T!_CG6jg$Jgb6Q(3lI#4#nF~7IgnBS=( z;5zf$K4qC73$t9>Qdw7--)T%BDF#Yyn`^%g@)U}0P0g|n3Z=zr4U>x1>X{!?Y8dl- z*-q7$p;nhQ?R2~xNC|SMdF<>t5)zlC9LXy6(niMma_gAyq=?AJw z9;BGdyQb0)?gn#t%hXPp%iD)Amv;!Ea236Cr_AMDVHGiqcMfGPr`MRv>5Q&b!o8!$ zT;3f5u5*HS6wKv=J7F$ojLux%Wthu{D($AlnheQOtVz#Ym{P--i@V-EOt8`s&RdP( zC_yyxJ9MH8qLKf20pSZ*hmrxIO-;{ayd{5^%w~H#nKVk>jgc;IBf7l2ICR>FHQbXM zL=G$;WU`S0l%oeDINuxPD4z}U5C-hdB`E*BCa(Bey=;=#*cif2W+u?V zgo)j-L-;X$dA-2F6Le1uVa5aQE;FVmr$A*CPYn@b;90{AmVV-CCS8Y8LO!&1K3Ut= z=obTc#@tEy?B(f)r_5(@#27s+(MO7Uwt4D}9!=~cQzJza`zRYj5mm$Jv3D(+*xQ`1 zbp3#90&Pel2sI<`h1W7M@gZSiYHmc?Q2l)i#p;Wyodp|`U}s~C1zzt>sgIlH?9Vb# zOFr|QW)YQSxDAryw5p`}&mu#t<8E+p)MplORk(% z^tdHZMGxIw6+Px8=vlah`Eu;Bd=|;XykhIMLFsPkb{%O|08Qn@PYYdv!w4c2w?zW(KCtKx6K0 zwF)NQ#-~77m#=6FSd7jmr?iYOxJ~gMIZ<1=y{bS*9IMPVQmiqpt(?3X zeKgov=Xv;!CjGIj)i>TChZ5-nbB!&@BHY@?Q@M{BymNPlRm_4+!)@`uzhvk+}aDx;3az9-I=%#i7OTp7t_SV zj!pToef?t-%!4@TqZ4-Lmn`t%dGQ#=cv1g4>|jg|W9rQCTXudID2&n%A=()IkAIsM zwN2Kxk)iY;&{%rrL}~DzkkEv*-_btSF#=JgV*2p~*p&?A1+T=*Wb?3*YlLe#b##`J z&IrY&5OZp?5Q^(AcX@K~yc%nyKQShnM%FN!WK-m{Y*-e1W7#HzH7g}OX90b@2qcp# zW|b)OV;GH~7i+KB@uO^ZrcW5VZVL4Sm`IlHOFr~JCz=iHod~+z*TtB#%I+h`y;1nz zxE7@S#r%9Gm9vc#rpqjXTE0aZeRVH(uNn`$gONjsa^Ka_E{GsnKal+<4jOu!nLi4g z7VO*sJOHF8?Ku0B6Y0srO9-LQqE*ls6(Li%LmZZE+@$|flb@VG^x2jkVZs5PJRysp zgMefa;3x2(i@~3Y22%In;wt{DfS={tveDq57sEdV_#Rq}jzWcA?<2MvnJjPE=LOGR zDElB3-Xv!-*C{1@!r!a|D3|8!JEjoM%+QF8woOlM#{NeC!g=P$`iJ&d4!g)Pi`2+uWL~VFrnS2 z>X?b^66&Sj7ngps-yn7&-1UMbH+5ue)h zuV@W-hEc6gU#zQvFBq%_{?b%reY)`XVtsm9vH1>N1konUY<1%GK>hgV2I$8h+ndy% zliSL$W7wDNtoO$-1gDM>oT@I@Z0$(YW^INCdVItDfu0!<!AwDU(-+V7_QPQNn6{@x@T&44+lnR}vQ$sB{t?N{=EmtHhwk8!3j=wLxLAn?=X zS3UrOVs!!#-<-d!+=E-iJ?&)uz}|tmd%lEcSP*{nrV`yX54hOsdZ#Wbm40CXp;28* zpR8^|WgR;zh0bfCxB!xPVbFw}>bzVO=OGkX!kKf5def5J___2cfiMFV5Pxbg1GQh2 zhcIMeDq5W#j20&u0~-fmU@O#}9hFvp#%9bAxs=qgS0ACaTm2O_c?DrmNq+X>N~W3} zJn8h%Hk(bOg*s3>{*)kV8h zAWV@etg<;{LC$KMvpPn!)n8-N*AP?Hz$*GhSResfTL-kx=Bx_=X^vT>t1T|ar#WE-D*dhE&HFMI1L(ECvVAddpe|akXTGg;L z)Cv5Xkzq-glrB5=V+5C-%cP=;4NKpuCdG!OZ&$P1>36D09;6IQmrSLX2Zp6<+-;g8Z*n#s!3i7=Tsnb6K=wk(fzIbyKrR-FVZzr7Q&W%@l#uW9C1DjMd_6KXxr)lU zz?hoi6lZGs;vj$TOQ-CeiVB()3@)Cs{@#}pHQvuPdJ5YO8~a9VbdpiW5Fr4kBeExe z?H(&H{chMv5eiwL>e^k%0^YToi8su(`67hFY4$`m=u$br z3z;qgiDI2wG_&6xieABq)*k=vh-s*rec(2|vV)Z4xq&ovU3zRCG3uo=YEX z5(|`lq^P^T5HhE(icM~FzJPO#?0jlS8y8% zyI`WItu(z)r)~#HGsz>fVBw}07b9PG@$HYvz*kjVU_SNEDXhH4Hk?}enZBU5! zC8YIKF@Ldq#8*u)mU8m8=QJ7wqrtD5Am22N)oI|XCK$u3x0s0*)*7ZP2o!U&HYOQ6 z750t%@<%(yJa$quUu`Vik;X5*5uH3+THlzzj9Dg&3SfTad6lZ7>>?-G40B|#Lm%*E z4Lw$9Nt4R+7HUKS4XHJl2U=}jX8>Ic0NrA^LoUy|EsVZQFKDT6c52(`owxLx3%FeR zQnwVPG@#~1pHaPT%nKKFubcm8CrURjFz}dQAuu3d5*M#AMBvsr#mmyj=S;)5Wsv~h zy{9v51|<165}c@j9&p#<2A!A2oK!a2FUw1U+c!;!V%}vjF_=5~xA?^;EB`jXL}bXn z!!Mg{emTD?|6P7z?D_Zj9q0G^{BoBozk*+uWBvnvamdTB&GyMLD z-xd5`&F@Nnui=;bUir2BuHyGPepmB*J-=)Cy@6kR-1ICBZxvt>;ded1H}ks(zqjx^ zJ3WV_i5Hv+SGkzD&w1>eT|S8)tXw=Yn)=+selB$KmOj_p&kbAx)8{(-xhK(a^|{u5 z5&)McFOums_LGLk^|{)9E-IEdpR4R=zmreuGqs;f1V+;*8a<)0v6FZ8xx#)vu9Hve z6KW~<@tu4|pVRj937vd}J|#+%yQ!0})aR7_+*^Uj`6O_ta-WE)QlHqe^tn$bU#-t^ z`?)Vtx;`ys(1&;5|;^@$xrpHJ=Nv-Z6Il;)kP~6EY!%l{{ z*-oZ^T+snP?99AF9F3wCjo>N6zh$uDQnzB?gzt4zXZx@OQR=ijO+a;~y*-DSICRWh zyOdo(buaBnMq^}3KoSP;Qh0DL%Nog!LO#VF9Zp7Nn|Nk;>qA&73ZQJcbzW zx0@KJ12HaA4aQn_JIB~lM)VtxC?gs?n%IU!10L#rEFeCL#N{SJLk_5IAz zbU|7=>2k$sR34Pq7K)`uKdjs2%!~giA5xxhJyF=!y?kYXkt2= zb*5dB(2iPlgm%=PNH9lji3D@hj!2+KZHNSV)P6{4M{S3McGPY-V>d&d1=3!~GgjIP zc?U>4Aus-DBjm*&?Sm**v<>nahju|;$th4$2-I@H03q0hM17`mh-P{f3g72Rl@zAtZFowdSn_=k68Kk?1=XkU8|vhL z9OM&%6b|Fd6UQP)riL$t{~zP6<3@mV1YhliG*x>ce6_b|;0HjISghP2RaKh>I5IWlT^L+drNgA}Plrg}DfDE=d}t?mkJM9^kFsgcD69)$-pJl0GSbryk>V zRiZDtECt_cuRoBa9Q4gx4hkEh4oFuc|CZxg{cpBPJmP2z0~nfP7om)#N0nk)n)bg+ z@o);#6m`F+30AEh58cvDXmZPL(@m*y+#u4CfTxKDjr6j)GTS6rMTf5=#2ZYUO0$h! z@bLJP#n{8+^yZKgO~{<-E=pt_s^NpUKk6Yggc3b+ro?3lFHQ4E8nPCF>ym7)tkeAG3Y*zbCGtzF;3pbt-J?cM^HBZWf6G5 zoIjcVU;&0xO}{|t;yLzMXQf>5Q>8|)AsmP1b7yzR*8Ae&@3ITAmkRUAe}Ne4cPLOyr>KWK*f^ez+a8YF2OGz2568ur)I%gEc!0ctc`Q)T!_%9l z%z|{FxfDQn$GE9$Im%29Dkw(nD%$SDFhnTR2=h*ja4CSU*BZh5s8W{*v_8!vMbq-Go-V=Bho$=`%Fk)2B_}1y{&)(W>2+_{v7Z~=BP%$)ZHgc&=p6OO zifm?3e^(5^dBvcDdW)}0m`(-52S&m0whD$T9fkzp8bmDO`BWP2Wa*%SD{BRLO0t6C zgTpWk^_M?)7*=Mip=hm#63z%sPW!ZNhYQs>-BW)y$g?P9flcpYsbTP??T_u1x?2YTISBU??) z&k$JB1i9k@CaIVc8P3BZaeW@@#j4Lky*yR|gV=Gw^rW5`R#>Qban~gYLl{$qUZghfXh(M8{a)4Q^2gn3t~%K{x#P~6&8wAj>`@QkeSGi52jiwV0*ng)ZJ z@R4qH7fhIFQF$^(13#C)~@+s7{Y{Ikr=~}37_ULtSk@5gdGGmat*tAJWMcQS73M(Z`p+= zv_+Rpcvc<(T`Y6fL^y&j+34FpWv@3|rs~wDCyu6Izvk2gUulD4Z#xE_*GKqOrYCM@`%^-Y>XU*znD=CV0YuGAz7lHejY+ z)a5ec;BuP^ASpM!QIFe-X|)l%%MWP8W(;ej?HfVuh7Ym4uCs9(h$xX> z*UOqO@KW&h@gmx2R0Y7F5c{*2~%8c&c4R=Kgv`kE0_XWx1iY7;4mn1b5 ziW|8IKHJjHI-;Qrx@snwGYsadjmQ)2tBukXP2I|PL$;C4hpuRi#W16A5=4vQQd5ev z?A_-yp9stDQ^2mXuTundNX4tB@XEuh(0BuOqDq$*9$OdUC=~$1o-~zyK5p*eSt*m{ zgBBJXFTaG+sfN_|j0B7zbb3f41m-&=V5b;hXFM908H^dXhckvK1m>#=m~ogiCXNr7 zFw+|~3`tlaz0zD**pzjn)Cb!6p4Oo@0IteivC91r27j(tLen-nth8ent!X(-kn( zxD3tVxyGqF9yvcO`%?3VzGVO{o$i~47J1Y9oPK+O=g?y);kV#?YO=(ciow`d8qw$X z7kI!t2Dd8x;lkqTY<1o|q|d|M*^E7nt^|7=FL(}|G{0Omgr2f$kMIm`DPF%&VnUDL zCO0~vEN;?+qZl)|f{`bavVUxW=3i|X|I&H1!!yv^6Hmj70zPWmFF2v-%R&Q3*_#&9 zn-z22%~yd*(vMW98Y6iNLSj^|(pXG?o`=U@bd-6+1uR(`SGbwz$zo@$rjYiM0K;G; z3ex$0YiK+wWCv*0sZjbfr?)OFuFFnu_c7ZdfxvQuUIcf#y#|c zH}?Uvb)x9{5?>ni#9qWhsn)?eC1*v==H^LMd=Sf~W|x}>s;OBu#pC6hvsu^FY>qe` zHm3y(3bSEajKVsT6-=gsN85s<8>*UT%KeAiJA41v zd%eq_(p+;7EGHxcvi)zJzhvweZ?3t=a7bz){nJ50h%k8&i;q}r<8R|Wx3$eT1+vx= z`L_1qe6otn_u+X{pYFrt0cgSknkWDjpWE!W12jv^o6ZI_&Fy>F81$|*9b^Vg7tn}35jLHLP1_Gn zvUotsX1=Xy`-7u5gB0Mb9zY5z>RssBSCCxpjS&4 z-B%kS>Zc20UX3!15*)(icq|i&E2&hS#Z}hVFUnfq@@iQKPK>6GjnPDuCCuQ9y4Z|m zhjR-*M32*Jp+OU<8}GEHUY(kWH6vG-f%(#1L>VY0yN7EFI3jN!kxv|PxO~>x6L^PK zM@@~5Rk;rjN>n{(SXD@FPa1_LWM%i=tCF6f_T}+O<8pt}Fce)7u@~Z#MwsDG8ZI@Z zI42GFIn5_04fiQv{-hD4O18GLm^*1S!b(U(uCO3R;<$@QnUqD;%I#By^9rLh9_1jC zKOTud#(-MJQ?|GV*O0`&u%yT*acEOTF=5`a+83)$LEFjq|I++j`!S!OK@K@P&X z`vRQgQ}+oxx2qzb>Q<`D5fq`HA`-dP!o@;nae z;beM;6SP7A@ran4U}1KvglGqhsUBwg2FZ4kEmyx(CcoSYp$n3ZqiXE0@ai2)`UM@aHequM8csQ~nm6*cZSyFo;*34Ax}rjwBP&7F_Kg7$7A-7e zkF4j61Z<@_@Rilo>dNv<4ca5?jUxd|kqs+D>N{#lE>cR8#-E=b|p)Uz4rtWVn~_k?r9klLj41@0{u*tv@H5t>RH3 z;cQ6;u#lkYfC!C*-33|IY62oODt$@IYCtj5sXTT$cp5!Vb9GtXpvBRL)2b^c(&)4b z-hQxExyCEvY|q$%kltNm5}X@##@ifh5;01ub}m+#m{oX`m46qc_jstjFKz4Z3~5hb z)t1#T?6{|~=vbZ$nXx}xSe(;H2NeXs6Q1U?IUOLm$+EsyF5*X8^5F>*P2r(hy7M~L z^_H85nN$3nj&JiNdP1n+nKzk6V$L{MoU&bSKn|HQHK)qBWYptAts@yHsEMZBebFsX z2a_5w{@pq-GBx6p-l@qh9rbim*Pr%~9OX9Y4u6uAx4(9*{MK<#+?AWU{=BFYV&(YB z#ohQocuBGoOI@HTRtu$AR9vH@xu8V)b9aXhzG3eTW{9#4Bzrs=oMy;hFH?puMr>J% zVXku!xn60^b#Vom>+qSfiG{fief6c&$zDc^JRnk6AAq(RIxcGBEee%I9ZZ{*gy3L$ zGY;|AO{h|auEtP;O8Bo0s-&Z9r7e=$i0#4g)f{TM33J3^M=tt0&32GAIOgi8R3yly z66ea|c#C^!*5YIA<`7LR=O#>og>d0y`148TgN@g@8%n{tp zkT&y-Fp|~NY+OU9LJkbrHBBR%g+WtMQZ-rQDN0E!778TFUEydRa)u0oTaATz$mPB) z7-1E?b3vy#Z!k0jGlz1u8Lt!CBSS}>KAY(#D%tR}duTh|H|vF6E5grmXxWxo^SYEbcz3IJ^;+44N0Zt+Jf(L!+Tm zWm-T9ghfHjFR{nZ?PZcjI!3-eE>N2w=ichK&#iJAw#gjobqQMP1sT%i6nc;>(g?&{^gX+W# zzBMR*z<}oF*jFWfJD@7%dk~eIlvzX!5Cvja!267sk1%Py$KbQS%AwvoUu zY@}Dn?`|A320nQVeUOh-=f0?nn#Fz1@-;34DyOb8QC@+>8Y#aiL>L13f<$F-0K|?T zr`76REkk%*tzD@$usbF$yDkwsOhrW0q_ZwOT?`XLob^lTpmjThCZp~z-4XhNW|cxG z)&3Y5Rs2VM<>%h13V*vS8FojMQ?z#}Qc*GLy)3xlHW*1l)DFepZqm$)9_VBt3al_C|c9y1Z;TAB}N_VhxJwk2k@ zza=XlanzCNuc4#>l&?ZT={Vv48n$`a73%bW4fKHb`8z>DG8)c@=%<)^kSdo}CTDtZ z#n3$ZBXRc*3goYj7h4!~&@%WHw;prrNMPcMi?_=VHQC*eJ_kH- zpt)ng6wU9mhrGRA;K>jvFk%r3JkaZT^q|a$%Qr2m1-+bGV9y8bygN7dKQ4YY9k%f0&48j*3t|5Ij81 zSr7TPqoP?b7*q*Kr0|3SF84E1E?lf*TH^@1xCj4cnclNzdW$~svH~%T? zm!Q8L04Qu!h=s?g_~VRXy$T9P1rc>41UGV*Je6Nr0a$uW zY#Nwx%R;uvN=X{FjZ#(1H%fN!Jwo~fUs?|yX^qsq3ud?%q~re=1lx_;!J^q4RM4pW zl#7!Un)>1@fSN8^ve{yZjGFf(4VELW(okyFFg6cO^L1JtDu$ccp2fMopK4hS3Q;~o zVvmucNt6@QM2l{xomywQ5$xhG8Yyl_danuWg1C7IWD6ZSk#m~qJ{2ivSAiZn3eX)0 zUd}d;bdcW9v3l#18rBwH1OUSQ`s`##m?0#jP=0;w9GA!?LpE}W>SuNf>vAmRiX5zu z77MhMW4l6L%351vPzb3@n8`dm62wpdV5Nj_fDJI9BNi!}%A>i^PY zNF##RB^mr&(HFSdrRWQZ4PJ*#t>_DhV%VVrv%%|d5>oKG#0IZRZ1B3o2CqwO@VdkX zuS;z3y2J*rOLRM5*UU}uxw*q(RV^y$AAFrjHQ%ku}Z^i{g z$Gaf?@?847D)cXnSnkUsmix+x<-R&%xvz~_?xGRPT|8pBua8*nk`c>YI$Ajnk>%pQ zXG1=x<0G8AGHO3bic{cl%`#xLqG$8d&C}Tp4s@D$fr1$p)6Uzkq*|B5y#D*%WY8Z52UZj<2&yHT@Vw$nif7a-i(Ek{(L!IvDo z&YVnNzo88BZErENYdnVU-kBD55OwS5uH8g!+o%fu5btyy+eN)5yR*}NPN3j@L)T5L zttiAgixXz_##NSskz6pv3~& znXwR%3o})<<{PwRT_tHukLlWb#z9(8LTc7GhEQQJ;QjFR)>Mt-1CawdIl*Y)vw%v#Uyp&KovOw@XJ zw9KgF&81c56|A6r*0=joh?XjPu=Xl?XoRcivA96b_RHQ(%Er2HN=6W2spOclg!d5z zQxoKK>DyJAtGo1_YSPlTswpGB;c+rzVAeE}I};F^L&o>d>Bd?ty`RFyCq1-m$c;FU z^$S(3ldYHRM>MI>erz({JY4S_QV@KSLN9J8>rX(ZC&`#mJ=g8kM&z+^xvi#}xZM9g zd+!2nSyAPAo^$Rw_jT^gyEF6V<37%1pL-Kbi!3YQ%c7_rW}0nNNLSGo)kAktGfa=& zW6wB1eV^J^O?}@~7s*TBn1CQ}l7|8cK6oe(l@t}VK*a(q1Qe7vK0ri7M48_|V#kh% zz0bLMFOM3lzXp<%J02@mtXL7TVyzV`=!;{F8jNvT#~c~r$I>|dFlDWNA}A~l>7Yo) zUVCGohtgC!M~${FpQvvzsNEN9#qX0=+}y5ZO;c2o-Bj&9tAgGQ9BoRvn`pmVa%_hM z)kqnO7qp^y?ue#S-U)NrKyD{c3l82(DA^^mRG`&ON?t5Lq6remcR=;NhC%}buu6qa zKtmIEMOD;v+@mjpUN@WJ2#+rclc{?ubC#;pnR}4(qTfDMVTL; z?j|tfg#1Wz1%Fh4AdXK?OM$%!@0JkiwFF;Btl@ADrlS8!U4`0A_^u~(0cVxBVu}`d8pFi_QPV^P8I9`r#>C>Mbdpm$3Mb+) z04%MM)=tfnxf4=$wBvSV%3Xs2KB$vy>vY$~V3f4Zv7-EZ({&{dP(C2_)8F)e_2awbMK8wzsw@^xk2@meh zrwhrRtx68dMg#*^`i%6`D3<1>Z4be_M&nc(-IYdntrVuw4XFERG^$`)=x%7|Q(`Ke zPd6n04x^5m3bxDaE-W5F^TCvWOhCb>$YpDu|7yL_fnKqT-5vX1Hct^bsD62P1&Vze zvG8-!2-uCj%|q_PW|!};G>J|!98Tr-8w&Bq=gK+Biuc)vaF|L>{^-$Gd>)YDde zQshv<@z$SKeJp$(8=CV&;#xffI>`C8Xb4B^=OeluRMH`wvOP`$7LE64nu!D!=t;La2W>qwPWx9 z_Xwd7{?E}bnD0NwwmzKfsa}s*8y*6LvrG%L*@m@+%PoivO z6qa~ol#R$JK{Y#CfwX!?j)~}$P8@L)r-L6OMPNfD~Aw@ zauTFZgp^GLr7|1RWPz2)@<6NjRL3uG&aaW+v?fZ$wy`QsLT+(=(+F+%Pz3bW+2j!6 z;R^{iGNM8t8LRWE3 z3ZyfV7TKq{r4v=GNQ<5MIk}_HS!t2?;N+vP8S{}&_7)>8hV3FPVuwB;-6fY6cZq-( z(qc?7c~q@R*UzU~jn=1WoQuiYwIFg{S0U&B(oPA8d02PGtYhoa^?`Bgqn&I-NV33r zvCT|6onQP!7C~7{y4LkW-MhY%jZ>4ITWfTEsSC_y|MXTZ%vtP18ILf@szoqyS+y{3 z5lhuswRnVyhp=SFQmjWFXhJV38<#xH%#%$2zgo2zhlZvEw|;Bvdd67AiKU1AtA_#X zzuT@N>J=NGDC#vM3;&JSuB0J}d*-ZJ4?m4Bw!0`DktF$Gr&MP-cN6~C*HHJ+Qr%+* zb5m14@ldlMR=(x88^DqF& z2gJ-VUIuxPUU~e-G;oW{5^7eU1OL=A{20!^s_{><6_bW$Ux7qiXg?LwKgm&x7hJf< zP|bkq!GOrg~0BBjHN{PPJS>aJyq%p zk*x3)u9TYMwupHPd)C|*;ngV3#<!@070QHFgy}g}l^IpwZb0#Es?3?stU&*zM*eL1#)!@v3pxh}K3$Yj&<$V) zsTnZ_%$w=r=3E1cbGj+v?RXqClNarsW1Ui=eE>q2hgKTZw$VKr_h};MC%=;JanRrR zylri^tC1$dy1z7$&FEYN@f2KKG&E5vWBiFJ4bJ+?S=OJg6-x|buPSppBjwBYVgtQ6 z*JuVAn4pNb#C_^W?a#>y{!>J^F=euihIKe9zuw_kb{zjYgkxEvUFNK^U1sSw8_sI? zh>s|8<4C5T{AR=1-h%TgZZ^C(Hxu=|sxqi%aM7=E1V?29Kf4rToMiai_b?@z#h2a= z@ODCR=+#qz%I)62b}#t#T(YtneB{8=aHgAH?we-meek82f$kF=vZjrC^M3n!k0qAN z7aq3{i>wE`d*>aExN|J^LboYX~fpNBwie0)Dch z=Y;uO-gBSpBY1|gU~l&L;H1N^*ABfHZ_mSfIMD;jG&l8h&{A>ktrv&PrA~% zj|C2Df7stEz_}2z{_-sE7wp~k{Lsr4^egLm)yi`i_OhJYjxO)mq1pOaE4y{3@P-a{ zEY@@P#j2RxFX7E4$aR7T#;`GmNob7jC?!dn+Dhyy{U537X|unWh~G=b^s=0Zgy~mb z6{d||nBKW`Oqb}Q{vDK03fyA`*Q+6Jt>*{eMOX_uhKJT--mzfDr;Ye<^u7F@Yt7un z$}ypstDIT=gt~Mf+uKa20US5Q+%}>)Vc*yw;)FwUj#^|Ra!e^l*AH1y%6iV!7giXD z7k$Cz1nf4S&JlH@ebhisot{z#bP0S<>7)Bn1a9sd<|~j(#buR==e|_tcHC8pggBeW z*n>P)l;n}!i=ujsUBds9Q$>=%eZ|0zkkTT_yA3FC>jc00lMZu#q$@jQq^hnrQ!Bzs07>qRJlJ;Nmlp#qAB^ zp!x6yaga=TcY`=c&2JEMH2>dB7xMW*^MBr_d8^LRn_vTnuV~cqvqmp+WHrWlU7m5k z{TRMUqPTT+YPD}_)?3DM*K@Ojv&@Evb4v|JR#Z+1oMsNj8TRt4ISkdK8n}8Weq1_) z3Gi)psHCmg`j&hxjZ5nmEQhzSN%M5oKq)Cd*yE0?Ic<@nf4*h{viF-8EaNg5jd=M{ zcZ|ZCN_|-GN0pO@DI7o*3Cw$4ak+BCHZn(CW;ko~Y*T!@qJ%OtH5zoHeR z9CcSk&Y8&u?0MnpjwzZygEcatEhzxaNEDw-hRrSG7$|IZ!EA2y?SGwnLF2O^=2?iZ zbB7rpEM%lG^#ZFN0{1W#MuP(t3&3d|6p}@)#N|FYCB7ppSa%p>7rLOr*fkKs<79tf zM^~+lZFQu`ng!pR28&Oje^JXs5d)&uesilD=bQjH))}5@oi-yGBrlvd5R}^(1Kz+V zhbLE@Pj!nG^&;zE95s*}HDY3M8=f!f2)9dyb>Diko>o!jP?(9G)q$s1u#x-PLPdhs zxKG*+GWRC)TA!)1xB5?d;h62-8Tq#DlPbc4qO$p6P**SWeFIMn)UGw5;t?}s;B+@( z@%J#)xwA)gd)#!)BQI#95i}25J*gLYLgV6&Ow0Rmm)y0l`YVes4fln-z7#c_PK5aZ z?iwYdsWTxdqB;b0k^9~Oi?*~Kw}3@@l3d!s@w^`?aL_YXnHK@Da8;wgyeBR2+B=BQ zSs^V}7hg-DMX3Q7N`|0-i%?{-_I6H@cxYVQ9BDm*UMQ-NpE2Uucy0xy#ot6Ibd@Q~ zq{9QqC5XeHMYHCa$R(1oJmThlgIlmf5|cZFS6$#~HzRvB7bqd|-pnnW)mT+y-q+`j(|8IjM>G-`;V z8ZbvR%~9gs(OO%dF1bMqzDmM=ygCZqqu!RD05%?HGv z@Hk2YA&ILqiHO8E;+ho3@*-6QM~g3&v2RQ5SQ0P} zqFC;W>H-##owua|aw^*wR$I}FYFy0PAg=J^NQLCQw$67OaeNMl5`?i1QdN1}KAyG0 zhOu7Zof^KsJ`ZEdc2VZUXB?dIFMfoIQ?^#2|JxVI>!dS;O{D`ZDCytnq z^M`v)){{lej3|Ill$51fJaFwV{5}bH?@+pEzcd8$Z5E4^Y?+Gqm?m1 zV;Q{c>*%3kzLFiffEvp7!=~&{c1#liXJehp*w68~(6X`AM6pzZ`|6(E& zX_%u7^v6U3$9H_Qi5Exp+)5jlnk+gk1ZgJD_ViY^0!=THkIT3tjmG{t8w<%L^`aJ7 z^PlE&@%k+u>?Y>w8pYVe<$Ujy7;7y4AsEjwU=`%iDu!oY7H$sMcOST`aEF1*emu)V zPKw>RMlq{+OpP&E7q#OdsrUA6Y&qS9xWtpi*B37r!EH^AVA%gC-<2wMzka(Beox{a zZB=;$O$?9!zF%ArZ+OCYF8Qpy31XX-iFfoLx_bCtH}#AO$*SV9DVq4vdOJns(BUs!MUv9d`hb>*B-ZFs{$8MQ^xvW%S z?O!yJB%0ZrbTrLu7pZ8PSt<=pGwaHaznRU;A-Bo`ijWZDt$gklW1OEQj1? zw!0j1o7pBgGzH6^0?fmuCt2)fjma30<*FwHd5~6 z{rFRX8S>aXm1JM2RnYmW;F!o)m0no^CV5V9hCQ4gC)w{;z&tK6=FVCL3>Ji0_Q{_K z%!mi`(_X!LLSR<(?3H<@WHfnRV2C@c`!v#W{5;9NTFfuY2|CS%E>R&;uI;rcDHy{e{4cdoV|>>_Ow7 z3Cw6uFnWQ6xHB&bOdv@ew=(-5E1mjM?+V;(7)NPa0W6CRrrdx3dHU|39gbSi(I z99+;L+3bR%U-#A^sCf-~-}d7aR~J&3giO^f?H5Q$~$iG#&A*}1Nz z)KheC12R@s`;WdgyjAeYmG+WYsif+Mh-uAxaHeQiyTJL@FVCSy66SZm)PrgX^W^%D z_F+}X?y(nS*G#mZY2??2d$_a`@>!$LqJg?zachw(7*zp4Do_mR+;2N5hV;ezs;X9t zYIEqt{X!3Ww;KBnpxaG((_6Zrpf2dUuY_n-Ek#~+3BqojnM#5$% z8`3?F2E--(_K~8N@O~P1Q<{|n=2u3#BeXr7j{IxGoDMj}kS>Rlua20j>t3e;duR}& zawdX^3$~V;mvpg?j$z zKu-@Li*;`oL^MD6Kb$$8Ydw-j)QbV%i_^z56Gz?%Z!w@r2JHvCN3MOlxL1-lOiR$JC)7da`4MNqn-~~b%Ml0 zCE8!s&fN~R_(c+bTox77!iT*^DoGp6o0~dipGCPPUJeJ^k~t4CqRYbR!^^LqAt}lEzVYy3d49G?P9bucEr{uw+6yzzjbt7>b_27lzWabsYv^`;tIWcW+=}1?%sYILM0&+jv z_!7No!}+pMARq*rC*s_Tdt1=?z0tH`bQY!J(Y!lqR1G6VSC>dc9GpJe$k)_M`&7*vJHd3j*-bb48x#t@%taNp z2dVAXw6aNw6Rsr7FCJqp-a1I`lB&t2tB!OO?px(N`dZ&V+bJb5KZDZvo#7h>6Y>O^ zl5?*!R_3K@GmbUUwRf(~I1YWn60{jF4br_>ukxSsEuyUS(L|1Rf#lYqe2r&+@N2EM zj!TA1Iv`}0SSj?SdhSWtVogs())k^=HPV5%BP-&wsY1D5CRYsUtkH`g z)Eze8%xd=11JBDEC#w+PRm3qhLK~nYv@xQ25ImyG@@+2zMvze*Ng5-#Z@Jlj(?>yO zgZ~YPWUx8%CG>G$s8*oR4wj;~n>7E_%u;y(nk-49b(P4{C;|?qeKcAht!lKMtJf#Y z{#RxKIAEoE#YwEjN$k2&Mu+I&3J1#45|JLa>3O)z25~uH1`lpKNVuP?B+~Od*9X&) zKgPqfG0#w82}kaOTA$I_BvO{0=Lio zS=d=>E|{|J{-~9Y&8BE_D-j1-8g6%mko>}B82-+$5C(Ll5#4eeoAAzBZ7}Am`(u-IjQTPLc)8`$EeYg(rz?OYX~@|J|pW z#*@T-%3a%elDIT!>A214J}I(*D~AW6`~V^i1g&o%GiW{K6Sofst5g+KgYJ@PR1ue& z7{;!Oy0aKI$}eH#2~B3M-9X&8B+51!CK!<~k@Wno9nlE`w)+&FFkrh+(doN02k0zj zFQGj!Pzd(S8{Z=Jw9*$9)kWWkkPRA9kG&@#!skXTfegWwJ#P*FLn2KDYA4-P{m;0yyT6^M4aaQ1tMpV(pmokw= z7~-I0TTen7gl8`P?R7={V!A&w-TYD!@HcT2mE6m+Jz;+EQ=f!e#(wGjwN3arvA0 zWJz(K8~J4ZyU!HKVW9XbWo{tTBcaUg9xk83^5fuvX^f4U53muC02^8;W8)iCX3!v? z#o~mcQ-QQ64s`L!P*dmr0I}pYy`39V?t=qC6(RSVsiMlOLGGfC4q!o}3){mM1Tts= z>X*8&9N8wNHVV@Aqp(lB4bn|7xNdS5Q$0c;z~5 z=h9XX(YR)8Z`bXStu+G4>b4D9On2I0rG zzV@RQv(Xg=t)MMs(iXl#L_F3-Qddk!ROp#s&y>FKv-zl@gzK(jhgg>mvO@^phN2N4 zKs4eb)Aa+Vf9oFEI-@;z4TyB>2q)Xs_2`(ZNhf?H5f2YkR!k<3A*fUEjF}K+ zq9Z!^`G671_@LBJ0<}6-DrIl@#mz)eMIqyZS;D0Z$UMfq6F9oD*j|)_eA77xm7D3u zLB3+ZLFqazWb3q$u{t{9hzuT473Y;WPg=6`(+(FY^lqpxYqRVd@73n6z`JZDN;}K% z-ox1WTIntxZ_SChqW@5q{T`=NqyF`!L>G^oIIL6Vun35j1YG2gC=IA5w3_XP&8BI9 z1|4GRSwG>lqk+;D5nY}M28xkrCcG`^fyP*>3BMwVXTF9~+`eocbcRY=tF2>r2*11@ zKbp_%xIqou{QSaRjrZYSY?kH)Z}EL>k8ICqatkNl2~oS2e9c~h^vS~L`Pummdo}(h zZY!9t01|7)ecw=^uWWOhHlSC~u=wL<&s`Ntr5=)s50R-_25r)aR43)x+-w9I=ZA82H&L>Cb+Qo|&uz9@V6JT80h)4NjELKBt2N{Hsm z2Bh#hxJR62u#Aqg)v`B4E@8N{8pMds$LUXD`Gn?_e2~oBb~5g}x(3hO&YWyrE3qXX z0VtDrNy*VoW+ z@^xc+!h;xE=BIb7tDxJ-bE$aXCr3hFP%*O;b8HB#hRs+}^oDCh;_%HqIPyP0h}*(;Y! zM?v@+U7U;&F8oy({I8B@CVWt((D`mn>S3H{sYe_;;Kbwx)(|NJDZA_2$v1mEW%uEM`nWlURlNjQ(_{@151@6iPZCN$q>tevvVp&}3ld8g zarK9}8L2l5?J3Pah^80aKHKX#xtsKyoT=6KIl0fU=*7>;-Pq?jxzCj!k-HwE_k2X| z^U))6YQK0y&VDT65xHA6UBdU@>dB6BQv8VA7s}bq2dPKoZfPf9G^T6&h};d% ztWe&nn1)XEE&cfQGN^bBI!QqR^krBqzF9cAMdgy4gir|U=KRUHAT1~%<@_yS6(!u< z&IbIGajv3rK5gz}#wqT}xNqU#6*v9aQbLd|U^lg~`(fGmBFm)bB5a3oXOqvtK)8O3 zk*#~TYhQHnE!wUK;Fn76x>+C8qbK%xIGhyHmY#=$rT9DZ!d1>C3@i?>#b@g2lF!r) zGx^0B=VHY?B=CiupjMTNhYioGSrKbdH!az6YXjzp>GytZ??|=Ef{soeQz}}9aW*5Z zhP)+Q0wWJsJ(?m|zL~3$HWiS#Y@4+@tTdnaId4Q}4b?Mm7oA z24jN5lT?^QsKGt1iohdFy3e?6H8xP>S?EX4Ny&=@&ae*^dGeqAhKX)xl9tx?&Ko;r zPKskBb}Q}+%f&$F&)}jz26Xa|CZ1B7j>!5^i1)6iV7zduHZYe!XC>YTpOW8=qzhYF z68XkMS@&n-dBAsgEk^P3{=SZsRYYzxCr~ukQZ6iRW$gl{%Ql!c z+U5-)-IWcoLbX56@fBIEVc)2X}e-v$NVWY*1j~NyMh25fBiQyL@5inN6A7qq2_w8KoE#iCzu} zSOh@S{h=aH4fy70fG%D+Qv$YiDEEk}+J@t1biG-QWDrHelWU$D$@jDe1?rwV2D9JM z9+Yo<1vX=J@I2o^5Kk_UzlnhPK~nPh#sV#;4>q@=zH$P3Lls>C4Cp{^cMx{QYb0jp zNqXK&KHzx}Pyx||*!^s-NDqe2#$=Z=;?m6Iub-Kdu*VXJVP6E{!nkY1iPK6AmhuJ) zvHUh_3a~^~AS``e3R1)2G&3{BLsgr>G*ch^Pz!@ItsGhEgTE$Wqr`-$FrxA(Dn^ub zX#)%Kk2IproQ?wT{=sas8BrFZjT$aL-!v$X4(a*QO?0)q=-fYT)|c^gg}Uk&Br)c= z^zjZE_3cUDo28D=xW;EZ*L;Vto?14nYPWtcl&?4tW1_&c7ix9^sIU*oX6MXyK*L7{ zt+5i_WPnx&->fJd}1S?F9m%ZYdkN2ZCJt9_%PX@j8d8eEC-Vhx^VOm>5 zG_{5!_`$SRtBol0;#Te^VwVbD4fU8Y1Kigvc(S~>&q-bp9Voumr*rPo$phw5-ZUN6 zep+v_RkbYmQn4>x?TB@h~RElvMb#^Xs`a+c~z>* z-p^FQXMs9n5!6$sDm2+Y=PNs}LM++gwQuM1DyE31>=sBcu4T_v6-|7rHk+N>ad6DwEEY0r6x9 zs~d0y+M`u1_Sq?U4(y|74er?b_+T!QC2hF~?3=FS*eUOLMnA%%)Z%%wjMB;i3AN=p z6O=L@d^S?IcK=0i3TlZI2tQajWHNW%6A9v_xGrCX{dj@dEXAw*6#I!=in)n-fM~Hg zg2GbF-AZHq_NWT{B`tX%a1+u_qBT)1JVbB}IGBZL9p?WKt5bO)7&nA4>Hg{YDZ)BT z9Wc|Kh6mTB(^}hO9`rR1foSWr(mN1vomP7H2^oVX$uuVXB74~^>5bMRPTWo2;Kita zXgZ@H#1))9A%!9vNQmN0@wHrxjBFd@fqMxLBfq0Mdh9ra&3h*%*dx*^a?G$*3 zaI?kNtHG*R-;9YV|7t&z)H`Ndcro4NxnP` zH84<=oTUNI{6PajW=bY!ewV4T1jKcp^dsoidcK;;cRD6J#L9ODtcruDsOqr*!>}RI z`qn9Jyc;N|q7e`skJxlK>g3{Hr8kPJr%H@L0py+P0*FVJh2=D?=4&``jlW%`tGaNC8M(JUN$G zylshiZHahsr-cCy9}b)_VDTfyz}`ea3R5M6s;cKUmA$>K9cLd_{IKjP91$|^SwM!B zMrLgoLaa;^-2;ira!2G7Q>~ya5F(A0E(CZrCv_Y*-KUdu#Kz@mfH&vgY7>V0)e z;L&z)fQ{;}kE#S>jYqm#46%k6eh*1;CU)~1w~9HV1)6Hh!TT?V((8X!Z z5mA%wenl3JQKwjPli3{Kk=iR80Xdb4p@bdloms8hVbgKYlw({n3&G4pW__1-cnQV% zQ@~PopF5cCqZ4FQ_ZKZ~cSqZsi6B2AfH`8vO4 z^n=0OKy$|+D;s;wG9m*UwmZfvG|@eei3=7fr9L!dJ#wr!5au{Rh%4d*D}ZSOI~_zc z*1MwkQzP}nh(344qR(Ak^qCY$R;L=#ORl$~k3q8=WFT0$ui=h<1`n{-`QZUpUZK$AtW6xI zfF}RK7_|<1YOd)N;K5T8mP4D?7H|b~pY%zZCay(BNw>F) zPoZ~8pct)%IYG4zlnbh*=_H%eC#H(hJEz{!bEa@WvFd0S4uca3gfqjUrN z!XBm35bRMiT!ym-r2*K4Tx3?JKm+i_)#mb=Cx}RfOSGe)=<^Xv-^DPuV~0$o%OU25 ziwnNQ*xkN5`>Krv<)DgM&E%>X$v|7u@xDD6w>_w^6ZS>wexE7!S96uF{>_7HQi$L>oL1&M9L9Ow6ydQj`X3$aAQ zcdyR93SC2hLhNu~45%!c?o&v8Wv2MlhE7j`yv8c@TK=`PvN8jRR7v|*otfau_D|N{~oRVqa619BSU!l85E)w+MJoJT|Reu^xk>288jqUJ~%LFNjCM|e7o;} z5tF?Oqwu|aL`$`Gkz54fiU(uRZ8iEe@9|0ZaBf6Kuc93{&BkakV`B_t7l%C9E&NcN z=n~`w2`9Qw5zcp&Or}WSj%gA|vL}xim!CRT>=#|b@dx`{z?jX5cf?7acf?7}?_NQMC2 zzBZ8&U4TXQf*aRZlVeo*iBYLFWUo@)c>86&wwt$KuWwqDt4pj=eX}Zg8fbA12&8`g zeA;ZaD(5?)4D=9Yvm7hXQSHlODxvRRQRJ)E{nLSg{_|_BwFn_(qEfD#AP^JrAy?Bx zVA2Ux5Ylq*BfJ*FfRbFZG0KVY5RqUn+z+&V;0Y%_zyRq6h)!|E%zcSv{3Z#H@Y)h_ zDRe5CaN3)g7e|Y_g5+@!BrhggZbK&^g|`V2>=A-&!H$0*Z3a8O!1(?vGZ+Cu_4_d$ zD;2%ecM~F%GB0nH5^3}Z{@^7K z5K5=&8mTmim)bXMj9y>iJa@k9*J+WhRvhnY#;-Lz?C~gt^};L;d^vDVctJ((L~Dk+ zniV)~Kab|&ONuKS#}4k)8x5K|rzE*qaS+ml4Q|2EdHh5oT?xtuwJZKs z(tNq1^6v7!Uii|$UZApM=Sp_~%F(D^CEZMAS2kpO_Quf^thHs+U26+6#|Lo#YbWA;}=_Q|^O)Xvqvt11jSO z>}#z&xMpjRzaIQQBew|ba?2*8(& zqZNV{b9$)A83r^b$FQZZ%<-)ek)rVMoJXcCyD-5*zR2#(Tai41AsS>`18!_N};xS_Gi~7t(_XY5@S$wf0vV=cwU!^o& zl*j@q>QO_P;p(bsj?vBB=^$!QO`Av=voMH>>gim2kep5!&Hg8&MRkzC$uJ6IF zLjFj6(~zHwD?b})to}QDEvg4Q*KODgjES{$D!Eg)H@V&1IFc7R5p5T=vEx7cw_Fuu zS&;K85uE-VUv{;OYhTlp9aM@z6NucR#BHQOwbJfHA$01W^hmpJP#3 zWnPQN@!>&zrCrxdemNc1$>o|>L(ak@;5>>lYV^+x&TQwdF?IJcyTgY`Cp9x}{vEk+ z9^tglZ&+mVi8#gML~;E~X4teSW`Gu@FekSS`Py%-rS1PJ(&+{GsO2AF7k9!`uisMf zlXzxKZ!zhZ!J|1kW~|Q!W!>RX8$JKA-WYlK;g)!dpJ6@!v0iqdA%3s}4fBI>i090* z5k3F0o^J9=#QJQE=RbHa!cc209eZp2tw$br%v)=gUXtBJ9p5+JgfK<9QLu2-$kl(r zVPt&a=#i`cTuY4Qi&HCgpoa!yMY>|)xRGlPvBl1;6dSe0Cen$8V=U;2g<~Vor&a2V z*g816FTB41{lQAHVOwk^zJ4cI&?|{*8Djl`N}VBFhsUTEjxRu;RVikkUT`b~e@h~C zpZLW|B6OePx!c4uh8(NY)ef1}C1g(T(aORZ<-}m3EvH>HAwh>eREEk^4-4m%6Bo8s zQqHcVoL5PyP7TxZH9Sy}55t;L&nv@VD)4%7fO2IFs@QFFT866Nr{%I{E{^IQLEV1* z#xi29A4@1yvl~mX(@4&m?iKz0o17ACxm=9mZtAC}SXJEDL51z7Zzyf8J92&-Lz_37B4FIOr-hK)HjMyglY&}N4FD2cxTb;kxaA$= zSU~-#xY^*TV$U?T0qyw_T2T!(&=lk7Aw4&2t^sLvYyA89W*+yX%IKhFtP=>7x;6Sm zd%Z4BVs(T#O3QhWYooloAQxTfy@JB@#(n9otn2YZcNp6m=NUKg4+Vr3nH0^oHWA#c3wqR$&5+5&U$_-8 z)FMH3R2c|qQOYBDd1ArC7Hg6{EsdvnSXZM^p}5wspin>-T4$yBuq3C_Fljo4bv%Ti zj!g{EsWiPbQI`?GtYm~=e@FYdvHF_69y?$c?8EfWeKpyYjhfFTuua2FpNQOTa;;ZT zL?Me74c3D;1Br_zKw_9mBCrke;FD#u0Fn~SB^r+X$tk)QKIr}0E?Sk@Xi2UD=;EK~ z#Yt`bKkjI-&5fs_qF;0)=(A+)Kr&IMF+VdCaRu^LuS-|uivHnT^v#`*rgE(va&aIX zON~1#>_?W>C}z0S-nX&t03UIUj#e6#hB@eX*aHbu&&`-zXHx;o#moPsQ!X#;JuL;3 zsco%DNWEMV^fC8vr70_UC^R%OO9tDuCC z`3LjlEH9`v-T zauw#J=}!ye+XOzXB9{lKrY8&VYTD<~H0?Z>2i$bmT?{at(?Z8zjvb~sE+eie6sHd9 z9@D2J*grLuqu6xX4p$fa7EY0~woA~IMTzM?h2vdBb#mV#Pz|iD?n9{oQQ9dZ`o|22 z@1xk^i^fN(2W8kBY;Q%gc)0x6zCZ{T2jTaOWz&>XJQNiU+&9er1!xh-mFq$K3Eo=0 zcf*^?ZHXr2eA>-}2uT{rF5SEhY1Wz@N!aat}VU2IQP z0b#t}(;*EgO3s?`JyVlAswPrN1`%vF@um5AO}*(ieVfx%B1r^|u&d@Jsb5 zw#=96MVR|N#UFd>FtTTIulK5|b%PAp%zX`~dos%IYmBdf;w#~+;=Zk-*_Y~uWB0TY zRK2JHwB+0E;!`-}HhFihcE5=Bu2Gf3)q7ay9Vr8crSPlsgHEu)51PIKe$ee9b7vEh zJBKBOO73K81Yp$lK_kFnO)$ZT0tc#FMzcGt7q6?KzBh|#M5T@y1BC@>WxM195@7le3sBN=4blf|d*_a)8j%lM8dMk@gi3xu- zT=8)J_Go?qDfe(zrPW0xu{%!h4q?II0xteh=HAp~m=RE-_t)>?F8#A^ZljRQP z8sj2rJ?7PS6JY%i?uVT&>aO+FeS9=~iH z+ARueSbjKVP1hcxQiJtUs{rvl=J#rxP*3MArt<{|Ryx; ztk!Dp{eo8%E=tT=tTd~8p)zb~uA7+D}K4-MEJ1ZNZ;Y=K295!OsI+2v-cipS; z!Fsx@?Z>V~z80~#)4_1`Ug37zt8q>}-OWPU&5}UJRZM42D$sA-Z%GDkO5Y?sQ;i>N zfOUSj{ng+HtDgxUjV&&}Y_JoWZQQGIK|S5b5N|Acq7h*s8ZC~;js#?gkQ?XUyjNp; zJ$$Sc~}H!6gLm)Np?XRpTP_4IcboZkEX@620NekVi&=WG+5E#hm|q>r0W zs{vZE{6_xH3k0JhMl+r~mIlH0T_L@WA0~!KL|2h(czF)M8vb(1c z;bTqg`}s|KHLf;B{Y_zqlN$%;e|N9OC+q3&TCVtA!xb$q_LXLanjGqf%SeRFTlQ*P zUr*m+ca67rTyAe?_HpOm+pBS-!R7ZNTrhTQ-mCH1db-)-vN^}4*%m(SOmR5kuvs*em0^ps?V#*okO~Hc>Ct;5dQB_0A5d2AaF^l}M0!ehZ`gtB#oyWk z*KN)=SB>QSW2l`5)WMq|*v0Gk0FaRJ5~} zzOz_M-e6O-gzkWtr*>_sw&W|w-s3GW#^6z)ZBA>_L8A2_Mk>HOle(@^f8j-)NnAn- zSvZ8aPr-N=9ijUcg1&VM!-$+aTsA}v(5Yk_;B3z9l&ay$_x3&kav8nA&nUTsx2!XE z8OQ`KxG z4`KwDs4QEFT;4I3I9yblGm-lg9k>S?Bcm}23;ZgUwu7vNZPGEj1d#;(ai4PkZYAIK zG!h*=WJ+5Ga^-D;UD}kEhwOzqc`ct1>PfGhDDjZnU- z{vCXs|A$;haLlTwoP{KD)vYe3F6~Q$FH|y2X!&O`F7mU&^}*<3_%V)IbxCT3gOrGd z1yBN;Uhzdzqcc+F$T17X$0x=-L|~^CC@$b)RZ77#Do$z3DJD)T;eHAaYT<5uB#uR` zh12nMi%T!ypjAr2ud0-SD^4i|x1czsU#sWP>W8YWRyrGxPy3j$`U*3kJL0GeJA71z zRpJY7vegKf_CS7Fx!w&^S#5Y5yZSF{rlKhPgBj1E>|0uU_|{saKnhxm2Kar5U)0yx z!~C}R{W8CU{O*mr-Po`+(?Me#4Sp^AMJ-Geh9>->c0XhC4FWM-wjz6z&g?~n;dE72 zXAN^u$LQFPJLZ!iH0s4wcnP~T(iNls0V)7V8wCjN>cs%c z%VLmamqnMb0cb3X?o(tK)UxOjAZ-Ad(so&N**3v0i%JXVlUEB;L@`gJS1}q^C)#&3 z#tN*LG8$GPYDZ%{thw-uT$zKmadWzYvA|j^+?hfe$(@gd+(b*%c+GuBk-0^0LF!Q0 z1NKCL;!^rf%!s|y#P&T2Yc9N)_gzK=QovAB5gYJbbz*fbjT%Wd5Pyp_VC$$c9R|G=1OA|Fno_i0e=nGh_FK`QmP)x z5>Kx1k=#qgUP_V1BOd(5(4EXwXh6rH978Q>~q7$ zQn7TF@$9=d>jEZxHx`=>|2|Q{rx!A8lsw*>oG4@hv)qfz=clKZ)E;{w5gwA0)ZT>e z{BM@ePd{8zdu*5c5n}0NwHH_gj~!Viv75;qc4T(49?YRiJq%{duNa2uANJ7 z@0Uwz53B0IM4dQ8?M?djE?7Q2Us_Uo*kcb#*Cc1Ey*0kQOGmPWWv&M=FR4A;&kn_| z`a!i9*j29_$;`vv#hl*x_`OnTFO)#887Z_G8lr%UuWaN_?)`%FvuwDBtl0CB2izCC zeDKA-&a-uTmabufeIV?rU}mH8^X?b#E;bUq1^8Y)wH5>QU+xjN!>f=&qioo* zt$9?&#Tq$^x01_&ogSI3&lxfG*w_W>Snq-~FU+ui*3$XplimfX-VHN8)s}q)O;MD3 zEzW6P+ zXJ6-c6~Eu$cQwD?jx1_=&y zUt{S!4CTHOz6Oe~Nxn=RJ7s6bTHmnwKzZY;!4S&?DGhU>yeWYfmyHxi2)0Ka1f{%j z4TF7EdE+uwb0~SJs=RRpR2zkX`xINFywPXa*%+7dp*g5*l{YS71JF2_x=&G-Q%k!@ z5OIAkDQ%TEuDngK${VEx7)gUsO3DomuJWrGk5GM60*c*N?P5Gy|(fda=B zSlW2>?0%Iby^3i%s5hRUUInE>Wls-EO)QI2v9iYzLRfi91?nDGV2PBfbTyherFriW zck|wde`gQdX;)Vj9S6H$6@l|%Z7hm506SVTuhwz>p~Kdq=n@WC!tC(~Q@S#Hi0>8v zi?a=MnG{!-yY)Ko2Lde-+pIFM2hk=Aw3afH;)hRMhhqNF`zPsI$hx)wy)^#dB1!-e zLuuc!G1fX)b}1{HhrFDXEk`I=>t2WPK&^I2x~}hdtP5!ntPH((8k`*uP1jrH?E0vt zpRaf~z9ZFj(W#=q(#E5@G%Yq?tNXM<>Ay3bUSe0LL+pCZS3E7>Wj!sip3fAeVLq{n z>>y32o^`D8s^+mDfu8f&<5|fr=CQ>t;F~HbmnZVbmGp>owl68;9b~a#nk@)dEUP%8 zzS}sW_Fh(f4bAgTQNPc!iudUI(z(7<*Enjp@i7F8gpzE>86JCK=v%Llo2eY2Q^_ty zW6q%bdX5IZu76{EU3*h(>7%hrLCs<`@JapKG=D8YbSmNPYiKmmqJE#zz}a+bJ?*~g z;dr<-9KQJqy)_&jpGtN<994>?9wuFK*SP~wMXEVEADMD>xLfp_OdjmDa%@1VP!)0d z%0d-UBIt!K##!~gy`8b{WXl0NIQ7QYuXMY~pL%r$ZYIYVKdV<6FqshV99fAl%#v0< z7W*|WKyBgZ@N$!`gCXg=e4*zL-(*_Z!)2QUlB{U2)ck@uH>pm0qsa5nYjMOY$P+QO z>klLKI+3FqZ2F%#)ca3X+q(|S4)uOYIn?_bHjt0}^Bl;(%^jN-iKDCYTBxD(>OJWl zIrFs7DHyuU4Niz}{O!na3$yeQiQ zmgHg$D)4^8sP)Q!i`4q5b9Q(zc6NC1wK+R{Zs@-|I|R-Sw+$`Z+2I?x@#w)<KE%e`wjx4&PtW`1Nsi zcz9^p&JM>{`iJfm^@ub7;;Ez+y{@~nT z?B4Lq@;T_qCAEk4mzOsy?hQX*J_kL$r1nq{@7u$@;a58+Z`s}HgvyBa8cvkW`}J^d zIBIy=?hVf`seiaP9MHqP;rQWYyEnYBr1tD{Ru%V#Q-_!B-tgj*+S8@+9_|fiE}xz! zE@}Mib@PgQ!@0xDc5gUoN$sJ0*0u4nd&9-U%XV)#xzb*!Q@DJ%&?y-A2EVV|;EeX= zM;Kvm7x#|`FOrAlpAaW~zx|%9dBkBG8(i!#o|pq@00xpDD6%l&d*8$9g3m|nJ0glb zSa~&s=LB>Af;`-zeUXt+jslP!`Cs1C9WdUQs9{XB!Xp1a=C_v?amr|Dh2>&N4a9vY zPp+8+UtB;-Zk|d`GRthlPS2KFYL?QG{3tikh5YDr0 zkF>J8`14dPTPc?rFnH8naLHXkh{XAY`cAtCDEgNr*>7seQzjH7p#1pY=K)G?02R3L zv2wPL_o(d0%h_>E$|uU%HhiRuDEXwz&il}6-{QJZJtjH-g=#QSY-$c=@f@*2xbtH} zX2dzavC$e`t5xPwgi&8b5k`G~xKEgR^w-nSwmHjQ_Sn*De{QHgV!S!FMDb*{;BpLA z-Nh+A{=p&2ed>xAA+Fu0u6RAw-f&Z$QE_Riah<*Pl_E@4@0)Q2-<1ViT$5|?2{)m+ zWb)+HhMVmjy`r>Qd%CTARAY+joi=D#)N#MJ0%!(K{vy%EKJ z)P|68D?*|1c59-Fo3Ah4{LOVpZjnGP--r{kLBcs9gT$R6@uj6B@yA+C!;b11a8Jn1 z;2&@wtd(v5kjHov?Bl;wn2wnz!5slevx-#B4VNfB`8pS$ii8rAtC^a+6To%!S6Q=M z@%)|iY};{up3$>x>)r)|MK_>*X4tyD)IIGd)jjQ*-h0}!@t*e6e+GNnnQ!=>cIMn7 zd)jm5J?(L~A@tu+^R;Pxwnw<7x!cIPT3O4Qh#blHcJI1WT;-DY53-Ia@FU4j+X{iI8^Z0P1%hHGFSbb18CAPV{aHIGCPZ$Y zO6%|G5|}(4lPK67r`9+EVe-p1uNbiy<6xL$by%0{l7q#^ppon1F0h(}t-YiT%q7qo zBmJv#QmZH+{9Z0+H!;x9u11z=Q@! zm?enA&>YFLxU^3e#LVi`sm8vZJUvhfshm77yxkptHT82ItI*ZbAT9V3z!$ZHd9FLLu;)UTmAy1BblIF%m>THIa~9?A zu&Aq?Phmn!T;8ago9S8A&N%Bq934%lGUOoMKBCj^OV1hII?LJ>zi}MDcSM1qQUU)ma}Gg_ z=YY~g@+o9RY!t){L7M;Hg`znrwwLud#8G4UO9@&bYi6C!&yN}*pMZqDaEd=s_J17W z=rILXH|xE9vx{Tp6U*2J{~0>>_fYZjM1sqsucVjv?!MqdG}2MPO4$i*w_;4CFy| zd%cYGA%nLd=bmNgV^12W51BJv4|y;a`)-j=%O}Y-gF$lw6%u3e%|ZV#kkY;XnmXgF zs_e&F!jL1bkrPdHBW#9N$rk~=W|{@pDDK2!fzT!>AD`~Fh?9V5ls^d(iLmhKlhe8L zNC-3A+RU~Nzc;yz*N6ZbqsnCi-9Fy{P+h{zH9y`IO~9F-=rKb`o>e^k;k>l%t4($uFDE z?9%%;D6RuE(a!Xa5qBXm#MoyjTN&}q8hjD5gdN&GL)psAGn9&a%H>e={t>z-`wXRd z6baqGeTK57z$ctF6$VAo&LEuYG`C2TlYK-(A@4h=%<~W;2w%nnfpPlzWB%FCf6EGp z6;JlWJKtwH(6giztpQ$f*22cGoHJ+AFzMCegNE!1Fi8jBmk$0_KV*C_xFD<8 zIIiU$xIM{|`8v^xM?Vd2L+|N_*y}SUycnu>`ZW^w{sAA`QbWyCI{`858=9|E_j#0b z5wvtv4_nT8Zqc@TF(hxAs+C?@JYD+M^aSN5r_P3&wCV&fCYDoYZ3t7($1#oz$IGIJ zz|qiST_U&L!CW`0V1xR~ykIOjs$+T`G~szb+{jCxA-G?fHy*>3MJLJyW1mj8mRl$s z6Ij%qp0dI17bSD@?U@piwf2ANzxoG<3i|85biQHr4^K-v5wZGXDdx!0O#YK8>kk?K zp??$Za8N_4vS$Dt70~vn327dK0%~G_z2g6{vcKJ8I4is`S5J*l*(=`ETs=?lQ4x{(26eZ6FsUsEoD$YIeS!siVi_RYEXGN?Ist_<}nq5A}rUE zHph^zOi!cclDn;MuHC4@T2JSKW>nm4b#|vqTh{PeE6|w*flp2qpU?sYrUMCf0j?^F z{oG})hioJFA$*O~`Cv6~+Ub@#Nwz_NI`56mfo>6YT9N;amCjAW~f7t5%zknWAe))S7d2Y70Li*MrQ4-e&+1?iww-c2nYOF>72vm` zRmw@T9W|YJ+TDpbXW>|_EZrndrMnGEqx_$65z5_+6FDE83Hy(a(8p$U=ei!I24CtF z>WUD;8FK+qHj*E&oeMX4STwkBv;VBHM{@2QIvEFCeCi7e^7g3Z5Hg@b$P5K)_K81A z&YRmAGX==gV6t^g?wB!Cd}Pk>N@?)3dUDQKyUL3(z=a>80xi0vP6Xr=$COy)*`NA8 z+6kjeoB;^S!LM=?%xYZ%UoyTpqM60Q&sBAv4GT}{(&+z_Z&(5K8P*IpmG}19vQ`y@ zg|o~)7;_KLv*~g@oWF00uTbA-dZOmrv)$F{YO+^%o1EXfD>;qn|Ga_<8#I&aM>wO~ z(Pxd(GSf_M9?>IR`ziW{xfaMOc>HL#-mHR??Rk8o4=A;^Cc^WIx#V29tVDnHAf7qN zKbZHj4kY46I3;3WKV@d;m@QW9^l3dxdXOSiIGj%&HO}v?bX{AoYaPt%T0t|#vLTjH zL>mPQHsOFHmRWd-h^<9EtqvuAwoBec9X(wSF<0zQ$5{n;K(up5v$pZ<<+VqiOAhrd z1htq>rx&h9lTzdN8h-2ie%xqQrWZcJub%EHO^bT+_qxv=^rG>1H2b-c?hL({O=qr2 zXRm&1`u<~evbTZ9Iny%q(Xa=l;M?F!D;jzlHw2o$ zNpcmgJtcW6nB!vnb2{Co4Z;#NFX@G#42KxL6aPg>ENqo}a^d^o0xKc&lG&nted2pd z@P$LulnISmZQC&f`G@_>JBu+?=ICDSczT*e{LhUo>!gxwWY+y ztjmmNIo%3PN6D#ERxN@iCArT$0?hk1-9hYCgJ~0c6^GKm(nO-Ku3O22$%FpAT@v&z zwOr7;#@!&mK$n`gk43ONWW|2;$f_uj>|C>ICeFOnXPPH|QSLl8ZOUiG#pl27V?c1b z0hb?E4AdI~wYKp;bHuJe`^#Hh(N8CdZ8y zpQy-6nHS^LBWB6X@xG=3J6vR{%|@p46i1Cuu=3`Wu-ca(zS1l*)%uw;QdMn)aa@&6 zQ59+J0y>BhPiFG;DXr}534F`ap!-Ssi;gWQkZg@?vk8Zee(z)TzJ^LrU%1``o3DYp z8)wbyvwBpLXwE$6}a+h{0rEP7?2{n^sD^ayI!t(PTI1OwQOv^^09+`r0#NyjkMw za6F4oT|+8`vvv}OlwC(d>OE%YCW*efCij4rct;1h)ST7PAP#5{&F#RvzW1tmtWh8A z{$>KS9|;i>u!Ha}$!s&|#*`{!F+#dWS`#yho671~NQ{Q49Jpc69OVC^9FiS|W} z`mhb+bs4lQi>Ol8h@=_)W|Dg(tl90#W9bvr-ViR{s~P;t&hL zu*uF>b#4#-K_3~1M#2%lxcpY&sr7!AH61bBzE@-BU)=svj@4|n4%0V0babKL()D?4Z0`(=1v(;AmcE*~@47&PdZb4n#k?SnBki|ywQCg0yZFIN=N z-J07BS4Gv5uN!xNncbM~MQOEl6LN85UsenJ;H}skG{*zw!{TSccPGcqnn!)1LR27m zY-U>TxSA7HkYl@Sa%mM;nXp=N$_zKHx}&Dyk#tlI^OKGop4I>Au&xeg0Vp=hQ)jp= zR8PlLu-zTyR9-Funv_z0)N@q==wZnh*@o2>!Od6v6%#F+Hez0)m7C@KIK#!`A$Ej5 zIc|bm*}F_drKPg(hsW%KW%oZ8tiJ0WodIjNRhhl4_>z=~^znZeoY%g)m0uLAit0d_ zpkPY4jA6oM;3DBZn|$IT;XZ48p3f;#g?$~RUS!+>je(X8JS=}Rm!090&>b+y2F+W{ zeG^>)Mm!3#xZNx(>Le>okV>C@DWP{62d1Kc5-!j~lCA~`L3#D=+Gg_Exwu5~xjEh7 z`v|+F#@c!U1|8fvQLY#>L_zvFdsfCua|=195L*crq*=HchAr?D?btQiP>4Hm@S(`y zvxWYsmUGu1mA|evPw1GG^)X0AJ>tGZg!5(%C_x)j)RztV+o-vbJJ0R9joFTKJsAO- z)za|-fckp{SF1}!8a&_T+UQecd!r~JEbf>xm=d19NT#h4s^`v5SB7{rD6Ect( zKRTrAAcm)7cpqs=KA8=GQJgcXbe(MeabfffI03PyHzVLkM58*uq(fTGHOM1&d1Y(h zEyly=$5>l=3(6|HKe%VMP72)axQHN`0s$9>PMKHYO^Vf&L?j-=^0lZf&b5Th*{J@< zxFMBevDuWa0*4i06`ELCd_x+(R~6r)9H)cd=#-bSO3C4V^#DeYbU2^MQCE4W=i^hd zd2Ei`U`9l3@IBeHjdZohvzpn;&x8@NC(@C?6mZ3!UN-OptTEY+3N{#F7L`xVSt%eY zmvfgGNqq2lK3QB%F$2aeOfy?VL(7Ve>mJ>Gp7=6*SC}F9)m~e)Z+WDdJkMRgXne5H zxR%uVHC*mhPfZ9JJ+^oKlq@X!XqfK``U5-)nqUKA^~+&686F3^n6H01^J&HdAEN zPj#okzdsi1BAXG+`anUR-PmZ(6Mg!iluaXmC>YNM-9OlZkbLJr5M}yMftV8rH2?2N zxiS`jcxQyvyGj6$Aa|Ha=R5IkO4Nhz_ff+4;cr0T>PB+yT&cvc6hPm^^DqJwR0NEz z$izvmo6|9SuAs~zwArxgx9=M@3R5hAq_O$-jH=8QRTv;&rK=^OJFstxEurUZ#3pc< zCgeOJrA4e(0Y_tIavzwUUr>l>WiN!;$<^)o4SO|?t*0Acs)z^D4Mjl)H=QrOgk4=8 zL%RmuP*W4>u0b(z{y8(ruV%Zu%Gl$0k%9}y33naN;L$#F*LiHzZ8v>#$u-{UPPy2 zRW+D(yYY(G4pzL!@)a*lik8*ARHmI$ny014#V>nc8ej)s1$j&qIT|=3!;{HPejz`3uYrE7{h8c$ZTnEZa_6d!N*EeJKANdtQG#x<|9pOz`JQNY;<3oO>Ua&ZVV8B)B3WX)C!>DXKMhL4%)!FTBKw{=@E6O=% zhNMQA!~mnvlpQDlpAIt9a=!QQYp!lnm#>0tJI zMkEbE-fIITz+PeMFL2)mVrG@ExxOBqtprDv^C^G0BwZJ>@E7Mw>Vp5;M@?#V{0f3r zKYT@_PIu|BSAR+I%~BJpxe(Z^M!=$kH0KSZ$Vj`@K58JhLiN_J`ZJMERv(RyHJYfo z8WN*{20AL8JiMIeIkXjd zvJSFLI{?NySbSl;6zyE5%9>@`CG^Puj07^@n5rPn+%(7eltFP7Wl#K=H&_ZmPZM?Q zEOxovm}5=BQ100^^^RFpdqs7oepjTmj{erwk=Y)lYDKrcoxO61YlhdSUwLlZl8uP{ z1r>qI15d6nb3mcCg4CcXL@ZX(}+Ow zlk%yxs0ytnw{@g)aJ9(K&#b}vVKh%e-p%XlTg<}IN{8A;!NW;5sLy)rDe{di*|>2s zipUW(2ns=UAnQR{i1Qs# z!8+#fN}(|$bA&AcUfA~9$HEja{1X^w?3SfAK;?3T1> zLH1Os2$1r^>L?z#Jk`U`H}}*sXV398(GG=mSDI%wZ_cE_w)=Fx?Zylo4>dgg1M}j~ zNYp%1xv&XHuc@SW=ugk>@B)sE(KQnI- zO9irTfIDCUm(vPOl54oy9TcFr)_3u^>`FT!ulHqLQb(^cN1?F+Yt{*vD!^A5`f*}d z;&Bpx;@ih4Whm3y>7=ILq|tS)W;G5*BJYX6gkV^$E~U?Y@$ia7egr`v`NEv+x(5Vk zRmv=R+Lk~E%psVb1J$!2Q)pZ}oSZ()Q7NF54A$DygCs3Mhf4sTNoP101UYzvBv+1Q z>3f3x_`Kiu`?069P?-=IM1ColdbALL2DhxHr6tr$Nfjl!cBBA6!*p=kVd?SsXej-Z zI)v_h%3n^=eDp=h#5#v|2p>$;2c4{*8dZ+p`~=MVpYo;i=WRw0k|v{C4iE8te^ak7p;Mfr%HDz##e3TpsUZXH(#II|VrOum(g32MoOgnxdmGy0=WC zdd9Z{Y-ya9u<@lVb<)(d7ZB&p@%pYt;yod@rkvodDQ^-v&|1~fHz~{s<`HCl_D@(u zS=kBJobo28O9;y&t8nzoj}T!7s&K1EFfbhWpG#dpTo$$1DsqzaO$!GVUz4D5#jMPm zcz-g6L*AkK?r+wzUCntiZ0dfZ3uE=r;lL#WQF;;gsh-`~=^_r8V4F62%Yfo+&9Wnh zrEK&TnGh*Ejsz8E61`;wyZ3myqS(Eo0%%`8F+Go^cmuLiSdp!4l<+F7)O1{ZpO6t| zBeKa8Yv^I(cd`fRq4BJU>VIuW!p)|1Wp0F98Rb4T%^Q}+I2WhijUfLvb}^b|8U^@d zxZX?$%i{NF)QBiTEh?F8AC|zg8N*IcKl$ObuC!z|Nm^3xP|ut#u9`NN_mBj`;sHpF z%jY{X5LBDuIvw_(y|M3vO|j&!DYbrUC&2wj0q#|pzZsTvu}`|zA69-$g;{v0m9A|| zp3npj8cf#}Ut-JBI*)vDfLd9vb)L=iz;r$9e6y%>Q2Hjc<0IDWMP9v>S7H4_sNgC7 z4#K9%Bc+goU{euIh&C&+WZZ})qjJsRT1>0ggE7#PFvE&hN7C-!_&GSd+Zhf z)uL){Y**Q1H?hZVW%k(37#=WH9oC%{cSyzNum+f90rv^jkOit6(21++Ys_xeD^P<- z8ole2>#?LUQeM4y^Jkbd1P8s~383U6=L_lw`2*wGq#0uyJ>PiY#4r%4LKxQMKUu|t z%~0D}6^Rl6+#SuhI?D-unF`c?Li9dTrHW0aabN@ z#|@Lv3eQ;;ZcH^{+0x#)2|4r`?N316$|=iSs2k7zz-+({(nf$^?@0-ULCYJ+{B%bO zOR%n?q&poYRl^NH(|Nq!~_b5AyYF~7H>(Q^Z zR{BfmB>nDMy&7mpfQYdT5Vb#yf#Y!>9e3~t;||9??mPU$fp~^^JooM~j#r`rqVfoW zfIPz+ktiT2Znqi%1qA|#@&+UL;3@cif!^P*>Z__*-?vux>ZH-=j@j(hUp;2cnl)?I ztXZ>WElI~DU=n0$`5iW~sTe<(M>vPvqIW99B1#y83pAp#FZhV#Z7vUHlevrc+;USo z`k)6%(o6komeGSesn?a6+!%P_->Pf{K`wmZhS%C*GcctJqI|CoLeCfzuDa%ZP-rakc=S_{n)cpk8n?AyTz6TotS^KcJPAG$TSu4K7Bf21@0uRj>_rz zjl@U1McW2T*r=S?`N{M|k6gNe7if_}f0Bc9G+>CuooK^N!M4zLtUxft*hwuInU*!> zT8_$V82^Zpx@aUdeO`ZF zPQI%j5=sM?x-($hTa3TZ;(FhL@c!b$@IJqDykDFP@9TCI@9P(a_ZgkzeQ`PYPFs54 zu&a1~X<>MOx^uj*DkrzM#rwux#rvj(;eBT3czpJ@2@Qk@3T9{`}T6Oy)A$L$FAc2^@ZVmPUm>vQ=TIL`8ReI z?{6*)?{hoH`@y;J-nOfFe`{fQf3|bHe>4}~x3s|fik{RFGJiKquk&1Yc^-!qUmKNS zxG2MLk;eUIhQBw?j2Fjv!okNEL~(2->=)b_81h@&C4CuQVfSSQQ09p-o_xT43HksI zycqL^`oNicCrh-=z`{eD*a_gYoe6130$fASBX+rdF=#Y{SfvBRe3=w6Ts%?cNk@;^ zIXjKmW#hD7O%-{i(O>E(Ex%@-G(%t5oopWMRMXZ@McSOdw|-}pb}Bt;+6b7h`I|28 zz*ifmJnYhY0}{YK9+LJ%nzs6&74R~CAG9$Ba_UQdh~FZP+i?prWPrQ0)eFIN!vV>a zyIYq#KU!PP-i{{GRqsyH(Z@GJQIYh>u2gUnzxy{*fplhz_@9UyxW{c*^ z-QQukALw#t%?s~`y4+{xE%$&fcXqZM!f4qTRpg)>_f9YIz*Zd6=CZ%nTLjNm4NBOd z>ATE>+FJ~FnGIu0r_q0+w+MKw6LuHVU-T7o&VDh5QSN1e7J-;DRa!kvAll$#1rHhr zTLpQ}P2NM<5KXxuc~85`?uCXi3lb3Cu618!oaG_V2+bg(00WIgxNHl10o`KZEdD;7 z?XTmX9HpMd?e1P$;Z~fb*Kzs1OUhBPRHolC2wS0%vx^MWygs7r)!xYZkR2iwulDKI z`B)z@@FD9NNBrS&6QA2WJ=0S?uM+j?ZSv|M3ejp4g(wuh1&H)N>);JIdhsUCKiAVJ zenoweIX&#x{GCRMFj!`Uw)n&;`QCpQY|9xDg-j(u7VU2%h)}~#)&x0VS$i1 zXGtp|Au9z!LS|SYQE1rI0ki>$U_aR;Bm(1X$Rvmn#7dD#q5wfa9QbS`VD@)$_J@g) z5eWz#^}Kr3*LkgwWriF0e>CvhUl=(!IcO=l2Q_!Q}W)jJEz1oa{%_e z0EBep^wDL|7W2#in!IAR9z7|6;Sz_yS|Y#+@<*Lfa~VLJr$)D6xyPYRFs@?pvHbvv zL>bhTodiwUN$DYq^G5A?8wS8kQ`4IVMl8HC3W#hz=u09Vo!$v|`(!bu3rFaNaPY_mrrr zPXbkBKw5UtMdeUb)q{> zcBjdKZyMfBA1ukFo6xCDOinOPo=pTvqdP$e!^Zx{m}LtGZHYMEwxu4`jDOuL5fY%w z$iy|RJXpw05|EYPwTKYNJQY6^m;sSmLS$mF5}RRHrN>4q408gg_gdM0s=|W z84g|+I8Y<5ON=W{fBXzj68rs%|Ho=_m$sn08U(Pzj~kiqVtw}`R`u)@#gL?LFa+dl zKEMNNivj^+TVOv4Fk}P{JthDL-`4^WnOCMd1~=mxvq69>Dp(}BOk$u58gUQhWy41 z>;U1W^R^5h47k3L3|sq9Pj|uicqo2VflYU0T!XwsDmF*`=^RW;6iQ;_h z!+ugm`Y)0M&xo`mCn1OAl#l^RLMA~xZCN!SHWR*rn`7-;BZq{o#dnV5Qf9yl`ppqN zbA4OrG4&$&$G=ON+jq9N%z4N>NTTJSuR|(|F=4?g$9YjMXbo` zzdI>32H}b>TZ7_+#~HAO4yqxlPCgecszDx~$l?#-e5OT{wD!a2{+Py~K3OnN4TySl zA)?iVvfYm+`}EYR06sQsy&KuBc0-&ex)?-e27|~1eW~4pW0Jnq-pI2uUL4iVt7e1g z5oH~CGT9ChZv2DA;OJ=`A|I`#9_}Mm z-imuauAIrHK%ze3*!Wm2aG)P$aHbEcF>}9V%rA0}*OImRcuc~=^%l7M|C{1%OfNXt zp=WUAL0={FR6sHue2w)i;5t#2U3zppqXcF0e>7gz_nQSGR#oZcHb z2AhA~xwTdBp6-l!ZVsM;nMKzMwG6+q4wriJXE?uhjN^XYM3!wxjEqY3&@eAWd?-`> z%1ZNsV(JmzaD&b2a9a~(!a~i<7Mn1OeETf+<6!WhM?5#$m?S59XynA7cxb4lCbR0X z1)tHZn!kZ&?C=1f;$eIc(9)PjZvMQ|7_JNl9xDHCRh+jK!VnfTLs--5j~=O^eMR8u}q z4-`X?9arkf9Oa-<+^HuH$!*4nP}i}?1yjfX@p}kU@qZ zLX+`kTGObymKXR}8e2>?p#{kT0ZeR-?ALmH z`HtWopoy27T9~Q{Y#**{t|sEB+JdeS=qyc9@ZJ{?NM;kn&4)Wenh4@Xyu@(+pY6ip zM0oos{1HT z?3@mX+2FjlO*0j?Zu^N!$)+AWk(UG28~k5mOqTto|77%)bcFG;uC^ZGW*D_&3mi>hPP$KE4Y{H}lWBVrCyFCqbcxhqTS;_5l;wM{nRU46YxAy*xt)!aS`j4QKKp@q)p@Pp)fc^=s|y2tWjX#NUibu zPP0{GQkoL&pftAe4u5u)mrpIFn5{2a1#p^wDYhpFt6-@V5U7UGhB(4i+NN_1vPay# z;V`v8CetiVa1mBrKxLH>d(0@=q}FAaAV$U`h3d_xvwh2SX7i^!my*?tbx7dQ33pi! z9$p~4cnq(#!D=S^(Fu(6qtx9$|7=Tev~UNamH|C^+VI`laY^}DzDUq06}idOrvUNy z5IhX*8y$z43h$9S5e+{LHv>tpj~~nmh=ULo(}G5yPG}bm64mAZ>pb2bKu9dS7*_j* zBUJIl1KQhb@y`+e>ySl%THBN)LU83EIN(Lcq1;RM9Az-MN-&Ds1^ zCAk;>JyX!Gc`*LRchz)d6OCKJk?CutG&+9%%o+;}4@pQ2XcVAw{KP8iw*2ThHYvSN zhijwORy;nb!I?`JfC-)tMcMZV_`zo-0g2O745A*u zSx6xbDS|CR)6Jdn*U z#}8(cJV@5Kw-!G{PaG33v3g=TeSoK(Cla_rt7N8Y=zoK+{)i+|fUZX+@Fyn@^%E!w zwji=V%p}6IgBbfLezrvUXLET@yq$Qyj7 zI_3kqJ`ZI?8^A<-vBi4<>6rLo*>j=`xt19hbXm(aIzg!JltuA3Sd?5yN~d!eFV~z@ zN)L=xphzj>;gM`RugeAF#HlnoXG3%LU|+N)jMRzX;Wz}=-d^GRP2Z_;?!({D)ed1X z7U|QeYxP`Zo*Cy30&yR`4)vwOl6|pkKy6LmbW&P%;hRo#KmvctemplmOc@y>jqM8f zU=ZTP7A4ZYB9Im};5x>I+!iHuZXV+cZ#ZHPQnhi9w_sT`aoBDt7K_K1Kg_i3LRMq| zFUZiOXCnlqo*7n%L!`&Q?ByG^*<@C_mi%}X>X;AQv_D*(%}MQ6*eNkhI1`Q z#g@3LQ_{5*D4x_4)%4MJD_aT%TZdtQH$?%aoLlHZ=aYJn1Pw@(0R8P(nGP56724Oq zbeZbNNA82)AN3K#7`8Bh8^%c4TxOWPflldi;87!NjQd!aKkzE0EW>>)XS{$XzR&>% zA8@&YKm!}kvP)nOvGK&vxFn(q2SH;O3i074&NjrFkLY*TJ$T~mzd#^?3cOJ?3pfB% z0B~_dAJVEmkR85C_MO`^K*ZJBs%u+QDEvH5AqWCvg~st$5S##Ov_8|d#+Wr!E(JDd zAEHtAfH37YRNHM_6CjnIhH&cFUTeq=1KTz3F&JbV+p@6nL|AH!J=dW>2t&=g{3u$N0 zDl~NP9A5iTQL?R|@0v#+h`%+YGg3){$Dw9BgAlg`aOzm9JGC==*}WEaQWO`o7=YPi z>L<&|5QVn)lx10)YIez~xdRTdUp z%;xT#^TekT{Pq!jI~&RYCQ6v~Z4=3ptAvHa8m&C42a(>v9zBDS7$MpMut$${Lm?U| zhS>E6=>jXXj%jrT&3+-OFe+-=1r@yYVY7J#o}X-9 z8Mq)%HMX)7OySYwMD*R}B>n|iB%JB_ZvFiwLoj%G1Q$m4Td1H2ARH^Ck##)zuN_Gp zsyy{rPQR>f8N(zPHCUtx(Cs)o1o{fYXNg*b3x~`WGwt#b9aKvz-lE0bK{yAzEjnXo zCP>RYlr#pTpUvOOiAauI^kpS0=iarfZMj%#LqWiC$to;6_ws}xyQ)|q zVe!?rc&_{%I5ss%F7qT^!oe=_VgjY zzDSRkpi7L6nyjlN@KiRGfY-5;pBQGHzqXRlmCsUY{&r#CkwD@W?c({XzaUsTU|8T1mz&%GoY4f2NX**?e?peo`_% z)jaKDAC(+dNibNghmiTNuOt&TpFSd4T7IgGFzFPcFP+z=L-d_)&sRcr&{`UzE><$k z4*t&y!pqVN0htcinH5f!798RWkiEh2$0z$%lKpHivea!+yje-`ESKY3UxISFvlgc- z$^I5Z2Q5xj5(KQY919|8UzjXqUeTe3gBi@J7NM{k>vnR$mvEg38AQ*DV9=8Numkof zTCPJ&Je5z!ENw=u+5PXH;BKNmfc_1t{oExn*pMx%)=7e91D_lX<~< zN>*zuaV7vD0X6$%s!N&Qml%9vs2muxg}0Tt~xfA=ac zk91Me{|nm{*m2ghP|iP9P7lLdN5Y8Q$wC3g0Pv27MPDCa_XHVm!h~ZDOe-=Ku4d`W z9{w-^P+)Q{yJ9u{R<`oc2GI;0Na41D0KYUqnP*6^T$Q{*n`-;~$qEi8ctGS}4WQ~T z)7#s zIB(8Y@Z>}V?uDf%Q|qg9CE8YC?Z;^I57`DLy~Rd%hM}1?)HT}dy`;bT^-6jk+U{J3 z+vJ?3n~pif+4ldygx0hTD>xLg2CT_R#K;|-`7@edH-wFIwHr8c?$x&k*7b9Rd4Z2kd+C9`?1;co(GaULB1Gw&bm(NoH)HXu|@p7W)o# zgw+8ZmHJT|+%sKV-x09ycEG-0-^0F(z`iRx8jm#{m3p!b3%pwFi~U{)lj=1cm3pcT z?iu!dV@JU5?0|hA?T~%9M|c`hKTMu;qQG|d#$GtL(dQkGOr_=*;4^W&K6`3@v8eBK z6_X{}$f&bEgp#-Pehp6V@vXhpNq9#5-=XgxcD2x4^^RZo6e>Da<9*)vfzi|#%Cz($ zJSVBal{GjxO=Q4vcBuw#n>O9!_YMf_kJQNj^JmavR7=h%v z^Sj(PqjUK2L19=EaFlL~n*^Md`@V4|U`rGBNN$5p-6uWDny1c|?mcsFcbI!|>uHc- zQEiUZW`%I%v&A0mZ0;S}y3vr&5H-A`Vz*}J-rcrd2Xjw*I$3_l#7*a7zGenDI!I-! z{c${BZ8w~uw|6*0Pl?jyHShdxmpMjoEWUS1DJqru)BIdfd%<(5FVj+JRR>0F zG*OlqmWj^CnMg^lBwWRyOPn%pR0R|Gr&9gb6q$BLKQv{p7Qoz!rtDY#qQNPMKUv`~&Yo{x?G$;9Z|3%T&jcW z*kWif1WL#F5NKKtu~f(sCaPBTzo#_m@ow0M7hYc~7+xYLMekiwjNrmuAoIYm>4}6k zMK3@BD081PL`x%&ma0#bQkS(U-vAJqGJf6wCT`4E907GBNNargqrU_D=iSNot7VL{efv_L=)wtVM>nAs>ymcL`UfBxHJ#3o;K==`i47ODd8!ri)gRV5sfs?x{I*Ov0Z8m>U zyZ%eW9K`jw1kx0WA3-OV7xk#WUAt}C z#!w*akv^`lxj==g=vWp2z;Vzb2C7oH_pRSIuluMO_pa8lII5FyF#K<$S zigvLLGU8{48RKfb;yd%SrVN-1DgxxZ?BM~npP=*6$5N%jH|=KCa)0XlTO(pBYI&9S zc{ZrMKrSx?&}Tk5IcRTqdg5>ndDQg4#lONkgB%K<&idvt;UoE&@T_1KWX;=mKf`vu z?`nk`LGmXeWm)QTd@l?8dg>75wqLnFdO+$A9Q4SY`lGMxu5W-4MFZ?TPWlnN>1}GI zr}+s7q%nV2RwwZ?GGm%qlt>gntniWKqm;g$V!Q)RIv}ZQ?|`8|%&I|G6`jKxfCxx9 zWyiyEIbw%sqLoA*wIhtt(QJ8yDgxpby;F@qMHuD@`v?~OqW(j+B}69128tez+KIc6 z@AxwR2MLY1M(;vgBRv~MT%%7NkQ}V9WC#KB<06oVl<$!Ypp{F%iHROF?h6v!&(j#va-hB0#5cVd7eP)U$M`~|?@a>)w0mh{3z-D~% zJ;GtpDV-Kv!NDl+ZAW=;SNB7JpQ@lVUzdw;*HB;OY zsr`Yxo)h~AZF*{TGACBg6fcj|YBMQT`z7jvHk0Cjnc~%vI>65g6g0Eqfa>IdGsSBo z!3Qn*@1U9Db-F7Du`6q4iZ@2;p!qpaQsXr<#hW#V*AT?PGsXXi)N3p?UgM}S2k#t| zXl0YiEkL>0YmOa48xPxBPW8#XBPPx*$0dxctg=6~Vma)P3FL%uMmF zNX?kw<#3R-4<}!BKr%&XIQjaS;=Pf2{aiq=wo6kWmUQg1=SCX(0pp;46Q`={;%|>k z9x_w>L8K1JO@iig^jfo2BM~z@1rLsyt#=Au4v{>0m7o3ha8RbXBSq`bnc_o{Iy8^g zXXn|#cyR5}@}de&>J7{xK~Ke+O?J7mvUB^HLmf~;5kOmO8bz^2ea-VoNFZ#kCJ&n_ z!ka4S1PNK0Tt8C;{nmSl@C~!nRn+=WO*l+q=G25Y5Xu6OhWLk<;Tva)Khbl+({SGI znwoE#DLx&kH#%H67;kc4dL13kGr+ke~vAlVv_!~WtVY$P@5gD1>FjM?PX21zS@HZzrl&81M6kncq4cdqhh}yimkqgKX zP-u#3V{Q%dT!~RcPm_{RCys>Pqd^==5dUSScuG+n2@qcTXf5c?t|MCGffn=zK?I$a z)q;-1+LVE^AqOQaCr0-jn0pBE}1kVpw6XJK?S^zqJz@c&f|;%r!C>1zaJ{=eNkObm@MZdYev_ zdR)N!LJEL4vkdbuP~kMq{)IIAZ&2Zi>R&*!H*k>t1^rFTAL+3Di^M<-8%Cq$MyEh? zvn3`MwR7c~Md27OrQXCXn2mENzhK@r5RJ5bvA{?Gym!&7uwg2wafZmGuQF504Vm%e zDjl{ZU&BOY(BT>?vIY!;wtlR}VRE)#0}64LY&gZ2^&5wSR;RXQPy;qpSB03NYs|IL zKgZ2889|frqcxgcb%6gc6qG_ml*4R`_oGqLR1%J}qFU7Oeu%Ak`W6^yN`VQf8}y0S2~ z-m@wVW?`XnP@ufP>c2+dL+n3MjGu?OOwfRx_8kH~m}h?-uOi5xYZf-#wYdK9bB6z4 z;z#HQt4w5MJ`bR^Uf)*&?RPyV(7?91-o_@j2zN>bm>S_7G3Zfa6#o{c#z$9qQzIhz zJ4{FzZEF07oRz`Doq{-Gen#+CT0KWh(*RSQ6$)#UJ7%&^r0ng>XS(Px3lb1upAG=SO zbKil70c5W-o6q0+Ua^Jc3|xPdT4DB{xTa?Jp1)g_?mc0xJX(l*G-NlG`W3&GvN7)7 z2Dzz(x$>PfS85Y@SOoh{T?7%<-=$LZUf|1Z=bT*Pp|#}_o*zn(*fQ=aNGYH@mJ5Ex zV->-C94%ZRgOT;!%B+KS!3Gb?ZQv(Ydmao5Lg&ZUOLLiTWkFn~2C>Z$gd&RY9T0Sj zuf@ujhR_np&5Ps+=_M~%Y*KCJj%ZlJ$iz*PXBa6OLRP zQfEhQxHT2C#b8No$q1Q|du>Ohwzc6ZIds4NPds$+2kT_gjdWJ*?#_m8ZEI+m0sdA8 zL-&b&)3sopS(l{lW-Yw=tV<&Nr+BjfOCua5%JKiq+)X&DJp^q^Ghx``C-4^NTa9Z# zp&>IKg6Gg%t2)U?X1jgw^4jBTA1?lX<`PG%M+}WX*BhaAGzqM;-fG3!_W$7MA#1d} zVt~5^ykY>kzN=RZaD7=-WP{?XN3DaVa~dN8T8x;~4;uTF8d3^;72=*zgpjzl7=L_1 zm$nPuI(Yx~PBB z=;Z7Bn&bVDz+sn1Q4O9+779>dzJ60s!87Tp%$tJW*f)9HcqZ8zDYjNMJVQT@2=Y0Q zB+QTTN;C+nJ$*bu$$ddNFmL+Q%)A|+0}4qb?ZWVunqsHyOS#hw+zQr&g_AGkYI}6- z&;fvo5+Qi+ z`ob~kYQu;g=~QWYQisKtDLZP_Nw_i1s(m|{-Gtb@EUIATtUC7KU}Nco_tOS7z2Iq1 zkjZBFro42p2f2{>KJ5@`G2hRb_AYXMmQiepRTK3{t?9}AXz<<7%<%pE3_o`ox3096 z(h?3`*4Ck-@#)2?sYwVX%?$d!4mmUDvvWPn$2wc(IJ8)3gMvFP6apw&p|C&PIY|fW z4)zZ14W<{`{jE^g-}R?6p&-c7LMF^P<9QLg@fOS_{A?6(=AX3cEnia`zZUv&%tV07`IKvlD~l%&4)qrBg5@dN>NL)z||k;n(*rbm z2l)y4?dkc|STmvyF>>F}vE*WmTg!7g;|Rzu8p791u&sManVqs@2i+|*j@Sfa($dSR!h)>`^^{+oK8nOX?X zYPH#4bTGBdh&seLwVuJ$!Wg%hT7F}Uayvb>0w~$31-H`=aca$QYQe>H6MRtZ+?ug- zYsTT*+1!$r(cewG>-$pBM{@ z2axPC0VH+E7Y2FJ0VKOx1bImVNQxFgn^MDm_Wh5O z2qEFtf7?3_224lx6GWzJZ9ik=V*Q8L+<;2oFSS`LsZB>VVGw0ujLaWs(Q`(FQCnf(Kf9Aw)_H6!a2CDMVvFL^)353 z3$Z8_j)Fop>~(EEsKfkTx?D`*lDW1Js6<=C_G6CJQJ&WbRi4l$0^3t(k`*kNf; zRu0PTG%E*CvaC#xOOD-Asi&1WqtT3SRUS zh$1K)4~e4pn)6tvkDACkY(P|{2Mxh{wY6=rW@p8I=$2URHsip_u{?4AIkh@h=La@4 z_--(ih}Oq|;85~f2Lx|9lo?9%_|2;C7)B7(Yxo#MsCc46ew;C~nF}R{Q|f^>ES4!&>j>E19hG{pO_P$Vuj`PjpZ=#4P=8y_%F3@cnL&IaKA z4hG=&|49Y_Q3izC({=zlEH>F0G~DxV*{YlYpISAicH}Vqd6arIwvVA`Hhjro@{>aR zOlh(J>lbwp>(&UL`Pik<_$w7E2Teckk zGMiM0f0a-AwM|Oje2=P^m7=;f?zN4-h)8S4n4pdD-8bFQVJq>`b8J$2UxW8Au^o}v z^7dsJy|mBM^x!JnA8HKcoJss`&GzvaxDHktJ;mA5EJ}4BfrHa7JYn4%KaSvX$8kT3 zxO(_}q7N4z`}p<|;Mtw{H+*aA5vbkA!Dq09hjYru9@D6!WPQ3=i2qbm zbp`VgE>EZJ9@FTlsxJ4@g-adU+$J!``e472S#; zPb=2=eGQ{Wvc`1uuRdhsHMZr(2z^E*^FpJC`!Lf(%!X3@kPSV~H-~K|g4KagNi?iD zq*45Ai5>_x7sQEwOGc3iztgWP25F)M0sdZAVZ!ffN$J?6{JtZ#zljCLoX7fPdnP4` zKA1!wsK#ebXeX7RCGd{E&#Rw%vVeeQ27}+$CJ`h27&5*cQ4BsVCu4~I2-o9b{52O5 z1h_o#--BMq#Cie=4B|)efL~Y-y*o~GT{oKRPPq<$r}BZ7)7jV4Up+fYBdNBVejHAO zhvg3;!1wy$K2ARb_B1vckwwUb_|p?z;1?Ab6$`QWwS4sgO1Vc1s$9`z*(kPQT3>0(ws5Q=Mfj=%-IdF8b*P&ZiCJ;0@MH#gwQaGp^Gy0`+7MGp@%I5IDX7>FSv(H{db5ERXNX zH>|b&svibuPLKZNyZDXp`#t;?@p~tJOZeT6-!gvh!fyq?_u#h+zjx!e8^1rrZx4Qd zhTmTN-iO~l{QexjRs4P*zcu_mjo&(ce}La5_ekbtz1b*STp8OcU4g5Zd-%0$AZLBwIQ{-4NZqOp^SFAQb$l0#}wZR@& z;I5;NNFG$=T}P~(gXDxBR|_m6-~$HFrz}V`5Z^gMQ#0JojT?0AGEuYnYbb%dF$@c? zQcLxWwRH)2sVhuWJ>qBv@zp&NQ~2(3WvB7wIdU~{_|Kn04;Kj8S^l|sjOW@qz> z=Dp8(s;mn-fx@6Io?x)WNhFV7E?WaUd6PU!m z27`p{H9wo}`|dE4aJaEvEi*G|ndK7GYbt_Q`?R%Y7}vOxpXOaVEXA zXC~oflaq3nX3}punMuvR|C)r*8XMGrnMng~a&RX7CY?!$rg5ZNo|{R_UExKTNmKuf zGik@Eo`d$RNk)_2i8blBoy?@kzyC}^2${F36=o)_aFc^G=~wAY!bPrksFk^yw9*w` zgqhU*XPil!PTMn+7GX{LT_-cCkz*jQoRUAiIv8#b7IUM7OP@!nK{J&G-R$60dNG|! zxK4SrGNuiw-gzy55vEd}5}peQ{?*9T`UU%=^ESaVInH|J=#Ehqw&wC!sFj z=LIcMo)>6J`q+e?z``b$L=Bjc=Yr=Uyn4C?o^g3Mu8nIMGaAU4r&1ZC1KEw`)bue| zcoAgGCu%OOwz4Q&_ z)t-ni>(InVnH`KR?c~PHt8I@w%9WC1E}-enc$nW?gI&1MInbpR%jn#m^nWLvDx~mk zqK{;!eBSDO!UT>bhH=|scaRT=8IFLGMm~&7j&1%Vl@EAo>HUfku0nDfdACS92;K}^ zB>Avyk9;sExZ>P|Vk}&1^70`kne#h^`3|MplYWnU;BsLOrRJ9pCsIBP?k4g<@eaQ- z@<9di;isv5Xz+4;BPSmkuJ9u04}*&)A2x0FEAbxv!C0v~kq_ZMW~UCV+mn8ed{~Hl zIEnIM#cm=W@Z#Zz)TEIQlWxk>cKLKFAMoDcrbsn&0;1_kFM@zrv1kHf#~uY@rxb`q z5D@K2zehkUKtNcrnvooGk+J+fi}vLgN@rNgq_L^|LtV?5fokC6`hxcN@$@bgqUAa>+t zyc?X84*R;&iy$4AEt+)LvS+*T_tGZXlYWncSb&7cXcM2JyoeVhFL*ri7k`}a>Ya5= z^M!FWZN$g469^O^&!^%8QETz+_Hcj``+P@=a~`GueXg$Rtz6c}B*r@%m5`TvO2!A4*l>_h+s#&fB_z=HtWBK6vwz<8}Iy$AxM zYtaP8rcdt?7&`XC0zG%agSVa1Fxr!TkHA=nz&L{fqnt+S5#FEipUabY4C6M09!ko` zHC`8Lu;MyAC#3h(q8a5u@9R&em!24%#On`tFjkGg zP0hG3v>tEmQ$<{Y$2*q1GE&4_(i?LcYY>EiSa~;TqI^HXNMzdRjvpLtyk5ON0pM8# zsMarQNhJK#Ckg!C*7do)XKbb^X@_EM4>`rH7idI8qZgO|Lt=%bxM{Q!x(;hAm)`*c zQ}`F-3DOrv=YjP6Xr`f>pgNF@Ka; zN1T3D(~PX&HulU%z@8V#ia#Ei!~=PFaXT!OalekA*Cy|<%sPhx0X@=_6ywuJs`CJP zg!iB3fm7CS<|2pBLw}V=1Z)OG0*S_?b4QYrk($?ziT<~toCi+Id*Gbf0Pg9h=lWRu z7b7#WJrBiC2SP&(ImgKpiR6VO_Z-1&uP8A4kL7Bu)Ox8pWTuE$H}q0Qctyk;K(y+i4N_VxrJk4~c zgB5DMStz+eg)|CD(Q1VXc+tG0-D_5;xgder!t9#zO_6KQ&96|tLMwLLwH0a}ivA5( zs2#i83gx8DOqNUQutT;sxVyHf0305DS>Zf5YHRo>9%@?`Tc) zoo^|MYq;)AZA>p>olg# z3WV6cXFW70Xv(6G8ZO`sI&>wI`Jm@~l-2w2BjS(d?ifE9rQ!ZZgP5M92V zP9xx6{4(|n_fo5AQx)F*?c9010Q6>f3CT(y2pc^w*91%{QkB=5`*0)7ZijAT$pQtYk1(!SqVnhP#KdW;ysU+r?A80}2v=lWbG zgBpi5AEvRu##$$+A9uS?hW`&Uclb;`d=X||?b`vMOy;E&2(leaX8SpSW-pk~pK0%- z{^|))I_&KNKbx?z%?F~S^xh@K2*KqG)#fWvqs*3Cb0OZO5RBG?uaYaNIW+$Auud>R zo>is#`T4MLEEp%#k^{@+3QP$dT-$|_W}xYh)`6eQ_EDyp{jrpvM2Vy%B2zOG^<9o* zSSm%fTz&sMA^A1i*x1xPc*QAlk*dq82$A`*5tqPV(-a)GI10oUPnbZ~=Hbg?fAvgD zowi}u?F8*h_H9R zFZ#eG@rguGW_xMH?32 z_h`s|l@WKJ!(zW-^+7}StA;N;<3RC%SjsWJ@R)=9#cy(Nxxsx+VaHK&UkZ(FnQ)(@iU$mZOo7XMfq`6sK|r`-BE`x9!n3FGClN0taw(`O zz)lkmWtHdw+NHcIyEI)Wzy`?2R~l@R)q0KX?yqjQT2p?6!?5IBXQKBm>57V_a-~bJ zH7U^!O*U^Q%_bwzpH?*LzzF_d)*-^p^AknfmGpYWx0Wz;){|~ z{A.wg!O6Hb}&fxqs-Bo324Cyq@bf7T^xW1* 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 z ziV5L!HMD)?^A*N6;ZftAXsV32ZO1t^9vuuY-FLl>Bi$Ma`wC~bA|SNlxHG&wKy-n| zeM5sjROgw_CP|}OVmMGgYAyA6Am}lU78=4`E)BFw*Uqg=8o*6WYUlv&cGWe08=LAH zpdlwrgH7dnbXFdS1TeNAJ@5uepYV*NZ|W`aYH>iy5!)dx8Ytugs%N1#x)Kh@Ln`U! znsrHI6E3D$hDg96%#xa;9KtLKp4Bbv@|LE5j^m3y!6(m(V@5cHSr!cr*-gLR?-pU3 zKPOX?ozp1E!s7=#nbj$ae3SPDX_I%kw#oafq$G2>LQBc&oS-BtY>)RD#0;Q$V21&AP-IO6Yg5fMD5>9)c(yx?cYq${!t}}J~K)5 zsZLm0$AftMt4`#v$$oV|ekS_W{rMU1SBJa&j`gcA>zC)n(qsU`>TDdNrr}CqXw$53 z)p}27M74F*MGRFw9O^iG0IEP;;jlqc?v>k@f`PK{b6p)qR=YxYA26>o*L1w!jph`o%vy)^8UIMaB!iwPB5pmH*k9R#r_Y6Yh^p$;p7ltzWvqo_6#DEwQZZVChcAU}cdZ4kjUqwcL%h6}_&pqxaGQv@$ zzAo(CF%X} z4sMM~#xfSlb>(=IipA)8tavl^^}eh$7M4f41u=aq0{j;-3ZPATd2m?l)YM+@bm6=9@S?z1Ri>Ncvp(L-S ziS6peiESBpHtB?G$=xJ5;aXCpI{2@tFN}smpUM!D5T{l>W`q;2WvPn;Q|LIOKhEf* zPwd?gd=$-dHAcT-Se?7c==Xp9s0%(fuItVRMt@qS+CQyP?c2S@4wnowM(+y}qj$OR z$`E@w&ocYH%hf7XvN|oO_UDb!`zjfu_XSC{FI89w+(|H1>BLju&O6rE;hEisu#XtH zlW1Pe^;30nxDCBksTRXg7;`m6Qnf7S2;Q=sBV0=iSEwj{YRfrHR$@3zc4~GS(You~ zgrgf~yGw!{YEQC^#d2OZfh}259$30`^OgzP4nMw#mxWz%wZz$hDXXkR<|9Odjm$tc zXvnl|nQK5}7d&}IG=w}xSO*d#EUNmvm6hpL&JaTD8bWAYO$aT6)L`81bQ=9(gcGc4 z*F+`5`XJ^p8Rc%NIT%-i;}jY}2o3zP7D8Q}iZEoFZOTgbS6TlxeSw z#V8`|>&>+gC`E+j(bg&urKq;rg3!E5*NQ~ zbnw9lPNfo}gAYcKrJWFs5?i`#l-LrY5x3nnM+9u?ve`i7eu{wIpAB&@<7#4;us(}I z^4qgCM26~IA^PmjkXIY#8D5soTh`GGt}dxMpI5)$20+cXu3LVig4W4ZL!c8F9Y`|r z$@wDrxEdY+_F|uAVC~~N(0al~Gh|)U6^3(|XPmV#ta3scKbRKcBm4h8>3MP_0s-E1 z1O(7UG*Kpr<|2R-IBNpnp?aEYOXR2dyz$v1p+LJbq1@_WBR*M+0xOELXG3i#%AQHm ziLzQ+2X0Qwg4OHhJ(Y7&HfD?zWgC|B>Hcv>iHYJkqm0gKzi39;Ju*i5zE4DCfluO^vJN zt=56wpesQt*S1sL4Msf-*_^V88Lxq|?aB@3Ub&A)ovj}}`fUC3Uj0bwT7v#(aRq&7 z|62d5Z8g0)rI!E*kjhH{!L>7s%g-YnG4@RMv?) zc_2ME$~WbBQ&ojmZs!_x0!o&vpa(jy3K3H!HHA?A{pT4u7BhA9Vxx|Bh~!}weZes% zN9vHsk$Nneg|mah<;bX2ym?2UU$q!C;XH$R51$|1^JDt>{P6Q5lH(USKW<#hJ2|GmNxz60dYh)?4I<=HX>!=-V=SHUfR0kZ zD=|EvqnC4nS7LZT2d!1~O6*3j#BTIT>_)Fdp52rtryIQzyWutssk!s#=4R&`4QcqJ z>b4%p;T53##hf>f)uA(2irt)<2)|(z^AFt zv%%3~t9Q^Gkdg>C)#(&{W>N0}qidQd4(sw!db8}EpX|g(%P9J%bxUK?_c;j5&+>7t z^*k{T5L&sK?dU&VtK)9eSh#0pg@Xw5M6?w)2v4>U=1m$y82uXvPZj@ocd^prZ)&&> zU`+tU_xHNJ;E}L769G3P0zzcPI4&_j5bhG}EJalD;;ZEn4>VRCy#qTIO6vDc$MwQo z#rv=qRb9=!;*q)=mp%s6^0P%rgNCwJl(eMYqWRdjCY$suX+0fp0=q&EckX<7!O6aV5v9Hw7Ps*WtB|9jWmRv zCIX1!{$$=A{@di;(fWetTP1b@O3=m?k`hM_+&(6g+sEy^Hlrv1d{e9k+&;KWsh3~N z33TEQ=c6fKg~v|A{YhP`^tg=3z6>vqtlnkgkF@VmTKA>#EeTcNL4BoUk+YaxUbIbG zhN3H>VzlI5lBgIhxf^O9WJX$g53#6H15}PGMk|gPs2KAGUz>uHD7I5Lx!5N|gE8gb zv&gJA?bD(Q%?3PIS=hrsU2R1Wu%tQ@JX+*PX_;!Dhn-=EI9}xB<@xkkF6Q(e9oD&h z5TQ5}fZ$M22VoF6aYP1@QNqz~jfBuu(ShcBo&suKz8wy~;%lWMeH{%1f&-C(R#R#8 zhxNcwP{r47Yh}E08_tzEh%2|3eQ=$OFK~TsN9age!nc{(ZdBMrGd-ZTU)^miGma@KOZQrV8b1aL26<0FcG57q3dQ?2JDW3~Bs+mrXk{**5 z1FE^vMBp#%kT90Sjo!9tloMKD5E%^|Hqq6^IfTiWlPd3}m(E{GZZ)heLt5Ts_1em4 zSUi0m!a^#~1J!S+xYFQvL zWWJ^eJaiJe&Z|7Ut)2Jl72CMgFKH#uW~)hb)2Ek>U(gSGjW!d96K`ImF9*m?(3>>d z)v0W(M6&Pgh+{Avhz`$$apf(;g$W^AjYTeOO^cv`4O#|BI?QGP4HtGy(AB#ObR6eY z5!kSSQTt=wds6Lt-!>|U4Wk)0Hf*0#^T;u1J94fD!4XlkfD!ZLpBpM=!g*&wujag8 z*b&CH=DcvQmrT_+Ge$Y=diVFtVZs+Ahh3M;JP0p-`mB|2W<-bGyL2-{OFUi0&{YFT z5Iz=%Ljy_7Qrrtb73nru#!WU}US~ zaaiR+%B_NEbWN7X=0J$Ui9xw6-DP%_K#CpJ%7r3K+mgB`@|>L^S-UPX;bfq<3Sb$z zzGV>TwhaKTZ>8$%VYt4f)p){})*{!p;+PQ(^p-_~5-pTW82xne_`*zs22mm7Jz`;o z8&q|e96y4`7iMvL47ly6GPp2{ryb?Bci=n6*Pds0;wDbd@hi0{9$$O#!Qq?Yn%3Ua zkMi0(e0=R8cP3He_}b&)fN+cZ-<3eRrnUEsqrCPGeE0aicYN(N>KZR}r9EGA^D1Yo z=5YFd=3#J6Ywy`ddF>rO`fKm4#}zU6OhwFbnezx_PF+eiPK4e`)|O1MGI$FZYpXH+;Y@6&EpIA9;!h-zHonu3-|V;yl@X6{e}Ax^Hm%443dt!6W&d( zAHJ8-8Rs-P35^9)gC6}Jld05_7{SVJ@p>$6at3m_%m3DMuon0VWwezO(p&C1mYfYh zF2xI~ZiI4ky6T3^+WTj0y{u@el`{UIc66Ffj!qBloHZslC-?9z%6v=VX;QpnacMHI zQ2aH~H60wtd8hfQ-EQ!vnr$^AOga$7eEOC@ga6JG=f}Feu};4u zWXJV%-SS^|Ws~XjX)~BYuygY$It}({koO{+T!Jqbx0E4S&4$(|``1r(`=RwwZUW(T zJPf-XqHAQvDqoO{RW7$Gi|>{o<+BuU=E?0m43g#=;Oa_$uVigl>s!njUnTQO@&!&? zmmwfOfK|PcesW^%2jCzERe9r;H03)L&BGI|EORi*vV$j*gNk{0h$m7Tdh|qcpG8}W zWngmG{I}#@lGsu#xx4IF2fjDir1#)8k{Y0Lw53?}m=P@Kmc__p6}8lvfDevHmZ6C; zFjR;rt{lyUrD&c8vF%v~@LXjf4+pS9YRg%|lIlzCERi6p{mZuC%Zk55%8gZBJL*M3 zO1=1MsWA#c=7URODplRP+2fTzcOxK7f|WV{0vj`-?4xhb_i&5K7Q%lY&6dnXRQ{tW zGzMM?VoQ31-BpNeiR;3FPfQj6Z}jtwj0r!_KRW`(G@dc03E?Zo1TX4{F**L27!wFu zKBmUv2SmYBHzRAB>VI@ycXmbA6fRA13AsbWos2d4g2b9!uCXScC8s5^CZE@H4wEil z^IgfBHO(4p@>Md{Y~VOYR{F z=dfgnciAm)4omOG>mfBj<;Xd#IA#RSVOb1}{4Feb8t?<_unY~{04Z6euAC)pDcX;$ z!!m&9Dhqp9hZRy=tizJ(Ow{t{Lu`IlRu7a~O$J?$6|2dK0ibeauo`OskcbFYj-*1l z-q@zxP zX5pd~(4PwU%8lHr3t?C`9-3m=mP-@SHOVrl<_N3VQ?qR6B``&W&13XCVgIF*(p4WfWl`~ExBot$Xk$)JF;PzQCZWn z{j!k_2^|B=hG6F7J}F0XB5yIPr;}IdjmEM)mchpzvksmvzLROq=GnZZJbi)gL}Y}@ z9Vu}W6f?J03s!OrNUc>}8s z=tq1NR^HL5Vbv*@CI-Do6Go8USasvanM&!1!&Y?>3XW{1rOpof9EO$1rV6lX-a*fZ zq-^fK*FKy-E<=YCb9h9}L5CdtyJ8$&Nu6A$s}6mCa>;T~%oewmAz7d9yX*UFgw(CB z_`%VE)T<63B}ik{!5vrqkHZL@c_w%ISt9J^~{wbI62 zU4dQ1labFGbN4x1zP4E<>y}2E%)^aj>`{tFdlCcwbfQ|Qlp51J- z=~fU|cj7i{pX;g=+pHzISfy>&k|loO2X0OGzPR+{nvS=yh>331V@B{?wJaJOBqCz4 zD`yL{lrB|e_qw>2<|+$2HdpDR0@s$75l zR-I#|Q`uj1D!#u=%HRnjsK6wnbMsbWXEekd9Y4 zEQ4weBVCNF&uQ)&iLaabuew1a;EGqB{VRX&=8mAV^>ZL92TK}i4`HY5YEkC2JUE6=jQm*ZPj%oWxT}=rS;izf*O{M0bR_T0}>04#x zwraDeL`SNa@=;@;Qeecz`u1_(_}JK)`g?;G`~_dSxZN11E5B z^~kg(4X}bqS{`t#i>ixwT)Q85kjoz&KC@cIUx%`=BN~O?b`8P#!;7tY+m&$qJ${HC zs<&Okv-aWP)(M{L3;%Ld%Birf6D>4tSk<-C{L-a>cYXVV`I3`3H=*q1Q)fcas5ujg zXmJahy7iY)bp44I4K{Tvju~N7w=DG;$w3NbTmt<-8@ z4+e==eQyo0ma$aqM>Lw;!MUc|DA4kEKIDGqQne%7jQ@q^EaCL&F#RZSC%W?uc3(nKr2-7(ITn^)JZ>P9iO)e$t_$l;;v2f*l^{k~uMTCtbUH|&=`CUJ zh7=0-YJa!dPhhZbZH@LcR}{Aq%itoSwh>G6;+3`$ORDw#wM?Hlxzd;DMpSjayRJFdNTj2NNjJwW+4N zvk9msL6AcXifVsSHjjjcj3S9_^dd5F`$ENpaX}i$D_yx=k9w6^_X_A7$hzVqE*G47yUq`b_+iw*-soU(e3Z4Y3^g)QI zAXbS-QL#T(thptzl>WymeKgSw15o2l1cI{HORp)-H#uC?W2Z=O8oRL}f?G3{5Zh?^c`d>1^}Tw39VNJV3TA?v zFBrbF9`U%@3lM3%{kVlFwB^7q>L#c>{?g=Kq`R+4?tq)a#K14e5XT)*a*ri(CJd4o zs{L-92UpbdplSFSHr0n12h2Ds_nQ>yt#-eWSD>#j(WF-L&yfOwHx-IYVr02`w&0%g z=iPdpFC@o7&|V-6n_J(tP}$Q21$MkT7yNxenm;aAl9?rEBkRv)kg)EphIZ?frI|eeUx_X~&TFA*W zNJb7nvbFDSVUo)QnQ#aUCZTl;)Z&3jXDrJUL2?M0_%i~6bT6YJWU|Q!2rXG<$l#?Z zEF4+Qr9wZ}#CzdVXuoQR_uocuG`37R!!c}@!rfQ$!Gv4KIy^RhB1Arp2fdnkaKL@? znq-99La3vFwy_uaVBw`NgxL|^ZXvlB$i*8mTSXj zepy_i<`FM$^N2V1dXs;~Bbv~2lukrPgLRx(;WUT7I#C^(uO<|0v-fALUFSAee4e`z zW$z8>6~`ai{ZqKe_(MCti*g+C_0orSen(EyHIzFhs;_t1Ux9*9GV#=M;-MEk{nA;S zsKtq}T_sP&am+50#WNRo;p8MwE^82zQ1QieO;Rp?DaA*{vlex_vg(wBFMh)O{|tC> zvBjR8xvuQL;i2U-o+do-BQB?(%3sAzT$>MIYP}0iy6@fC+j7ywp9$3ubuvNaL!Cxa z*`isw1qrF#l1nPSAW14NS7M|kXZbqlkSqgm97sa&E}xYYmg!ry%$ZTuz%z&|TTCPA zzLix2HEnI~@C9gP;L$|5ZO{=&0wxCT+--7&B+`xllx-RP2SReN`1z8{!9U(rI9C)J z^PkbPI%F%>H~-PMwnvSL%ZnNl%h(GF2o;vxLlTXNB}<5Q_$QN1dUyH%v-jRXmJ~_e z;FDFa>XpcDx|>!&zOHWQUDz4EUA9N;>@11x^vpNA-|m^++1Z}@#cXXOUe@fx)Yc^k0N~golTR zhsYJI01%^KL`*cfpMZ!-Bq9Wd_Gp5jRkBod#1pbWF}U~)oBMWl8)0Ttr=Qh42e;G0 zFQYnXkh1RrH)(tss&Am~jicN3p6m1OU5O84se5iUCj`D2J4Js<-kM-{>~I{~2@8S5 zs_-zuC1CU(kLcd`mv-xkd}bxKF9o(2|JWUL4kalDBPkwP>Fpd7;?X8uK=?Da8FEOX zLD#4U!y*hhXRlr}yrHtIhwBe9IUTL;>W;cYxB{BW5-4|+YT4OP`Fqz9xuKS~`lVS< zj0Vlh)Pkx+#nKmHD$eTLT@+o8z1Urh{1&$s!ML?Xn(nY59Ca5tFR!l0Qlt8fl}MjS zd3kly9renaTBAc{+w(siB5TBQ;#+E=yFBX-Yx1bJhRdWpr8m*6!AH6T4}ZaQ%A3)lSqNbcjn=4K;yb zmFWI;{Tg*O_C#<2yH3l?SbI(jYx$X!n)Nd<$x+`0&+*P}|2b>G<<`=$0Mq|tIs{-8?#!k_%c2^TImikl~ zkuyQ7fvi+Typ6jJ5v#wqb+-))!dkz9#ZiIIOg;f6qJ?^Thz-fXXB@~kcPlx8 zJbOyos4k#3RLUsrAX0J$#15T}2IBEraC_=5T#3D1!kH5bqRE*Pf1zhiQCtxbF>tOf zjAw*M(*2&LhM~+|Y*ActKYg3P;e1)T79G)fXqC4$dA9m!I14lqcX}6?5u|0YMt`jq z1EMYr(NTV5v5Q>7rBVOTs|Y&Mx-+I1>(K~02Nfs`pJ-JS^T|e-5PyA2%l9Q%24kPm z?h2i-vkc(wgh!0o`Yl*w+2bX|maEYioHTLlwV#l>SRFPOoH)wE3lkn)Szf8480jF7e$B@+-l&e zX}e^r78c^O1s&Bnf)5MV@Ko`6N&l*DjRLRm1ocx=rnDzOzlZ2BarDIi6{{A!k*&Ls))o;9F4m-_#&&s)=zkgvIrS zbKAg;UU?6%vb*=qx8MHX|0R*IOoX=&+_YPH|J^G8-)uuO{@69cj{~S!FTHM=?2EBq|oIJ^Wu%Qg-##n09ohnL}J`NrX`hn5GQN;8yGREmfFdro&Xw!@a3_g0%~ zZI}?25$e-hI(z88<>|1j9BO>Y@K3NX6{SF5*r%dX#9;LC{O&5585-Y7PRTT=T>MOz zJ;Z!8t#-*f)cTo0$!X*f0O!jZo&H>(RhJ_=mJf9d?44qKkdmuIm89f2A3{n#>?=8r zWss8N%M_&K!@iOa`$|6SEBUam?`@OujIqNk`MbzKI|*`u&?C9zLF37 zN`LM6#!@iOa`$|46m7Hp4h>O8`F3I@Psx|oR3~mh&G$Y{?(LB?@2z~gfY1=bG zkg0kGyBT2XgEf?kwqa0Y=$gbZ`p!2{2kL60?x-r9jUs9@w_uPq%7x~t`w4QN%*AYOHncq3-ibFp@xj|@x=^2M~{YF>MpfQa#F-qAjvX{#7C)d zNnlN**Cfia8Hf@yyeuygC(0`j$N$bf#6e8a6eqIJu_j{563De2>j$i`m|W}~3AKD$ zp_IjE2x2`#_^dM)C;>Z3{SLOm^}7eR3QRe{n7_QGwdGd;GxzE5@rdOu{T5k!?Js@* zkR~|LCYBjtndt}CpOI;_pMWXXpjo%)>2Ip0?dH?BE+M8aXH@(}G*joPDn7>&*gT!3 z(rktvgX00Xo^E+y*(kurD=FB@QsL(6r`0GKn*{aaa5mS$-IMu-^ST3RIV<@g*UBQN+&FLn-mMw zkE`)sEe7^65GDsS8!GRvnvhnOXps`}m$js_!6TM(*JE*T5bKqLZa*!EL>IIn10+UA z>rg1m9*4<1oM+oa3dH!Jc#wW1wnLS{!l645zB2QM1Y`y@5=D_Y0%VYu8VA)Vsjw@zWjRm+&eWBhtF}{+==9ow^|=iPqQawXIGBmg zQRwffZL)>_NN=O~7x8n4|B+g^KOT1bm^L8mSXsiMkSj&l&4|L$YCbAFLo7`O3;oC% zeJcW?Jm;0@kpg|62M3`vQxE`SoPGiYV;I3qzR{C%JAXTW_d{BV)(lSC4&6l;M}{jPZ|T-s(kF2wkJiI59@2UkC-1xwj>n~3 zZ!#h)vqqNV$cxLt5?;cg0k#I^oQtDG;F?z8z3#VlZ)&facVER@OkNGNfRlcT6(XfZ z>nkNv9jGUbX}D0?t$4LfZq2Lg@zr1n2N@8gQBRxbK4I!zEE_CW9#6M(P*QXf<)ub> zktHm@h{|3>`7Pp3WT~ZJH1GoZ-t{BVy|N=I|Bzb|sh8Igs)z#Y$8GCxF+~1KJd%wr zb$)Xx=}EL7>G*BEZPltxu-T0l^fB!V*9pYPnYHkd7`b~DEARwaprm}UpPUmc7SsOw zlG@I7;t(pIzeR6PR%bWWWvTigjvtc53OmDA1=;GRSplCMtLv(Q8V;SvdWkIKjMt9`*cbkvf*o2uPxc_g#S4e}p!e{n*7GR9*k) zY^ye+A%NQqGe=n%&~#4V-*@|>WkCIkn1ZXXABm~+TC_v$XYO!R#JSsgOI1w|Hz_cs zHmgNdMxZn5YeunE4KAYNj>1`q#HLyq2@4>`M#HC&F{jRGC_ij+TkLOgW2}w6TV-U_ zDzLixJ>>->>iY^&@tJC!JZhZ}@f*oT{0^};_!SCe^@S!eUSfW$a{{gF7_WQ76#RFt z*-lZhhCgxc&YXb-y_QYKzi>QLKVoMqnF9StSI2)CT{urx29A?{8yqtf3*%#N@&oIX z9pu*l$_@>rAL*v~&ewh6Go399nkzbRRssgSf-u3@h7BM4;lzb9zcaZ0PZsAhh&qjPr5Sqx4Gza42Y_AIZV) z_zggpB=Yv~4+~~*4;;hLx$xh zX@ejFpGP(be@~muZs{F_xxdjNIb3JsZwCu{2hL;PSTBz#GrU%8d0HE8dE&REihXzd zMHEP7sh;D19D^mnWYhigECodVCMfKkC(j6;2rf?@J2|?@mp(_Yj5d2u!wEflYgJFd z7wLVkij(-8BkAl2MkI$eV3QNA9}x{BpBKIjrfIGI>aK3T=lFYqStgh?=qI{zwx8l% zIstrvAmh(59gHrYB^*xqPz(&W z=4`?T(ZL>m`-51R#wJ%4B%-Ydk_}Oyv(GlF{ILG&D971ITMJB}_cO*9c*PiZ&1$S@ zwFYU6En`HAL?sL&yVek@cF3<^cZ|}Aj_^YXXXb?8!Cypv2TRp{2TKb44wizsm{wqxN`8la z974g$@6ZXv3H%Ov493k-?RRjJ>HLmLq5@ZZ1!kGR@6b;!&JrrWLnnYQ+LWUoSJQz! znpcwFp%cMs-0$f3s(WBx;{fg4tc9e=&c)ulP0(Y!ni`C~s?jTQPI%_iIVX%Rp*};sQ#sV z!{nTdxFfLwvB45o0gsS#f*i0pZBuJlIVVlYGn|vjqMeL+ZKE-TnvIRVE#_KdiNN`G zi?z{{IBpdRI&1fOCPuoJ-AEU%!I6>Hx{y5MiF5_;H+OP4t&wJY*d~XVy=&^3xXHK2 zHMqKmGmgXBk)jkbKZFTR@-lACMS}wytSgKJOr0Rsvup5M{lONFwB1K+!Ctx<{6*wu zuvG14@Faa3I8W23yu{`J8W=Uv5XN2QXy^oN9v~g2$LLx|a)+Wl14I%z8u54jjwRfW zL5tkcDX>>s(N>V`4LXH?cqr1QvGf;H>6gve5=CS0bU%SXeIU~khG6~{FAd-c? zx*Y8eH~(TK5HYrg<4_Cj3&$OFv=h9HA9V(zK^wwx0|6G?u|2#&`@*r3Nc+OEA&B;c z)2&oE{6O$QIs?(5ec^-n8QM7992!zv>9sIaBR_-hg;)nAMNL8b?K#okW+D1{7NWn) zK!h~~T{xOJ6 zO=JrwEGmbW&=$~%P?j4T^kQE?!zf1`T~oU{B1*F$RCI`hKF#&BWDH2i=8TJF>U;s?u{ zsGN&e&{kKSj`EZV^Kf&dNW5UxnkGyz9Zy#KDkj$WyLbPMwy~hU(#;I&&O@9X`L%yh z4$E^4S5idG;d@@PvUZ9y*G0e58Bpbp|2TZaSJ4nm9dxdb#8DaGo{QE%(=@r!vmsG% zHb)s>bqt4{%~8fz9nqn)Im-B|LpgnTQpQ&u%4y(98DDiMXAn<;@s$ne!S29t+}=_W z1jlKi{03Dy6ICS>RW+H)ED~QpPh!j@qYIl8_&3OyI+C)%oa^=@%~s|dpYXtG%*4!$ z%Aji(6N)sb`je^1r0cSw(7s9638X662B075^M)|#`jPs@_`X8*nA*_y_>w=qD0*z@ zw}*D_nr09rO0&o;6d)}!e-T+^mZ~i>Ptx8SPt!N8mU;LiA*>;y4Pltbm&6h#^1U}! zsQ#FXX|W$;7CZ3X7%H^b^d%RT4hy26)~W~z*06K}#gbUa3$doiebY1)OOjbAi>+T% z7O>d*G0cK2woZ&^q3#^juPFr87ZQg#&}j-yf*d%bK=?*~5UR~+xY76LDorx_SgMj) zDWk7(R4YOxa6m?1zbA&c(bwtVDKh#z5k`LqMt?{f{a3ls$49wBqYv8`7<~r!jlNFU z*<@~~ICEt5H9ZLfqpu&=qiSJo$>{4Ol>r(3!Rd{@rYA9B^brj6J?;_TD2Lv z?{Sa#9`}fE^hbP;d&D>TxRjAR?h)VUkN6(Qj&s0X9kw>^{1XNl1o2 z6Cv6DOoU|qvk)?6B2|IO)&h`TDwB;poHzoXlAR$j4JV1k8gw+CB+`-L)*PUwi-x^t>^#sz7YT z$b7GIaPfPL7rFgPW1CJTMw4X5kmIL2Q@;}}cT;}}m;;~45ooYf}tsfmVA zjEXqu1S%JeNRPoc;?geXppD9)^2aO=Pl-4jI~L6{f-#Gs*q9Za5hP|P9sosTq;$m} zwrIHh|3;JlYnpqx&ejO} zFD7H?zoau!efh02LPyAGm+?+U#rj9n>BuP6BODA}Ct*F(5fGh-%v>khXM;_{t;Oyl zwDuwz{&5v%IOHx4hg^oGAvY>;7w8{`fBl{cq!Cs>Q$u5f)sH))=wO7^Nh$*xVHaZ= zN_Ijx9#KKa*(@mZGkCjV*Eiizsis_8(Xd;_6I!o=A2gJ@t7Wkp9ot8Z!9D+c72V;2 zL3@wZ5>x54u(~(3O;G!3d^Lw1-f7MT~Fj9G?$ZEYc<}IUh9;&@IwMNuHCN;-m zz7azkWV}O3ox58~Nh5{M3dug`<@^M(~65ubQfs>``fs-W#y98JY+aspv9P~c8 z95J_V?eTK;SMT7Bh!5Ps!fMv&NShi?bOLxy%!1a+HBAYi+skw@y7TaALyG?`{i6-~ zpg6^B>fy0*c((M>2Kp!rBk)78xNH>;U7vG+e_%b>%8q07dVBCt7-2b7%V^Fj&~YI#r5&QN)S=S-$iHF#Y)g|Ya_obi2kxdL%)oozbqZv zrJvR!n5d3B=!DhS`V$eaM?GO;q+f!X?p@K3F2KP$QIsQ9EpFAuXG0Ln?F(rs8NMGa z(p3HlLwW@8bAijHvjr(*0Sw_Q&B#kdS;-w{bkq^_BM~ZhSSL`Cv1&*8IL2v~uL2ni z2P+(v0|w~^UiuC!;=G&90fvVtZ}6BPgRC~|sv2Wl-z=uQ4CM}zs~FrYrUJXlaU@q! z1$LD?NUkFMM{*V6Bht-ca7*ZBF+_X0s|W+bit;17sFdJ4w)eNx+epJ{s?X_FjCVSE z6QIJq(*amTQtLBKrMACq6^3Sm2WyrpK*70I(d3LwP;35?j$P>ta8DEs$NG`F6Q=F@ z5sKw?_U{j$(Y;uY0kJA- z`U(xE9H}PUW?+$NC6*~J?3gxFbNrj3#ccmBcZ<3Az@M1kc=Wmjzfq5&3lZkRn zCroc=n(+6SN$<5{TbvwlrkAkwcN z!z?g=#~eC(LD^uRsrQ#)^2yb~rsQa$U*kdM@9xqGR41Z9lt2M^{hkU81Mo~%WJG}p zOsa5RwJ#*6WCSK?S5?gqOz@1Vyz)WHssVCRU_xDS?1u$35Oll}iBJV5*!#G`q5QfZ zn9yV{1gV+jk1!5EK!FKb(+>g@8agWuV9P}#C&(bHjRF&DuN*5Db-88~YkH%4+r)?K z*j_mYhFxLM?Hn^@$BR2KQ$CKl1~Sp$g*sVt)5vky-QqV(ej!zZq)q2Uv^ zP|@%?h#w4}dZRKcN`+K#E(zf$?1=WiSln$Xc_Pb110u&zSjCDlK@F^EDTR*>Y5 zX%uNIGgj0q#3l=S&Qd$ov_V${wJQQG`jHGH0xkLxMSGnCgq|=90AfGTqRIUP6==~( zqzADv;!kcoJ7@dYw1HL7!g#hYo<(Nr`#PT8v;D$&mU%p*2%6ol%khlDXjY6lo>4Gu z#vlr*SwS-%&-&{gUG$P6=gk_=#t+PWJUhKn9-MahbdY8~xVEu`Qy60Tl)s4PXDn6E z&v=sFsLj*#(V23KrII76ABRx1a;9|x@q&?=9)qQ)K|OopB<3+Y{w`(H+qZ1A3pTwm zR5;qvMs1dk8HavaOWrOy@Hzp^b6H%x4<~4v2J#qLC=Xb_PRjxx5DAN+DzPpa>I{h( z9xkn~szt*A-^0ac;3x<*;Cr|OzK4r@S1AZIK(1{ce$;7@0rF`Zc!Ez$xu~Of1L6KM z^dDA~H%{&GIJ|ew0cl>;#73^6JO+c!bNVAHlsh1rwp4p^HpIKzDoR z@)VUd$gWQz+f2>w=C9e;_AO{O)9kaqADT^D&Xct}b>d5BZ=|m8m7>H3+1}a64#`G# zXbRb8_MC}Bavu{GdXAVM-nGzkbimNV*H^QIO!mu0c6c_jb_&^M_MBe+J?F`V;48o5 z?2YeF&k=_}Wt28U;1v@knl`EZ%4)tufmcka;?pK$2--hI^$oJ$Wg|N>8`)85WKkfK z0;w#nO0!4ARd*fgi_QB^n|)^fR%bqmoJh+|j_+4wBfBAmY%}f3;=d zZX4$BQno=%{mE+f)hQ}#X!gx1WSgnkox^jt+2<`p?D-t?+wX&BCtGYW zU?N`1Xd?cQQmSDhK1(6nOcT+|-$Xn72(Ph}%}Ivd%`*~nhWM)qzdvJ95! zU09-*Q!SBwg#!2UN~4=mfDbbX;QcX$Y%{Ie0o*7uRM^pNM z(eWP3M)q7bvgfmry`GKijcjD^XCljB)!v6ydp%F9mQjF@GYQ~*kwUhaR;_*1f>qN; zd}F8oa#>G$eZi{bW!1VVeZa74k7OfzCL7ta*~nhaM)q1ZviCBPWw2`R!K%HQr&Y@+ zz(<(`@IFr=+f1uAwP4lec$NIfofc-G(}k#J;Hy2J(gzHy_Cz+a7qXGPn2qesY-Dd` zBl{o|Sq7{20j%1ad0MrM0(_E50Po8bvdy$=ouhO2)fUdLh#Bb3-yf^yChojXJ+K@< z`E^Um60>2JCbN;B1fTNS{_$mj~$tx-b{B9D0mC4DZi!IEi_A5Pz4lYwpE(&tWKW zc@Rs-%|H5SEh4n)@*tf6=D92`-UpWl^@Sjk$9nUR&X9<400lSo`ZxdJ%1Ju6j}Nra zx&4MeNukfB-~dX)zxk)(-~7|?Z~kfcH~%#Jn|~Vq%|8u(^A9V^yAy*z{9E=E`s7si zWul@WwLLEi`dFzjy6W;#rF1eyKa#en8-E_f==u;zVD*N=W&k4N0~qaVSy*F}%k&rls$JN*P=|E?dIpziw7Nu&y~elWGrqxo*Z z!~P=X;j`-7LVGm2GWBTmVd~Mif}@Hbb@W5^_Bx*6wd0y_|45nY*klmYU0!C7HkAF2 zL_Ic$?#)6(i_!5OVdO+n3>y*aLusA)5p?DUlRGng3NyH1JsJ%RE@;+aI-8wTSdNl3+Um@aFbCE#%FZ^LyfG#^&8ys&=!rjwi$X$)8IJKW~yXw zK_#(}PWNFZ44=8Uk&n+$m850=xV9N8Ng2P)XWY87JCIm7H2o$vGalFPWbzNsGI2 zZ8KDow&BHzHd7@#C**D=KUkRF@BqdGTYyRi=VI9OMNe@MlqezafJg-eED(R7fCXJ0 zN|E>|G)6%=7NaB2TiqVxU(CSr^=JtzuB92W^1o=wv!Zh?@vJyo;A5r{yYUkj6n<{q zf)D?+6rN5m#Ix<5_K{!gm)GevX}v<9}GZAN(C!c-l}J*V0)jJnidKiJ{nRAA8w!hC+RQNa`D}qa~8t>Kq zzP@R*P#*{6SsWhirwg;755Q|0id4n7MArHHX|@o$k}$vRgTZHi7?=1MHoofVeAH5` zd10fOUP3h+Szk6X?3~L`D63CYG7m_SqNq)S1L`xNDVfRUP+zjvlGENkw$%@N`S?~p zYSM{QBbxv%Vol=j8GRtqDL)}~t6x~Boq=E@&_b8)J=f>GzR;zobKx`Y2u7DST!3)v_hEOnEkZPDfoM4kRz4ult7o=aiAR0p?IBWnH%z;|5RJRsBEqD9< zg8}+A3gYE1!F%O6)ThltIS#fg`Xu{q*+qwI*RzLyGkfT_3DCPL<@&UW*GCffk;Hvc@%W2K@mQ)>JeCwF9!o*n`lnnf zEtX0OpdW`&uu?poK%7AF=rL%sKCO71BvL$<3dPe;%iTU-@pJ+T;^i*E`#|xkA&8tf zXbnw_2o{x}vEgqkIbWJOvs=2l)v5B~cb8D)Wl%g9GZ;)}4lcLoO`vx5(Pp<=?w__5 z8Z`4b*@M!pdeoE61)%1ho(WG1ch}TaV^SCFZmIMRanFrD|PZNr5h~l(0wpN*bu| z*a;P-v-CIwZC0~ch9X^{$DjtF)19Un3?9^9Zm3R|Hp^fQO`Q(Ih8nZWTmzh_q8YiaXr82x2=X*- zJVllyjwTAaU6jDPoj+en>vr%Y9LVc81J5rdaIoKB27v=ji=xmRm#kP51P)j_>jkc* z1FzN{m;whZiv%g_{QdN^ewGpK*y$%HgLdrn`-cYmJ#}cX-#;|i?;jfM_YV#B`-cYm z{X>KO{-MEsb;Kx`^|Q>qyJ)n6>QGuR=|_drOoCJ0pNR^W)MdyEmp<94SY4umX~wVF zA&pTp{>Msn?_r!QO3X|)g_`l}4Avt9%=q==T0G)#pMIp~oH)Hdd`9zQ#;@Ok7%GDq zzf4dwew~!4!CP!!MEpuK{vGzk%fI8k7?(0?Q);jDL%gi{ z?R)rsfjLs$lcLd^H6To$k^6wKPv3$Pva_IHZ?Q_KHrPoGwG9IPWhQ!9C2NcuW)tkJ z;bh?oH#-sTKeH3zipvBdiYhXu{0-DP!R{5c&&<6Oyj%N@JHag~uBc_EmPwwW#BJ1O zSYpf)S&4dGljbe88m|B0FV%dcK6X;2IY*O{xL{JXwIh^ldU1ty@R=hf5M4Kwzqa)j zv@HyX=`d8LaewC8cH$PQZFCCX|ELz%wy)+w+q!4vZrc_<{wA(Ad-|_p8?^W}_$m&A zDE?}UQ7j#C82z-?9rS}|IsqTHrr?==bn#vV&uI6BPQ=%)jVx3kRliQl0!xoPi*R~q zB*PEDwl~@Awq8HpouQMs`*PhRj*dJRwD`jh=Z@HnOv`k)4~3?4oRBm!yzwX3y;9-!pH~3)*YN zewejs`(dKBHN6Lf_MSv*Ydp2%!iQ%GY>vuO$Igp(tOR>sq6EJ8W$mtb;g%b+i>#@to&0tUw}r~vSJu!knBjPrEpVZCU;^i5-n_&e@OnL@dd=Kj=IT$lnSRhjt0KDi;c?3Kn2uQ<=FKqcv%u#?R>blAuU%UJw< z+j#HX=c@Ofqco;E+Wc;KZ)f4Xy=C&AOTFJekL$f4-gBw<2j+3T7sPum_5R>IuJ?j? z&!yfUn#c8C5bq~u8JkYDj7<+0Q|~8b;r*m7llNTey*rQVy&&FmsrN_balIGBdoK0< z=sd3Xf_TrR-XELC^{_rd9#>$ zKPF3@0IM?7t{oJ_d#16;W+MyY{n#w^e(aW6@44vvTgB*mE;>^X@449bf_TqmTrG(A zT=f0zd93dR@t%vm7sPum`d$$4x#;^l^H|>t;yo9AFNpVC^t~Y7bJ6#Ai_!O7{P%)* z&&3xji1%Fl_kwuO#m*GOdoFgSAl`GaGw&5+XEOCwTa2S1-ZSa@7Rq}jecwWP&qd$g zpU3)M5bwF@dqKSCqVEOqerT4Mo~^IGUW~pUHII2eY##G|^gQN07yDk2zGv#IwzY$T zc+b>Vw@}_Q_0=tu_e_0t3*|jiU)@4^&lKa>LV3?LZ`wk6&*Vqi_Hh(sBQyDtwtXBi z-XAP~7w7phjZGFm5(j^eG>`bbVY-&zjX0T1{`?UqlO>%$;$%`bi-DSN$~J$*$)s%a zN1QxH!!1bJ@)#huAaU{-Gc$?v-5f2?G)=M?YUe|9%=~V6&otH8LV3?*v$jy)GwF=Q z-fq!4vxV}W%M`DmzM99N7T1~Y#y8L8{aN~IlF9$XG@IXzICC}CC`g<Ks zVxYDlaWak3^GBRa$~J$*$-^pdLCTiNF`0#-{=67NovH84A8|7Eo%th9CS{w2DcF*g zZT^Uphp(Ju*$Qf%xiZuRiIb`C%)%6W@%=K?1&K3PhPoheGAY|EEL%b1Wbz8;k2rH> zs0(VHxiZuRiIb`C%)(HA`Ta7~1&K3PhPoheGAY|EEL%b1%$1=oNSwJc)CGw%SBAPE zaWeItSs3cCzF&sAAaUl(P!}XlCS{w2p)N?AxiZuRi8EJ*x*&1p%1{?1PNu#y3q$?& z_sdWhB+gtJ>Vm|{q-?V=)CGw%SBAPEapuZU7bMPH8R~+>$<%jdVW_|Pei`b5#F;BY zU644Llx-GOR<|hL zPtI~Z#>tjzl4Hkszngl`wB6ap`-8>kOs2753*|l2A%HEE_e_J<7Rq}T8#uOw@}6mQ z-9mZKrLR6vjGf6v-wWbB7o91H_e|H9+Vs63-gBw-@ubTPbV>Z>+=FNpVC^!=H6 zT<`Ol_ZNz(_gr-5jd{%b>+_iR-xtGsE;h0t-gD9Sr{;0J7sPum_5N`&^_~mwpA^G; zE`7Bi-ZRy^ZQiuk8e?PE7Bttk@xJ#K%)8A8-e(^3{$eqGHIu&E>V0Y+^ZrsXyys#g z3*tQ&oq2g4*Ly*{=Th&l%;S15i1%FT{ndF~?*;Lm%NDZNimCTpmbwe#Jr{ky$E^2F z#GIvo{P>Dw6v8=z0YUf3tE=TMP~|Hmdl0rf|liS z;k}@xtz7zQLA>Wu?*%PwJ|Z5bwFvdqK-Xxzu|>yysHy1uYNdQtt)vo=d$K zv^xojCJi1%FT{lj@&?*;LmOTF(~%(l8* z^t~Y7a~W5ES4_R2YFrTSxzu|>+b(jc_kwuO z#r=4`n5l6tI#bY=kz9B$Xv;`0yce{Do(t~Wu?*%PG=Th$l@t#Y)7qkqW zOT8DwdoK0b)S|a~Yey z|Dn$lE6y`3+_L(nhg;oHskv4ElHw}eTa1K~Tct~i^&`DkmlW#+ymtx;eP-hQL<{c) zg+4R!Zmai#LZ7+tUQp;W7v2jBedfY@L7~rFcz?2(oi(}eUQp;W7v2jxwUrC+1)Y4# zh4*LYvA#byk9jX>i6s}Ed2=4u`&;vv_qXRU@9)fG-rt?ayce`gk&B%vXqh4x-V0i$ z$c6WUmML=Ky`W`^TzH?)%M|YwVNqNM@_ABPXs$BH_`ycwurHKm)eP-hQ zq%AY_nThu;H1wGZ?*)ZEbK$+9&}S~Z7Zm!;h4+F&pSkc}Q0Oxk-U|wS=E8eHq0d}+ zFDUex3-1MmK6Bx{pwMS7ycZPu%!T)YLZ7+tUQp;W7v2jBedfY@L7~rFcrPgQnG5d) zg+6oPy`a!%F1!~M`pkv*f?Y{Pc0q2Y5_Gn0jD68) z5uFRVl3N+OQsxN$QxFzRwccqEAULtyS#0?VBe%e~bjS|tZBW{w2t{ri+ zMD*;4TO^|Wj8%?FiRjo7w@O6Mj<`)C+Rs|Kx?LhVcElYL(X}J)l!%@kahF82pR>ww zw?uU8h(Aa~*N%A4Ks;~d>V1irc)^PJKq7i}L{B2xFIvm^Tq3%5#61$xo{E?8rL-l_ zMUP}lItJnn*pjaz60$x9qH7@T2Er)g`6vS_qh}xz$}kY^m!uq2hG7#Ql#+K1M1oCx zNFv%V%Q6xW4@*SXj_686`xR>$k4Qwh=ei>MAtwhl<|}-qh}xz z$}kY^cjIyx7VbquOWu=+1ba0l5tDYr3lcH@zO{^dC1TQ!xKAR+Kd_c@zeG&h5f4bj zc+XnKa}qIWM?5bPQdZ%IV^3oBQTNkqqvcw8d7cErcBJ$iP;Clb;5 z(kjPi64A9IK9z``9q~trXn$qpYD(5s$BuYOBD!|O%M#JEBVLt=_SaT9K9PtiJK_sj zSL5GU%lJ|vChUl>Bx2Hz_*x>S?1*n9V*FdH9N$XBgdH(n4P^K}R@Wk)d2 zg%IO=TjgM$3n3=#2Y_z_kFi)526>Dm!5$TB95w3hLrMD*+k7SB~y^eAf?EILbw_R&@Zi?tGB z%8p>MJwkMjv6gY0lzjYHE8_PO(X}Jk${TStah$abw#G$>o*nUw0_-WppK?XGgI3I%#6}Oluh|l1+%tSylv#WD}x&wiUtR(uC;Q z5iH8A#?1-Z!qJ5!N zj$wx^~1#64A3GPL_!F#a1~^k%*2R zajHag?TFJPqGv};NJRS*s~o3GM8}ReLn69%#F-M&vm?%ui1wvcInI`djvaB1M0D+l zb0wl@N8Bb6?T%HB+a;o7N8BM1T|44ViRjr8=Sf8SGOHZtOGL+xxIiMhcEp7e(X%5i zl8E-@Ryi(~h>jg`i9~emh)X4+XGe4-qJ4!`j>{yXV@F&r5nVgt3W@015m!n?`%0@E zS4l+2j<{MPx^~1h64A3Gu9b-PRaQB!lZcKTalJ%z?T8yBqGw0kC=ujics6=$_h{q(NXGc6P z5$zkSay%gs9XsMliRju9zn6%f9r2Vzv~RS^@w7yA?1*P1qH9MyD-k_A;yH|w#xC6M0D(kmnEWWN4z2tJv-u6iD=(qmE$#u=-3gj zOGMX>ctaw3cEpn%?1;A|qH9OIBN072;$4Yo-)fcPJ&EYp5${Vx*N*r= zB6@a2Pa@j4S>^bHM0D(k4<({&M|>m^Jv-uKiD=($mE#kM=-3gTN<`O=_)H>tcEleg zqJ4)|j?X2cV@G@;5nVgtONr>&5no9}`%bGIUrR*Cj`&6*x^~3364A3G#^s7h`!1^- zdr3scj@Vlwx^~1q64A3G_LYeC-BvmFlZcKTvA;xg?TFt=M9+>mKqA`rSmiiSB06@& zK@!omBMz2`o*i+BM6~a<%5kVfbnJ-3B%*6a94-+(JEAQS?fa~993c@MJK{)*=-LrS zNkq?%I9ejw_gm#SMj|?P#IX|5wIhy`h@KsByhOAgu*z|QM0D(k6D6W+N1P-PJv-uL ziD*A)mE#nN=-3hGNkrF$h^`%Ru|)Ljh)X1*{jgPz zOC_RXM|32jYe!rr5j{KNa*1ent#Vu;5gj|?N{Q&&5m!k>&yKiSBHE8w<+w&7I(Edh z64A9Iu9JwK9dW%xv>&y~af3v3?1&pBqH9OoBoRG3f}I3YdsrT`%E3-)sr@B(1Uo^c z_ORFy>~s?$dUgamN2KI<+$sk<?ILhJ7RB%=-CnbNJRU|=sD$#$-WVVlEaSJPa?W@#QqY|vm<^d5$)ec&na>o5K$;O z?1%#;qH9MSBoRG3;$VqrKNUTv$Z<$Sq2#b54wZ z*bzraMAwcuQX+bG#8DE_ekOWOk>luyLdjuA93v53JK|W0=-Cm+NkseE=s87><0A?s zhaGW(M0D+l6D6W&N1P-P?dPKB6gf_gD3ly_#3>TdwIfcIh@KsBnnbjpkDgQHn20Ep z9CpO%64A9I&X9M_eosT|43uiRjr8mr6wYrRX_Dj!s0O zj`&C-+AN2ZGCr1wjveudM0D+lPbH#fM|>s`Z6;TW9DkIE zjvev2M0D+lFC?O8M|>#}ZC2YUa(pEb9XsM{iRju9-$+Eyj`&t0+Dr#hVJv-ue647S;B}I+{C8A?T94rxC zJK|7@=-Cm6OGKOX;uJaB649|Ej*y719dV>Y^z4YEB%;l1ONtyvOGL+xI7TA6cEqs~ z(X%6tlZZC6cqwumFA*I(;slB4+7Ty8M9+>mNg~?J4yVX*vP5+3h*Kn@Ye$?a5j{KN zG>K@l(IG{S35n>~5vNN;*N!+tB6@bjnG(@vV^)eBXGuiIjyPK)x^~1l64A3G&XtHZ z8%a~-I8P!vcEtG-(X}HkkcgfgaiK)C+4!C!$3+s+u_G>)h^`%RiA415h)X4+&Ag5j zIXV*2u_G>%h^`%RxkU8rh$|$b&3vI0Ij)q5jvaB8M0D+lt0kgmM_eNjZRVk+$Z@Si zbnJ-hB%*6aTrUwlJK_e3XfwYtMUERKqGLzgBoSRZ;%15H*%7x$M4NfDDRN9oM8}S} zRU*1}#BCDMvm}6`c;(-EwcmP;-#RCo?@G=o@uXAZNvFk=CgMq_$CJ*8C!HBj zIxC)Zc0B1EGid^oeXT(ax9ps25|o_tbds;CZn?QjpsTg$8-(=jL44J#RUvJx(BBp0 zcF+iEY)xr+X3)X20UbIU&|$Ly9X=aSdp4jWW&=8MHlU+t13G3lpkrqPI&L&|5(=+iRk@{!*_x=rgV zrB=1FYjsz*TEl;1D#rBejZB+M?ubL&d?3FhuQ{=%8`Sri1s*IA?_*bv` zZ><{HrIO35cMZgZE6^eha7XYZRd>X>Zlu-c_8Ey+kLX6()arNZt%j1k&+Y#ur08o6 zxC5vFCH$^#qcup`4WJIzG&fX++(EY)mf)a->qn3@;M_1GQm-0eWW>nzE8OyLT0?Ht z9ij?v4FffdYIklNafjUoiPi|X+SF<^-M;XlPt~3j0d=jVBp#GD>I9Sq!>v@2C)EW) zX&-+bXdh3CYLd#hb_B{umA*s`2K&{@ebau%7FyDvn)5}2{H-cvU`dRi<~E>Zr>`TW zLle~8N=S%T&Q)lPl`bhl*?GHKm)SU1Q-5IjI@gSBL?$AQJyC|&atI|{GvZbM)vNv6 zub}P`kltKA!prkhyz(A!Cz{R~>zX8C1V9@?<46x1E{7qVQBfvWkF4o~ic|mAEe)lB z__9`@UB2k(4-nl_GpvkwiPs{hO^z}iys}^ujCO&@$|j&|)ZG3+Me#ROl)O~}2bQNX z+B~CNt|&EdqCTv@W=y}TsFLcfDhIdbTrfgCx#m{k4kJJ6$iXYhx#Uc&3*LvX8bF;i z(uC48VpNoV!h2|pei{Pxnd??kW{y(T^D5=~^r~8F^${0+)C>ENv3{zFr-s`HH6}H! zxD_xDgGPiwW%R+|AzfLH-%_uZnMO~@6beYgg=!347D`6Vd*%O%eo{qKd9^iU%=qhT zp;{2N{tv7ES?Q^KXAp-f9av|P6?z+#*YhQf1o+>B#!UM(HB}M@3i?sTxJr!)UlG-h zwyf|ss6|ajef#WnE2*#eMKyN~+|PvZO1Ph)Gl~M7U(cYN@=!4&F0tof1YhN z8r?LlKN9OFLWX(! zql#N=&ZKd+<4p5fPo7>pFqqUh51OgdG|odNZOwVuOe#6uc+w*}DQujX$mz~Z&O52W zcy-ihT)fLnokq^PP1>4skC{|*?u{qir;|cC&#eSjDQ)-*m2kDUEtgZPiBcM8k}~E= z73Wqnsp{NjBtd&`i6`A2Pr6zv^c``EYb3?}@bJbis%)(7>6PpF^Ww_Jrt)6AiO=ia zOM_nBDJjp6@$4K@c76bc#-6A+hn53*f{L1%;;-cu#alXA@gFB~IGIw2C(P7o6yiyf zw&wiaOe#4~#gm@aNufgQU(KozJ9{lIryj82DhSFbMd6-Y2=ck8E)WJ>r~X+pottul07Uw zXou>I4DDa=cHoMXtZ%m%0eF8DoHSE?eQPAeac(tfYtC(EQpveJo^*#!3ia)LZGfz! zpzH0#<@x`fJ-NtecxzMxsEq`Co<9colK`3?AlFU7MSUnwYF4s<}H zz!G#oKMf%deBxF=QkIcQ=u`jXNmZlyAu~AL@0m$5cJ#jay5@XfCPi6N?C8xAr>DHyIg1_L zwp~i>=(Qk#Qb~**y-s}daL60h*wLFDLZO^DQe#J_4f7xn(Vhm?@MA|eCB=^3$`m_# zJ%}CkEU}}v1JP4rN3v#QJ+LQY`%UDu$@v49oI+iv4##3grwtpiBdBOv?C5+wxmg~? zjxbyTCzD69Kj4-2MQj?SsUnFHDGl@Z=_gmKae5!8c_BA^?(q$b$9Ph3YA3-z^sy>`g zsHJ7nr}3oE;z@tR^ve6{+i$R(c z2G2+^0??_te2p;mse=ljFrH$2n39}CAGvU!(oAtmo*x_oQPVDz_)Mr z3xC=%{#xBTe?>6ui1Gtd>G{!1nV(VE%_`!{5~)6LKROe}o5E7LekRip>DX$S{c=2h zxjdu=_pDdaBu5G|sbTt}V2 zbp_+>iRu+!KhaW9z1~fOj833dkgr4C^49v+Y)0<%&Rp~D?zD0yIGLKhDSv{ePBVQ| z&IP9poC}^*f;Rz~Ws(}5C@FNOXA-yAFf%#N>o>|*a-MIdP9x_9CT-2R&`c^h7sZn< z)=9IH^G7q2bDz;9IrlYFr;&3%leXsUZzh$T-^G&-&`GnB^T#uj^AFUAxIU@&{LoCD zM$V5++M4sRnN)Ht?%6!;jcg^#hC`xsMYZxI)f z+w*9MBy;~|%vW$8j3>PqPkJSmgh6bbHz5ZxD&ngcrSo+>>5F*M%cRSUbqsr-lev;f z-^78puM262fp6m!$8IYq#>qO!Z10eH>=mal^4L30ai`4Vz&OQSlH#B^#odzP;5fxS zlH!m!#W6!M@%D}Be}{ z&GDqkc+ze0q)XySop{n?aTyP_*ahvSv=NIdDFVL!ynG{u-BMDaXM6WK8GV9y`&O21|ghVb&J71+{K3zI1O2Yq^f2cX*FSw#!^+dIJ#p`&-d2wEpr z$&u1POHe4+kB9u_hM;n?xA7x2qm47_#_^_ZWW+r_%kmzbCGN3V;x3;h?uuFBUi5cK zM@A)MeIjtBrtWH^78#?TX6xI>k9y^evxZh?53QQegBrmm!?e&VItZB;-NmRsT~}>Y z)YfA%bZ*5rmy7_$Yroar4>qbDe6%rDyd&ed-|De@%l`Xa$p&p|mHpkqu<*b37yQi~ z-`7=th0WSA%i@+{b3b26F+jEcwtEXpiLG)|@JCx7X}750BVa=9NE9!81~vaae=h1A z`x|}Mh~Y%BktL4q0 z1`x?_RfeifP*=fZz%|Q>@+ARy6M5KR;nOFyr9m6Zs%pp#(^ylrPqBzK*xvL{FvyXp zRDMm@Ju26&?e0~7=~t{lr5oax&E(gC5O}ThBB`Qli4{$$Vf`glbaj)pqWuc1?T+fE z0|UE5=TPmw7DH&NNK)ot7b|K!Nk;fH)Kd}##L`0WE=lWQsv;KswimUhI_Xdy=NCv7 zFxmwj47~##%q`Wu$#O6(s@=vkEM`5Aaq=hzKv~);qlxD+P8}8JF-{v5wH^)Jn{^)J ze+_JI`u3-Atd5P`Y#b-&4cnxjU+0y6X?Se^kKMy$eiic6PuL{Go@kedDnW0=Zog9Z zy7=#{5~3)ynF-$Kr~(JxBHS#jHa65sPl7|Dj(7~x?(acrZ@5*|-~7$izh1QlKKz<~ zc=G+fTGhf4JO4yTM2^!TZex>M{k7T>PI(3X%OJLdmpCJJPF71^d_wmIzK#H>^LW-gi&^@9{zOBTA>aMgd5O^4*qF{{8I{sVIn|!Oos`g zU1}ggm7Y0@2?pgK4BxfU=DGFYltQ1o^(k(>C#bu@MJ={(Rq~y*2VP{ zm<|b0b^1F^dn(XI69l!>G###Xn)27tNgB%iELDD#Mho;0Hfh-iK0U8$Qe`YH;T#8) zm+Yu`>-Ljb{Pydrb|3mlk@}l1{if27X=lX93mD3-6=eorq+bnR>4gveGO+4?(aPpi zkKwZSJEm@6<{N5IFx_Z0FVJ(kH1~@J5loJx(mPkc|2L8@L#L{vzbILlJ0iEh!QhZysk6@&VO$4-uz}pk!A^umP zdePPpeO1_kI5Yy?H>c`8+jk#rTzt1>-q zRgKV`9u);u*f~%IEtMOEfKU<{B&9L#Z`H{5$I`}O)TQ?_e&Nb^AK;hVFB}{6ae*Pn zUJTzQ#r^?mP9swk+^WL|{6VnWweGpU^iH5ZguY` zzi#?ENv>aodPGI3WsHk^%Ynad+GvzRvszw%hpY+?S5k&P-(cUZ?2gku{-G~8KEK%= z6(Mj?rgxM$Zs{M%)iB>upL=KZKl=P?2K^Zn9Y%sbMm1Dx;lx}GwGAEeMF}b*q}(G# zAKj93?P%aJqN-4ds*+0H+VIb@o6G-1tc~4L_W7W{Zz`)9nLpZ;o!8e9hvo$DAszKF z>ko>iy?IEW+%Hmg3dHQG-URAS2TV~V*iW_Thh>_URK4*(R)6D-ceEGm&#I{H(FG~b zBqYv_p>}-awLm7&BI8bVcW-bHBD}V``zCLEytc{6ahgiJ-d2gX29if__`^UZH;L zR=ij7O9ldcZy57Q?{)l=Reb}$)cN1SZ$EzD!7m&}?_K<2m#Oz2eh2aUK7OeKk{!UN zQLl$z>~`@!#4k=UdmrJKyqb^k>)`iO{4T=pXZT%=-_P;8)zA|1+3WskP|kh_*B$C- zG{1^}F7gLLB<8H+mdw#YNW@sz3sL3Q) z%^!Rs4i~4?$y5^B=OZfA5N;e-I>s37H%c@x6G@mp12Y6JWj#*f`^&MS>ITfjBo#F< zJ*KlHUd*5Y8Cpbj*dN!cUQ&U>2HIe90+(FI1RF9iRHCepZW7FQJyM&ijjt2Oio!{M zGL4~v80GYm%4r&yA%`lY7O#*A+{YO!(J|0QiIYi~MFxgSloc|S1Y2yt49qw#|BSJ> zm4O+8DS#FEM+^eXZ!;88leI2Umkr8NW0L!J$)wU3I8tR?j%De~neoDzjkto3d6rNwC!>Oic`Q?&Lvt zld5K06IM1$>n4?kP4&Vy;QY&wI3`I2j^nOc%|O@>S|$?VGb!Fg5^RkL8#G~)Nw6^! zHekZW@tO4)lm0om)Xv&Y=-=BLB^g3ZC2_abzzpGf4_OyoeBL|8-3|uKz)YQxfLU)~ zhA^K`9I4v4E;v@=pBreS#K|PgpBWe`Q3}^fg6(9$3``q$6UW%w(ZCG#nMF+|!G2)C zjH0HJFn?iS5CBF!_Qj1?8&@L782w8FZIswa!t88ds6<(h-6Yr#4VZyxCwMde$$*f- zN*ug93Htxn2G}UCmjL-I3nWRb9~qdqQElU9=~%^YFkl9Eog~aI(_Zb%rpNu>8k!yVdppqNxZj(Ce=&gHbu>5b_qM00alf~oX2$*ApV7p)-}`f# z7x#NR(zLkW+lgky{oY^Dq_`i^FwBYjy&qyqjGvu14llvaf7&>_6hD8tad;Vi{%Yg! z*7(_FA$*bSOh^IP}4E-F5uv$Smq5VW-9py zCV67TK4(&y6&n;jnUU_+7~M>204t8uiS%YH^8wfg)IeCq=4JwGUBk>u&rq4 z$4sKcx_#WFiujcJn5YedSVrA3y?K8h%Y1OUs(alePvrO!lPX0U?vBxgEs#O7rrU%C zPgUHfVwpFmlk5$XJW;YoO{y8S#gIGXTs@k^@$RG!pT;uRHWs}nvdu$!%TUZrQzxUn z9NJR*`GqP+OG+r_PP3RqN$)VJusk|EBWXw65say7Woc9a6NjjP=O1dGeGR~J&8WYS zMbG}|mZaVo-NJqwZi^9OJJ(Q!bJu1F-4Bw`-W+Wo;Z`vf)dW~S)C5RU2Nfk1^2VOl zMSYm|uWCYCG9p;ta(pjqTE^+xO`@meHQu;}J&)H87OH?~Iia);hIYmljLX>Bw0S|Z z?vS-BDoBR?Uu7R2_`F``A&+0gq;^28Rp$D~rVl(jAvyNi7m!V28{ z!TO;XM}C5+iw9yvi{Z(eeJ^bBu1TI)7q6LAGpdWN+^u{TQtBd6nc^Vq%*yQi8x<3D zgZE=%7<8me&&G(hnogPCGszPx@EMZ|RWgkYx!)vD%=BK9Dy3Jyl9BGVjC8lh=)#7T z{!nb>r(r*wp!vCk${V!NA7Yssbks&K*ocD6er}q_6h;#@aEZHwX0@qZ=j9j^OQvhn zo=KkArq7#HDQ)_9rer?Otj(#6*?kzJ!#SuyW7ywS9fJ~s6V>y6tDQRrTZrP~W|Vbg z{aZ_e_)VX4-Dv8Z|IKx4`kc4at`bc8>1uIWSn{`S=rYLRSt@-X8tLC&*IMQ-Lwt(% z{a}9x`6tVq8%9+GL4^hkSHmAgml<_tHo#I+t&fbFs6(t9$v5*=2a!9(BU)P{3ZbOK zcpz$i>>lpakOu-%$8gc$zbFqzLKTw~bR+4bA>FSUQHW3Zxk>pyrS1S~v6EC@u-%d; z1=}rIlE2-O7*QLHnkVQ@X$c#B^hQ6rObF3CssNsJxgX=>N!YMgAA17Zq|kczQWv9r zPfZ+!5=d;T?sMK*r($nvXBpyUE*je;!`CwS{!U`!-F3*3N(?p&HAbnO7z@}aD|RH( zP20F*$jAp3ecmWsWsy@;J~#i{lxp|mjdYz*dH0b@8TW1@riyK4q;}>W!1s(jfImyg z6HtB73Y)i~tT;OXETsjK;(5P9^&aIbtf%pold~otLyJ! z(tA&D4t6Rt3U4W`5{o7+06*TDqvR)~5US)D%yt?TdRLQgxTntJyLaT}c+q6+&1Y$c_l{;>5{z9h%P zKQf09i>9LEMibkqBMpSB&_bOb9EvhVPTn0Qtt;=7pC?~_Bwpsn6}Dw9L3L|hNusFj ziSvEbT?RG9G!62Ma_lTRZ=@6GV;<2H#kMcQxzku}fQ)KMIcONJ2^}2F$6jUM8S{^8 zN2&i;N<)W-YlggjZvU8W!A{&k`p=Up&Yfmb)wxS2>E+nwyZW$1nso=~W6zf9C;-%r z#?7_QmQe%RfuIATkvl=>y)GLiW~QUKe3W>bj^c_@u&OGJ#uioQf^84V(*FYvxICO-W^V5?s?hWh7am zI;KG;7a524k-x9{CzyCrlq=SSaYDsE(8MUh15GRq1BvoVc~af?N_kQryi)p(3Z(_= z&_9~v=<>BOx@31KY0yH2>Sk9544qF6hw^wma3nOPK!*81Rh@fB{kln~xNp?2s&tC` zNBz@hi~?g~Sc}blD_KVj7Yp0GOEdokUHSpiY@QU|CrG!4JZQeg2`^IN;Kr1P%-7Kc zDTIF5cnwR{jVC=444XP*xaA&P=&&HVdgK9hP@MWHQH8f@{+p!|g7Hh+RWixZ1r{`> zN9LMrZe*_2P`$lxQp01mCuwbn`7UKJ#s*2}wf=vmVMq0CZ@i|i^VqxWEmLPjVd4;s z@G9!?qy(xr&ZBDCp6B;EW|QhbB@Xjp^oqVsMU~-Cd$XS5e63$OPl%Oc_Ul#yHsWVE zQDh~<8O}%JXE=XjZ4_^!63+8+LKStO=kr5Q$%*a4N2)4}Z;SvFF6RuNAkYF_-f-Qr z@@lo)XR0J_Jew-v$}>{ea%&s<*@g`7HqKY;{BH=!RG3p3<5ms-VOaGKGUAs`&@!-h ztMDE?6&c_JZY6wbpsagHxgkTvyS?OfPFCOkfTJ*^il7N04jIv08-j;8@Q5`Ul( z4C8@L5jHcFj1wlH-bthsac75 zBDROu;9~OSxJCShrHIyz)V=Xnap?ZAhWC2i+ktv89erI*9vZ7PquIx|H%cremS|+6 zJ>DKUt?6w;Oh$#1)NrIZFXAO5bwPRsIYpY765vW9=%-Uu+c^8IS~I$#vX)VjPQEfz zCBUZ#gZ=k9dt@`#Ay-!?1dSB>wnn;YJj64h$aAieFg2u-&W6f*H&_GK+<sTyr-K%6sO&;2 zuy}o?wq~mhl^a5}JIyKT#@TQC@Nw2vw`4XvP&{K{R5s#`);w=}WpmW2H1s+0YCY_jS`G$g{C{UL;UW{N#R6Zwtn zj;_IU;2+%~e1o$|?J{k%+)B;j@6^`ShL-auk2)b!k75mi42)(S-<~{UogckV)_tzY zpn}rqW_^F%FizmgLd3{P+DD>_VrZL1q&6;BNv0%47-B2E3hjZ{fb1R?{84 z*lmUdEOnQ-OaEV@T2#kfIFCnpEJGe!yUX0IRUXS#9=Ob5(0i%0`=%By5XEl2p^M$& zFsl_EV1xAc5$sfc8NNzr{x*Kr;{t%Xu`&^bkafP{RG!S z)a&X}sLGxYccr_iwaQ)TuKMpGh%!ew;kBqm=hMRrBoHzS&d2IZ(O_eD(UPZ5pwi)0 zhrSm}4@<{HJV7FeV&nrKZFfsn7!Vp})r=j-8N#P~z))p(v@u*##ttit9CN0HOOzId zv@8cKi0K@V8dhc`KI#JnA&NEHTCMb7%{*3*Hs7sP`u41_S@TW%NHCoZ%!2|Rh70*bH|X||{oPrs!2Bl@HYj6|8@cn8%jCqfTLtjA#`6BGf` zI^7PJ$miX0KGnVgoo$RUm~LJsD~lMy`~-V(a9Bg>j?M&J#OVC3G_cx9wfA(Kt4Q!H zwFk@WOZ@Mc6-tIFf}t4;SjIJhh;lSla$I>uDi%~~ zsp;te9a_TY;YY(qy3`Bp1lOMqEomZ3g?3WZm?xpt`}C$4|GF0T)~&BmS0mwM5GtJx zKKR?Kt6psnTscNI6_>j-l-YFsL|k~YNgGMLtKieSs-Z-#Fb-JOMpvtGUZB8g(=d?+ z!JGlL`$1s+SSm~MjhIdt!ewY=e2^7v21^ZS|0lq2m1WyBM74H1S(u1rm zWD2GOne4oi+pIZ2^^d8Zpc4W{Lu<>@r(sp*=<}nLh~SY#e-p&qVv$J^;r1wccHs8@ zdWC--57sMA8VD|`OH)9}11S{^@0x$oGc~-I*2o%)NJw941&en0N)ro0X=M8yc}SPewabs5v5~_1dRmkd#TCcv3f>)QcyzPmAXjPwK{#dhw+8gqc@TJ!YvxI&`S& z+cYdGl^7+Xxv&(vr(3Cedp4Z|wl^wDGQ=nknx4|bU14FaFa@&uWv;4o(k3O@v=NU% z!(w>$&qQWa6*@lq6*;dw zNez?qnQp8Hv2=`v)Za0Ls_u^U!aC+F0t%)tQ4#)$%9;kOiHhjcFann!W{r$cLu45h z;2;v%?+<{wOp@WN_HLmo>F%^@R3MS$+oQ93dn6;7$@G&0>K z8f;Y58Ts%0TPH2duNm~~XOKF##xp6X&;jo`8f5dT3N-}AGn2JbaSq--i62=n&~LOY z+LR8twGbENVREIJ`(R2&TgQ2MZM$JvPhGiheXb}6lo>Y7w7;U6-SsfZ%r z?ohvR0`Iapis<2h^8_Zed9jnCb;{AwEJD0Ats`M@j{+1;DT&@4tdYK&!66Xx(v&wY zS@xCJ3u~LR^7>?K<@F-COgXK*UWo4y`!jTOW;cE16-8!Qd3`dz@~U_DB+gp(5~~9r z@Wgt!#7Zl!r$mof?sQI#9!roO*V1S#`Hx4fP>+GyVfFQ%RpqtHM0e%tYnN7E-EwOO z(#IWW>2(La!tgC_!jW%iO%pbg4&lRkO3);W!20v763>)T*W4YP{kJCr3Wo{#APCFe z5(Brgyp+NBhbT0y=2EKH^_Mbtz#@t2ku;HB zf|*rtt7QlUTh3#n>ek3OGv`rIPZvUkrZIzbKU@?m9+NWPCQMUn2nAPZ@e7m7dI>g_gh>e$k!Il3B|JVdUsi3A?{KnBO9ts zTG8JTm5T*^EOh<)yB4U90aZ?6)4YZ|L`It7H;wMLG^ce z85~(}YNmSx16!4UabU;cKtBRKI*E;PZ&d>$i!0%C<|I~d8Stozx1w?x5(V_w_N zGOke^t=TOn@*#32{qT2@tCb8DC-|OFc5a8ILW}>5S=F~i8hS*bx+jSO6;*D+Yv|Ll zrksNOE{5ifQ`8|dYt4(|>A=kN=GuYjwDnt>_I^unow}_;$0d!^SGp!h zrk~XzGpTKI&CEJ_Q>?R1uJcX)zJXXPrA?--c01kcy-=ar?{$`s5~TmUrn=?6qjqf0 z!I@_Te7uWn(*^+tNC6Iy8c|7HBC2(glOHkq(wQv#b!f}j{P#k;zFbKozSELME^koe z@byUxgp11@?|T?Q&^J)hy02Q&x&aXcXH=>Zs=Gd*Iz`^383@`lVG>;v-6`PnytdX4 zL*R_$rfgvpoVgu+&YW50!D2}@SVW2OOq-d7&knfrTm*BtvZBm+KOS>DI#(*pfe1YS zAi|Dg>X#br(+y|7DPK_JoU{2?QF4nmg7xr7B89ByMlesep!L`Y2DlM;DGiuOH8R*o z-*R0#r;a-;0V+M^mWDeCNCP+8H20$A&Xqz(pe@;Z(W=y7)3hAS>~^U+TU`eAx@t^( z(ug?SIwICBeD;l-+|(7u^-V?q_e#%KeO+TvjgA$A$IgspWLL)W#a$W8`Q66y!p@8Z0akaO#=f*GWBGo!vEUsB zSqc5Gm#JMD%c=2LKHyebeAx_a`AmOd21_kidSEwL&35V8Yq(f?Kae|!oo-y(qie-b zxt~2a)~=@2+54+JuCC5LfZr;1U2K!&lI|rV+%3&4WA+JQJKRRZlbn_VmCI|eIHeP& z%T94hhg(hbT+yl6Z=vB7x(_`8D_KU-7&EQ%>Pnwkm9DdQ$ls4ivl~KRIJw^t~V* z64^`Z4HfughLXUQ71g?G3z@zzSlp!)ueVotGsQe;N3!x4-NQ|{OAEW^c) zNy%GNZi{vY9C&2sGFeQW9b_PInHkDX3#MORX{;oVP(lfl9xWz4R!n*vcXnR?@DVY1 zSer3;n70@_a36pd-OD_>?xH-ztSlr@yc1<~1oKAJE4AVqQDJdRKfG?Lzy)7>A|Ir~ z48Qrh6X?}B)KslQjlCzK)VyhmG5KtH;F69PA!%LDJb%04#n!|Co9H34n zY>XSr&?wT@1{jBzTfBd9Ye_jlq=e>nm&o_XvcUXoOznYD{|B(<|=yPdgB!=YH%E{=f*7KSDlq58XEr=7a&OPBB>1nLH8#j`I(!MUU&!3-CumH07)+3pQ2acfo<_NkU z2mz<9NI-+*g*AESDFpA!#+?Omo$^$6ss&b_wKPTc_G2qxEx8c)I-O%{ZrNLkYV)aJ zv8mYxaPmdf<|iepO^U5m%ItpC=HmaU+BA|&c0#rJFCA3LJOCryOjQiVVuZJRQpp=? z5F9K6vpQydNxb~i0eLA_4DymM^75Z{=jA^u;pOc=0Wbe*%*#K~bT2p;86ZX|dLhqy za4KR1eXlJdRh40coJ#UbGv8QnmgSkiICfq0HRhnj?481p7AmuW1-a`hd2c;S0 z6r`pAK;DT`g{{Y*B$&e;rQ%3B`Z6AW^6kpe<8PhVW4>2YYmGRLT!}mU2RNLNEnl_bi@} z{hXXpXL}Wh3eSlq|+i_ z^_&I(fmEd=xN5*xi+h#?sgti#XfwE6jf0k+*6;gXcuvAH&Rf@@6SV-UEnPTkUWM$(+Q_{FCo7KWfur{xD!R986(F|uSe;lu_FrEIO5*Y7(;JoTrl2#D?r;@HT@&bBRNztYb zN}-`h7Z?&=M~T4Foyt~)8|lhy2;=nChfJ3+>|bR09!IU}W;07^I$2WF?^sIHSd0p? zUQla^0gI~#N|Gxa&v()n$DjS6VrFk8JpS=tS_i)fF#{(st1TNbtgf*}Uq0s|oYpB@ zB@lIg%Lrr*?{;_XWM(3e$K-GzU?aiq0PF>p`svm^wbVE2AWWzx=F6o`NmNvMQS<8Z&XAR9Pr&sXu0>*w+ zPd#G0U<|kTc$zrqP7@VaOUG4!>Rp+$?nuXV$wgc>G)QlGq(3m3?O%rUVfZHl=?H%k zpbkhM1=2^-QHS&(I~^g?5k+nz;%g|RBxlj69Hl+bw6@@I{ICG~s-&)K{IqtNkfy3d zviTVAvxHR4uwB0CO<~jQDO?>4%p^n5i-n7Pgp)sFJTa+sNilYOIiINlu>*IwbfvQb z*|0xmgRpc5n6Pxk722iW@u=TOoZ)&1aIT7z?|Wqr0qG7*#{p`wdsPRcF5IvR+PA8f zAPJZbBqm8Gj(NFCzFj#hF)>kd+FoNYG81Cv9h9yp2R~RVX#z%sU_xvayX$)}jZZD7 zkv>l%+Z)fn0BX7-{{o;28>nm~D{1WgXw2%blClXY*TgK7+N2Z!Lim2v|kk=$Enb6Ub)C3vsp=)~GuDszf(>lM>|(zHK$)?gpquxrbR&2vTy zDjK0Q^AQ27a|dSKLJoqPWLevw8p@rjewGMOUZhpos&H;UgY*I6yR3O$me-ZNEfe$6wOcMk@D@z^)yFyYfqb_RC_=* zd&vae)=~})J{zo0IRYr2B>md0FjXSk=XE_a_)dIiaF6);Oa`lGvV8RbE7Yk3|5#Lh zo^bj`ccq)mS#KkIw>{>i$CN7WJ*IYHtxd{WGpE%d&HCP`@oP&e?WQ4Jf~u468cXU# z2xTm)U~^JqP-WQyPnax8W;tO0yHlP!c_QYX;6vGQo>nYM#8^mM;tcwdZ`vC@yEVo` z_xwWt?#kE2#>1t!d41kPst{uN%5Ne&1oW!k7L#5qCcX5AxOv6kVdsj$gXS572RAQ( z=NN%CVh*(W^%=Nwd4E0wS1rdp_x2h14$eG`rPcckTw3kdpq*qV1#>4BTRH`J`z_Cz ze#i0ZY;W{s_U|3TQYEm3I>_kzPyc@ZZUKuqnP4|N4cr(XG@U%Ol!GRWS}o|Txs*-R z3jx?kAt$Mww9`pc!AXi-GkJB2ZkZ;0P6Q8f#g{m1npYGxxOhY*8!6|m$Z>qv*>cn< zRUdZE;w;UYTuMg}veiHoNN$*)GRmLhdwdy#wpU*T9jNZGtp=R9Xl=#Dp4=2!TX$MQ z*a4M5#;tbrSaO0AtL#!CLHv(8VK5GMnj{K!dbG15ySRU#p}ng zZ;cuD!%gR>TdKAVQWk=9Qw4TRdIo@-sH9T0P35c747}<&wpQC%-ih~&QW|z}U2uFK zWxh*VbUK&e=HIi<0q#<#0w#O6FAh#?g*=t78V9h+%|;;2HM9uIhDHO}ue8IOw>YlM z9_;H=4ujCyRXNq)B&^38wbN+DipWxa0x91&9%`wohgk_k(UsKtR{scK}*b1 zD?DxFi6Y5Ya(Sj`$yZX)OLDtenAGqj6|Ds1i&Y7FRk^AxTcCz#FU>j)4{$BzDEO3M zf<-h5Wh9=~zAVZH1uABTN5QYe*?uc$?N{S$FS9ZGHAg+F`)pq&!2M~Dg71uvf?pV} z4x6LkO@UovleJ5jm=btLse%(1w>_w&tdv1R+=jT@a12@(FJsUuAJiaULpb^nCp36; zTEUr_*(PI?7{Nx;$V&q{Fk)3V7o5Q_U|)BS0r=)oA+pcycOSIBBYFZ{M z2@`}=)CkB*l8%?BGBPpwcIE6b0~6Iq!p@yaBG+Z40rqSj@{|Pj(5Yvn8z~KA5BuUW z_uZihUYC&;iN_$bw0%1__PWfZDo>E&YGkx7rHmH%&5oH7RCc|KB z7bxe<6Z)l`hnGh;4nv=gl$U%v0 z8NtjcJ0@sRzG&(E7@z-;gyQ9? zBizKQ64_g@ishSj&^JP@zBg8@Pm|NoqNgZED8k?CeHxnEUcx?ueOOds1(PbRO_bqj zXx_G2Q+h}s3~4MBu6x_IcsO+5|9DRIlrhOfbDS;ZyywnNPbfo#JCe&oAsb0Y6_buG zCLIH>px6Iee+(X!xEMSv&=@?N_W(SHGCA*AieJVZ0mek3Ec#`9oW1Dm&@bcII6L&q z_=MvdfCybcl?RuQFJuO~fTZ)fU>-LEi-1;S$zzYXmzVdNP}!<58*-P{^;roEX9pOS zkMZ4tKxpdKUezXbBwvh!g1epMyI}xi;~yWkj;`>(v_ZE~_`ut+l*(-skj&GAk=yd5 zv3@J~IoR-4J=^jZCK2M7Q5Q>5yYpznJETh-?I7>srwG?(-Xk9J z{+i#A(L%48W9$OKAxF~f4yrG?DMbE;00qb_rKpXlbi(Sqw?%wD=w1>LI-rEAps`x9 zBy^%wJ@uTt5ZC=4U3{b2-(mCBFqrjm*bFWhA6;B4az)Yd$F)GU{(f_T2!91WBG`#( zq7l1`-ZON>KTw*bOjQ7sDPOc;J!JN0a5qbp%<>)=%96z%uW7<-6XsLIz%<4^X$N_; z7l0w>4RhlMZA!kor(#y3DurrD`a}ZXS8tO;qAEfNA2t`Ir7c#{F%JQ@8WD3f0uZAT z5mk%??DV18Y=hZ6a8qC|>V8??8?p7Y*Z4bj&aQkd z4*n;DylSwBf#XfmyglYTIMp7;z+35Xap1lrrVUQ}4^8D&2@2la6%=*^B}KrtEp0>Z zz(rO8iGxY;Mf)GmW}_T(ZUM-r_lBx-s44Qe++i!t9teayISj%99QJql;@gU!q!cF! z%=RZo%>Gv=#i=4*EqV7U6A5PZb!Bp-)CYg z+yzMwYmD#Ja!|UrFrYmNG}xq7X$U{bBj%_R12p7fH)Bg46!U6`+S53^&4-hMK0*O2 z%G5ENU0^^3pDG**Uzp%h7{VyKU}3s3FLH4(`6XfsFTbCm+=1sBjEehWbJ%hdcc^* z^Jl764LGRsg~)UeZ$I*xYE)>=R@=j5^5%i*>1Nv}EF8$h0PB3pn{w>6{ZI+Hoyod+_f|FKdsd%kiZ4c)H?$ zmG`9wxMd;k4olXozgzykv@{BY&fdeIosz)b_50E)J?~w;FD=<@$Gk5s32X-^7VzMmw18B>r3ol1=>Py^fEUi} zmBVb>$WFK&dULZjymfh3q8%pD;#{DS4wGo*vw}|qOs(30sXEmWtxk%Fb_9>EV^;&& zMvtz8?Al{U9tx>hHD#$8RG)k*AvJ?yM?jyWpp+yXHx#>qRNUdwb@Md4c_|&w`!0)L zO4t1qC|NRxQv{4q1fbG$TJn^PSLg8F_DFjIxBSeD@A{$iG2CP{gP;b_^j)LSo<%LY7pv?qQw`31`9(PCg>l z0ti`JKq`Ttmysc4Ne2LykVo39K$nh?S0Pl}z@Lhcm+vYeUxi@7F(H4HueJXf5Hc+j zeBRRr*$rj^>3n)}qkmOaWf!Rp?c^J@6a<~*q(&v)asORkGdKR(uNhD=-aAu>SlWU? z^<7ylUv1QyTWf~x7b7l{-v@^9k~rCp?TfLSzGa5(!z{2xRc88?V|=(b@bfZEJf|FG zZBXqQY9N87hr@DJH*ZZduHcg<&~82ZB?Im9RaXxx{m=-2eWzWum3(~O=xi>KG963% zsrBSe)%tOvRy1}{ImTu7FX)nd0a$@*hi%>>RjCOY9S94~-k_tB)9FsPRCKx{zZXFZ zvcFMIt)2*UMEFR45|82bp3xs|#NQObieMZfF;vqkAeMVlOth5X(j60*rSvtCH~S>VFNM)miYHfc4x`fZQPXSDMS%RIJTKEdI+JJ!)JXuS zd_rNM=;LC=>r@Pz(JeR=IvL^*rpN9RMzTRbS=v{;^&3sXd4qU3>k0uXJx2iUS};N*ijkumq~cX?4XMfFqElR5TB4d{WC%&W8yh@^qacOKBpiQMCK;%gZZZ zh;4Xvw;7QHzRG`z<}eX6I6T8t08do}#f56X-~FnUcUEbA!aN~WH31VDOQY15_7D{= za1Vm&p+OH+L2=@iHc7I8>%(qqvv9#DlqN$6Zv@J$fB>@!S&V70JUMCgOe@>^PiPB< z#uy;Sr`S|1)c>8H^*bLl|XnY^co34~3>NmW~7QThipO z03q&rf4FVThNI^1O>@oD?hd4@%vfmZx zcSX-mSD?5wEFG_K9k)`nu>}n!=?Z{ODjH3hsbG!}S|GiD8?C2X>mS*}2oDW?bU@Bu zX{T&8<=-h640Zuf@p~%fzu#|d&ysTNyF9aI8-`OKXs=y&MP7J!yKN>8{!!qFpH3Vz z;J!X%OOnwa+OApx=-PTcdo$^gYC!)WnZn85$0 zdgb6-w_SbY-{1J?!OPP**cvYVNHc|9^u6!B^r#ka zVb6MC0|M{Gs7MZu{wS_$oZBufA@lr{Ra&)=q;u`{81~8;1X7;?%Sl`BUvns|2sIe( zaI%C(Esq=K!b!k%(!=3S@IIcUpe?v;qPr0^XFrFza`K{PLFf{&o2wGp*7j%_q8uji8(z8j68yVs=M>%5mVb8JRSRxWsRyY zGaeX9Y%7KUz~4Ru1(}>|{lS(01(VIWT9IA!FYosxRx!v}kzG;yKu&fqY$bx$U)!EB zA$Zamey+$?eE@*rCmY-HK?mCmrU5C3wpV74pTj6X^$%~^r(Qv?XSZjvRqYjM=HS=t ze`9~g>N6ABy8m+qHl8i%9{-fBl7?1f74)B)_S&mVW2;nSI1OZ8R!LVJ+TPP-@9DG8 z88+jpKv)Dk>)Z2)@H3gt|8sjGolh5z!T01P>B7IX7l7Q!>~O4#bpGI{kNn!BtG2Zl z<AuILZ@%{1>AnYVI_4wa zP4~I>9BFD_HZ^~3x^O}AnFL51t~Jd7_QL>Hr~CcC?TzVv>BeK*_xSaox1d+?fvnY9?L(|{qe^~+HXzYir)*` zYtl9U(4IaxO{XvYm-eRF3znsuK7vNmw<6&fl;vchjZMcMmF~}^gV!B%I4BU_X z9@<{bVVl0+mNnDW71NaU+tat3&i6|9`iJ&9biNLqAHdEJ zFrB|03CEzU>-+$8zL`n7bCf1Nu1z=Q*lJbqe`)*tXcu@#t-7`P5wnFBcV7Jh-qX(E z*zUA=Pv$E;ov>9qY5Za=?)!8CYE67PVH6;5!=`XqNuGieS{fumKTK=ZEFit2s47Dk zaLfcvWMA1qg9ZvkA)Qj~kNQDm$fxGFw84~u+OB&@2D#Gs$^Yxq~MA0(D1{|j_0vx}UHzh;Bz;0X(OzBICT@u?@o(&0-_ z4SGk8K=sS;X8j0G<+9)57rI;aB7UK+n-`!4hlfals%h&*BndoKsz`4*9g}n@RM}Ay%Vi?n*^v^LHf4kn|qf^0XaEw0%wL45?x5=k)M;RM@P+Bsq zFrGs|i{9}#c?n0Os>05c{9;}uphot%^aB2hy&&o;`Kj^Hl0mbJpUrb;4ggA?D=P&q zSs$qw(~j{CZrvb3nF|ko`Ktt&M1(xTAc7>p|7+`~T5i;Gae%X)&rk6|6U0{J+UwMs z9k6Q4bdFR{cl@hUePjM4mC^i3Dy!m`REE=DLuIrCyo7JwV*zb8NeuxkX6BnzO!BJ` zZbW|SHF$PDbPDFf%$iQK^PyAhtW|U;s!J>mPzHp7tcn>c0FzwGyRh~JwARDRo#RUR zX5}4n7>WSzKbu=TL8_n4Hs-F~3~}A*D}|K~0(^tW#;Z`o^+2|as2<41xXuT%RYdea zHpNvwkj-$B4`lB+WCTZ<#6Ao#*t13u_!a&Shm1gk&-OoL1V)o=(;*{p*~vB^GJWE4N|JY-}HKW{%|BpDtz?AN;|VQfI3I2+MD>1^w4*}J5RlPq=Ns04RUtaQXl zrc2In(zB~eT}gY{yBknnb0tT6wt1~9InuM_w_VBMUL_G~ucDAt7^r9S-ya?G9J6*|X$bu4JQU$$MPMde4$SawQF`QX}ST?Dl8? zFSzr?Q0LXGiYVLxlchwFJdroA5zkfX1AB0Ow$1lKC_;9dWr*F&=>2{g%UbJ74A0Lq zgpwXf2+S?8vRNNTfBLnQI2fM{uI8yLljv2x7zg77=Q$~9+>G{u$wIz&|5HmZ#Fr|+ zUw6T4N^jYT5KD0ruJ444)69ThDguEjRT3g55RJL-U=~dcFC$Zt@WqVV6W_;yY2G?8 zs!T$H$jp2h?I3JXY{=aS8^WadM%ZLC7nji_C=4{AKvjjAZD~U1ht+R^q7+p38Vjo< zkeGEzCmDwYJy7sRf?3*s(_P6r21>td>Q_eGpEhjKm&JfW=Ri>h{P0h$_8UfTI6E&O zQ91g9EfV0#7tb0`bR;TijO940%9Okd^ReJ@dUt5FgqP@lGvB6K?kwJT4*TbWjz%|X z1wPxz`&V#?vZsRDj~c$9@<|8n%ORjJ&bui|b0G-_5_Zi7q*F!lG_7#G=iLb^=QDI> z_YVH>*_Jz1@KD4tq}3zXV7Ae?iy@4L5z&J>K%ewUXa3+dOUWSIM;i}O>{v}BD66b& zhk_HGh7ejkNs9B1yYCQp+{-%zB-xHr{r!4WGfUn0$+9g!BD1IX&mqIn+#J6&=I3IW@h%L3?3F|vShK|y*`zAx*_U|$oz34MX0F2^gkGoc ziYkm~AG7yWv*w|rc%r&admoJNc+Gb!7IjDN4vPv#C>$266rzWGf!``_O$SjZC=f?p zoHs?>_CK_wN5sDuT&s|q2h@Km$!FzOt_zHWq|X(TPAVqd{f0!BjlqLeAqEc$X$&4* zP5>T`w#X&qw(&_YMi>`?;-y)v>pK1!6%)TWd@t~~4W13#mFNkK3l0QoWz(M+ae}zr zR>Ql_nlM>zpQSf5RMO1eOK%3ZD+cI>*#U0I)I3$<;tNVpK7yT);*cyTGhRDdSXtr> zK?EB736HbF{M6qs;!Xn@hN5$!*8)DNdT*~3F%h-5ZN50f8`aJPa0c)%;JUMqQ38^| zImRZF8K+};T)H~iK+EPI<`G!$RJ#gkFRTX$3~<%Qu)`t%j@NhuRiXNgxnPo^jn8#1zO&OD}f30qPa>gc3)>$?@~t zX>l1uZ4LGoa8YtW9n}Ki>L$6cSqfTwyIaP>S&6O~*-Nde!0gxh9X)O75p7-6XI=RE z;DCd(-5o(zBEY6U9c-RChO8unqtqI#*XBf(M+$28h%>*F0%vL`O%eMC5Hx2XacoEt z7ilZjA@B8ltd&jRUSAWEMvl6<0Qnn39+;QnR*Spcf=*OQjxYg=HibK{`T~T>=b>gD zp4>I&l3hH25xDyY=vjJnwESjbj{r_Pz;s|WRMXhzcW!3@t5Br@b@5KG3W-i z8Yvo19-$thlisS?bd*=NG*n$xdI*iXrD0BN-0d|Mc2O}~&@=~i&n9#L*m(#dC)eEm z=NV3X`~T5p+1q$`Gj9gnVnoEa0*e^;Jx!npSb^l@llZc%Ag*XGdr8SjTQcXelFk-( zAR3!|yK?rZgo$dvA*zeF!KDq(&2@^$k;9n|^0sywR0ge+Zn}Vq73hv4q;L$A+YAC! zhZF$K_xFZ1;%1*^jS)Jq+HtqioIJ+Uej!e_G@Qwk9>ZOx5G-jRKivS+P{1co4T6ut zA&$273CyX@fZQnY3;~icl?tnOwp7%9K*LWsP+WDFTNy!%hHFd0`9TJ}kv(wLaZGa~PRk zA=-IP3F-#VQI+gONCK~G`?2t{cChJ7G1`9_j8nc*&2c8OZgLVExCwsqX75#P5>B9W zd*u+b(990_wc%`#+%d!?ubz8Yh*zA?l$-0z2M*Znp=>Z<)uu)JAB^b{VdL$}55W(S z71qUi5d;9b6s9H)0J{jW==)@F>MtaDCXh-eKXMEVs!pkV9^s3GEB;VQNCz& z{$h#Ic_K18dlQ~9`C6T>-g=+2FUH5jFcz z<9c)4TQp}H`835^&$T+P%mTSq>y&pJf-nHd2_^y`6ny9C(X0Hm3+9Bu=twx*XK^1R z1yF#k3rx^B(;$ujhAesJk%;^&4a2hV#fZzvQKWSF6B4hj<5h_{V8glkTR^f!V^u_y zf+f7mbDJj&ivcw^8DG4UZ`ynP%rn(q{YaN!ynQt`-X2?Zb6w*1tk1zOaDh^`;OM@R z*0UNMY|dSsRi`k;y4*{&K-b`IkLy$*yA;P%$uo4gQH4n54BpBl|H{nAs*ZenzGXC= zo#}Cgre*n<#gv>}vVan`fVjv!8qES4Hq%yLLS)V)yQnh=IY8{{OC{joIz?WFhe#h= zn5kG-^WCwYk617yW8Dr?ILa+07T)0tpyVt43q|=H?r@tYw_+s$Dv19OH z9gD$(bqwG|*0Fw9#a$zGPl5|tk5%zwUW)F$Dga2lD*6vOI+1M;=1vwId{n?hSU;INSrw%=7rtvNXkn^Aq0LmK4{W zlMf}8W2bv1hJt0MQdL{1DVhQv>3~F@N>n12cX83^LEumI=|SKfZrSy=1)ASg2a&f! z*t^xEq%;N-D0-4kywY1$zFj$Mf?=Y9t=rr@{^v3|R_XSHN;G=Ffks6vBmj?a3|*mj z4qw_=Vi6M%`bv9J>A|#Bw%~lt>m3;c zSnI9bqfK0H!4-4dZp`*`muv`1Gr1Q5X~Le$#^Zrx=t0ZQq(k~S>*4vbUBCv8EyMLP z6-(>+aOl7`%ATC80Sm(2_3B`UJN%Xq#CQdx7zsf>X|MA^taPd)1f8S_0qD_LBm%l_ zd5a!eR%O_&nMU3xN}gU1V;oT(G@`z2aXXvhD^fd%q8{-26uioTm+Wc$(mVYZ_%(r0 zsCrZngGFg8%#y9cflYM5#F|U2nM63pGO^(j8zvFKIJcsLgraR^TP?MzLC(IynUDk% z2vdF2;n>oEDv{GbWVAJND&-t*FsDp$a|+w)Qk1zL1iVRfFDe0{GWQiq*g88@=DzCK zm@1KJJ>rd0=DrXsb4xKw+}p)v=dwt{0RQ<~G3oMR(%0V*qeKiI)=CT>G`Sc&D5(I? zvY1@sIjQEh#V%1}H)KBya3!Ha5bgzHo_sMr~BQbn3Ss>A*wF3w}O`Co1s^H;FbhmbQX}@2{h`%&@$D9p0$%RbLn^H7bRO}TGYC&IeQmzd_2sP!a^45J%Lq&pP zW<)um^^d$$HXCbiyM|Z{lddf$eY2SKtv7_UWAH%QF?b;D7(9?Rz>7$`Uwhj{eZHJ~ zaepu80+86=wq2;H=hRJP_XSH$>_5iFlv{&9N6EK2UY#A|eTokfd(8zRpY-D0@#6$8B7KhlvZEl4d@23`#RSrQ&O)gpt)cp7cdAh-w;rI2}xPU zNYX6-E92uhsrV3G*JcTITa2RnUYgjRwT$1(z;TIr(H^r&=>=wCB(S z>vxcx=y2$nJW^-3Q)ib>92WA^?I_(y@=z0^ZhU=?^Ly&7+DMDi2s3wTgs}e1iS;My z+HW$QM`&Df1PF{UqN04-3j?E6JwUfWnlfU4pfgrx?>7EG(lP+RE+AhFFwJ9C`3AX} zg(cslW-Cfc3JLOzg%G#&ypepgZ!J`kfC_}Ybh79q6qVzpyPa?Etliw+?uJh-E{B)0 z@q!fml=MUF^oJuJ{i6Dd4weYal(s^^L$7)mjIY+Tl-nY%l+C0ln&d|nb71UR1Q2nB z0?I(L-E9OaHQS6)$v4FoZ_K0ELhmNYH4gLnS5a`eGY{;~8ZPqeQ0xD8gD#pNXn@Hj z5^AzuuZ75B_70I(06id)FKW-w%JXmP*Jm%7Pp|U!D+OH8=c(J5`#W`mq#a8E-;;?e zxpv1F9*C{Q>{zd&k$HGglXJK8bL2%$V{KN#CQYiRu9LH3nPv2r{ReB=G}CBZd4^g? z${>pRf|*CrR;kx}Eg!n8nMcW`r;LAZf;w{GMuc5QO49r2yalWBPMQ;SsJsvUMRlVw zV?0+0#PjDWydG9-?@!F_&%^Kixn;fMkhZZ*We}JEl*-M19q%+M(`?#2cd+xIa#SM? zbn%@97g3Pr3YZO?zdbo?a;o(&L89C-|2z-i`?K~ey90G9~@Kq07^i#)0*MIPVw zH0m0WM@mehd7K%^XM&JEL231sqG&GiNQJ2W1j<0k&=L9_BP$58)LplN;FsPYoB@6D$xGM!JzkkHM@Wpb(00IIKcFXb5Or?6_ zco3ND3`sg*y*W#}Z5&sECZFRe-mLX&$@%Va%%o~S8fmL zasjSIgRytzRPmrexhtpg(>-$ha3989xk0#{mJX0kld2{MIAO=P(y;6xH)@x6<|sr2 zWjK^o_I0s6fr?4|TaABH__qfCVB$bfJ>Fppt7Y(yw0n^u{-8?~v~ELwWq`;$ zqd>4BMT*I3^E2ykRj--u#S>s(2V|OEul6A)ns;J&L==t}dm;)^VPiyfkGro(jKL2$uD^>A8~(U7L!K%QJG4h>a=*mtrLy&Zk6=K z{lYKHPCc6?&bw7y%oLB?suFP!zO)!-QstTHF{gZdvAwyrDQyEcC1V5Ai7<9mq-3Tu zs#j8lwe89{-N=mn9NehT+||3%9Cr_@OkA-ZnZ(O>#p4WdmT-tmbk~3!hN@-p+ACMS zquz+<*&c{a_e^kCYi@JxfOM`D)rI=FcQvzqbL~Jfe$31~!iEb{F+x7&x==qTolh6w znZn9Jb~=yuTW1zG!>wddR|7lGwhbMg0d15Rld~3VWnYL>h+CklD;UVa?9V4gzll=u zK&(_k8-+^BngeT3a?Zlcn>N?plfEgh#1%0QBd=c||>4mp95j6zH0q(H`EBD6}U>O@a)7HG6r#O%_{2 zc=4?&)p7*9&8wPEF2PMj_k@m0p8a~iy*8r(;|)^PPIlQu{>eGuE6ov8I8paR3W`vs zS}?R>*a0OR5cb~D(hU#F6l6do&7xD*bx8p@`whL4-4yjOd~xPNf#I5^HX^Yn6(njX zz!b>CsQ4i@nIT}{3}~_U=Gyzyy-WFlIqvpMjm`NlQe|+tRl&emT&CSM6#abPg1+~a z(h3ek_s(az8_^q$FjzyXBBAtqoS6v)HH@<9tokM&2zLvbZ4psxpUt%of-*L!vVdO4 zuEOk*`IpG1_bqiAX#_3P1|HT8IjSuqDurTFzFIq;)bY|pf!<8m1DUrj?Pr(a#4swy z6TY702NFX-u??GRf0J$~Co$^jTP-4ig2N9JEjwHouW3Z|v$`x~0p%%sJ!xbxZR;VW z`{ZAwkq!A5C`8dfim!(H{@VimphR;1!pxgD*ZvL|j};#s34)6NNKvhk!UB=9mA=^k z;w8`~_u`0cysBAWmxWU%`~b5aOI_>2PG3}-e$HcdMHyuR%nLXkRz;{Vl6X4Me0(Uu zhk;{}sIvyVEh)lSXmNEq6}NciNgZMANAI6b*TyaGC^hhMx7k;rj5Drd92MsF;}PWt z)W^jhaxb?w9ESbWu%E|bfz%x;Mc{;+UqL2RrLl~}4`$!ZwZBjI?XbkdwQPJ|gdX}@ z%fQ)ws#}gFii^~N5q~8@Ua74jKv~b>TK0=uQTuJK{nvEA(h(bWR$|<_yU(>&V)6{8 z9eB6XKC^Li?Z3I+;O+o!1CEnb&31x~2}$Kr*(3FIW4*YJ*DuExn;saf4w*CiO~H}B`z7Mpb9Fu4akWV^L z`Nq0=H^qTgqy>2Nge`>Pp%f#WD&B}n*1{F{#V+1g^hfs4(&I1?MWs;=gMmTi+qg9v z-Uyb$#B7r>?7&@*AKaKuUf{jYN%8^j;AjxZZ2n*B9k=Oc=D{FP8vPb5?hDd?3P4XW zZVhv)9$SC6H%VjY;y5AoP(qa_qC@ZS3yd4Zq6r^Za67!tT;Cn*t<{g(SCfva2J8E%s$JmgIa{#8RMPbb-tp3Uv&2;* zSAE^z;n}&rVA9}~og2-~pGNib#1fgc1l z8X3p$_4r+ZU%Yj(5cVR|cn2rwcJ?K_LXtN?U_t599zHD}G%`G1Ey;6$HZ|&< z#e!;r6rcNg+Z{omK$eZKCwwXknRX_ zVECmt)~gppUPAm&Y$h&_b}$*LaUeKB)FnpMmH?a4c-R$YrQ0$&%wMQ z2T?n-rd=;D72qVvdQ#wg!RKNO0z+19C-wYUv#^Zap2qP2r`<=!4a=_Do5FfzV>u|G z5c|}G&h{NM`;P_S!d@Z8PI=CU(*|FiD0U1453H@gbDI!`zynv{Dg>F}3h3V4;Z`6R zBX&6ZbeV#r^u~nBS6z|R8C(k%)s>Wp;G+X0F}Op5x3VZ#sA}Ajb7 zp}g!y*Jb-qJ(vwMd8M$p2o=QW1R-wVE_Q&69wQ^*iqdzCh?tN}auFPkR9IEwF(M5B zP*njygqoWaLqExD^YrpMu-S8Rd5s;?8VjeZN~g93w=&f<+@$1-h_jJuB!xrNi=j9~ zjR5$qBal#la(huon(IazJI?YOb2r+MOY`9%Jl^}Gk0Tdino~1DghP?oQ>Oo@g_%hl z-O4AZVKvT5OQ=EXNJV0>`^yW)?ZLxK6#rIjeZ}QvoFW8;hE#=-s}0YkcaiOUm#!?s zF-fz4LLs12CuHo#~2;zQ9J)S7&}u%1bZ0V`5% z*vU6XzSBI9n=YSwPsv=Qw{~5m{qKR#_P+;qgMTI2{Mya6zfIScLJ#BI+I%{Q(&_vQ z2vf))g0+fXL@-JupD0CefFZ2)nZ0<_w^!a1@pk;m{1afvZDS!6PDQ>=Dt?BVC2A2T zHE3OpgQL>pAk-nDn7*9**59j|gz|T4c8$GN07RxLiY9PID0!s3PZbcOinHZ>bPxh| zIB#lcfTQ%@)Lo`qwb{SQLsnLW0*pPnLj4!sf&Y~lOc!enx|#jAG$nLuKy2F&@56vj zSvx+2&vQIY{U7)|+V3F$okLZXnH^O=Vm>)?K23ALe{3w=gra zx%U5b9ra9(Khs_JQ9FpbZuJ3NrK=`6zDVRY?sGn=H^xvR zIk5;z36>AXwzN8wb z;xQL97}^)K5)STn>*XqcFwuYMx-Wai0n{eJLlK1^t;-kMPA+o;88T-^2$+3awcn9U zWS97nU>HpT-E;x7^RFQUGrBpBRul#^x+TsIgJ<9B=3KR(;cPAMp-b@WLwk$`f{{mm zC0LkTrrjpuau?&s#)L&6?fyf%4rk{Ch*R^S=8C~Wzwd^wN@ToRD&HowYrgcE>X!aa zKkRXZ3odHu0S^IOEWt&K@v9AywwLn<$32yFd2&UA5vUtt>Bi}!&cz8IBR858zJY8R zjN7!jH*^_LyVMv?&0kHr08GLK;Mm9o;E8tDHi!38AxU}2C0}^n%{V&9H%_D6&M7Gq zNcqkByuuJZZyNzb91jl6{IFE3D1=r$km!@;nmmD2*5E>2!y;`dqn^4j=w z_~i>&3^O~9-{8h+?@Ijs3cmBMkg$(_SyHc91;v_NjL&@$)$GwhWF_Wn`IC<&(zK!#DZo|evSZJ;n*&~npMdK zjUX@2r=Sr^I#I|oEBSWitWqBJ&WZ7JOyn%j>+KA3zG{)Pv-7<-4&eiEc#mtqxJ>6@ z0Z66}TWc6YXUafb&K}-QrgG>m<%^n$^gDr}I=9K2Y30*BQaQu}iUtd*xX9V|*Bp^7 zE`dn!BIO*P%smKVMl?-|NJ%8x`5)!OrL_bi!J&-|vKNsAbf~}~a%x!>cMr{>RTB}% zY5pIkbT?c&mLkcuawyo^aQ;P9`_%!C6(D{?DF^$yL;L~}kN+7n^CqwqSeZxQ^11M~4-#*6J{6H{X%t>Pe50TgDIG8iJl9JVGn%O}8oj2v;2H^=Gp z;Df}12`p|wgyuKv4RU*Jk0~h49FdOm>hgFgrKRIJB!G)dW0~`G=tj*HVFe!mnd2Lu zS-~sFE39_2!uwCZn1YiV?M7;FP|$9=&JIag8Z!qT1_iC*_2SB_9eUO9BcPgGTyV{Lf4Z`CN(o2I zn^)%O#6VPgz3B}llB?Zv*)s%GzIqK@$PgY&9~6(JXqw7kp4crg(+|s_$*4=;XlE-( zi}cUR_fbVIPsj_U#n6@j(NGy2Nbu@U#VJIh!WiubmA$X^6i!=3G`COlCr`X8L+$^LSiKLm|2yOCQ2XCeqW!-s4YmIcVbH(Ostz0Ny!ePM zcnKd?OR=+85X6UanPsMi6lU;pDO4Y8qpCUv`Ft~baWLCp_@l0SdXrSf7`!_58cQbG zc2s+5(7u&i)ThHrV2npk;~B}iQRDc;D%D%)L`J>k`7PC3=2N`|XE$nW6Tehj!AQ(~ zgu&qq z<7M?8i|a*|j{kBAkUxtn;gK6|#cI|`)O%>6#sLJFLUJ5!nhj6Xr!aId7%fe`6C{5> z=Uf{1wiqrKFDA!rs|923b@9#Yz^Dt#KYb|Mw`{?{43I*(*U;((bH-4%jMYMDNV)g5 zf=XC>(3R()19xibEZ0=nTUIuMc6o+v*(JFgR#RG5U=ueMA!Fzc`phmXo27>fvjma| z>+LA3_efkXs`NrxrAOmRh9m+cXJreT!;acFe5jSSjM=P03v&qcnHTzIbAIyUlKzd{ zG5bKA)9Yz$bB-g2B0Sdm)&gi-5_sz6&%lt41tWPpW%;H%19MNwjkPWss5Z?$Fc(~Q zo3nS_BtAJ}nagEXl_Wc>zs#yK>4^o|*le->(bF&}x_u_i2T3nJD~2%XRsq2Rop8d6 z>IAk=)p9{5N(T@|YhZFVXUySvBFzeizI(J9-i30`snS?D zHy8>pH-Yh`X%m)*5K}%>{mu;e+b*cJaZtAN#;NQlLfCU+5^y!j9!^c0c# z;)fS;kR2?+#Lk{`#6KQt2#}&8S;Oswp8&(o z-PUMl%F}ROuf*{L!1^~OSkFD~(BIS7xw>Lb@6&FFao5F%ao?<0>xRvjyx8D}P~i|P zld)F>{AiJ7S&|GFcc}xO7^MqKGNZIlF5rb|V$gSoCTNn9n&=|TEN$PQnGUqrT!yhk zc?_dkh$4}MQx^8Xmc;$u%70dS4MC=vTD1>`?)57SK;=$jII!qQ;fY{4$SfTW9!BCb z1gcVUy?a+X$6CJ+f83kkE;{(a7U)UTknkrsjA0j=c9Q!Nlp;5QDhIC+G99oIkhbW< zB(OSHj6LGD943V-f1WIvqG2IlGSk`D{E|VVikB!Z&+X+$PJLA+vQ3yy`8J$C|Ke_{ zA3w*fYxU+G>p1Ovp!JXa_`(RvL!#i6@-R$tK_qIz>3?&hn;y$XK-9O02vwp=hw%&Y zyN|etS$urT+_8}W1_)UY&`Xpq%gY$P7tM}ugJuAIswkJ2d?J8Cm|5Dsi8R9Hg^i!j zG^pCb8eUtUy{iblxqKj{T}+2uUXgT;s(SzsJr)9(Y&WqqMD~-0;%E@o+8sorP{7+k zeQ&|}*VtvwrksLbcpfbEZ&#sia)Y_#qx&uzsdR41Z5EYnZB&xb4OQL4WaOxFHY)PE zAif32SbD)IK-NAM31g%9$z|LW@=+4%VYBfVVZYnete__5 zRCR30RT6+eRe7=-I(NXrs;YHFE|n6ueOrVgf-Vduc=@Sx#H5#? zJ|pOYHdCS^HBXYket{7W<&d)P2d5-rtAdCTTm67A&D`uI-_5!qpH{Io6S39zVL?a4 zR;kWTRm4`6%!sZ1^$LR;UP55FJ>QWXOkqY5&bH4sL8LLU=p$)iy9(fFhN|$fgKvvI z@n&H~m9V8??l@DPD1jjLMO>FIS`H7PO-H?UmLbLbLs3QrE)bhPG zO1C6fAbiz;r9Q*~t8Nsvyki%BB@$nIj2z)1^t zG24=&=zit(`v>}y*B^ixsSkPm{-V5or^xFi);)QsZvz|(^8+eNH?m`6M+ZLT%g7M< z7aydiGp*!OqVUoOVy!7@V-jCpqN23n!+%lM_|k%S`b%pR6yISV?PHQNYW+F9X8ry6 zHS0&lsw<4p@^C1$JnV#)Rm3S`Aym>;$>n3&xfDs-R11;ZVrfX_tI}x62`TU}wVa0q z6}TxG4zT`WEb;dk#v5ZcElh_B%tGUa)PstS{*_=6Dq6EX?a;uf5F*Dg3JzQgj4aPhB zL+%Swq0{7P7+d1^B$dMXS6IV#m5N&z3+ovg&if=ycf^`6wj`{X0B<4_fZl6x1kSc! zXrgCvr-!_t`zMBn>C?rX*I;WVos&StSH4|2Yqn>i!Y{w5h@8AI1GlSdVnc}fo?M}+dUmEc(Pw{$GpnpK+V1R{7^4^cDc ze;CO|%;AAYQQjGDO8gz%n@q&dJ$z?>9B~mpb!QUsQ_@H^ex?bIiTJ6qixEFnX8*)b zQ-)ORM*Q7o&#X+3Z9=Pfad9Z{$VbReUx6h&1Lf>O&=a888q5{8v|5e*nLO|JA{4q1 z112AR_6J)uc|K5L@_Z*|Kx+JXnmlihO`hK#bf?Dsnmqjxu}F9{4|TLoA~Rs4Qi)=r z7*S&Dq+-%Woisf3)hWs>2I*cnrP<1x#wg@!(-=ipFZ5D$)uu5T!t6~Cfe9s&JB(>D zbqCavLxWeyeYnuQ!HjVDo(P8*l8K(*h{4V1^r}_vxwCLz3EP@|ysqSGHh|S3wH!u8 zQem>UyD3qfFnQq|FeNw4n_xlGPyy&&i4hE3m(DYx)y7X(&Tf|>?CzM`V~#MZffwPm zY{6Gx2|p>so3diEwH{VX+ft5A9^@-zh1T9~1J;IdKj1h(vsDSC12?U?F(67e(@n`T z#Mx4Av)>UM=Ew;V@BamUpvi+gU)96Y5#7RvRR& z7(Iz|4?Xm}s}DT%0IB3L;=w(RUD?BC#H@I#(an)V22jBO^d%rk=itGqelo3K?^lQX^qEDxjC;M|c!P1YNPWpGddm`Btx4Xv*Zg+sWm)qR~ z)oRU%4+Wn<|BMYLGr6YTuA;H(2SH&lOhS0iw%ccGoOcc4kAR@%9UD{ujUGKcdu!Fo z`ONSoTUOJ^s)x>?u@9ilpek5sRMj{RvQ1?DVajylTQiQLMR2Ybo?GVZ6F|ECqM`g7 ziv*BAzCMS^dF60?cEE&X0w{UF#$Vwlp6!_(%$oqEBri|qpJ-7HkFNl!Oyc%oyum^A zOd5`ij(%HrlTrq`<;K}$c5Sd*sGSvX$`_@WpU7_Hc3CV{j(?=$oa9` zexw!d+o1fUJJ~;+IB97rHBB}Ebe=gag4z=JXI%3#aiJV1WNxRUw|G&3Cbu5!#$(n z2*G&ojgy)|jr-#4M)IRL$@j=Uevu^ivrp?r+&a2Z9WayEk$|f0Ax?xH8pcmYQJn4fJJyN#(dRRVosEK$O9Nml<* z*7(Qw<4Trqj73i~TB0;%Q?lxZv+Cik4xsyX1ilX^#MrKmmM?vdw`QH9T418;Smufoi=uuAyK^Rlny!)#oyE? zTuHZthsIi;7^{vNGPof;kiMblMQ1McP^8Dd2LAD6T01(F+EjmN?ol_Ku~Qc>Gj^(c z)i_;6?lYd9VC`7b=$i#`pGREou$*+&f&7bAe`FjoReo@SM;;N5Ljfk2hE?Uz!)=0Y zC1UJR9)bzdX_J(SuAH?=GEo8VJThZ+;vh3rm82~?mBeb4&MT-Kn^`3r^)p^Vu)^q7P;@yGYbT0AM`#CiWr&V=^`B&t0%a9(K36c{j#&Xy@DoQ#J}sGCjZtTtp#yVmX_ zwp|0S_jCii$z>z-&^tg)F5&o+_f6xVygM9`@+H0^pekT!$thhbWRxvc`2$h@>4Xk) z2c@ItB-)%lKeY#(u_`!~9`$1dmJ~)=@zI4Gg#`3*@Muq$O!-xk7bt>$^J?RjAt*2eEZ#wZ~1AT%=F3 zI|Fr8j73)bkT2SPeoaA15{ywQ`AvyEbAN20QmV`0O1Egbx#nP0C8Zug(MXXD6} z3d`hiHFuCwqI7%x6Bcv|9h@ssNqHvVZ^qymNh1#!!rM0O<3dIiFomC*=MH8Esap$9 zCZJ#%wMcrSDrpaJC50;JkF7cj%t|VtiWK69MkAn04>GI~0@rVsa>(|LKIi_og}Kk? zn56My2_3vUq5~ffgow)z*?L`>DzRdRnq{DPDq5ix`=^dpaw~TKCcT$-$)xwYf=Tc9 zy-j+*?#p^~RWM~jH8gH`LM3JWkyEC#L+jDM#o6`b`*>9HDW`i4SDP+PngmkviXpx98eOb*pD)kYp z{_0LE8Yp_DxF%mMCcRcn`rR9H(i($@lhznKOj`^dOi}llfa+{$$-I65sEuG zt_hJ9R4`lP@i5Ow5{9fAa0Ln=6IC$JKsPfMcU5`TDCv^WslH1`*T%ZY z;%bn_QWDNmBL@&&8*NXz0Je-|A>VTV%}N%Mf)a_9EEZ`?LSOh_x-4&z6nyCj&3_yC z$UB_#jb?hmL^f?GczMg(p*+n4d|GLw1LCZee-SrgrI8W@0ahCMEL4E3G?3?F1Q7hC z>?Tx&-9dHn<$vn3jN>fR;FIrL=^*QwKOY8qQmDbOejufxL4obadrJwwIx!k(M#Lk@y09 zC0C5`cGG*95zt7oZJhUm-k+N1UV|)-gh~O%LpwHZ#e9&}$Eg$GHp}1OMfeJi53gK} z>kcwCB+ToEnrTQYqdFh0{c?c@#x7+@Pv#(B+AX1|pwWI-Lr`HiuZEy)1AU19NWriZ zs;S#Ad`$7u8Jw{~3bNROIW3U{&{)S^fmX<<92n-#w@3f;lJ+RRG1-rKN$)>h6KGW; zaTHw@J~mDg^)d-cWOI=nNlYBJ)ULk&^sD&&r@Plw*BbHWfIvwNc58$d5F6$$#Q>$HvB-j9+noc@V<+5Lg{0_xzunSd&7SV>;*DAUT5TX=npu_K& z^HLZ!tc_o?083Qx`FTDz1#!#mW`-BM&GG`svnCv<*a!H~3$~Z!yU@@nrXdbtGw+p6 z59D8j;WXTxw2~(76kx#61$(cS|U_Z zHWKs^=A>w<+FrDHNKT@B@+BQanfVyFnIMuNitMuD#eVLTj2!%8O*b@Po+j%_@w z<3V_JeS1ZDcMp;Fis6@i3hq6w1REM+jMtUf45Kcu%-+E_iB@LgjJdorn`FpkaH>N_ zn)n%Hz~z;=>5k`!R%Ua2jc8>y&BusVW^dF2CdfrggNoUN1 z>Vu?oA}>HDwQar!_Teq?OFN&82OcyPte8F1Ju~BgwkL?Wu-+ev);pdgSVhyQ!0K3l zS?W+(_Nv?b-Ne_ttHq~R4kvqHKLGs_w z8#>HSC-Wh4LT@prv;ntO<;xfQogUyAV`1Y2VI2-=#!AEpK0PQ9-01H9 zxKZ+iE!P^Zm!o|(HPenjg&DojzIvC@{)AmuF(h`#Q0xo+O*L5M}-uSywZ|?N-mNlu~?yan_O-92qxFytQC0&wf>d$-Nq{ ztj1tI{@I~?CQyWYn%YiU9CV?zl0lz&VtH$|+<>TAtfv(48oznq{S~-hHem;@wAUzU zgTmU`)9vZ{LFt-wn$mta+y`UPWKD9;bUrw28@yR0{p(#MML?J>?KRfWYsjm|YbvlrjY+RMh2 z*vrS1xVVm29bv9$=?)Z~16Xr5D!^l+oQXtI$j*PgV5(;a7^CYt>{uaw3KK}Wi>Q`| zl+vaq2Rn4%^oxVlt~flzlat5t zPt*nhNaipyzcg(&0Sk#4qU83h3L6_RqKm_vD4)fiSiGw9u`vIkl>v*-LPY0lFQ`6X$@c zv;62%d|rwNI6z@ijlTGPnoz(keKV<~AQR#WN^ISo&FGrAcOvbWn!Nc!MP3roI4&N^ z7mBC~1nru7a?)xlXR9TicKvH=E z`c8nRDF26a5SJcN9rOE;ar;N)f;=4!sZ#9ow*i>Rlk1%kJFh}We8a4AnFo`AU1H=e z-v=rr=ZzS9w=r}q*G&b1VsbXBz)pQ}G>$Sey7YLd{ z1PW`E$VsC04?X?v@-t03$NhYt{IgPY?#T1t+5vB--!8BpD%|xeR3V`_R`OPR_xPge(Y)Ewy0puQrP+>Q#DT*HPb{k`sY>baBiQ#c&gKZ%pa)$>i$QCQJiXo7fOp_IC^Jfho^|zFE)K z8Wv<%t3ATZ-#a;^!+|JZs1g+Sx)lgQJ}YpO`2B+Ubi=BSwQ%jzMvW-mld=QS_yya= z9Y@|1QK=Y+eBokBqF8RXVqm%OPcRRy3Cq2{Zr+su>Ra5sa8o^K_=xfRlVpKweC*cV z7)migpvExa?|YCmFeSHCc^4Cyl22GkF)I1Oc#}Um6RSl(Ze~7Nb*-m?i8ZB(Rc^O! z$ddeaTZl}YrDt@)RESew2&J!3>;mp5Klj1)`5J>qE+g+h)Xdw$;|wa3!TWs>couzX zwFD=T-We*sk=#cA2!la;m%GUoYDs=N7~{0{^-8v_$@}DlT-q>8&d{FDP~G#P0=cgN zZlz0M+k+ufl_jW0&*w!rDnAa4DtX*yX46La0s&kvx5hRF;BK7!ZO2*grh5%sV1K(O^|2J+^j))BW_ArF~GwmI7bT#^Pcj1XY9 zp#Vl35x}ZRWagTZ9dfqGOg!$1aa;rBOdBE6beSoID_|q}4GxUsrrz#Wb;%`o%|?$N zw`{awKmZ&4bhTPD(s}HkQg~74=y6=_&$czpK87Qey@_;=Aly5SfdQQR6L&K5Tx?l* zI1>PaG_vE5u+?9xWQ(khVQ??;{w*)d-r9+)iytYS!@Zj??_uA)+HFK2HtSXESS&oj zEtslqa@4qE<3@LcP|?=8uOZwTbVu+PY~HNwv-t={BiXj7%SVuWY_T&W*u0@YHsl0{ zoq90)oWxJ;{3L#&ze)V$E=}TR>K*SP6er^2W+E^FWF6j58}m!lRFX5Ngx|>o(W&@1 zqg*hO5)uRQ9RV<00NtuDn4)+urCI;nk^GZqZ;uRTb!%RhLYQXmP4d~RhgWebhkd+Z zh$ign*m2!Ta>Sw|scxk}VMi{S!$5G;K4G9vvT91v7x8EALbP6l+-nwj$;A-A9b+$? zeYKiAXEzTZOtx9RxuW)Ilmo#_Cih_91_h~CjYMet{-sclDws+s$-b_eBCl|Jy1mVT zT@u5w)FVX;jV4%l*w7FO#&2lXuFl4cEQ$>c>=He#d)*?;-`hT7SV2K8(36soj|yJ(SiLbuMp9{J;+oQv3p|>uULmu zUPngV*^eVYhq)pw?v~78fE*vv1}abTEZ;us&?ifW;Q7l;fCt2O^x~AKurG>KS>)Tf zRJpy9o$Xx_!np)OAw+qq;!W`Y`%377P?Fr1M}iV+;FQ#rENFv6HCre2OZ&;WYYo|D z6e?aE$*(;HaIqIpBZLI=Bp?9j*<%?gMG`1J`7wcpvLPI{Cr5etlXUfQq1wD2X^#Su zw8K?(-rBHX-Em`fPggm7r`g*X+JB|Znje&iL{!WZMRjpXDwsgiuDm~@IHxzGjGB@OgPOC0E_(wkH9 zfej4wv^cfPKu?d$Hj*>qBuEU!q_ZR`ALvrn!2Q8M!!>X=TMm=XDJGp;OgirkSpzY6 zSOYP5SOYP5pecYCt${v;Q`{IJF}v7SOVTjRO~c+AhFl=rISu2^T6NIKLZ!9=3|eV@ z34~K?H!>z`l>@deU(|nhthVw4H#M)pvaVt_yJN(&ztg{hQJXwlg3|ENL{eT{xZ`zlhU5 zlj!&e>}mg>6RkV%4BA|ZHpO@fl}CLs)Q{$;Lq+P?eLfj7O%_ zrEE(-449bSZ_2l&uaW`iVuo8^7N>UM)?bUuHj>NZq)PJjV$v0olymDhA}H21(9@tf z`uI)^P<7R~Y`PtTVqF5CxG*TzrQ_v6v92A*Ez4z`MjfW=%5faMNCNx35cFOe6ziMg zI4-jGw>%EkQiEa{X+!k}R&PWNofHPeGSY?4cG87T@u`UFe zhkRJEDg*gDB4O!-Z;V^5U!|!M zZ18Gbg$dsn?-Ug4;&I&{%U%pM6Nq+@5LcYTPqCjBMnp@fi~o3-X(U zKPwH2b*&pZPMr9bYtm~>hc`^7N z$tKC}4w#kfB2>P-I>jCBTbv!89qLTqj_W?;U;MBJa*m$^ZYl0d)`vUJ#XyIJ+B9?h1~Od z9k}PMmV16bp?Swn|gB3n{^d3vzt0{&+7`@^EyCdx#t(lxaTc>anBna z_k@_ym3!XmhTegDhL{QQpuRZ7o6*vi#KOpV_jEkLb5D?HC+>OiP<6Zwdo!^@PRzOto9F6Bq64ws`K2?g6wV{&q#SDWQh9 ztVM6Fxvu>HmmKDzDT&L^8pM+p5unQ_5yoId#!@L276G%O0?dV)8D^@P!KXp~=NE(i zPDX!Sfn5Sp5Gig0pOh1%Y+IS_Z;;Yz(J5+U*M4%Ouq2$AWQ-u8#302dbw|np-H^h} z5GjiM;3K8JP;_>$9E<~jJ{MK;_ftGg$a7E*lj6To5)N%)RU{mWh~V@RkZ~27M}X#* z&P_^Yib%5Srq!=X{)3{Na(lU)az`kq-1%ptlArRrtK_FFc2UW9#47n4A#2@RCTrc@ zTh_V*J5wlY-Pu9by3fj57@f!|)a&kwWvz~y>W_AVtYyr_(mnKIXsX6mtdl}n%b16C zwlfdwq)^tnXB^gIE}Yj*Qw8;uYpQoSfumL`Yu&8{C#tSL>?v#AqpMI5`C&&{>-K`I zbvvN3vexNkvevzQ$y#?iSqldEuCmsBZs;9ktq?Oxx+-d__n@UMiLvf$SqpqEmbDyT z^RgC5w3DoLcHf%naCUE?smft0rX0JieDOHxZ!w&~1ljGjIe<-Q0MXabOI?%Ok+7fy|j$@ovf$&1%a?rsdviJ|ZXr zd?x1`LV`AHEZBU8K!yKIKE2o;gasQh=V8GHzEqwnX&!t}j$6#L8BDg8f8o7w;9jco z?e|N4h*m@;#Q-Fe!CAkwh_g&sw@pBKN+FWT0I9xJ#&$hbi-4Vron}NpJX7eUotsuT zr+g~{!j93UA0zE#wG1xHk6&aS-G$VcLhzF=F~Z~w$Yv;r|Ea+e!-$juS$xjiQyOk& z#~+E?$`C?tSz+S+v>4D94sv;0r~(NkM3Dai_8_cCzX&)R$T>l|pcRy~a*nE+%Q-={ zuz4frNFB^hI6ThfS4J45W23~z<Hkdy)G36Z^rYHrUhbXS_8mh5g95dzj;qIqP}adb-P5*ef`x zNULUjtjEEuFjd}Ef<`~=hgV8fTPETcR?G zEh=h$478}|Fpl%&jlLOXp3d_DvoX#*XP#pk2oPion;>f-?4%(eAd5>_R1_545Ea># zT_U1_1bN@@sbBr-)bDri%}u*}{(t?1+rL`QId$q()u~gbPT`iCN5NM>6$-rHsLQhI z##&kxpUHNUo)$g4*cakGRO1CA4GW*FjC~p-2%tJHoia8zPDq?FM_vr!}70o`2>&N%+;dou1y|md3nGQ|bb7b0NOgkDJV(DMXjcEs}63@gz(S zB`>&ekO41UUUSzU#XoT=t88`V+`KEiop>BtT3_Kp>^^DYg+&F|0H}1x z2G3=oBo+<#MdE$K=ndqX9r^~*Y5dZ@v?Ayof4LZ4FcDoW&Ou`eD6lJz5TQ3))5VBx zfQcbp{Ne58Ecvr?R7Vm7H9zaw7CSA9`lE81rUsg6u__7T+*f~agTBr%JLZUC~AUJUvHDbcxn05<)#m4|FC`51Vy_4myaAaG#8X=sMzP zsE}Z&%1UCVU@|L@A5j`Vl0iz!kPosoC=25kCp1@;kqz*S&-?yjU+U%-_(-<Yh0z@& zX$1nXOBlWI9T?DuA?CiwTTcpTQ$vhp5_x9WOs8`8zZ zHQ}e()E2G@k7di^0%A4^MCFs7bV;de!ZjUi0_~x{*h7RF zCOw=_dL*CpXg=w3e=mVE)KmEq=g`F=#CF!QG=Y_#&R2RS2@R&|VGFk=?!ma`9N^Mn zkXBz~fg`@bmv`A;VY-sp0y2dgVh#eYSNNFdfS|qbaluGs;>BYHkVSu*-Vk%(=oOl% z224tx2=8iF9lN(nwY%;9S)1GLXWQF$!y7NV?Z$zSy;k2S5-gg^TW;#UE+!fJ zj)?`rU%uvb;zN5AF9fSJfWfZX5OT5hxKCbB#-iaqc`taQzuZkwN9-h^xG{xR>-Q0mHmShs69RYB%=Aw-(~NFX!Gktv8H%{{BC1joz%^AX{_*WgYOg+3@Yw}iidfbX$1FN&%f0<2JeOX=lcS4?ExGV?Q46$UyP@~ z_&ffTke;+7DWqQ+rOjhM<1ej48WjU6syB6KvgNWsP$Mpk`Q&y0p%@IbqAEi zF*&;8yjJQltU{)`k;7H*5$}0S* zD)fN@9KF6q#d0^OX-bK+#S)E zxJ&kL)YUWya8zJ)$$qgbS;oWdfF}wY2r$^y$NmGI?7q00!X?WIg@D@++;qYirZK}6 zY_;Ez9ZJraL5qs29nTa+F_DhjUZG=KznZj_lY(yo@ppz z_e_e|_(B$AeU!jMyl=!D1cvo`Q{|TFYV=_uhMtXINZGg8Nt&<1lFE zQTzi4I0F3sSS&9j28_tCxSFy8EVjb|i$#W=ID*QgaQbEvAFW2i#xJ3<%O&gqNNPA3 zd}0Z6xfBI2Cdf<{sXW@PZWeEBhx79rCk{VVghruqPDLxa^8^ zNxJzDjWAheU``nC?Huo`q}aKLc+%N0XyA@C_JAjp&3wcgFxgDcP{Q#Y$uFNbhKkAx z2qakhu>6Vz8m2(n-SWMFSxwOa0hYPuudiJ_)D;%%q_BYk{7ezESx zZ)LFQj<|+k)A)JYbQNB7@gCFFYCi%vgxK%?wGVXwvyFB2e884T0)!xvN2b#HO+BgU zD6RBhwo*T^hsZWJs`pT~UZ&FBjVe8ytz?60I|CHDGTv}PSDwg6a`nWTuIp`SRPWJT zJqc8;>&>ihfbS>SdYQ&O*a+F<*-HHqyjmkO`KJ9eS4(0%>slKck@#4yUU#zdXNJPN8#U_}*?O5u z4<6Tm_s?&q(o7=?pUzf7v{^jtpr&D4!1aPmpm6TugbCXtC(I&#F#9oR-)}J|a#GHa z+i-UHWfpU$(w0W!=f!L#1gy^1Yc$G#m93Yl^k5@ozsXkOix)P{v13D{!Sm}}yLl+;%o=h&sI!yvL7n7z z#Tw5oz;Pj2ZljXk>l`hbUJGac=I^<}a(wNQCLY6ETY3zyqkEb&Kf-Jl{d~I~!_V=c z&s8Z)mAK>JxcmP2R+3)ts zz6~87)_qFu9MQvW4Qv=1>aim>jQh;l1}EgNJ(v$~K?Tsg|Z!r^F;N%xgP~08*JGPF@gCWkKROY`UxBWH$v! zqBixxSl}=);hG6N%QFvit-Z|cvcUWCV>=WzD^M1jVV7?VPLk3uWG0(ovFvoD8SKI% zd-(#~gqg2XG3u{{M=)f`K_tdQ%L*ei=XVQyxr%3CZB4mKA>n z#K{B}3q3@=WmBb!WfM!6-Jioa;z3|o!# z!FfS}8Go@S{Ur8NL?-~U02XejJ+r_n7a?62Re9jC0s{$gZBjs__{+;{m5$Za`f-zo zav5afZJDnu=i$VJ(s}v=0C+N`3Kx?pZltU6o4Jv$#y4XJUE-$J3nn`f;QM(iWEB?C zv#3|h^G6-0MltUhS5n}VdEYv+D~u$$ZX`E?|~#Dsu2Fjq7~& z_M_-j?2BP`L4@Yi*nD9W50GQnvvD8U$G}<%$NZo?s+jC!Tg3Z>*W*{cXD7Mqz2E7! z?mgpqdnWXn4_y9XJ1KHPQ7<0Y3!6A){IXLsn#V;@Q#zg9uoJe?hDnj1pgHR*HH2%Z z(gZN8(AiCcg0mYzHJ|di3@V6J06e<9`+Fwy2avtQ;Z3~7wr&!4H%9^Lt2NGWRf8(x z;nQzK(Z2$p7cNifN9~|AsZpir^KjA5X=yZGEl=dkXL+*kNWoHxlhQ=_^7}ikpuP|> z{BF#k{~Wq3@SejGLw7yX#dnpVm+Wc~mo#YE9wA=vL9uPO3>$V23$w1`3Udz=&pNM8 zpjoPs8Ds#j>$4A(46%psPJrX$AHNIbP%4QSaL4v8aXQOKV?PACeX(!oaH&c{YTOrW zBw&>L!fkR)2KvkA4PzFEa^W(Eu(Lx{YG}hZrLGq)568k8gn=1HsT8b{`0l`yKv4n^ zZh6&EJsdWei!#N`6Uk~={UCn^s~_KTQnk7I^>nO;385!h{eo;9Ib!wW!s%AO&|84d zh4o?bm9?)=);?MjQ)bw(`PcC;*g1K6HfoE{i*ixaLt zz+fYblWm&s-bdWxly}WaFR4w$Uv9BB#SE6>ZgKrF?{<0*c86Uqc&WJ7?u`>P(uUp4 zH`0o#0>GKqeM0|to+S11eajL18Dw;6mK* z@Cp>SmMUAk^u&j*M~n-M&KTsw50qYdJ>p>(dVrCcDFwuQm>yt^oQT)YdhAGt>A|;#jf3eSTV#W0 z4I2m3gQJ81pfSipmc9_^%kb9o0kpY=MP?s=>z949ird!89lgZ`BDZ%I0>QnrkV@`C zHgF+z(S?*T_gTPaX1DILP!e72zWVW1Our(06@o9HHw=*Ia9452EKC;EFQ$8Rmj~=v zDBKqjddh&%wHrf>W#T&vvPoZSWQnJn ztk@(w%n2am4$~3FoJ+@YJ4}_09p>d@++nVAYpnmp?oE~CYRjD_p5x?B6K`~Kr-?T@ zOZbt;IjizGC%)jf(up59zI64&Gr{v4^pJGfgd#LS^dL8nY7_dog~=w=;mvUt6PC+k zSC-Q+^j37^#Ap+I*sSh`&FX2~^s3G3O$*~)Wz*|m=I}+A0w%m98ngi$+}&Xfeu8a? zyi)O{h4Jp&fq5BV!kpRwCibm+m<7>Aq;r9XdF#UX&8=aEe2KmQ46@^L4NEx>yVq)L zY0o5v0gvIUJBT5}`I~`H%ndnwgHxrw%wY5sxiskU-LYMK(U+)tHDVIpY2U{TMK2TN zkOz6!!uXA?nG|iA$f!x*Ug*>$y@xkFyo2jUG?<4oA=fm>NOYqFm}80>+t>9ZUdp$H zli6*4GIOUC1qjZSRXIz>knQqgj(=fh(d97iaH?e=#qG9_;&$6dal7rf>voUga%_c% z9!Th#+(B-1 zX-#Sl`?3UfxfyJ%VJk2_$sB<*HAnWw!DK8n1&y)b^2X34e-vZTq#F~o_KETa+)DNe zG6dCL;o`ygmhCht#EUUVO=-yP9~$*bvYU{hsCE;V?8z^5lrpb{-m4 z{(I5c)x^G-dPTxJ4?2x2gZ)Bu>vH>!s=o}KFLT@S|9>}|T6=EW5e%TD{ove2B^S>bs5w~4{GsY44ql4bmfqY;|yzTm;3zFm|V~*C;eqeKZ4@Y3}(a9OHMKn zOeBG9U0F;gY9?Y$6_kz`jx!(f);atNEOeQ`lron&HXh4^;6vYb2z zx0^lrQT;)-`KFOP1%edd_M;<+2<(${O?q99SK?w7hbcrENDp72#7c=!uhNn#b|nrj zDaB(h^I$@(nt6!{F=T1bv#Kg4ecU$2LoW^%NLK4N+jIK_SDn>nK2}8Q&!RYp?G4Oo zRc>r~qmxin?t{hcP6Fr`))|WL4njb=`42uPkV^N(+3Gh7u>QFOW``5iOWABc^Rf1} zY<4+?#q5`}+1^W<*}rw!iF;R9+hG-7X*0gV3=Y`a2&;$}$FlJqZYw9tPGi%TjW1>} z=nzW{LG)Zqv@+efRv>g>AxdHqyBw4gYoGf@NgJatOmMM?U1|O*zO2dA^_E~TJQT7jAfK>>0mQ}F-< zE6%RKm#3a^zBZ8}VV{28zRPG0QD=1|w~ZQ0k#8HwjeeO6&gq!M+*>n|u~eSw1rpm8 z-R4O`X_fyj~v3w)M5cxi(?+phE>MnpC*ieWY9KVL*q_p}xc zH6nSg8m%i}{d7?g4=YN*2v}c`Q9Lj%#W+~xBdDsPNW@7VgBPQt9X$sFI;-d0Sxoet zWISlJ$OS#ME1`kq~HrEI%452%l!kRMk}o)OG;F9vJSyU{D{z2FYT(+vk<7P<^h zUI?wijnn$W%JSUquL|)*1mhXnN0IU3vA$HCFVk#}oI*`P!NH(kfI%PaK02&T2vukOb#{+t}KCY?u(W8>4JnU!efrl@6?7|6?K=zUQM@B+57v4ob>! znpZ92fH{Z{09(8XM;74Ll@rrux2`}vL$0}17$zN9>Z~y+*zjNgxH5>A$CWy$#F-n0 zxKcbE-z^fHmd1u9tQ&n34}P-SemD`xMP;p9eVZ}CBkD*IA&@O1eum=|nB0g9oet=0;T;kfKerrxaY70w z&Frk4(~+D<0xolS2nrgbl-NX^$Ml&VbRD0$?ue4E<_>ghs-fz`WEXeX{rY`k-y1Rk z9q=fbG0~G$QZ-6nhA7b!KAUY>2hD>m#6b<)5|+My0um$nv5ka{nPW#)Pdt{&g-I!W zc&BnMs%QFoYDR<9s^{$Qs(P+&Pla?UKHno2Ejm>pca%N1=h^dR#hz>A8R#-58vbjg znWxVqwqOq)jdcA$&HP#fK5LR?hPq(S zso~-nT@G`WyGu-o?u|By-(x@T7NjnXe4Xf&0VE+#zrS6~)Ds3&Fuj`&V zfGH1CGd3^@RR_Y)D!rGQyb!{L%y~QVQ6e8^h}aIFpUEypYqLq-5tB8J$Yw*A&L(+` ztZ~vnbQB-PnB$v8m-JGVPbG%iHSeX(Ye^l^?agi=pD>^|zWPQmz(ni0TX&MkgcAq2 z%L&rd7jU61nS>Jun%zLYEO!GLEJ$u3Kho$1^2q~o=LsrAD+<;R*c-@4%};x};p@7m zBu$43)#!EIkTWeYo&-n-M(fzgnpv0TuO(lWy_O6SZFVjB){f*^`^MKT19NM1adHd7 zTeif&Hv*Le0_`kVNP}p&FB-7Ewq$SK8J4pb2_*JZ)dnVlIC5|XSg@(kbx)GupjbM+ z-t%-dasMh;lGDhv2I)btxUOlB>zQV_Xor1x7hRRKNX&GEh>jkhKTVf+wD?&y{<`&e zP~`FKJ1*IE_!J2fipWr&Qq&p7M#(v<8D&7sbLnL2=?-=-TU90DkJ{a%+(B%2_lV%q zbKO1uti9bM!czYZyT=_dYu?_%todnY{-Yj4EvyiomQOl8pY)kOidi#D9<~8l^00f! zk_Vd~$jg{D+f|vr*VUdm=AOjVw4K+yKuA_)e#~w0nweu#5BlNwj-c;!K>k8pwsA*9 zP)P+=ndl6*TNjhK{by!VQ5g$x54K|mBQQx?fe_BhmWAVXHmMMulTSL=B_&!>A*7A5p5h`;0{q&FpWkRKnUF}JiDb$HYUwq?6&$Q z@-K8TUK(7lqvbl)w6_!8#W9i7Yc{&eC5<$)3#pMwt)|gkHe&q>HL?o^cqpIO$S%$5 zUK_xYhPu~ff$l~8sqSSzsoiZmNS$2%^wXx8wN0J{SGa+y@ZkWDVSOeL;i*3q6;awYA+XElqgjyO_kto@M2ws z2^R%Qm8-~{^9QIMg(*&{dKwmfpT}lgq5-oJKAXTU9Dq3-sttx;I)G_6rd>&+xHMFy zJdixdi$zzG!RsK9kYr5iq-0FOas&4{hH!yM;cuw(t`$Cp;Et?MTZ1{yVMKGW7+tRU zVUsrHlVR89Dk{+sAJA;do7E(iWTh`+Zmq zZtkCLeeAY1f9%%&$%1s9J1Tvy5Wk8?16HkfX5j+XHP<5;WOF!KIC8MKLQWRe7lWHI z>x+Car&OCD!U^ueCt&(AAm@;1Bd$zw(p_JqeUT?{x)}EfWt`c;sHQ60RPI)!E}@p} zD%cr4!W}`U-w~|uk9T2PomUGB%XMNt>Li7`ec=;bVVDZ&Z>MlVwRc}bW+K|W#7^ff z4NV$Kk1cO3|!|y)F@CoN$_c?4P6u{PHQB`&@h3I^E@Ov1Ri!(FWvyQM;oc{{J8|uk4zree2^Y014r3evB>U$RwA90Gdp8)*c;8fKeqniSKJ3}^%zW6hNm-B$ z^T~4)4B>zqF1i}6timKSkJ{Bdv1s#@P=kh?A$WNMIqOT*JfO3@NUpm`WOH@h<>LNW z!e-TZStTi4t|vE1q_Db4a)~P}*Fpv~C1xo7Y9VL7iUHGF%b5q*x@;(Cz81+q{N)U{ z{CX;O^`vtO^PQF;7J)_aWbm&m@ zgB-*vuP>S^?Qa&LXBVYx%hvH-j2zZkJXQLTS!_pdP>mDT@KoslGt3Dq$RdR@VcGl? z83mIQ)^M5vBxZ5?#eB?0vdjelIUS8ml|F3j>oj&c8mW&?l|E`l)9R$yPDe|oN(W;) z8Z%3ROiV{hF&&MWrO9*@WScQgN6V&4|7@1&YAH|67^kB#nT~|Ukij>1*OyO~K4x&C zKuI)-x*01Lmp-$+Azb!V$ajD;Q>Bj^WBDFbBj0ONrB9d|`5t7Ye7E^2GROB?nnJ#t z^h@(S07$;qr%E$LQx{4sx)z$kblkr)WT6c>>7rb4c0)t;>#J2RS<@dhTw{*CMzHo4iDoid8RQ&SU{5E z0hS-AG_Kw%(Dw_d^@u12qlY_7SH;QJ?{+2k*yIqON{_3~+|x#LN{`Bh(sTN#ja!AA zCtPY<5$z*Ok&n-VFr^aZ`||p(Bq$Z82HtD!!Y@i;GCpe=_31qrdO#E7MS&f&VcBRV z--oDT{y7M@nA|iJr?1uaHifKE$u+aTO}3`Z4VJPulMQ5W6{+FHr1MthFDC8i>F*8m zavQ|!=J^d``=`I31?#uBLA+*Ot%u!$?MM#>$Bv)={@=v&tOftn_75WNzUU+5zj$zn zYggy3Y;o=Crg_$%NPOi?hd5~1N3>cXcQzMVhXO;A`l8PRkZ&Dv$P@d8MZ{+#;Kdki z!?E}w(Gl8il{YyZ3TKalqGK|JqL)zj-)YRkD2?%yCdQB=EIPEyx`DoX$)8~@&gNwj zX5jK6VV09MIw%e{K8M%TY)jp}l=+qOI!oPaIzGXn)xeF_Nk9P-a6^Y<Yb7#HC<7_WF2U2j_eEXI+z(8i^AaZ48O zYWH9;yuY?siV-X9g+gk4N4wEncm<+C44})>sDy-f*&eWNYb7wiR)!U^GkzGs24U@w zpT#dcrU}pnAMDWZ;!>^1c`r`JlM(onRCHl2^Usn+pfUKP>R)J(7NNA?`aU$$JQSzbVA{v3URz zSnD*>;fx3@Y{6uPKIk*W&z*0|*KYuc?6F#htWY=_?mIstRBtI2*A$ycXz2C+V&Yh6 z4?Hjt?C2ExM1G3>shVQjcYWW03vb(-V$ZJzQ|ykrzTebY928|MAG*~PYw~U-cKHP} z1mzO}2A&*o0?FU71ngQI-Z&YDaF$?@fNYlH3d5C@;!Zx$Q;NIsK#z@Wz=ffhXm0i( zyu(|vuBgT~N{AwWx|zGhipo~eE7NcWUrbGDqUd3T$Gve0fTp29hsy>)Q`xYpT{%kA z(~v1>m@q53Qo{&@v2DWmAYT>4{QyC>K~Vq3U~3YSiLy1_fbcD1$D`K9l9d!5c+0IN zT#8rl!es_;e_GDsm917-8T%txobdE+u5vY78N-H`CppTk(s)ZXUQW6MY|!6)mCpt) zReJS2-p@n~(iARTatG+V()yxKE(Ft@QdvO z37F_el~hVU z(H==>(oD6wN|0*Dw^eOCTkV9ls;$UYTi;f-m6>X$s1hPJZL@BE)5h+ks!3x{ZVUa+ z*=nb>Rc#_$?bNoaO=hcox~*!j%2dnq=!p?kq$!VfQH6v@pJ@yIs%*70+N$>IY_&7n zsL zm!NLocsXSY>t*KDswH)g9{*jBaOv(+wY ztJ<5g)h=$U+FxX=<@B!7C-W=+ElUuW>e^!G_%+2!4VMsUGnq9VoAxwEu7%+uTGv1^ zeE*y<9kak*d@AxgIZY!;TaeDmD0Nad$dvx?AG;Z&^HTaqL*! zys>+SS<~AR{s-m+|Ey{aH)Q#G-mIy#gunls;NRb0<&qcIs^su?qDYArDxFeglr##9HUaZ{f)<1I1$?VKfu>Nwqpvn;CT7iKOH?188>&FiUj&#+X={Fi*=^Rmp(U;Z=Y}g3_bK3dqnVmD zZ&bKo#D@*N5FI^H-yNoV`HVg_QGXLm@%H1GiTa!EBS2E{*opdEY=B4ixra5GzcsL2 z&}0?eKTpxkyW z_PS8oclX3^;CYLx(~wt2Z?DK-^JZ0rc82KuiGCbaH^%;ssnWjY9nm?&{tl1*yFD(V zwkNqU`nM=-f_@K`An0$I=~~JsX9s*c z*t3+bz3T6rD!t#l(*~=5r^kL@PyD8KSkI94^87#}*zcm#=(}u$bezz;Zhf%F9`7k8 z&6TfwQ9)iRXoUXV^gn&KjVu3dkN(k~*uEs_>oi0!Pb)~k8(+}#ZD0DY?rS5<@9Tj- z-jhUs_jMWr=Nk+1B7raHfxm|itM9STEWF19f4V1m56ahR2;5`^Qr=sTC_%oa$M#=HvA6FEF3J&-_I)pJq## z_uhS-v7%=bmV|)vq)2}$Wgk8tWAgk z`&abVHGhS}@f?!zP2~WO%t7lk5Wx(ue=m&$+fJpY^Vrm4tHS;7Pb4ys%`qR0?wzRr54s?e=X%2` z6^|aM|MgU9edEke4b=Z;s&oo78+Mq6CTu%KGg3M%SL9e-#C6yKQ>D|3<^V5rr}f55 zMCcBv)cbXL*)jhs{G`qSv`s&pnI`TDLC8uac@`cf}KLN`MC{@qk*L(%*lL`IV= z5RcO&OXum`coU?0BPd999YM;Iu6%dF4)KGD(YRRqP^bAIW#EGqxfZUelAb$mp#DFn zN*74aY1op97~~(GDqT`EdXp%mXSZ@jbBAp)x`Z6^X&5}ZGa8*iLiB(>V4hoRZGbQH zA@OLbeI&=3==&43zsCgg5%c%WMExTa_5U?h+9W*DTQ1=Vr1_&$rOie2(MI#aPdbd= zIZ3bPX8{dViUbnRZp}jp1d^4o*O*28q>r$7Kf)0X-#+Vdj8SISgg4dy_f+YcqR~4n zX~cuFC>%Idx}Nj!K}K(jqySchgTbbQ%)tqpvL(zx(L)pUf0!zL-i>QL90M#Q#(MpQlQ<7tKGbfhe>+EX4oIROwC< ze~9^)YypJ8`&STui22uq_-qMt2&3SAY^rp(BmSQ6!s=HoI~HJma( zt{{>+7SecSX24?w|1nj1v}pdrQ+!Wvj4&o#hyOz_Gj0a`&#BVmMf0CQ`K40)KP&bB zJ5_pGFy)rq|C1rd{9l#ObgulwRB3C`d;-HrONxk2miy)t8GzARd7d-m>o`WA<^rc3 zzKP&VH5reZoih4#gZx;N88k<$E-R9PcNYF@s`Px({8w8|`!7YG^aGmKu+wvh5U1#q zQ>7P*=9Ac0eNurDIl8(t`ogGn8s0vGiSU#4HB+T+MYAUQ32z;*@rvr>z46;11v!an zyAzJrYhRO2(2SKLfdxUjCD*xmxJ{->=*)+3qC7;jqJ#M7LGq`TW$C?7k7gNp7>w&G zxYMtCZ6K*YiIA#iE^AP=sH*u}9jfY!jjB>aLXSF`NB&Wf zA;S2R1}CY3N1asD(`VCa!TFL@(^GrXYJo?cRMXRWvugP>l^iXMrEzhICqfX%HNv9c{@!(`ks_7ZEX|=$k zPOAM!JB<;jqPga%{;elr43FA+^UCGeY(YHJiHn^p__W~ADTCben3z;Q+%deM-D9pwj{~_=|t_YA~ZL)I26^&^mftlT;Y zcqTZG&;UiPJ0rI<4UkG11UT?Y4|(qb2L5Pi{YYS2UouDXZV#5g1|&-~LkyK8HEwB4 zl9M#{$YT8{06V2*j>6`RI>S-$WN|jobNk}gQfa8KLz&Y{W?dHA_~E7KY1~;47E+=a zf2Cyd?aptb0*InA;A*pPw{RlR2bhvrQz{MUIgIq=`7ti(_A;u6E`+{R3X6-z84%G# z*$JALFC(O%s2d}li1Vdn*B5lT2ui>V4v6TyWi(y2Q}W>jo%v2Uxg4^n34?#n-O_-N z`#VBukhvs>maMVN>CCs8A$EFr39q3@Gslbc(Gb_OO6KTd^bke*XeH8H`s`^<{ZlBj zA=CHL3!le!7Fbz}tI=N&vt^dBKoD{Eulo)gH^K z7J0{Vs^uh_n`n=biS{@!{Q{XLkJDTx-+348cw}EvGRNb7CV*HQ!turW2}s^lGAHD! z*lRuOk-eGgz==h(K34{}drm5fwG`PWIr?(t%!x%_^*QX zvUxEt(p_rPR)WMA5KHzEhTdr%HTh0J`@2BD3g(d z_yc}c6Om;I0+dN`%30~r)!+AF-Y^1i8+y-^NaP3sPbURY)q!#jcWRRrO!T>UB3Wj9+gG} ztoYGb@zSu|JZd?5i5Og6J6$lT19KP73)_+K-PAct2Gjl-sWIH~z|cu*aPcERBHBk^^qYxorP>WV#JaI)ZYa*08;i=Ju;C#<^zE+t zP2kxn9p$5d@)xBr<_|T+{oPG7NuM%ILEmQbn)7a4Z#KzQeGYG0mM+qb63Ct6Wn0!otS3$r_4(>B$0Q*V=r9wyTLnWdreN z^GVl8z`3Acw06?9jnxw(OO?mkCUO`NprR)_1Pa9`Xnt<&lS|h*mhb@#a!JPi=d!6y zh7BQHpDkOCZpbDTq8sx`H@T#=H+H0;%~q(XFiKIv;NDQ)PFOUc62>^08xsg_;i z=YxiZ1L(-fbVT)FdigvNg(Z#(OWc|-u`Vp}^?ZqI^GSE)lkUtVVT51p9*1R!L%eI9 zAKlo)Ig0yH;uypM+jfbN%w#lP=@4(<*5kp@iIL4r<0yU6!~zR|3Gc7UK0+iV~}VeJfWqI-f%0%2KTEWpiqfZxsoJSL>> zJNXjFh9$n6FOh-qy?lw|LKydKx5W4JCBB(Yx;LM6dY(Z~<&&PtCq0%=dLp0nP(JCA ze9|}Nz2%@+u++Ie>W36OUrs+M6xXhFTCOXEzExFN<_cLqJs6aTE-3RYmxzmIn1M)g z2>d;S*y0LcbSy&Cg~9@Bj4whgh>cN>CA6Q8@qrQG2aXlHEAa-EuS#N$TL7PqOxpeZ zaS4}<5^Is7rS!>orl(Puj~uFEL{tGYQMsp42#;Ld0_w_fE25xkPT0@{csLs&XKT2p z7-lBUOnq^wL8e@bX3cVg%*6kwFOC{yCQesJTmgOPFt_sI7p%Tw{e@a5jxc@b?{$q1t> z5ZYZycLsm-)rS-u;5`U?+~y|cA1K~{dWZz7xd_G%1vj_SYCTK zLzM%P0OBpIGO(0@b=r*br7?uD^_CSBpk1RB;ncYB4k?+u*M{K0GcD{sV$el+T109F z2KQA)j8I_c00x)D0;TjTDZo`*6(9*6coXd;3n`%h?=k+YShR7lMtLm zOl6)hP!XNJ#Li=Jf+eDb&Hzgu$i_}i%ZxFESWE$>$Bop=FtUPLo|gGMgy{tY9Y!J$wySyGQ#_! z@mMtw5+1a51UV!H{7{9_=|5S51FsUvDJ4u$`4O0);>7A4Frf=fuyJA$L)PU*cqX}% zOmGRLX?vJewAh3|`^ux~o?p4PJqe6{n13wvM~xo~y)S$$^v46b!<4{KP){C77QW;e zQ8DRKU=Rzu7_a%)e@TLJyKYSL{}>OuKiudU(FeBwu={;@+ED^;_ta>oMi|{6H+e?% z5&N+FqXX%~>wE_N{_NwTH;y!UT=XZw^>Y`Lt?T&qFn5fpy5rey8hjE#{Iu>MCLp76ad7?eU;^5_me02 zLM;X$>>oM{%xv|r`vcUD9VDW9aJvt?KcuSwIjS^!*!@SMlsWJ$`y){EG3YOq=#

<&{}7v8j$Q;7rF{E#crBT3V7UexGe_mDFoAJiAgeh82bjKof- z$;F(&bx0>Ab3zS|xtnf2Rtgbq_OSaA#qC-7O6kJNRrFZCI!Gy!WyL=A!10CoxF6X+ z7|^A`3$-XiDBKrc^Eh>qkwh$xb=Q530oUm=lHzRz8%x|r(=Ra)zrpnTGdkw>`bK@a+r9wG$Cg&$ zEh7gF%w>S!r(K(ZoM>AQ-%Oe?66R14UTEqhp8QBA%;`3V097eNi&jPcqW7O92U(oM5ByJS5XjoJ8bC`yPQSNx)C- zqAM!EMB^c_=t+}lQDXh{WQJ?eOn)M{z8*0{y~C>oyPA2Bn0YA(=3KN)R29bRQ@F^H zi+p=o@ZM#7J0{!4)B8mm53xc2!-ELBLA#0YD1vJ$fk6LTAdbY5SwJ<|=d!I)bVV@0 zKwLwVjHeP&`HaNx7OuCP_S{IRARFHty(K=}xjSB^I*c)Q2K-Rj(rpiw`N+Z^cveBt z823P?>O&|$)S1aKBC6jVsqjfmT0A^A$gumC1aP?b-aF9)eL-+x{Hc-xyc#ueSHe-i zUWOm9`$R9tTYv6*0@pR-gqSrG#G3OLEygn<*ba7P9X-hyVYl9~T%wZso+P*N z_zB+Ae7{M&^!=O*vecZ*R&5(jiA2qDKU)$wCS*Lnxj)!uU7AMgV+`RmrmIBf$-{(8 zr%DH4B3WjZ2AOckTaJz7GP68chk|UgjBa>%9`nOM!Oj`gm5oWiNDLkgtT8ZB&3Dz) z-SMb&RjtCeEe|&Jv<4c3C$6o65b`(#tE!MWerh0du(q3JoWPdJ1O^Jz*()Kq#P>7* z*^Eb@VP}o|&iZ9{yn>xoU%_`oS7^GTpAP(PlahzlPzqCA6v9T6(k!2>PFoTZw?nJ- zN9v3dMeaF$G|a#9Lli!LVeSlei>7ZH+WPqmqPrZsYCiZ zo%CbwaFxjoJoEz<7LSv|2qwX_gIu^P_M?>*(@zZ|B%&`Z3AA|GXJ#TzV5>eeX%HOd zz?zMZLt$MdJNHAj^P(cT6_`Fju-kaS#SC44@~GJTU>XxuqhtpxA0S;@jfZ4*WrgG% zbPn&QZR@QSL4)3uzSt|4yqGR#Kbw$8!@#aG{&k8J;Bh`!?o1~(({ikPV66*VAw*x; z?)zyk^rndTMCG$^&-5LJeTt&Ol%uVD$d*Y->w4x_RyX(BbbcPB`qGNQo!pNdh#j?U zihW+LG{5q@xjzO@3U|L^nkLE@<;-lj+QCcXuChW3U#y}e-}NAg0>xeKF>Wnl|b5XoI-SVKgQO6^B+ zX!p9%^-Ha_gY*7{W3)3wrc0N=f<8HuV)xsXGGrM6eQLv&TL@mVnuzRvL=*%NW)!IN>`*d9_2uF?b%x;ei zebuy7LZ4nH@JyYeshb<=)!0O9w3a69dG`WM-1F*8(6j*avEA{KrXU-eUeJVX>OL*S z=k6gUsj548H*ks3sJ+2a#6Wi;ZVy@fa*HJfi?bCjutx?dittyxr4ZE;q^W@g0_8=AW zsrzIh%%^445j`67Dc>(8h+eCx)-K51vZ(k z@eJxdv3&+rXM&{cGpH&X&!A#zgoSQj7|M0}VERQt!g6BNJE)zR!k+G=FvZFzvWZxG z@S5*_W=J(=s17yZ{bpf`iUsXF50lvbXbc`_2{O@`;f~d2u^CQG5<#|E%*Mb1^PvoV zBPkHqn8n8yomdJQ$R-Xz_^5FTrd(=lpJ8DwMoN!hOELqm^U2?`d}YDkz5&j zdo$XI4hp=*r8d{nL|=bL-)p~Qpq8~aTsYu0k_#qV?kSbMVIvONx2KU@Fc4@Y7s5Q+ zVo!MyM^b2SXmh9iG#Zt%#9*g=T(Q|^v|*RKzJ9J?Pg*%p8uuhD8Z-z&mht-4-lL|3 zW4UT#!76>DR}32S*7v-S~v>1P3-Cv_(_ zDB{8*z?MEPlYto%Uo}?s5Lo3qqFBPsATjg(v@?EsvAlf_r?d*s<7q5}bR9Fv0ZA`I ztA5DI`Y<$MM-QQ0Eb0f8Fuudp14T$@UNTwh#TwLOdNF89vXKl5z?N|7By|^qO`EQ` zd30}SP`m}yJ-;~aChORgu-GHJ@Em&u4l#9Q1Xk%vf`GF6uYGkws3cFs+pulb#LA9x zFD#BH#b~EtLHm?rWFE0%iAs6VpPa1*h^;E7jzKjftjB&!Xn8ST*G@NuIJ*qe%jp;U ze*-;7Knb`#7Y<|f{?2T9 zV^4aL)~y?ktB&5V{%>u48(u!-nHN*?9`TnPLlPE3C*0pKLcvIy!@&erl@+UwSEzHW z8lgt`Av0?ITwp+wqdj!T3Bxwfb-*gs#sh%p-2N0V2t-RumXmN|Axn5L3gSH3AP$F} zx)G<2jiQt`AM{X<>!BWJr;ARW_k9>zsjJ2op2_J#Qq(lHBWlZ!TBt3*aLc>bWS-9_ z{W72Qt3Qg`k|hsnOO`ySEm`ugrh~kU+H#h=Roc|;uz<0E5fu-|KMXkLR1kZF@hl;S zNn3MCSPF2t)0Lvr+0WZ3^IW4cmrn+8ew{6|CVC;01i{sqvjpQnAtl%yv{Y^@CTeh5 zAH#8y@ea@hI2->4Zg!>v-elIF04nKw;VBTW5s&1=G!MUG162#_7aRmj2iD7Rq239P zz|ME!zAJS)=eGcOK(R&_s@kItBVjR0dB_+uCE5Gr(6*`Hpb?>dv#yu~ zU}(^Knp+H3cv>}3u>|@+06ZVT2K)(yQZ&&-DYxZbg1fXRs`MmBNoczC!NjSP2L_pd zkak#ejy=;T&#(N{QPNCG3BY=_8)zCdc)vJc?MBv#I!QI&bG`>kB3^$G7ulp&v`=<) z1#?1+t(<6!%f8YHA=ADosrE!qddE} zI3yb7ZJ|bao6{%@wMFDS*6M;;6un|uZu>%Kpf4aQJurppRB#v$nV4O`W|aw+$+9mG&>BW{6zf&dbRP)ON@zFg z5Mu$yHV?DG^U&aVrkf4+tpF5w;UBjIuRDjJi)P+|8R(u(Ak)l;xgy{1J*!|~m`kBZ1Pc;ohM~4p9WEZma#IP}*mtaWr(r|qNo&B&~_xkV~4Y9KUY8JR*QSsF>J*_M1FG75SaV-x^P1=@%aZ+Wnu;=kpAq0#@99iU1nYEwP=%^?ce3t>81m(Mrz@E5xE+Aw z-082kZ(xwZLIBYodB_Qd&mhe>_0X7~5TEx5f}m4RwP(v2qPO(~h2Uh1=~C|fg+yn{ zUDU~A5pLBr3OM3IN6#f5SmUM-lTAo9!gILFXawX?eI;ioE@ce);YqeHZO}bj*l~uE z6j7j<^FPls}-o;GP4~u~+ z8+~DUt%^a~Z>pF+?cO{nVEUuyCb;8Yg+pLf(Fq>+onjmav+2JIYXA>$6geP{88{x< z4d*5bnu*dca2#y8kb8aAEvPyEM2Et$2SC9|&B53mpKwxhpX?To0GR-Jr!NgQD~!2p zn;?(xk^Z3Fyg-17R}4A}QhaO}Boyb`d%=X@s9-82Z%||m;x{OZHs-s1FkPuakP(cA$zI#aNdHn9NjrLMC7q~)R0K*$E(feclUAm5u>$mf z-f7<0NUm)FWX$`E7&JT4+j=Km8aZCR&?Fn%)t}TM3t0%d>tU{-*kU!E~7Wa(D7gr;3C5nE6C}?Rpu+u6RPs%iI zb=nF{J7Qane=kuS@LVjkS~0Kr<0vdn&fW%Lx8WX6g~=yVtWD$8)19@@ICY&f2@MCj z|8T1MYvhLwGI{}AbFCVrvd|^$6;CUUv&Pq1B6*26G97VO;-EbQ8=*YWqa3u4D&txg zt@;Uqw9T|`9tV?O(%xZiB@A4*cZlx8cZ}|%+o$`4R&*cVfbQFi#U9ygHINwP(H%X5 zjsiP%(vzM3=ofJ$=*|Uc;lG@#xpF6dtPN+h$2+6rm$W?Y{VW|@<+#`0EQWje2NTh6 zVAWKDVT!Pqe+^;w5L_@hfPJJhz8n9ZD8vic3O(3weorgK&y9!$Gj`ukfIi%)~}eL&3uLzqZ(MLA~^)FiDtxyxZs(t7;egj-j}uMx@TeGZoF4WN9jJ2{W# zo(2Z)z99FBQL&;pv@5`lM?xynxG4px81E({D4NfeTb=KhG}!S?#q^UP`3g&(z0Y?g zTR03(M*#cd*`>)oo}*T0T(E4qVlDgGoa-i=<$R7gM4rQsEu#ZY8t-449t^ve&AzuX zIYsZ6Gv-~IkL|8M5OWie(1C@6D56UH{nXa`y5f7j zU68v{orqCI&jQ@cHuLJRy~8eS7A1$_EcksC?Bv7+f)>Nps0q4}y6EBfws{Ns(=v)X`4)u5&;o3*_cLR@1&^mK z7^`s8{C?aJ*4WVk_i`{r<_XmTOjc~c%uGquY0(7R^&UKn7CA#}e2rznI~uFjhMh%O zzz%Z$$oHVOH#E*6|Z&dQYe0j`xvW z|K#r@U)fh$xTZ@~&HF-6iu=4Lg}XC``)9oLl&G3=j0_W^><9f#Q(jBU-zlZE*y+Im zW4VpN-L~iplj50c%6>Kc%H4(Jc7C}cp1P1c2La^3eb0T_J9CJp1T7W^S7p+zABye*8(0G#$uIlp)YaiwU_EEcH_#`{4O+? z5jrZVZrdNwhch+mw&bM0+eyN28%dmXp%n&qIPLSs*6_Oqz8;D$Ykd1|VzkcZS)bA{ zJvtNaB3PpqaY5&5BAZW17&gPnqQy`&{+=Sc$=``ZSEx?g1Ej+Y>WJEn_a#H)B+eE^ zg`H31By@G$!@^qUyLKNyP~t{_w=4k@JVqo5eIsThSzs5{M$M>SVCfv|C~$?Bm?g$3>l0w&V4CQ3&>!cYwicts-WNj0%+?<+6uKRlcyN5AZ;vY z#H}M?1pf1k9DGs9^Zv663OF z8Pu2+)6w4OlCeM>kR-~I>ld~!^<~kbz`EDrfIhhad!JR64o+s=X7P6+nneFU{(>8SXE(}W8eTyCZCdclMq@VfC9sUvmb;R$`PcL)*u2}^m|uizcieFt}rYZ>r)k6+Sr|~sZd&B zso29{SFg|!VtTZOJdCjv9P<)yGfHbU4On`*3JTyxtsbuVI1nKsz=7Eab8&FlqNyLwIv=M^X7ck#=xcNeu5w92-KeZ%BvO!rw zxTuq^1`=P7tC#~$j)y}Wlb*{IW=5Y`E@!;yu)hGL_fnZ?#VEyFNSzjWU<8K(ndYQR zt_@M9VaWOr1IK6N*30xzE14cjiO3~CrS(2VX1O;&G1ZNPi&KwM123?V75P>!~ zMl;Pno2B*`VyPGVE$Dz%?0}#?P9ITo!1AC1RsakVV93;XrKe_$i3{)b3&fY5q{Kz|2(=his;?m)F|GilDAA1u z_i9y&pW$%Q1B7v>kHn%>7Y_m;VJ~)#<`k=DU=fp09BawJb&cX!mxF6qr4r)~YR|FWdsYqv zz>xx+4}#MVodG4qX)nc^%jic9C@Jof0HCDU^YkDUN=n&IKDsOpPLd0w`8=p9c2DV- zkDp^?+30dz73wjJE~miZc+-7>E*M|!{uN`TKtF%n1u*PKe%f0AD=?EW5|^FzI+N4F z6bM^mk2Roi@Cc-eeT2inOdM;_iN0#)@o+B4LmauM#^6Lh-}Kex&Rd^}lwI{Dv_#G( zfSpYbSV&j;NxDn!Y8Lp$Z$lNvh@%%Z7uMY{x)m{?Vj%tA9mHX@yKH{q+JMg|@p1&x zo0dTmK$OyNa!?%T9)_#!c8Za!T3f^3LRK2Lx7bVe79RE80Cm}RJrQB;{xI9V zm~F?Z{ZSkc(0c8vkkuX{m=|wQyhS5bS@NPxPTA--DhGWK<9d1u6{g_evd|<6K~&kc0BAOxp3;^AgU2($)xxEYZK zFav&~ywaxg*#o^bF6utU;_CJ+!Vf~JPOfccoDbgI9Dp|Y|Ej|j5!d6*g+hwHf@7qj ztlL?~3wSJr2L>lrewPD?^_YP|cqc(8^9K+GxwmM~4UX?DMTswk2^^mcO(-~Kr+{Kg zD&PRJGyN*V*&WX|F;=23(3O5A1$g|g3PiV0%IXXe=;MM78-O@?@e^JYSd;t7tt1zg zTybUL=P^sUA;)e?d}pu(V|gZJ0eGykUz_AUnRfxPanqP@s&e@q%cSDeZy4qSRS?Vj zg7llM_)3jJ*`KD75iqevU!R1DIjmS7zZO?~>D%wp0RXnu;hMLt4rgtv`NA37>bw-1 zpw5tY=ty+OBnZONGhddTpf%CWxPBHAj|L%XL_j)A4Z+Ugs0N;B{Za(G_p~vI&za*^ zbB`H-f5s5ZsC_tpF5p3mPZwbdd>vjOdma2cUWZF-uQPp|tQU2xHn>gq-ZHLXYT&rF zw`B~4;NgKnq?)~MPz3Xd)Of6L!SRr|`inUw|kjp2h!yTrAkL@IKmC%)sG$7XI8DN4DTh@3CTH5{=BjC(OW}YmPXa zQ5y#F5MzWZWQ7`Bmu5}xrajG(Ynd@bnOMia@J0fU25OyDg8~W}Pa>OSI^T)Zpta-A zKvyuZB1FdxrT`FKlL|yMJ3>7q1PfGIT*v2e9gq8$d0ao+Aza4~*1B@IP5>?#2C^M; z{2&YnnU*~ZZ1(?X2s<%DHv;nG@rYctt+{HMdU%Pm*2lQn=;pq7zC1NXCn;QVn>GDu zC-G#eh?A*BnDrK$;lD&T<#0U>TvCkm@!1l*8Gx=hX|Pj%PadqWb6p3ZTjcNv(T?D& z#b-uFlfwMX6dsa^b9MwA>_{PSm~fbRxdlws#i$fLsQa7=rwn3}I00|qC{l*a{PC-b zDO?;%!AIuKNd*e1qEjgt0d`%<0LHPsDU22PJkEcTu!9uc%rWs2By@@hqlaW!&o&W|q?= z6o7s$yv01!O+^LEjLdmh(9oqc4fN>ZNc8Xl5yI@SMfmFF9c`D;F9@kqVB3d#x3Xvl z(6}7)VQW`|^q_OQqBD!Nis3!v2ANoxJI1dnMQ5Q5Ui5)e!`VgrbVTQfhiw)X1{_vz zSjx^V;(4X$b>NM4Evg*XRqT@mctxJFBwgQ{l*QSV zV84g*1-+1#Iak1-tsVhe-a&iCw%b3VxQ?e^sosQ-8kCdx0;o2x`iRP*DKUS z^Ft@XE)(6*Q7g*jCUhColbtFe=b+zJL8v~DujGA}=&_X)j$G+dbi@2wM`<EfAvEV^d&!cHjZo)tV}5Zo%HZ@CokmQ1mp z#5>%4bx(YJXBzJ?x@w@b`v2Si2QMP%3}tv{S0OfVamFKv7TChY1-;^6-!n;Z@OB=&;04? zJp4q{RfLz17fe?XrXn7gt}ejO;B<8WKSR^iLHsP7t`6a6(R3BD(&NR`)kXLjo~|y& z&&YIj7(b)a)e-zGnXV#GdptH>U4oyb(^b4_5HFjqF2&FC>FP54nCa?r{M4qa20!)b zDq?cSQ4BXn6B=OpULU!1b$vMU7f_wF4NUl z;b+x!br<~n$#iuUeqJ|SeKmewKV5wdes-I#z7{`kn6B=MpQ-8UpWx?>)797EXZPvq z>+$oZ>FRFydGmDj4fuJ>bae_pdrVi~h@ZDkS9izH+or2;!q3~Mt8d27&3KgZE%?0! zzkA^KR{XvdzqjG{ZTS5%e&3GYui$qze!q&}7{9mUcTfC&4ZnYi->>6$FZ|wt-@WmB zCw`~#`wjfQ1Ha$I?>_jw3%~Eg@7?%)7k{d-~tYsl*M9G9EEH z)4y3J!$QL77o$4%(48`GxWdfsjLsV5R-y|cIPR7ZyN}Yv5K|;t5q*DBFAS})M)zPX zPmWJG98bd?>|~Azz(!{ew%GuW%{J;Sq$ZoVl8MD=Cz!5!a!u_)W@}z$sXnh6)#nWM zzo#`QP$5rkL>CmX^7ZD3=_TKD^j}yETb1w5EQyyjBk|n9{(UuqJg9`kEDtX#f;8k^ zjCGuQ&J2-#!o^~AiD;|2?8*)^`PybJ*f7}t?zUP`j4p-7Z~Ak@^b3;_=o>y2kZ~UU z;ksTU>7Ex|F3t8=?=sCUMw_H>;KYVasF|O`HGhX2ep|DKpEub5F5Pe|@b@iJB(>d} zlhH0!N4nQjq zIWM}>#@vFbvQc9OqRrA-dDJI0!yHzVP)!T!DHM8Z|Y zkOs?}t9N)Vez6&4mk;*uH7CkGyTdfhbTwIMHx2gx>6~b|CPRbe&b67;?ThrfW|Td& zsDDpQnMLsb$a@ngyNV-C_-(bmC+SMBsw{~@+*guqRUu>S#%1irHrF=Trfs)-neLwH zp6>Q^PrFCZ=d@@1|7XrWeTHIR%u=jkrvR}^f?^XAYk|ZjwqoC*K-lb1>^uD5mwEH% za`V2WO7_hEk9~yn@%bAXZtFz$~V%bS5+&!nx#$Cd$mKaY~&iJG>y)k9+O$U*ifx}eMXdB>(C%6 zyUtsBy;Itl-bb_O-B_&*&xqa|92z9O6W-DrozlkiKAT1F)z!+^W<>8z4h@ptO-^ZJ z%3jK%?3!w27n3sCz_r!NADE@-1~O*W=9VdYCyTP{s+F(Kh=!XT8f2GlaZ1x&a%amY zS(II0t$bxhl-=skASt`eDQ!&IK^++u%MI1a&NHIyc83N@*%oi<9ZqRudXLJYccNPP z@{H)c)1g7qdzVw%n6eYID7&#**=a_U-Q6+`r)SY{Q?>G?8PRZ$Lxbebq*L0MJLhIm zwy9cKF(b3-RCX6-zjZO@5Nd4Zmw2#H0hPi-dwE=nWgClGPK+S4rLPEgWl4I zoYHh7uHLyOs~5LaD-FDH8T3Bv&>-o3#9N9N&|2K!ZqB0j)@lXsW$V4NZ1%Ql<%{Xk z+pCo?n5AhpW%LaXd9+CH{aN&Gsa8HeBO37hN{c)4$FgX+qgp{?NzJpS`GAZT79S+D zpL9yo=v?W0HjA=5tCgiQqU*!xVoHhNq;qq z^t-B+ff(kFD)5uHWr#gIdP(De^D0w4^}Hkkf|F;i$sPjz0xub zmuAuMP_-hS%E|UiXVCC!%QS4rqT%6cWzmfI@R~TV(F~L$^m@ybO=MB_NVT$%dTBae z+n%Yrn;0zUr6rKCCE@ly30o4pA*jRckCnA0EvwZ#GWF7<)e5rWX;w5XOK&>dl01A1 zhkvd4d@V#Qh1pWN<8uB&ENc);!286q7JMj(#|7b) zwOY$!`9`K#K3T0;XWUujIlRgTA2|amhxuctG>y*X;fGl~e5zUzul2U9_&#xHkd%Gu zE&a?XZA|Y0T^Wo1)78rS`r?zJs7DI6A>EjU!?S3Zs#by-(XgLGgXG!%-qHiSr3ZRT z4{}Ny_w9tNzCBZ|h={zF<>BC#X*ey5hG(mlxijMLA%X^^#48~8;((noBp&T0eAFpzJgm26QTBYb(lsN>j&W#^^d9S!Hl}Pci?SE0mChMac3jIeJe)m}gU2^uAQBw9km%RSpf3-jkft#+1E~McK>M3U0W~ zfRiV;OvCG0G`v!+lx9T3DGm*iJEuCOjk)t)7GzNEVZu7iDAXWxD(*APu&E*`f5X3z&pl}7@@&)3muDm+_|773PRTmc!jvky` zHSaOtrbI1|?M4CX!&$iDf?Wr0F3DYos)Yb|-ZT!*&Iga+{vLN7;(g>MdgxvtxPq~O z=M=o1W)I0oyNg!{MsBMf;`Tz_9u|Vf{5||$R;qxUNNB+Pi8*xbQAX$S+KDQ7T-;re zsjWHe z>L*iJA2cYCXI3Fh(oUS=u~2UI>6*8Y_!p?vjc-2Q^|ow3;_V#V;6nnV62y*w>OEca z4zj}h5=_ArQ3F|68t9-DmT+aRJ$Sc@+k4haCJu0L5nqmF{rF8KJY92YKE4O(xj&<> zUNUpldsWN_Uh@Vg<=xES{pv3xJUGGR#PR(e(igmgd4(8%lDjW{z6;O2Op8b2SwFrr z(}s-;z{H*4A~)}h=C{AM@UG5d-NDm?oK9d;G@5=_=Yy(qU#HFmDpPJhbW=C)8OyHc z;;O306rmrQ-FBl1~O9MQD>~o*fkR6q*g&J7}7mj#~$1qMZnj?Uc$AhnR~Y zNNE*^NIX1C9E*{i+oj_mr4~G_Ra2I;Ms>!Xv*yGG6s~Z|w_7a@kpkjVu0kKgGXe?h z&o0KxRMtgPla`a?r24uQQuuLv#omBKj<7qR^Ap_zuxRv(&g3`r43Z3qJWvJ{6qfOe zsrcs`zwvt5(uXvPg<^)PHv0vqkZ;(j@L;wp~uv4USf{ZlA4jVFLY|IMJ8;)5l>#qzDO zqQu1713VhRLV#}_q7q!}%@d%gyLtKcWUdMfJT$wdmM?ZrX#1nx!IX=qb3|Qn% zJPc^`vQoTwq+iSvbn0O^(HaJG6~QoY4Fm{xz9v51CoR?gARxNS=t+-9jD}cQap2uWwdkeT1l*-VF|SG=B4KS zC53o%QIAAO+AK)~*N{!kOQ1}oBOWYl+Ti#!ZE$?%H#kOmEQ4deo|zjQQMPrf6d=?T z`j`)3aJ-C5JwK3|NiL?)Os$zLFV{0!_U~~_mS%0W1F$d{0?cWCV2{^UJIH3;!M``w zy*6vsy;hHPhq$bJUfC8Eoju~axvv+6p2Y3~IvEp&%57ovLC)NA7)BlD9cI=(!BaZ@ zJ2Z80Xb+feg2AfYJ2=cOMdiZ2k$9oR#c;R_TMB;d7UhB?(nUwAqNpMkf_(X$Vt$Ue zhMu{%%8Pv~yUG<;bcY(4KRWk`ivJ=n*kiA2P|M^ERMB%$EkwezPP_sL$6-5qCv+#|8T;&5 z>hSN_B_S*#Is0G{HMy%ip~u-jt@^!9+mn6Mc2(nPdyqYC4_4Fm6gh1V=?PA(J5^8J z22)jNT6?MrHER~xQ&nhI^K-0O%_4iMp3nnDOYJD9>cumks#u|tsS4&mULA1{R+&?b z^Wvn2v+@M93Ma`)nX~f19%LlIv z$_$tKLIiwI92L0Mhh1J;~CpkmlU=N)Z;JXr1m1z%4 zQ}BU!9GEg`lwyTczbb%vL%v^4k*^1K%wp?Fw~^npMYyB7NF;?)CQ6ZGwYpv2|zp;hg^JS z_22{XnjO*%Lz{|cx((cT7OQ4F(`{2dCqc6ieVEHU+|1>obA!+lR>%NCcc}V_Uh@nr zz-!-l*fVeQgQ@?Je*?M%`J9l6!)g{JK`s3P=`C#J@Zp%qPmNzYsS9*|1+m48XfUGxgarC`C#Rh2tbA-9XekGKRVhdSicB!+_q2uN9^0q z+<4$DhwK*{LQJmY7yLuUFX))y>P5kE_4eS;Es*XDX&WO$TC?tpGt%yhGyU$1G24A{ z*6+=I@#(DH7oXN+-Px}D;`g_!Ki{`KSlxJgFlKKL&QjZh3*`0yJyIq&_rvGZ-6~wT z4Ymq5&&AYNP0C&UEpCy$Rk+ptTncV;i!@61;=G>Vb~X`j6=t!khcqNxg=B`)NInN_ z&ED0oHa7z_%+77Ne>l&q!WPcW+&`R|+CQ8LYJMel_4^Gm-~uc*P51Mg+CQw0_Yb$v zP46ErQ2U1jZ<+~qqsA|So(Bq723t68CS_15?xrGEDSA@@smt0_+?tQiIWjjDIF*6% zgXLOerxaVq5V`TaY?-I06mA~^KBVPDuas)Sjh5G;a9;Py)8kQFEY=Xd273qp3W4BcIlY`)^K3U8t0 z!hW9AaSa6$vlPY(&Av4_AT$m;ri=2t4`0^G^A3)IRTKN61BPg#c82ZJJ{>)vBn}JT zDn<)wpYni=uYj(@DIPl37VINDm#{ZwhSuP~A)0YPShgsFX~v|=ut)iPlh6!c8JUN) z`&iU0;3Kvh2+(?f^Cr>u$3^kxQkiM+A-!f#pBvn#CcKB!I9oM7gdNGRg<#Xi3uy!~ z#KVNCCcg-Sl+s9z2}@`nA+Tb6C5d?2C=7cOVDR0b0#zXg3-%6P9Hd1FIp~8N^o8@8 z&(*G^TSp}W#WJ-1+@L`m3V0BvXkBhWuK=_|VDOOeeR%oGXaYs7^r>0KX15N4 zRLxRJ2^ipV;uSm$l#pLi+5;t5w7}2J7YyPVL!7z!DrSXR0Itd zQ%@}po?widQx*q^NQu(modADwkb8N(7t~*g>`kHc0`$Uc;wiB;gzuSKLnvMABlJ%@ zrX_OiQ%U+4>j5`GOe;cP&Sjex3^2G}a` zgu{-N4>y?fXzavS;WLlt!ta-C4KW1L-=G_&jKO<>!@Om9V#h!hyf0)7OV)D87~Yn! zK0?Nrj5Cm`-$G|Vl8S(u@1wymAQb^Ef%NQnbOGNNT#=BsfGgO}*utCid@SgJV`dl7 z(;N0!AMqdpm!jUV4>HdNtj~D=XLLL2@Lg?&iM;409%v@jBxuJn861vNvRg!LFf6ufh{x zhC%2q67CVJ6bw)>41@jkqU0w-TpNYKvI=4t6$Vz>usxcITaGQvLiwmdY$2zzEn zz6c@Ml4l4MH1EO?R=Yt2R*YaBy|yTa9W4J*Q2!{#|41kxfmbkYOOeO|)Zem1#G=b* zqmEu)i1u9|9%Wi6W>!$buqqqg%={XnC7(E>bu4i~Uxz$;Z==K$W8UmkW@Kp!o~ zYe96~u7FNK{DJlHvoF>v&?)7R_8#f8K4VRJX88cTvpeIpGQ~9ZZngf&Zai5*QhY2( zn$akAs@%0h-Onc@kPuHEtgMyAMoMF1bC`~*bvAcY{LWTgpywBevwO4NNQDt~@VbH# zbC(`xvkBT&JDb4?=R15LP_KB{ZWnUN8U{RQr&s^Qso^@|+5Y5T>n3o!@8Bi?u-Ons!#pAJ7Pa$H#T`J&7c4BqzP5}Lt! zK2S_FB)Ed7-%lG%@KH>~L(bv$Y;Joou$>=@FTRQN?;ljV-A@LV@>i0!?>NkOwH{$sVYWk!CC=5TJ{9~bhAZN6v_6MB;?<&oFNxP{zm)VE^`a5{FCRR> z%u()#0L7Z}JMc~lduz9g2K69NoHdf&K-DcvlE%p5*O#{$02GpsI}-r*Vzv35HH_~B zKgU|ygCiGlb~!z*OVEujK^Tc0ITAZ6!#EfGdT?MTKF$kvYSV$d$^{?Np(|(J(7>0) zo4sGQIv{n?&clTxVAs{Y67Fn$#UOnZSicf}H6A4EbNCf1qdyofjOID=R@>npB#6j| ziv|aF87|<2bQiH^el6T3`5X(wFxvTAI86TN0m3%}lEd{izGkH+5ip~Vct$?_8d>r+ zvZNgDlzeA(n~oE3vilXnenn`iArmw>W6-XPg1yu`oT^Du``UssRGI^OI=AeK(_bGh zoRkm0Zef?4-gUTe8ae%qa98UqIQ>m<;2YsL(;U!{IQ--Kqu`*#oA*AHKMQ|WZxkMGViZdD zC>XrV=&X%2OXU6}{F9`!e;WR2{mwcl(OI7q|5^BFc4w^_9qtj_P5*=`IrqB-&?6H$ zDhNF~6!|Ol;sF7I$csB{1`su$Mm?5?R9>o=#@+B$Bjnd82PE|Uty#i5bH-OsbH{ci zM57(K*Ks$}d(^(gMJ}H}a&S(n4t#sKusR=pi#B7vE&R6m8Eez=i{j9ncJl+Qgn{o2 z7cP+XJe7RAwWXK4JaPpR?MY>TGcIEgjJ}h%1{yL|vkgpyEe{M}*%5Ht)j?v^0uB=; zkdX1Xo2L;21f;zSUj%P30=1*7aK}NBi|Xz^^gGta^-Ds#;Ho7?bs-lUEV&4-)Ia&z zpbL!|ofJ}&U-l4I=U_80TGn{^LJ@}1Hfn;8;qJl2lGM;0N4r$_oV9ij9>8TsOE7{5 z2V;4$K{XJy=+S)c+YovR?wbW(3{^ytTkEt`fX_xd_!x0ZDj(TaRY;NU6%jbweoX_= ziK&34rOhIQ#J#*@LIqF;2O}GG(JYC^;CEDwvcj=Ar@-kQ^opLwY~c{w20IjpBvYcb zc@gUv%`5+F?DMS?fRz`MlLy}U;01lvi0AP8W50_=6$Eb|9cAATKWs>RRri7Bm7mWy zY!Mp`G>Mx}&sbh&)e7hU_kA~?#_9hx!Nkp{OWo2sH=izZVN1c~Zc#3{B3*Q)DpEZy z-_UeNE76qIQRTp;PdOJ{Ow4xCCF!DH4<#@RhFkAIK)EUu{Osa{`#ixJcc9qPNIh$H zz#IbqNL{Vi#Y_SmP%%>1xTSSQ>RK1J6kO*P<$~+eMK`FTWTaN9LxSu{5Q}6OJ#BSV z#oCub++Gf@B4(=y-u|v=a(yS<{mBPJc?26$kio`u(UC(|rHK>-+Pq?s1#@G3&|*-5 zp;y1qGzR~OA(di8m4kdpKtg`ZnD%CG58dM49%?qS^44@@S8$}PX2$jaMG z!RXMe?$inlb<%*`;YL<&%Et#*o}?2hnkpyXLq^DXl*8pW8b^h-VSerZ{BHic{RjUA zedi;`=A-ek&gkw!)FC`I0NpbN-GcyQGFU5)fZ{XCd38L%W^_4~KU&&{k#+?h`pM9z z5JoJDpz!ZRESn4qlgUJY>zv=)?XgK;c<9}Y!$WUJT%K|1bBhWOy;p{ZVpvqHCIc() zVtDB7P*dJZpZ9Hp@X(iwP#vmC86NtITV#iazUqE11+Te98YO#iOHc4R7l9VSLvJtP zMuQc)81mBRDB=LUmp<%_ifFwooxon&*)3;uT#Be#v-KL9~OyKCDXrvRpa>}8b zju{fBB!oWw?bsn6MRSjgZ*oN0cL<@CR!Hw+P927(Rdkq82UpkW8`U9@JNri(8UY}$$An%`A^A(4ZTyV3`-x!!j=?Z*#ZAE z7P)6;xyZ3Ku{~4G%SBG?&CDXb$gzglj+vk1?U-4l7dh5=st3C>4v3sL2bCITHn3Kt zRh}#d2>>)U7Qaks+pLc`b?PX>%@uaU=X=&?>;ZAUhqxdl*D|Z|47MbXU~wB%Old(Bl&1Q{%b>c> zLJ<60ybQs_6g8P$gwiiAu9kO?6|*OoqEf-oTft4Zkjk49%$z8cS&}{I)ItkM}>(;*fwT=9nK{=CGZ%_!5Yy4!KJB6Fkcx1!PzpL9hXtaz;K{ z%FQ4H&>%%-J@T*1;NO{we-@O*KZ7nvr~0*!Npq542(AuZNb^s|B0k=h?-Tsn%`#JW zOYYqCv3m#t%Hd+gnl{EuVhd&nSDsOmymn*)u3OAVIz}L3Qu2u&@Rs5FGQf^kqsF{lFoKYCByZ%I$YnFkG@QKY^+5qK-Y!01}QSi7AO6lahT zNJ&S$^)BdIHC$kQgrxVNYt^tP?wa*EtWwMo$+jzQQ5ZPubqyJ7SJs#$y3FWBdt{S( z!kJ3gUv3hhG1c8L$)S<;{ zey0C6=mBdPI);=B@O@#%w#n^no7~PtQ!lKHa zbC47&n!D#5=-FuAo^!hS4u$Tr7(HXfR(wObK{Qy+(JoN6gwW9Y_dzeKG!)>_eYxoF zoR~+dKD+r`UwKxI;m+VPTuC{Jjdkcb`%o_0l5XrbXso*|UxZLZWOM>*Zn;OzJ)Voc zo$AABL-Hwy1}LElSHO-DL3Lf4)TeXNt|^pf49S-n8lZ$K-5HC|GgQXi8s%1m-lcng z<`7;_z!1q%g0kHO{=Vl~wXCZ?pNn>}sG)q_-Z4<27OLQYK;j51T$Ogy=n$E`J8pN4 zavbJpbhrf|q7bQ|zt4u}CbNTxKkDQq%^!yI#PMKeXK}|xeWT345=^7|w37EZ$I5x;Vna(P}T?kllI3~7A<>dzqDTfI!Dp()UA>Q%E zrZP4Jtk2kwQp(K2kqp%$o>whV;{m3`Pk0SJ|0Xq z!`#@vheYCFuep7FJ5K7&-B$A%Sf+8;qEQBxH_AyvGt0noU?m>YtXu+QL{6MEa@OHr zwIcp7`=-j{#B@s=;rzrfNy|FDEUOZ`77Xr#a7PrISFu31a}mzt7ec%X_zP<>obFtU zdA^FZ7;`n6!v(rM8sGxm9(|DubbIs!>O;t)Df} +#?O09EEfkvZkWS*i#VXy~^ z!3WrJQbsY^JJAz3w5j$~5h_L#H*_YyV-Q&x$0J;$n`_P6kf4F5EOv`i=@$8r)V6PE zWFplyS^?X>p)pTGNR7Jf8=CMmgtwfweM3{8hVTf}EE=+9VC2Ts&}gZ{n@V|10?7C_ zYj3PhdssZF8B1l_1bIxmZQ1ZdQw`&tq;1yKsX8t4fulS%$+qm`$W7T}sdhpuX2PC{t2Nnit2P6To@cPQ5qn^;_eWFL=yoJ~ib-!{_P8J| zv4`?;&X7SY3#6#(q4Nvk-i*nzL?W8FR#U6S!tN%~ztF?ef)G{`_Z(^{`Ni6E*tiWy z@B!P8(e09|Y5?@Uz}q34)~PhDc8k&I^{L+2ongDi)MF1`70HN}0Zy9x9o+fAACS;W zpw&b4!E#p*9?&1`@SqG!5eJm9L2rG=o*h?Nv8UeIA$EFHcTe%7Vj+HzDXTOP2tn2( z)pA?~$L~oI0HV<`O}WBqK^Q0~o&&+TLkR+J1s_T*C`l!@I)>H2AuR0X`r1wRqys#e z26jP=89|z$-HAOC8DqjZ^U6Pt&w<>SvM2{RQYS&;FdlaPQA0@)w=3t#pZYzbZ!~qN zgfNHm(R=Bl_tQlmq>DaG7k!j2`Z!(mNxJCMbkS$& zq7jOTHI~7C>7xD9MF*sd4onvvlrB0rU35sg=+Jc0Vd=hRn;xR$?-X>qR80!_QLj1-fUKhMXd79Hc%n;!#+a#Q8b+6|s znzMW3S77iuLB>-wrz0yO14&f5Zs`)uyR?Q;q9A_J2y;x;wzsL}-#~Z(Rk+?wV ze!Y58I%YWmkRe=aj1Vp`5J9}=%M?U%HdT!2!9Ax}=FTz73p8A*1E(Ot+l$hnfGbV?v?M;z(%PXt#vLMW1yOj){;yxIs_gVzhw6?IRatp z7(AfPa|5$tou>n{Ab44USvXNBievIjODQkz7KrCr8$_gF-pt6l7mf6srbr zmfKT$xfy4uh;fGkD}wq(RBMNDKvxf7-4O0sBvp6`n3Cq!8J~8zhh;idp>ayg~)>cm@_HR#}Onlas#ILq+GVw8XqK!@_K9NsC zQsd0*Wa7bMzDvl)a_dZRxjYkGx|OlRD(r|MR%i8FKUepgr-T?e1&h}af|q585MtFB zAz^+w0vS-__kn3cSRY}oToNZSD_ND^D@6hH11hjiiIcSlOZN!ReB0!i@5HM12>E

^!7n!$#EP_FzmYXg~IdRQ0n=9ZpJR-mRGjfm-?Hmls3p2a6P?V=-)H#rxNUaC5DZgYrV^db&_ zDuZQGcDsht4~KAQIhp1>`z}4as}0fqjxx134I)(Ma)>9q9ret+b!+i8%_9X9_4N4 zfZk}@2YtL3`oP|3>`o6=M{BB%@l$nBZ#3zvd4jIF%3ssVIdEcB*F4r=^N`+XHUg*Oi2`T7k^lq2X4Tbor5`PFe=9f_YG_M^a zAh=504`S4V0Yh;&B}e|-f)IMht^@@q^$dgDsgBwaREuWSFGdxB zbK;JcE(MHI6bcYUg7sq6<-dwzeT^oNlt{r~HHEWNzYrAy4NhKM5JVj$RWd-v^hw$> zAi?2`YJ(vLnox!qXwU$ll4}YYRKw-3ezCJ0FkJ)Rqsiwr#a;;Ty*`F%4+f#Cg!rhs zY-`%!R@|0+CRx}O<*`aW5XP7{@3@W_W$fCyOT-cs(X6RoU zQx!yJRSN(%G)}4ziWhM_8T`PL38L1QAxcEG)|iLC%b)yW*s*-NDtR1Y%c|VdYa5IP*5Tx@YocjWH Cp%I*va!c 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

T;R^C8-KH2w#wf1t9*pLW@)drT zZ^<=P<5-Jp(_)mu?Y;XhYAb=RJ?KAf0}R*`$0}i%^$hi0EbWslQ}*{&LPSJel$;+! z0qH(<)A}L%H+nX5E0Kyg;HWo=+ot|r2P_`z(@*ucF42`mE*Fz2e}k0@KTc{>RSZ&`vR9!7&kE%-KyR zNy$12WvWGO8O7Al4yYlcM7zg3taj-(+uIP7<6cH2B11{9T&7eg!_a181&@apyr&YSalzgySN1uRlIBKfsto z{AYjgZvVmw&JZJ5_?Uc`W)|ov$AhBv!<@{#MepVU-AIe=P&VX3x3tVu@-YMP+VPUH zWf?-mUR99ei!s zjn=IxrS8*-h+ODI#Ng7=%z&10eu|%t>Z_yiXc>no-J|h!G%k(zXO-w4$A{6aq%3*1 zb3n$2OMXdba5SyulF{P$(Y^_nHeM#bvTUN+|Fy3nlHU_OFaJG_FR=^%r}(PetIfZ3 zdlj`#l#a|c+NT3BrzEw^1PZ+gJrEzE&$d^U`%+@8aQcZ;bEg{@HWH6;Ko7?dNbp1B zWRu2ZF=RvrzNR*&e7`m5toyd^DccGihzD7T86Z ztO#Y6T78)A^X1+aaMu(Z2w5Z8{5fZryV`9JZb9H#3-ibjS{i@B~kr7}tdhbcU&O#K~kl@TeqkbA4qSl3ND zNlqfV4z_kFs#CU263;)T$d-?V$vrqWYo#da&H)PZ4|Wc7HCoFwQYavsxV`@qkmZoY zg&|xrs*f9h!sBUnnNpFp9=&A!)SN7aBt>qcBZ=p=dh9UO$C*#2ut?)W;%d&JXi_k3 zjF>NCtYwXz817ktXOP&E!j^eO(ZtB>R#`DZ{$#VoY`Invg zbfkmfEw*M7PHEU=oRuQJ+1MvANUxr zjyL=E4e(-0&nOOcTsMbFrjuRrF%uxEx0*_r!m~;<+n^b%rJMteXs0w~V@i4{j))!I z+;fV_i zla4ewd213zTewH~yvD~N4e^nr&8f!eZ&g3!PmDsUOic9!Wf&&b*pOt8E{?P&lk6pC zm8ra_C>c{lTcHo`<2h6!8Wc_Tsl5Un|1hPOG}Fe%E5f9<#%^4mnsJ*9uEcn7Ld4@{ zhPQIxl7=c4ADePHo3C&@LkizCUzL|rwSiMBIVI9`z~&~jiICKW@;{oN3~3y2c-$Nw z;}rWEg(g}|Pg8zH(Mp=WdfFlpsu;y6GhzVgr09~5s+qpxVx<`x@~|2DkLbGrHnNGU zKuRO%P5xDF1u-A(h^e!lkJE^;4QDyK5%sLLJuz)!2eljEy**U4>4z7%`L_mDkc%c+!vk{BfR)NbLVi55zgRPyA?djP(lrD!ic?0p`V| zU#|A{T+fo(QAss0^WpPoif=06{{XPH6?~n&1H?gB9)EXcYYPnL? z6yDPA4$rGeMY05wp|RY?gmMu>E81wa)jGnc;bsg=smj__^pu@oCL)XvB@7UqX4*xU zeQZ2U`Jal^HU!(+lN0m|oJ33shCwz+n*7^}1?Jsf6U-_Ofn?e^(~|j-xCFvbARfUx zcG%?pr8K)2n%x1yp-CX8G(mO(^QH$G5OId$w#yM&$%{b{|0qvg(vvft?x*@q70o7A znp}QwiKeFd%{6pm?wyo%@HS|N@fq7=4vgzx_Jj$WO!6l8Z-p$!U0(;&;&I((*EMW9 zvJyp29HtDiiB7MBE8{`Hy^$+V@X=gy3}`qVr8D`8!kyfJrW;})OU)JQ)ZZ5YpTi30 zjWYYdT?J&5Poy&Y%;1>Ml#&rr4ns2W2kvTAhTq;A7O#-*(S%24^zCbD(O82Mqxv81 zZqV@*D0q?n*^ocqcv>U6h74AwTo~`mm0fgBd@e&FUv%OQffAH#_|w=+*hOc z!njPAbPUCExk~T4 z+xoUDHe#mwsTObL!Pn0Iluq8WOdm7xe3LO2{h?2^>Vy0r{+%O~jP=vUS)wy-y2=wx zh0ip;&#TE(ys!9Vkq&1sgAfTnXd7qybA!grK0zfff zi?ri{ADNBRM@FUgE(=)0V3$8v7Ju8~O1g2W&o~{uB&Q{i_05VYevx9>#g=evs9!v5 zft(wLL=1aXvr+TGet*#8c9--<60k^&Kxrql#_nn|8l%gif;uGgnGx=W_{~0dLwfvO zVg@cpq7OW|vm%^9aa&vZQq!KZ(2oiJSZmLjM(1E?k*uc1ty0*!ebR){m)vKg3!;{Y zi=rvw9Te(PT#6CSP4z1+3OW^hGYV?nj&sJY?axu+$p-YAqvxEI6_k{jJ?NAWql zvm-u7qAux5xS+S|7n>~$7pRsSs~y4#Jvv1p`YU#y`oWZ_JXOs=lJhtajL9Fb4V!2& zb&Id<(Q-4&2=6z^jIaOvAiXFp1#J%JAD7s4^6uJ%O2trCcHUs@ygz!Hh1+*tk42UF!=psdQ3Gv!Y|P7V(%bsnf|xFFrI{(`~kRa-WnNIa~X>!zfio zmZ?|q@uBpzcL1bw(L8Z<%{l-&yuQ`qKa?SK)fkZ8mCNd3%MELs)gYmpfIF zD)T^%kaeSX`xF@a#X*irBQ~6-ie{5hDp&uFJcCN(%4kPso{XU0B0ZwKtzm76^(yXI z$xAD!ou=wjq(eCj+&MLtf``1n;1@L^Zc(fe2N3`JnNP4#q* z4?b!aPYxxgxHyY?QlVMqSc(#f1&a84wBsM9dWOaaGX**yR>`t?2=fXJNW@g<^-&&0 zFM^MqFv1c%iPL0WR137V083tEqP9{Rtgnp{sfkMzof0P-y5YIdb>Wwvae%*Oz~_jE;u%`U76%@>qB44DHn#8?)}SYut4%u zmd&BqsVUDIQM{_dgLuk+=+k#eTLpaCgNdoty3G7hm(^oidgS zB}7j6?5QYDs7RWr8-$v=Z{SLW6vW9>ndIp~s)m&Trz=%dqa4O!f@SXbR`1sR6^~_{073+PxJXXN=ekikQP6iZjYZe}8B=$7G?(2%l=o zdiKQ+2^GVKJ{=FuS#q8>`~MoqgF|VTrlBgz?tBvDa(=QkMp^POlFVo6L;Q+Z3c6M) z6;D#odXiIGPb*JrA$X0`!}3F!uy5fDmQK%1{sOIE*E#*-#F+w4Ho~~uzJ->>rh(W? zHxvo`scXqM)+2C^!&LsH1vhhWX@|g8hthRpHqE|p* zSQ-qE1PVzO)?zdn~s&!_K zWE`kOQ~lv$E;TKG9vMXRqx=_5ofz~_z%cOXhiMo9iDC3fTwj7ze7XyAWP2mSEiWkB zVJlyz3>%--)3P8*?_5vBPM1yb@;=J808HqI(Z!4g^p~Ax*KC(4nq4SQ?~;69uFRvh@$miT8_d^8+_q_9+NYhX$SEuZahQpWS_cm{Zrfz*f}d+ zmUGgs3S@rT>vq-YKa^_E5OPkwt*9%G274uDHiD$JORrZ^$T+>I{sp>9r zVDEc;txWlj=8b4-nvVminFF6;9a>7tEvcY1WQ;y}h3ha;WC;T(*W@++HMG231n~DT-b#_FsT4JR zjT zO!K*4*x?Ax^uDgN!>G=^b!1HdWl5!+8hT<={=4Fp_*RoxyD&>*cV}mJ zqBp+f5iA?zPK8J*SkYtK-QvB9&!wwRHbWD@o1T2WT9WRvEqoIVo5Focv%E8$Y}Pgs z3bu)Uf-(-1zhAor^eisb58I&^{ng)>W@ov{X)vqRjC zJ5NJb=(-iLZDOFA;424B7ef&(BfK$b21Jv8QQH*B556?JxTOA@zrm4`K# z#v9Cy_uH;!#a>YPsaWJQT*ZBpy^hNqeKf^V+WLvvk*LE=n^ZWEwzI@P>OSFc2}q5>Z9=OKGbOWuia_oRO4aFk7?t79WHI* zdrS$A+zn&J+r>v#9&WJ)g<9u6r(?}c=v&+|3-1!!T#@u3G&?pI5S3aO*vGUQ{VFWd z`gLOu^ow$JUD~(WH&cBgEjEe9RP_DiQ_OrkR~OFhLC~=+pkETVP>*da6*ci9ETY!_YvJG zW?7&@^IDv&v1+L#hM07UPj5@atwnhhjY-z(+Fkl zMgyPTNWUFQN5IES6O2Ce-57`NLW}c05CpjbU-_3c?RgNFXiCK})7*1<%46{M z9-dsYaA9NYfrwYOaC?!qDu_apPD&i=A03|RH4V6WFbir<&yWK{;Kem2b zA8m~FyNOxy5A8<9)wmjeS|h%kwmp+DDjNDn0}V+(M_o@;-_snRUF1s$BH@j+7tRY` zqfBve+IaPJKR8B7qb!`p+v?$7QZHZYll%tLr7>L2SFoX2F})a#cyM47j#O&2+O}8~ z#ngA(e*xX+!XueiiPqb3mD1%+ z9p;cFFDlthYG$NmQo_a@3K{N7V84mhMl@nIIoTX8NP>r{fQ-5Uh9x7q!Do#aQv^gz z{!PW_Q*~`MF=+fESMos@C-JU*&^Lt}kWI*jonpiz&!aPtlNW-mGp~u39pZuQIa0`2 z?!?I1ZA?>T12T!P*IgbB9PQg^c8aa#{;7!YySUPhf@02tqAYF?Q$)1{b>5&GV2kjK zEjv<*MZTQaR4o%r1+|aExgW4-cANi~CBZqkEGJWVTcOVRw=NRBqitDJ(uz?MTwZZr zY{H_Zq7_>qQmmZ<`&XStw;&}Rrl1w;jVoN!)(%tBim?mwT5nL$RJ39gci=jtoXNeT z@W!4}AY;7E@TG+~Od+ipcOGS-cE4B&#S*h?HC(ca80xSyAxu@HzAUN@hOqgKT>fG5 z|5kWqmo}6FL9t?5u}vez%4x;?9^0a(YKysw#xY(rH&8U5vGIpuAgEBb$H_FREF2lc zG4Uz^JPoMx-PhRoLkYIG0oe(@8qzq3d$t)Ye($90;ZL*5Z6f$Pjl8vwT&qfsonQOs zAExvlrI`*~8;`=Sjc%kFyD+Yimqw^X?<(r?eO$KcA%@>k4OTT}RP!xI{UNB@Vzxbu zOY$)J_Y@}R#w-)Ohe%HpVZ)SAEn&W7+Btp(TY@OmzX$5Fm#*0I2xYQp@=KIzKg5+i zBNb&7x%}AMuU0~}1XG+5>+rHYOeJ1SmrU;c7&X0E0mTxNd<`^aa}FDUKbuM6->7jI zMO0IL9V1iTYn0a>HbUBh^5+_gZ|B4glm8%v3`2HKC2Bms;!bA9M#wr3!{^vx${>^I z1hs&R<3s$%Ph@q;xcw+w+vGlsiHO3crD8u1MHu5B*fm6m z9Rk9D$$hM}PRVkd#VkpRfzo)Z-95wWAZ!T`#z@U>8I|!yC&xp>g|HVY>Fe$$h4b6fL1O&(Zhk z1KVqgsFvt7rw-e8Jy`gF8Tpl`SHjk-Ad}ESdV9XX&WK_sY+u7w1z&RD_|O=|$>hICVVYAXWV(oA36n>oZxPJ}_M#X$!3t zwQB5}0ehnD_Qn>?ob0sv&kRGFDn8c)fbS`KkGh2Jfmv>lu%lF$fTohfO>7)C@yY$_<`Yq%Tqa$FX6w&8!z zTO6GIU+jO_)TF6uB~(-GUPRkWC9Rn4;t=)%Tbwk-L=n{zZgUvA#x)XWD09B{?WJ%* z!&D0&+OZZlw(c;w;}x>er5S@h=8fpg`6wg*=Tp1<%)yrXDZI*t{KJ$%HX$+wERpt2 z6~)wXY(KWmCp0rS3)$d*Q#c{0X8%kLp~mk7Ciu0T;k)d%-?(VXsFpCV?YKfW5V}FN zGD-!9$)Bi*j3Y757YZ#i7nw;iJA%7tsAy^8Y$_m|;BH`o>=u5Kg`=U8Gli2B*)YD{ z3d0i(lWR7dvO%@PfYG;aitfSwaqnC!K^ifla;IZWY{rITAdjSI+xdcY7!9`j7k8^qsEan#%7PE|&N zmhx!d&&bk*A?+ZSJyS$Ae~P~l)|Q}6=N4^M5sgbBnTvPN~5GkH(fhS z5ycYW4mF;|>=07(c^{*8n2JW7ISVS%5w@Jkou)8BUae*EshWaTjHyDtqrgu2p`a;g z#n`1yktnPkrjl0d=aFK$(-q!GZL>(RLRzu4BgINuF$#p#YTTJhS}{@!i{;Kxc%#N_ zQ0pc>m_k~yjUvTLS~2!?Abx6xsc6O6s8a}y=H{jFwr-6SKA3`5jE!#KcEXg>ifsg2 zSUXH5t=Og*{Muo1XDYn0(Vt7USxTCMR*ZwiVznf#DQU$hkoAO4K&_HiY@bN6+*t~5 zq_%dXSV1esF0AJ^i!ECeYAklN8||5jR*a3-bd8Oh+}SDAHgF4?LRztnBE?E+#Rf)- zRkUIp1*&C@Ka=}I3U7nMLe#gkV(UhVm9%1Pl!_EKT1hKL{RoTY{;2TAz+4n5C};{= zF&WbuEp(xjR_y4oNffK37279LEO(CLyxPH=T@N!X;Z`+#CRyIJan`{o=O3n|kzw?) z6M|-0FY*>^{I#Q?x;>fPxr(Hyh>ZPe2lj$dm|h3hEz^>%uur|u#uA>(=@{dtqP0f9 zL$79I2dMpdit}UMf^iHNV|*+=764%Yil~+d_c)wUA6eF@)3wSY7dybA?ua&+VXY-A zK|ObVj5>oBQjZ*_V2f#yPHhEeN+_1_?_BJ~pIM4huclSwh);pMQ*NbSptQya_qS?1 zVI$l!s&zPa+@oS})VZ6I+`_j316NSdXbm+8;jC^~}@-7rk-(TSdQqyL0`>BmTJWT~Bu{{`vZ6 zPy11CsqZ=0C#`YM?0o?M^gTtE3AEAMg2lU-vMJbugfA6})g>m5%0BOm|5tp8-!;V&$)i(HP`Gl^@*+}S020Z{cEiy?Jxc)l+QNT zefIl4PjpS$qtBQ3Ub&vsU+7$)H~Y19E?w01-K9SI?YjrBAlK(R*BAZu59@X;>N;kl zk1o1xPOUG4VAyH48l{A&jO@;k!cBrc$zy50tI zy~DY_WZ?8=`ajmy@9VKU?=W~(;ji7fzHox(}Oz%vDl@G|REBt3&?{w-<{3yT2jt_Oc{`B3wUwC4m)Su*B zU(|l!{9_*MTJH0gj_JD7%FnsJxL>bRu6dwqw{3TtHSeVcueUq(7p?x!6`#GoYszak zUizyy`bqnqbA8?wGlzVAU)Pw4{Vv|(qBR@4zW9Ssz6&mS{mu36>pEl4W#;|w_SkwZ3^aBtV9M~;|$_X?|S=Fg9;>+_xZ^VV#y9`^UHO?K`-;lv}~m+|Rzt}j{Z zzdQc%o~~u@J#5t>r>!IHPjaqL8vM+_Tkq~V=hBr{`%CAb#;$ib_2(@*`nS(5?D}ZW zw@*H2+VaAG*7bI${^FO0o>}SY`e5Tr_u6@Gpg*2--P-{3EA-<`r>UjIrOYMx*oiG&$ma63G8Fm_4!Wy`9q)G z>hHI89klD<3F{vn*zc_ColgBpZ=U+(l3Ti7oW1cwqs|TN*Cgk9`_f~V`O(c?zuf2k z$$Rz+>|fUP4yXR&AD#1@xvA@wl|L)JxX*^c_+(sfcdmC{`tHaBZ|GX?(lZX<=jiVT z@^`PVv~bAs*LR(H`pDxh+I^$Ot}k8^j!)<6hrPV{HC@}yeD=*>AG?Os&$_wSD{ua5)!mT|q)x$YhL-9H_B zan~Em{r2efI@g!>v#w8a>UTb~%#UtAw`5q9fs2pndZXjT?~HwIb)lbi-E-^v5{>;4pEvf&PhVSl&$5lLoa^301J)gX-q_(Q>@n<)`GJ4%oa-I` zJY{b)f9y`ry}#GOmD)Cw@qgE8f6&v{P5H~%0bkxZclHkg{pfVAFTD8sSO4M4vA zN#maQ*||52{nJI?*>&$>);~Je7e8^u$9LW|_POm}x@?~ZgZVkhxjz5g348qO=CN!3 zc<)V@o)+-m;ap$%&hk%rw~ih5p9`-#ZOw}4ujgFv*nRJPHokrAi(B8h$zCh{G>}il z;qThh9{knc#=d#bryKl#?7eq<6~+2Lo{;1!>h*eU*LF4HRk0C7RIWx2LsJwGDRwV} zX$XH-2avSGQNlJZ#!%5KORYawc1XLkLlV{$hZ9S zK)w}Qow&nIkEHrvJYeYD>plG}2;HA~>RL5RA5C3(=Sj~sT~;ROXNK<2+hC!aek?Vo zZNIHV(D*KiS2r|MJfQ z`PRujH2RGCO2b{L#xzye3jz8q_ z{k-;F5W2t4iYI?=$){f2;esdH3SWx&G%0j{-b)Mj`tS3pT^DZf{r10k{yQjif1Qti zTYKE%RNrsdq;1!IRJ2cJ=zhstAKdco;?&>gK9JsE%V!1ulFG{QkF3^YW+V9|!W!bBW%E#>cljY?8`!Z*}L!FQqP9KCiIb2dj(wgF^S8KI+l4j(RE8{z^m7#oJar$m4Hi=ziaS zT)zC7mr~cfw#KG&D*K50C87HZ2CQ~#ua{GYJXLp6>qC76|K%SA^t}Atf^P08Zq@(PbnMV)2q|lXGT7TL)$Np!Yeainef3m^*U8(iHYuI({i@ECT zDH|+X_aNt9&GY8;FFVrSblI=B)nD3`TKmDO?Z+N?zJ0)9>nC1IIQ-N1m(8p`VD7a~Uvz9&YM*nj z{cM9xXWGXda6Q{1;Pv3KRSL%fF4;EG&JG1%%=Y;tqQeCO@Zn)w7U*=v=Jz#Qs^RWZy z{yy2SHu}$L)v4=l-+%GWU8%1=-r}Mi_MTb&*75J9hwadn`p@b|rH;Gz0{f)eZ{L0A zUtOu4Z|*tm-S1~rzx(zU-(I#k>Hp!DO)lMXFMHnWZ!G!0jk;2IuCZ3ztliJ7UbF0j z>rPp>D|PmBi|3rPeslGKRReFlZLO}<-8U~B)jn!=^#=FsyvDD8=}L{vcDz?Q_|)p1 zUmNMRmUgA~{bAV=|9fbi3yM1-HGgW@r+&yPreX9NC73WNR;=9h&lrj6|zu5O2 z`?(wU*!}u1J5zIaI$+ZuR=e1)f30HLt%c6ii@TjS@ROxS+23FBVgENj?o4g4>Eb&! z-uPns!yDFnY^V1-Q`1InfBimJoKoGZ|GFcud%H7rMq}?|C#`#~z1hr;@?mdurVg9) zkA2R*{$P9iKHqP-#w(qvO)nYIaOsZ6+ZWz2=JjuvcBcN`@#v&4YKK(sG^b|L>We#5 zU3GuivuFJU)d!XQ^9%NDXKF^-m2bS8Z?0Za{m5NcJ=vM+yYAmobALOx`t4<}uGs#u z&eX!&j(uS9yy?~3Zok{hZ#>+YI(qr|&ma8fxz&Gt>z9jfx2Zl?A63%-ytD1=cf4%+ z?e}%2MqGWalYjd(dvN^=SG{p}XKLbrzdiWm+sD|m_P^}F9q#N*eRueAh2iU-YX9w= zBc8qHzeNA)FB?_tdT#X_+upU?-nVt8DlR>v>Yj^^tN!Jw3tw9Imd;eq@teK(ZtcA4 z?Z)r()@nC*rapUe<1wc^)xY|l;fI{D&5fO@T^H5u@KL|>s`uIQmJM32?@V1W{ownrU>mF%8{KlH?>(cL?H%_~^tD)Ae+9X|l`xTw315RH)elKUHee!t+{CEQW{=&dR zPpsSG7&|+$@JT!UzVL)I7wy}5s+~RQ+I=pe-_Q7H!sh)pKGlAvVeo;U)9=e(>iM7N zta;U`Bi`P>k@)}f+EMp8{f@IwEB!pPKFKq6QN#FO3g=b#d!%pa7xeptrdMu$_w#i1 zy&8>g6>Dg24`&WCm^~*(_scjd}-@(1@sOotuuAVjj@y^r(nKjr3}N`?z^_{oQA6w_0as>i%1u z17Ck^g8lOb``>%j*PW?B-(9!Y+Skmp_c-Lkv)XZMn^x78nzHdZO*>9)sBWCsh3!{(Us~vW$Dg0)}2v3 zXjt=M)2YAx;{828xPSM#_WBQ5xBT)Z^+(UoAGPP4qpM$=clk+=eB70qlb^&MsTf!N zaD4YBGveXRxgv>m4{}%iq_4gn_v_GNcodOhZIu9r+?k6FZSn zjCV0dN2Zn*Bf?_R^P1AI*$eO0Y^MLUD|gH$GG&DeYf!O^ImN-;;$YTd%_jjMhVH{Yv!($;cXb&nD^ps^nmM1brfpRHo zBG*sX-;!B3V!Wu!V}YW)Up5 zU9@bQ;R?ODHU=>FaceD$?n4^PXD+5-p{aD3Zg2nc} z_9fVOf;I5PXDr}DN82q7Ne5T_i1UF>-&mVZg3aHyb~gq%#GiVd{`xvc(w%q23d zG$W{9D7TF)0jC5&0z45L9J>`*D#C$svHZ&s&FTYIfnYI@z-}IdnC@Qa?3YRBv=miZ zJ_?gTAgmw?0tC}qyf}p;e7aev(#(2QLxu*3ZmSFtk#XgTEcTM^!wEB(8d-lna-jH1 zzR6Jh4zrLu9&ylz*wZXl=ds`}PNhVMB*iiNwTQ|dqatC`N<%Tn1cU1Qi;i$HaFa2g zLz(ru0j6xHV73WX;g?8Xm}7#$=lqMgCfI5|hQ2WC4TEe@ihnUX3X?Vz4p1ap6eiW% z(`Q9rm}`Pzv!#DA>rI1fYx)@a!fX=^doKKoIVRX&eGGkJt_g;4>|e}s46^;r$IusM zn_%z||6&foVgUhtTd?0q?B5rUx5RcD2~Knp7juXZs1+9QHHwu&7@SK)^F>855 zw#VrnWc!DYp)Yi>Oa%6X2g80R|6)!QCb@0wW9SQWqcF)0$+~|r>)lA9s43zPV)C&P z$LuIf)^t+|!6$Q~uz*`O#LbPuB)82JZq|Dm*$@gac4{RF(ZQ46qALs zr)O}yHNTh}g-LF3V*g^+`x@EMrh*$Kp17DDg-LE(2!QyXIZ>F@8=lh((gZgOliVs5 zZq^4H+0dpqvf&sBWp)%Mxos&S_+(BLCS}7h5MJs?FgFU5+*d%GOVTxlx$p zwu=I@3K7|){b7WG11k8%Y=Xry5hN>&0*i26oV~!ijetL$Tod6gO{0GRf)jiZfk{Kd zR0Tp!8gSMTg-LF^D%|o>7`P!wgU>VxWrZkAa@$Qp@X2zW8ri@N%JI|#*`hGXZFhxR zJ_?hvVPa^qgt9^uCbqAmXRn6Opm2+!gC2 z?v9CjuqsbHm|Glo#afB1<7R zNeAC(xMM`1YNnRYD*9zGo5-~GK1|{6=(xva$KVdLl-|X1-y66Omk@li4iju|1(r9# z_EBJkC=77~10Rf~F;9b&1xR5(7-SovaO*I^_Elhc6Kp>PRxrUvDzMy-2H8d_unrT9 zCv6hS@&wZwUic`bKID!tl^UPSHF4ixLhwmP;MJkm|$ZSm>Y%3HV!}j zO|t!LkZqj8%{IZtD=^0do1nm46YM|*X1NC04pLyY33jjob4;*96qsv*9jd^rUo;kj zKp0+3=|jm@Xk~*;Ax~u5U~-tkyUBqya}c(C$WMF zHc8=@`^`|O?>>OD4ijv$!Yyxt)he)p2^Q)|snFca)%2|p%Az2f30AKZnm57x9tv<) zFu|rM+;S%wWK$0AqZ4)vup#88J;$sPVvV{wSB1D!dY&J&Hlx#*#=qp)T+cWn_#iX5AGw0AJXbd>aLN9 zVV%goSb@l5)9}6MejpSG#1V|>O(${zl{_7qI@uuPQGQYMh2;s>O=%d_2_;~nOJ7>< z6hmokN@*Pgi>U;edr&tV(I?ixkuC6x&f76?_vaUZW3CAnYCM8jr)sK1 zYkw{iCH%xj8*keMz=OF2i&YsD*}Bq1!_rMUeaFCky23qAuo!nFo;vR0!FF;1I(^5$ z-Crt4Da<;3CAh;&xDm2Ek!dv(GIQcyAXv=w)OHAla9XqDLUznCl;)o&%3*ne#WaQ4 zu|QLiAsr`kP2Bwj1`e~%=$3nANGF6MGOebL!)2-RYjY(7Vb#cb0+s|0&!%2-c0w zC@Tq`W*igunF@Ee81A7}5087tT!ZW+|^ziHWOL;e_967#&4S(g~N zpQmuQ2^PyMD+vQPnt=!H;AbH$Ph?vAzd+$$AXuy} z+bDI3bD!uPVdW2YS%+mP?LwurJi%h6sTsK#pQ6dP8q>nW40cl+ro~7Avh% zshe6Fw!k*f@KCu}!BpDCVI0d{u4yMV3S#J~%t}yQY$DUP(qL z!o9-;vlLj~1iMUu6-=S%PSu+rLGTk!B?n!2j08_W;2n5aqv02`uQt@>I;Av+V6oCF2@;fs=`B1J zf=xWJz$BP4>l#C8*DIyj1nZ_W@m{f@JZ)e%m3D(tnssfrr5#1ngu7Dh@Wzccs$FOR zD_Jpz*l2C;MhU?ub9JTZLa!)I+hrkKU1uomCZ#loVBKg^Scxo6A9}6p4W-?zlxCY? z9SY1b!ERAtt_gOl0<&%~$ab3ovrVvt3d}LV{;R-T6YO>cX5DCz?G6QIn_zb;FvkSD zOM$s2*xd@uy2&8hJqpY=!R}RHjtO?30&`8U`xTgVvq8286qs#-*$T`t!5&m#t_k*# z0<$^{vOTQ8Y!hse0&`5TM--TAf<3ChtXmASJ*L2H6YOyX=9pklC@|Lqds2Z}w;E)7 zN`cuX*wYHkF~OcuV6F-FtOB!cGsyOw0<%r9yaIDfu;&$+Yl1CSVAeu|Y%eG<+XP#p zz#J27sRDCNuoo4W^)}_E~6KsV7b4;)=6_{&+eWk#x`wX&ut-x#(>>CB< zm|)*3FxLe8PJvnX8)W-lfzg>G`eDfr3d}LVepFzt3HFl$vmP)M`m+MFO)yu1IVRXI z3d}XZepO(WZIJCZ1!kLI%EPO(TO|Z2Un6=0t z+uszJZGx?%z#J3o?+VN{!PZq^)*}Yl)>B}%3AVlhb4;)e6qsv*ZK%MkM-8(5LxI^Q z*hUJ>F~K%gV6F+ai2}18Gsw270<%r9%@mkpg8fs0xhB}=3e0-kAlnuS%r?O)6_{g! zZK=Rq6Rej4vz{=>wv__2O|X9{FvkSjT7kJH*ft8xdeR`fw?Bw z_6p2;${^bg3d}aac2r=F3AU30b4{>53e0-iAX}9JvrVwR3d}LVc2;1n3D!@6S9Qm|*`_V6F+ahXS*nGsw250<%r9 zY6a$)V0$Sr*904=z^uGMwv+<1O|U@<%rU{30&`8U!3xZJ-XPl$1!kLILlu}~f(=t( zt_e0=fmw?UvhA(FY!hrB1?HGwBNUixg6*rotQQQj?We$O6Ktdcb4;*N3d}XZMk_FD zi9xpg6_{;;jZt8Z33h-2b4{?Z3d~w+kZqg-vrVw^3d}LVCMYo11UpcHSuYx7J4k`q zCfLCW%rU_ZQDCkKcBlfgmKkI_Oo7=Z*x?GyF~N>dV6F-F9|dN;WRPv50<%r9Neav{ z!DotRHEegyw!CDoVV}c!}z+4loO@Udj8)VBU zFxv#nDlo?cYgb^d2{v7US#KC*J6eI+CfG3w%rU`cC@|LqJ63^NZyIDfPJ!7b*zpR? zF~LqyV6F*vq5`uVgKYn&z-$w2rUG+Ju#*&+Yl6*EVAfj(*=8#++XOpVfjK7FDGJOr z!A@0R*4qZzPE%mE33j>yb4;)~3d}XZ&QM_1I|kX#RA9CVmQ!Gk33iqOb4{?h3d~w= zknL;*W}9I16qsXz%~xQq33iSGv)(nxcCG@mO|bJ6m}7#SufSXr>;eU5y=Rc^LIq}< zU>7Mc#{|1rfw?BwB?`=X-yqwi3d}aaECuG6V3#Q{*95y@3{1!kLI9SY1b!ERAtt_gOl0<%6b$ab3ovrVvt3d}LV{;R-T6YO>cW_@aq z?G6QIn_zb;FvkSDOM$s2*xd@u`ph8PJqpY=!R}RHjtO?30&`8U`xTh=xk0uE6qs#- z*$T`t!5&m#t_k*#0<#JR*&bG4wh6XKfjK7FBMQtl!5&p$))xlZ9#dep3HG=Gb4;)& z6qsv*J*mK~PJ?VuDKOgvds=}xCfG9y%r(KDRbW<^LAK`l=e??uum13 zYl3~Iz^v~LvVE?=Y!j@Yz#J3o3kBwyV4Vug`oSPumjbg*uoVi-F~Po6V6F-Fl>)PV zG|2X~0<%r9Zxongf_I%#;!Fnn%*92Qbfmy#9WLr~#*(TUp3d}LV{;I%S z6Krh-X3bn(zXA1c3d}aa)=^-N3HEmd=9*yZDlqFLgKX<5Fxv!MUx7I$*aiyBHNiGi zVAd>yZ2wSTwh6Y80&`5TjTM+{f^DL}tl0+HHdSD@3AUL6b4;**Dlpds+gyQJCmUqj zLV?*PSfv7UOt38#m}`RdQef682HCb!V73YNF9qh9U|TCN*96-}fmx>-WZPDO*(O+T z1?HGw+bJ;D1lwMLS*ICf+d+ZZCfJS&%rU`sQedtL)<=O^ryFFeQed_T)>nZ!CfLpj z%#Ffu_b>DldV?N4C2Y-!$OhP2^b%m^8hBb*{JhE5-7r37Lg{VbyI%Eg>0Sx>qTvPFQ?55AWxH1rG0 z|z>_OZLQJ9`vZf-<2J*H#qcBtny4=2`3Vg)Htg|Ds0tQ1xW6mH8tObzSW?1OJ zZ|3M=C=}fMi@5}g)f~nr&S=768F=9!HDLH+9rFybP9_2z1H{k3V0jZvoVSA}rHf8d zGjI!Dt_N6dz7d9V0&!3~U>yY0R!I~pURKr~xCe-c%+Zk{0N}t1ymk?XIz;pUq0Z5i zCduT>0DV{FMWHmC$P|~9Hi2{O{EJRf({M-gKq$N$RJ@}yc8tuq8t$tT8ID}{BLkhJ zW`s2p?`c8~me;}1JK#tN98JRCn!^eNi|HMj2p`%LvOSNxb)H5DbW!!3vp|u;bTCw@ zo{GmCB>2S~f@y`Q=aF6<0yD#7>VL4@`34~xNP54~S%(e=r)nfI{EOwyuu%Q!KsAl5 z>vL}6WurJKMZDrAOlDo6krmC+NbsOJY=Xr!u`Y+nHz>)MiTaY0VHR}U5rw9bC^JaY zyrL|3p+*R_8j^sJ!gMf^ShSE0!==bKSe{^7S#io8bbwQr#fwkFvbs7lSR77$!5dT% z7UI6wagnApL54D>5*eC3axsUbfSv34u-}T zS(#TY=ICH>*(}M|Dm6^!s%Z)ZH*`LJMVNJ|1}2ivDFpP+9b>i*25zthKTa}72LrdG zsTaY!+j#pkR|i8Cgx03eH@cW*MP$>b8FmyVgZ^G60|h6}&56SF+}z?|)@8-XRvgSJ z4(3K-s40Gwi&>XPWRozc*uUt^H3JL@s(&%Z1Vg*}7jsRpHGK?yVb&FfLgDiM#cUJo zuReypFvkSjR)M)DST6-;Ezm@P%?NTL4?~kFuY||S7j1hPE6Wp^62bI_RVWUYyHXN~V3YlZp7Zjkzr3(w=1_9GYa`m|L1p3R1p4tWX6s-G^CC_0fOOcJ#zx^N zjM566*(cJgO3G^Ry@@(yvQ(D4PD6$a0Vy|n2Qi57N|7IQ*qTOm1fL-Jq+gh$gCVLk z5NEvp99b%vj}C^wh=cWyl|3V~uGh$li~#TX#CR1+P~;U{#67PgLz)8b#W{vZy^sc} zX^Kl^N(e#IKz5MfxVw5Hp;o-X0E5oO(Z$rWGus3c@Aib+jv<&suvmI161El|=sX~a z5xQ9JMvV~2){jIZ%ZqhHVWsj`_><)cHtF!tpHOpj+oQOYP?UHBd@xq5zAH^%po>oMoQu76T0Y6Kj>7%BvUYGhJj<+3AF$-nQ2bt z^$4kgb=;w0+mG1lrNe2@I0P3XNnuU!F)w!}D(_-0v5gtyMs)YY5ZOf1;uMk)EcnGb z?$nSW6$#3!q_V{c=i(grqY*rHWH5m6H>Q+@Fp^w$Q14&KMD!q z5G-c%`w{?irNK;W&>07lN|mILiKGm?bP=Hwo%yiP za>Odm2ruS}*$`FAB{nge??Y^=Xjx!;Dlc5VNG`&Qag}`WKpEH)Ev0q$8dMxMmr6jx z7jua$rn{j82`1_*DFTR-n=vc12T6Dk{XUtrCLA33G$x+o_7qwZg)!$ouO*|g zagw*vKM$YGC0NYEQ)&UH2I7Hu z*i1astho>U1*>PC12FeNo!l3Y+^XG2LqR?7Vnk<%AcS&)Tq3AnZ$;LmCLa~5(~dE@ zLFok&=$CaoY-pClOZoyJE|xdLCQA@(#SHVOi7xnxIanN%g4 z$YSvX+0F?i+i}t{)J2MSpd(SLCPxx;W>{ z3s1JtQo%AarbAGlmGz6by;ssu3l@*6s+Mm*uIc}foQ0z-(y^dN9zjkh*S8RG1Z$-a zWVt6aZG^lBZG=uf9CLgnFq_Df6hnr`P(xBvIs}V#+SMNS{iy>yk{S?N>%+B)a5Y(saVkr?rLIuRaE|3q7d*%Wl8q2mdKK?wD%4vE* zR?v}Qco8lQ8=sI@&k$u%Y1XqEA*C^hRqP2RyYW#Kr1LJ8FNSOvdiSkzF;_>1Oddjt z(niqhaw8Y(cupgvN;W}5=IF@Ox{aVWZ|tTP$8vd1X)4(S4Vm3N*@%+3N(#l0#T&qS zzFQ%OYf8%(Ll!U1C9>A0ke(3d4yK>p^bgK~l}I?TNW#RjD#ju(H;nvxm-OOY174!p z>PKTSK9T)aFXFT(aX`@L7b`5*R1!TW!Z|W7(dE zRUikAfplaDI)V&oc$WKfh=@w-SgI*48a>AHUJA`wM-1s=4w1!Fwmsd6Cj#NxM;I~d zMMLTF1`A~aEKg*nQ3t~MKAw)y7wk_>pQR}&vAGbLib$R+{YVUZ!mKFr8T?;K2=vOL zzLnHV&!E4F-58i^lS3ylTOXc36=NAO9%v(jN6!u}{-|S_CLKT&LYIJUYs;9O3Ss1a z4$MVh4@{HD;m{PYn3ptKgxRAW0jbh~5}B(bL+TTCvK>e^|6(04d!>cPR}xo|I1M7p!c3J=E@qYc@KrK} z3283(xVxVFegkLBL3=#d2?GN{f?4QY~id z$bz&^mKMZUFF(_f$*e+bfYK#e)|(n3qh#@{BCjKp8Ivq6o@lu`vS?}XjH$!vR!Chk z;uJ#`PeyWYX_Aoxskx)3{J$n6p;QFkPsPSuVMku98Y$t#Vu=O2h1Kkc()+hHx@Bs;8Q zxke>%kBVju4w1zwfd(-pA5tEL5wqUalr9=1(5*56i;gzkyZSZwkkh5D1y z59Yq7Nj~-lJ2O=RGIj~g9R>@`$)qk7+6R{>L%S`c^#Y0sQ@_@gBB2*0%XH`{WBNC z`;X;5)@U9om2CPF6N)qhi*@PfQ7TJP^s_VlAU*FJ=1pXdjyv+dUL5YBnX7|gmdKy_ z0g_pttiI;F(ws+y4Ar$CyI`8&$(0LY618 z_{!3eL>Jad*ah^7gNhKV3Tml+NUsP)eaKK^TMbzLYn>ebiO8X!3F zJ$frSHYQOqT{M!rVgr4j!mT=}KmW!$ep-Fa6{UsHpP`o}^n9q&zjGycVO3>U@YvOvof>_9$r3Bhl$BG?uM?^!+9TvTdD zZ8KEDod*AALb@tR#3ltYR@%S^k^!@FXDoh52xQzGwFPN|MXBH z<{sd-B4{8x6MBMv#c!xdxOVva4)m{)%N}>M!-!i{d$NW*a~kAYjXX#~tKk;G-u19M zGio^u^O9UmElUO_kwg{d^wcL&V+IQ|pEm?%o;!o0QEW)QdT9xXXEt-u8-^pa+>W`vlu)tk2{7!H+jNld#v9LHwq+f;o|=)? zWHMzjt0SCI{2w+MVNxhbN`dunOvCo^%f{qamTx#okU;nj9qH3^&E-AdKJr3q4x-7QAMsti}6F7xvUl z9%2mx<#um5L0Da-k}>-tlB+CN3L(XXXmKq49+k_ipZ`5D2dgq_r0K29Dv9A`F~JwI zhU1I~_Nry+JUP55Xtv4jD8rVhmZ^3FVVrDLZ%%>bFYPIoKf*%>tYwbbM+E&9BgALx zzT$I<_c>@k@%tk0bIeHbJ8xV%vZm+no@UhV0|=7;@LoAIz#o}ssfv_&gkBabCL&hJ zf8nHAok)xZ+M=^FR=8Xf-Num4jwUY0X z*Q=)w?W{V49t#~t$?3$BG4wf>K8Mj9-!OWnZ&=A_x)&&LJL*ltbGw0khi1cAVSyoa z={s6jQa|8N=ta#b(gxVtbP9fDNKA@M)w^NwG^|j(OCOvx)V(m zq7D^~c;?JS=2P4#g8x{@wVF(2I00bnB2x*cO){jy?~Be;kau6#Q!_ie8CfC9>0U$n zuDZJzl@yh*RUuehiAo_{QcQq{JH5a)p@Hr?t#An{r5bC)O(-=ihWqvnJ;jEuaF>N8 zkz_@7E9TpvYkOhTqhPYZ}3< z+NlB6pfD%XeYfMSZUw%94D)8)uzYAKyfSc$aD9WQ4$X#5NBE{RS#?bK|IYASZLQ+7 z!zA+#Ye6w@scV+I)iA3yZ@g#T6JW+21Y5CMLHYubmy@R|)K3xr~GTH7QImkoLBx|s$dcbf`84D52x?7W^ zU^)e21SeZpmW<$2u9(A-&$Wn78tdy=V8tZqXzKQH!iJdX!2{Lah7;yeG4sm9Z)QPw z=`5Ay1iSaped9=l44<0CLr}tXF#%jzGMw(T44rs?lsCx5W3B1r>;UO#R zjhEF=?v>*;jZQL~g3kZi(_&dsECZmHkX^04PBQeqBIUtWEj-4p_A|Pv-LQVK5iZa; zTCR6Y3SF)tbqPBW<%`pQ<8_co-x{dpy^G}@p!u${<4ffqM7J}Ueg|JuJIQWGr;i}; zn_4MAtZc_1180~6bPijU$9jqL5aN;Q?~kIE?-x z_hR46;Hg10265omU~DO25@d5iVp_jq6+o=FPMD7h)gxn zQKX1gG9gicpjr7hR-j^5lod*YzatDd^gGJYH@8rl$+*?XFB>T80xGJzI*A$yHKOja zrgHr$?qbr!!5ROg98n(92viMXib9NsRJq}HQ4S()#L{TA%%Crf(jYgHCFpt;xmci< zE;b!SOA7Z;C?|N*Q>B*DaYJLyqqH@k!bW3z7rtIj|3O>kb`OGgT<2<=N{y>hL_+{d zOS0xauH{9jL02Z0wRPRlab3)>c2*pYAzcwUlDE}F1s%V>>Ww9ow82Ud|Ta&yn zmx|#JTgbVK*;E8}tIbQpOlTjk_c^Fu{NA^LK3T^L8dJpi1*$1V9zSMIab%Har0JLr zO=);qL6jChWdnlK%(adTdnyFkaB|%iZU;(vtWYeO^0+gzmTH7tn@SU_JtC)#_$CRN zC$iX+v6VyybJ52{!H^)q#d0qe>7B*;qne%=Y?irHZ1LXt|E50{RntJ#_{It^c`LT^ z?{E%0PNxforfSFhk=ZXBym9#y;eC~j;&Yz&IrB((V?mOIr9sD_E;L4rk6Ev1EH)q$ z78`M4Sgei=zOR-RA*2&IiYQI-MAU|Lys9CKmlh#pj*e_YU&!$B9w9eoxz{wMA<~Gt z86%C343S2V86!=xWFZkrCD!X2A^Bc03K`MVn1m1)%M)4bSOPpLs*E>TLBhg4!de7d z*d%OkIX>w`4uc0EZmBMn^c)s)>`<=A9AX;_hrOxvI9s)*3L|E{sbSNL*o2AH(Tq$; z2qZ7&5F72Ih~dOdu6s%<(v71bgUw>1L%c*YMno#LiA>u-3Ya+rTUfrMXbfH`zT&OC zP^HLJ!Ve$zrb6Z01#yUFn>RCt#{|OjFX5w5MQAc}5l_F$lf(oXEfi#TaU%#Ghtxgw z+{gHkB!-;9VY65)fqCJjVUQlr$?Eyxpgxh~_4aBlX7j{jUyv66)J!lcwVt!-aZXiI z=sl>j`dj#6N1V5Y;Rpt!dr+4zj!_p6U0@~`PoZOAf~8+k^Ey70i-Cu!X5yh;F$n>~ zriwF2^OncCEbOcB1pmp!q2^prF}cF9_6BQHZ%={+@udT z#|$-4FK-t`aM-GNjtB9nkK!zT+q2w|&wW`b|SS)uyDv4eKu^!Ea6CdQ^gq%N}sG%W4 z;))~qYlsM41(c6>YzOZ_adc!zIWWeBp)?U`ZMYsNj^zrPkb{7dWDa-%aOjX?Vw2ag z*`^yd@`Xu0E0+60Q+KE=sP9fZe?pa}N*S0{GRv@w>Z8~UDSTyWGEcXiELV_3A zh25o*1|1z@T&`N;}I7CX>&gL`4%NLs4|fhQ^gJBoX0FzVWv} zFs&zQ3awaPu#g`%c3aQ#ZPfKb+a_MD@^i`ryqRVjDA2NVx_}e12D`KPmPO&PSfpEC2~J#N=Gjjf9I87Hd;zY zrgp`6!86_t6)Kk%h)gSVG=3x~j7snLQPZG(NWO6N60Lyuso;sxct#g@U6YZ7jvWBF*HCx zA3+4e>AW3&G3#dycl1gJ5$CZ41$=J-4*q9(B8!cqFhap&3}cD=Sb$kU2SenoB<|w? z!Nqc}hMRzm55YQgFjT7&T;#>_Iv8Zb;B5~Yyj23q3Obl5w8z#Q!eO~zG_v6^D~}IA z#I3^wJCWYzPqVhx1MMl40DLIwJe(;i-#tm9;jkm&!yrHL6} zj|3mgA+nf|2s(=Hm`gB&kZqJ5RZ-^*r;+1TSQ2cfj!O4!h)T0h(Ub<21dkR}Lnwm9 z+6jqo02@i=VHSqq@?yDDHDrio@Sx!BOcL*XGTTH}%^gp?l5t>!irP&_hS7L6FAu4s zc=0o$m`~2E(=G`1)aqhGNPC{_VhAht29L26e`yDj&pOaw~#2gn-8wEe4XXJdwqOfRvL+cK@Y=tf1o#o78tDs5o8BnyYCiOsXXZdygC} za50D2#DqlDR`!N5S63SR5B$PsL5a=A@IU3mWt2sw*=K7siEcCKjWTrfV)!@e3t2%& zhM|?{h1AZ|KZ%uD^E9P_45zS$J2ROP&@C!0Ph>Hbpxut}%7d0kC>;!%!@7rWj4U@_ zBLrecxRO2`oN+N*M~2`omS@D9@IvKqDiVsww6bIV4O7OI0J7XU8W>~`rBVdzAXqHw z!in{U-^h>qQLLMnRvoJOR2#J|}o~D+tHY}Hm{u^TgyxKOTWmeFU zA;L-JV0uhE9TQRyv(DEjC+LnngJQN0CK`HsVGEF+IRuNf5QGqmoP+oP9}AD30f7i+ zbb&^Qa=PPnoE$}FWP(i!{DipW2^JGVbk2}pA7naY!Y2R4kC{J%(emBc3X(c}V30jmHElbu* z$`j_n3y%DU`;v$J1O(sL=?QszDD@X*iaJPEJxZlcg|4JrQU-}zr?dy>=YLWexMaD! zOz&^_dpXG_<(HrM`|r6xFRyh!={$2a=7=S>&$~HD;v}H@T z$+Xp0H8i!St0p%#*R;(@H&;y@?0p+QqcuIey}7n6UEia3H@IQPWYcZUge=>-8zgI< zL9p_FbpsoA6rn1*D|TGAt-Ur&$iHmc4L{b_R)d09>rTEAyX;J`)r%;(vAKbeJ$LG+ zWRj7P(;L%AA2fdWfHnH841DL^)-0a=2x@}0x@*wU?M+Q2^31lKQwNq*)H>KA}l3>^|t!?Q{rm>}Y?{s!V-QSa1V`NKhP187nWyYt|>+X;s zt3-llb6xtF^|}QUQi9j-7ECe__`n+SrVWz7dpEUAu4xjiN0WbUxP?aMiH*DTo7mJ+ zQ#W8@`#+LYD!i4r?ccgllA3(n$aH;n<0Scpv@~b@nvB?`-zM8> zB=4Gl0K)~{EXksjwnq&5XOhdP!tU08WXsW;7hSpGyY$;uAyXQg>e|xH|4MQ%iRWOJ-8#v> zM%0r8BkISuwWqg964t{FuW8Dpw@oU1T)HV;%iW4I?VZ#BAuMOSU6O?lscC{&jjw5I zNN2ZCl67Pwh02dKJsUZ#S@0?T#-rD{CpZLrADBsYD}H6iNiFxo&7orp*$P#>1nO9CI{#oIS!|&f`XA}}n?S{VK@TBNLqqNcKqmSs; zp=n6)pIsAbBSd3$bwksW+Z#qS*S8FBY~o6onB-bSAhP%o(^_d5JxS*n$`lI$2( zq8FU9OG3j)5XsM*1~D8&jY-{dh=|90nA(v^r3Co`X<%GqU3yr3Jte1^sY(74s)A_# zrlblJV=30Oq+SfehvuX-Y8(>5mZUBRO(60pm{4mHGx9N(IjS23&A}u&n3&iYc2p+O za(K3%O%gk3gdr`hGuo3PNstlH0KTz}nreDda*oVE0*~${KRGy zz_KmV8f($0$0k{afbph1F3C*=ZtSRoj@NZi(gy`<$h6jDYNs@u(7kvE)ih>LOj4j= zIJza4!DIBrUNeSK5<^wLD1qoQF{b4rs; z6#@dq?P_FAbNYD(ys_W>M0JsUP{^Wg|C~gwp>9IJ&n-<# z0Q^o}fX^#U3YlZci>C9*dGv|rC+baLMK*9jV#P>rLTMLvC#ism-tVGBNvT@n(HjZu z#YJI-1};eyf@B?2lgY5QhW2Uc=Io`3UPCR$g|HG)Qq;>53+9Zd^byT8l&@*JJkez& zcvQ_XSCsZkNO!1gMoH21^suHh>N76gfR6=<0+STuvNdhlD-#8#$|FtplCI2EiLOIn zi5xtGPm*7q$XtSnZg5N8jB66LfjI?8Ls{9i#Q?$axHD^!G1+=N%T1% z&ue;Xscu$HrWfIKis~yST5l^&8ec_7LQ_=>OOq1w2%SG?_1{w6XkH5F4|zP3xIM8M z!f0OmI}$Spbg0C4Ot$ULMC0Y1t^nSZXk!w{%f36gRpp$y->UZ{`UNKENCeLL-o*A7 z8MVaTmnemZ`pC%$KQ!Hxt+_wZaQ&oJXybvz)(C^S+;*vM#zZ!?lIjZn4<=evlz=)J z8a|}!9xB}}DK7Ig-pi<|7%%NZY<@V=6h(1Ju!V4o5nOUWKd3_A+R_{M4JmiFwU ziOnY{L^3agdMwd*BX~hLq@}$%`*>nYBAxWIUMhxWHJ|7f?x|J4pG<7{Q1T5pR$HG+ zthUH*d2USvSp9su+XB2?obY^E^O;05M*&`5Oa$!Nl>iTZZY97&^4)@Y77w+gYoG5{ z=@QI87bivuR56HuFC?Zi66+5>NFEBBOIDhQDzP-N5?&Tci5L|zG@Z%5nAorieE<6T zOgg))c>WmFyi^1nLs3thmx~a`gO6)zZ>vqeQapc%^J)=rjCeh9UQ2Wnp&bv--Rkw? z*+ZH)65;+59|^;`znN%o1V?H~V0<`tc-I?!rigF|o$@N8d&>=Mv+L>rzgWLAUE-MT~ zx)NQ&15(*55)DPH5Yh6Cs=6-|wH+q%mG@P0hsQVnQ6WMhUnd&7;4i>@T>DKCylH?f zcz;_2Zvp1KzbhKfL*e&{qVS!ILYoM)KNJhb1jUbuI_I1Lqe_xTb6GM!C0clxgyUKE z=S1J+1VZg(IBudhgs@zVzjV*pZ=qki=NxLF--<=^I?n8oG#AIE9+`#@Q4LS(kvM9> zF4RzlKm@aTBn`Pa^AG{o%j_OWv!7v-ac#9!#K}F9<}V_6UcxCwmp~P7$WA#maf2|4 zz%ryBuFTVVB+Y_~H6>x~lr)~6C`TA9Ez7Xxx-%17R>(3c zU6Y~BL&6ktMF>BvxwfUw!=JS>cv8;X#AX!&`TY4r;n_u0fo2$JrIl)cbZTA^Mfe0f ztD0YgO8so@oE}NDIbIEr+HuzBCc2?Ob2}q@JFiF5Y^%UxJ2tDEUPEhEqQTBzX`(SL znG1UKPnbW@mBcrGURZ=?Nx+?VBhiF(7p)uxiFR=j6xcLAI(>{+#wA5kjH1;CA=RZT zM?u|;RRqPjrpDSdRbP~GS&wcuq|pBQ5Cu2&%U7-x^6x7W1F>jGUJ6tu1Y59@Bvkt= z6C)+DC5)Ju%v_b|9Rw9PIZvM$`UI3{(B0DnQ`&z2O_$?|FY zqQIywrJdI&iY_@5cuY-O&9ux7iE%OnADhn5e0=7{V)0bf18dqcHzmfI5Pt&SoY8VUMIWSh1EU zWc_bqeZ-n7Ri?3yHtXJ=Xv$#pR^FP%L!-G<#?P3bx@7jk!xq#X~$dN_@+M%84e+>>ZvLz>bxZQ-@b%)QC+jOGxV zj;@)J8PVL-*qo-NL!|xp^+;MSfiO+!V;Zs08m78GxpN}DH>WWMO}8mz5A@h8sZWD| zO)W=r5(>T2BQggyW~X3{FJmVvg#010JpW)(0f07hLyhUoLy5sfSe_4lIMMV_c~YJ~ z;#`!dW}qoQ<{OW~RF5QonRlZhzPDj66=>?*3Twt%*S)y&n0%? zk>(atH2K7e`fG|L5ijBS#JI~h>G0|C#fggMbLqsAvi=tmH79|*>?MiN3E0RZ#ax;Q z6^m|!#hBp5ME&|up0Y1XGjPD23=puwY7fzF_)#qC&)q8}0HVI5qVfiKZ3?^X7gtv4azEZzWUkcM^kL zlz@7DzF_)RkD?b$shH4$>D!6zD~iK{sSxg+MAuZ%QnKZVIjutCEttNW*nEOQta}Qf z-s_RH*&%`tEttNa*pgT=^CrBh7+UuFpj)`7RssJovEjiz1jmBuM~T%2fwurk{NeH+ zcUwS!=YIc5qM4%rZ^4ubV4to8c<^T{0Uq*sw_v{ZDYRJVR_PMVKfg$f5~yMj+&hye z79nb@!jTr8M=RXl%WtzQ=b$Lyvj&NoGf z9@u6hdAFA0mlfy6X*LxHxb(L;5-2TP&|7`^J5~MCb7g`eiDXr|0%HpBlxhR z2nu)oIk7XBNbaa^VtPVLmBbS1-7kr<3S4MO^VeiJ79NSQpLPG180-Bt#4yRsvZOg} zP7;Jv{_9C)NwfH34UtOVx}H^*Gzu1Lh=iptv&)j^`;kGCzQcl_T$VKF84!qU^OUlr zjn>2(3xdR+zMa|~6bpg^dRpQs9a!fRxYNs$)+T65j1J$R>GW{*=9G0ay-y@G02KVs zC<07K0Y0;=o4I}BEWo@8bBVn9qK6P2u6S0lU`(IQO>A<`88DKC3&OHzCt4mS@KrJ| z(L6#}zD_g0d(OW8&gq`Bz;e##7K`R}Jg<8>Xn}^Eg$0{Q&;vcc6w zR6#6wkwoZguPLGkpMZC{*A}5tzbn5k(G9&Cpx@`LuTOMCf#!BbUUfs+O0AHI2Dovh ziD((>rm~ep=B@7}UXeqdT#wyL&e+O(GDs{IG=J8a1Kts2tVJ=*xu z2KSZylS49mUqO{n0KebFcSYP^wvA*#k55m_RP8_cNSZ>~DnlHaY0VY$Fc$WVd=K3ulBT7oAk?$<)ZMP(bQfa#5y z#_ZUZmTcw`11+k_X&+4}9MyZwa9`@_@v=?TvOVG2vD7j32?MogrxA5emTk+aGgE5X z(sfl?TIy<~=lrX%=7lf3!Rni88Zu9ntt-o!I8oxBPEc`UW=uAf0CnQbNY@ zEzcUHoQ4gRv?=JhvJGU}!UQHx6KV&~%pJ~%@mce2} zp-@eRT<3*Az6#CBt+T#qR88v=1AjD&;J-9N&(|(E12pT4#=9`hW!k%t474v9 z?}GN_$XzZsNV(jv1S;dTYU2+}a@k&u+@gaJ(`{LP>$SkgI8{xZw+#4t**~P3`3?9U zJ@`lJdm|!7?UZ!w)Cu&sDQEa*gduE%-*C#rQH*M7c+UV4U6{YX4E$`pV6T6Z!3r4WVe zGO8vs^^27#iJmHIqy6KZWdn*X$s-w3(^^wY%lutsyR9s#=owd(?Ygpr{86AU%ht^h@YPy-cv+ZZkGsqLF#-+0`RmCpdvMqVFP4{7hznFM<=JRXW)_NWh z^ZKo9t3;fzrJ3cu5>ec6PAdOt>g41OtoQ z;l1|BS|W6BrDA5SHnTF#F_iJ?M})5`gg5fMmj6YWNzkyM(F zTdYl=Ud}hzL@*h7q?3=EQ@)|5CT;2ZGh+3CC86?X#wsuRI!ak`S|U{btnzgN{Z8Yj z+s!TiYw#zU3_QDhgW&hN#+ruamQ1#>HZ!mM2;P1&IEuy$C%HRr-ERPD;h!dq)2QfJ zVYwBAM!X0ETlf3-UIW`9jbgF$%WM8n{;>FS{-`>59&v7Y`j4qY#N*B@ul+;I5gvPf z`Q$&e6z=gClpp>(3!#m6jd0hnSxs+gtW&J&!tzOfBzqXuMSoBYyf(kMyzURFLBymk z`Q443+zwtb!lEwy-9BDaA>5#>-|geNGU9RSvQ=7#IDeSb<$qKiyw4sWF)&@_vUscXmy}Ie!_%Is-EIKc+?P`%A$X~05cz@?0FS)s< zoS*UQ{Z=(bq&#A@&b#Mpi!ZmuJMZ7*Ua!$kTE%*O!ao56{F!4qlD^oRWg7 zV1{iV7f#G&O}wF843MHELBgZJZ!G82%f(1WBT+g`X*4|tb5l8A?SvFq2n{6Rf+#h( zxjZyFh}2*_RTbN9WgXm2DAI zvk#Q-4kHgVI*Q&gP}7jk^l3=bxzaR4Q5U*7gqnQ3M`@RD#(QR7t~W&hXQvqyI@qe| z!E(On9Wc&R4fWG$uMlnH(!VJIHTCbP;DU&>&^0m z!Z!QA1q5&WAVw*U>b|Rlvz*|6tNg%KE;Y~H-d>gQ(No7et2EZ2m=S=Rh>kLCpwAuSEa08gMFat_V-&ZWc7GT%l&Xw`CEv$@VAdvl~05? zbD#M5&r4xYG!ILklxGzO|KsvtuYH6LKUEXcKQJean8j!1nLoF_yk$TC(?%O!bqjx9 z{tZ*2IQfOzqQm~cp$19}f@tTTqFa>dMcA%CWh56W5aD;lpH@rHg1%JS^AGY+)H33s zU;QZ&DO9kCNMHXcfgw~Z4-DUw^PQCXiG=XXMhNk(VJ3AA)R2DROkG*(>eBD1H#EZ&b|wl6+e4PDf>w}A&{M1Ks!CGl)Nm5^i7U z&I?B;RftimoUK|pYQ&aVzps4HZ)aBw`90D{y#C}0F>+qXT6kQ93!hRk=zoy}i!rCJ zyeeRBo*1XCd?iBEq7tW9gtirVD-H1`l}pjsxiqID?%pN}-@VVM*o9-lF~LL>Y%e;q zBEFDgqVfjWIn_Ld@w^~T6SHtACg|kPs;K5Po_VYk7fMd%7AZFh_2fRgNUegz*Xq3A zXFi@M&tG{@M(G|kJo%i8fxlZ#d^m9K?__{@#2K8YHn(WC|1r{IV_Vi0718Z%Xe)I)+ky&ytd#6Ez1Na>Jut2A(6bk)%ax+YpeN*r z_^!9BDngs={P!GkaCS;#1}eL{g0FW9Rw{(n*{Cck6}Zeb6@0Z#2W(3p)lR4L)KMZN z2r}0St?9tD6h*C_y{>}48BB+0<(c`lC&ajzP<5dHNi#Fh|%f+6ko5GrfsQmuK=Fs-Vn*|eHTTV-35jWFO zu}?TmX{y7!1Ib}%nv8|i>{*4ftaeMq$W_G(0rb|2F=2LzZl5S#5Cd+j7_n+tQdC-4 zvEQoU#bfn~#by`>=s*|_++n_rSafFv-K-x9t}@&>+mkLN_;6h{teP%|Hiu&iv}xVPfp zT+J&%>8AkqRq*HjW!zK>@#@3h+XD&iuLv!bgm#r=>7Lk;9M1C|sL=00iK2Z`Y)vW& z1w;vg{O-Yu?swgwSMqYChlBx{>k1QixPtGpkxk4SZcJNCwgqBvjnHE;SsaU+S)^tk z-NgmYN{I%KR16OL$I3H640yC+c$i61F(4#L;Q5cK`P|AfB7c8e9Z;++2kzxh=)*CZ z(QA_@^*#&)8t^H7-;CS*Q6R5xep=)uvYll#;pOm&f@jRdAd)<*4;7&2q2f8wVe9x) zh-je*(b6^?&(-D4754g{=kDzO+I-4@nZ>p^FHP4B`Ld?LDL9Jdy*!U(*Kd(2e#Ot@f6hm9!d7zae?N z(L9MK00d?r0R%*VoIRa(afPmGpoY~|t@^4-LQhYR-h1!8_uhN&z4zXG?|EU;#rNgs zsvG*jhh}{dk&%&+5s{IRnUDU=a}oj@EAbf~UOPS}o5TGSZb?Du@cQwec}`3?)F?Ie zL|p$Bu_t4BMmYk{Pf2c^P9cDuCQm2(00ee?z%#4{XmcF%kHHbWWJiJ}eR-C{POUGi z!P@8uf{LTi{5WSdtO4&JSTMc&L->yzg{8@sh2PQjLwH>hAb)M#Khz;$p%+C zb(=M~wX{|ZUSl(4JaeT71ANPygoz6`U@qX> zY&jxL$+vj??q^%MkzQK3=p%u{{k>eyvO*H!XyVJuj@8f~nh5v=TQI49%#pf^u!BQG zv+O4s1?Q5DQc+g4om+A(_C;?(y1q-x;-<$-lS13JYfGk$f{1WX&lR2BTEu?E;-s{8 zgboTB25R>fv2&7-hB1eGNcrZYf}B|G+p|fzAQfdW_iAZwN;xEOO6@%ZPSgnPBju7= zfsqqMLfhDVTf~a68B#nK_G?msU7k>Z_iq`ExNwR}@zlZrEtLG!T4&=-zB>e-kq-`R zq2y;21Oq?5ae)~=sD-i_Q9v-?VBFviyc*o)&dc|MTPWEbg{9*|0Jvg@QoRDt+6ITT zh-|ORVX*}F&#$W%8t|^op)HhxjuNal8f9AQ9o9mrV@bJGDdJ6hbXx}{rH*P5XRvHP`8J!< z#L+Ecza~wwRG93{m1A0(Nq9H}aIziSG#6@~9G7o?INbG5+7qN<%^_CJ z4^FZZTapr2C_@vGoYaIjaF{2Ddva5KcU%(p{gkH0!XcxL-lREmL*>&z0$8?qKnlUzI+34i1gp z)h*Gr{YssGwEzhS}6>;uJ=V4WWscW zaYKuL>n5b@Jc3x$bE6V$cn8XZV77a1YKhhXc_ukEV(uimS?N`VhSa9dE!i-z{|e*Q zY@I<2)0x|RK`cVpAolizDY2BU$%9Z=7?3+!IQa%5h}c;_2CM9yDUx+??GWCj8jF)` z2+8#P?iRjND2w^3E3801(e~ov&x3WG@k>$5AtDNd-$UPMeY%~ zBm%m4?-Ws8Q={8C_2TJKxgv8ROS}dNIPLYApCsyCh~(ofbSHvhg?G$>uGo0R%Oqiz zn4g0uS~yxxRU(7JGfZjIlPcWHi*B_4DK_=7HrXu6$Sem>$0!uyW0KHRM+q*UiBYH+ zEW_Nh*(?s*0J_ERxdgZBOb-VGUH9|Z+ffer1v!g_`wq1ea^Wv#vx&%|!epEHQVVY@ zz=tGT>fn(pf4Svh{M6lIxK6=eJvCR&9lhsgXjtzcUM*sR4Pn zMHFtOE&08j42|u3EnDZwHYbtfDf52I^4TItbLoQ_iqFx?4`W437Rvn8T>ngVm*+Y!uEn*8?)3MnpEUxX$E{HyJm84n z3mJh>B7-88a8CHk7P?Ue5HXnX#}%9rhDF8$ zE&lRGEhI0x>hn)|adDm~+?`uXxGA2ESjH!U0cPZ6k!o5 zxX3F+NNR;7-?v+ET{mq$AJ@wJF`kt+<~bZlQ#`xn z@vY*vE*kYXVBtC=Ap;JTvXUpX$~%P6pv{;ln#&Vg|JiTanx}5XeNyYH*(MGK^yF4? zg_~83=2$ic;FQ+?>2f>6ffJVCR4L`zA+1fqX|3{BteNSC;+tZF(`Qwc73DK#S1FXW zICFND0;e9i*R$lv&4#ks`EmBF$rq)dOvO2~W-1(_Xe!Q~Rc@6woG0ZwgPDQcYUNd1 ztLM+!jCP2#Z@*yHCY?i?Cf$WHAO{~s3wyI59s5Y0( z25)L$FO@L?Y0H$GLlF)&hPRNCT$U^DOQy-Xae1y7Etw*z#1&~OK{HjV#FaA@yAyp} zHB*&vXrW46Er)S&Bo80W1$d-{M6E5oCV%W1LlZ)bYx6HHVu+CwxlS%`BA~QJgX;h) zMJJ-XKFgqk3}E{a2y*`BhAcRsEH2KCt#mejN=+j_b9y~^Q(8}OP{KXAIgKks3iafc zEI6T_+&U|xhI5HV?Y5a32JDtHHf$JfmwKPyd^r?#^moThjg3na7le1thT%}%zH3${ zC5{M8%DbiXnzR~7%vz0m(v%;iqm}>OR(iTY&lLR%#qH{#H?0k=7(!xmDnHA83_VkC6<4mj_$vEh}6q(M>A&JKbyi zP-}9*7Xo6z*TbAXid$=u1d94Baqvhh70D+;(@E1uS+y77Ha~&x1(!ikL zd1-fedeeeD{sfpLW~cQFt)isA30h!pUThV|aGD@OZses_&yi&u1#x8g1rR4Pt%3*3}E4#g7~ZAF|o<0oqP{)at$P2@Su#@abcAmwr0odz?Or=U?69^l2*{ z!SazS7e8zLIckaTBmVYzYo_yuA#`E6zK|0<&iW;hK*RNAt2msQXeYe1tlj!b+T;AB zz-)cpn*BtimmRWN-}u#(q5!F;-_E2xq(|+2*P7{gpqJqitRLYGUUq=r%hAX+sEUvd zt$)bo*^+po<@=8_P*ug!Pcu;r6f!8r&TTW$Q?df)u9aQdnwxw`MTHH!wh8Z=d7K;) zIQe#)0VhhfyGyy`;v}Rod$cvD#n>rDinVypwoE})MD-j(qFY8&b2?~C zAV;-Pcq*GY*1h zzodJXoXLG$8z14wg@hL2_*|{2S$9I)ZzFqu@hpaB{fTYz@%QBZiFtlf8=oA>)=S+k zrfE)=b5YBY!(6=*J*AB@4;VA2u8w(OsE%Hj>Zi6*nFz)Aq0FQVrI*6_@10HyD;mv9 zp=hVK{UwRmvzH#0^pNwtNP%17gtuO3QuGKFMy9(?z zxr)o$#3i4?1)|lxTuyhg{^Z5Af5c?i6>O#Tbh1FO+AZyLC3_>B(fmRq;g|80ANbdm zg~s};n28WXK<9<<`_=yM^!6#PsIOr^9>TBI>hRhqzHfjuu4NH~VDOIP>)QMWJPB0a zO{cdivA+5GHm=U`r3g&cj}c6I;0C2u8E|Z6^NnrM`{Z$odpJ{Nx;ObHrF#+F?3I*x zB9?6GE$sY5l7d_fJiUvO3~pt&8v>}5tEEK+P`ul`JkaM_WqPuDdz;DldheblJ%@3* zqs^qIV&TfcKTX%*snI*b0ShX)8?fBfmg}|-Qei#jR6=}rn@H`&MeAY?2m)yF?`fI~ zWoYir7U+Ap2pP!xvMqz+3GsU2{x-4b&mk4f55^P^G$j@sV&#G#Y-(^E0ysDiN!hYF zPDunSJwZw~oAPj5{%bEBLf{!5X%qSJJggYk`)E@mj6G39!z28dluE`CcF5?g#^X(? zic1Jp<%yA;xWb+AwbO#qbKx^otgeFSYSKzOGj_7w4*G zUvA^;cfByCp;zK4IURV_I>u@ZDOZRL|x>J(Hzjtuy3#cw2TB~ zy)^M=o4AcjeBJ?4@%44Vs>bx%x7g)+si@t}62iTm&;j19sI{t#|KwN~9QS(^@)7T-(g3W6@g>;&viaNfY%6-r=01UA0?2Xc<4SuM?% zaM&Ma%Y}tG5j4=Rd^8hYl-2sUO&*3yaZ9p4iiS4CpS1l>N7hhymKX0~YXjK$H+_Nv5mA6Al%lpe_rR35=DSg$fA~}S8rJ_FL^PRMuD^-;$rG}uJPUXV)a^8GE$SUq8cj) zD{DKJ>MJHT-KCvQO5)loQ|1gg-?g36*xppYM2W6r40db(tDsSYm16+sdMg{o;I4d- z>X`bh|6N^MMTeAkZ%@9CNcT+K%&|v1-zwocT3%#S*8w_q+P4&IoMU)-6xH%b{4aGj~|CQ{N+i54IjOl`X+hYO{ z((po~03NH}*suN15(t^|zx%g~1s6}fjNP`A?tpf-)gpPAkqXTJ1Dg}OTC5$^E|y1G z#jdc?qaNHY7W27;K#t;&b`gJ(&e6;dt6FfVnh82l9w#K>^$%;8dkC43uw#ekYE7x} z5$$phA-Oe$q@B}|?Q#zx6Eds*QSEXMArmU)SdY%!P4rx9;E%~HR0j!#daRUBvbL~+ zuruYjc2Al;zNgqUOpxQ-J!$rMEHnh9mnUQ%4QxmaC6C65vX`;5N?1Ux1t(=5N~c{K z%9C>qrQ-OMd_qO>fKX4(CsgE=gnF8kOxpNkYj*rkZx;(JYbj{iY^tNqXb%^&o9e1H z6OfL_wVZK6XZnG$;VAG~?P8N0h#1OzQF5JlDg|dNH{;povf<5^=SX4Du8RFEjw|xNY0nuCl3+Oq6^ypj{K}}ec4zbZMv|X_N^_$ zSH;e zB@H6t+z<@VO0sz0k98rmG|rK)Yq#Mg4k+}J9dqi0?^+MDrtu0ib z0o^H()1J z5)y)M+j3(!w^KEVZOn=l_2iazs=KhCod&nqd|7SBTjM!eve~A$C4Ajt^V{30l0*^5 zQ7aVDfR&1Oh%dk`ep(1IXK-iu%R)#hZjbW3tDQCuEvxip(fV?wNRHv|umaid3mW&d z_v4ha$V(?yLs7@QVW};hSc26Y_l1XO6`YzMZ>(Nls^0Jav>31+2!C2ss8m)%O03j) zFy5%HS-5P)qJPwd@(=j|$y5u#hh;?Rn&~ww7XHKHMXNQ*NBodPQbIoJhXnqAyM}Ai zHOfhyeZ5`WtrwRv^^Kc|+&SofLr#aLsp)mVo9*Jlq2}pfy7H}=+K&>~ zSHC^uIf~MUIr@&2RuhvQ30dRu?o2v}q*Pe_-b@UnLkA7y`!nT93H<{pt9+V(JSjR_ zvp$@O-aGVI??0M}o;uVhQu#Q+2%@iLBlw93&6ZOjPF6X93L}i&J{94h15hb9K4bsv zH`|rMzirT|#^Cez)M`ZyyX6<{T(|@sid^GsfQUz>XkV(udS(RFsIQcHRY*K*(57n# zC7ZI-!pQT8ZFbckVP{!=F25J#!R&T}}^pDY3g0aap`Iaw4Bk(2~>ox=&y^j1P6wA-Bc zo2u>5IxVqA>^_IHcG=rQhqcEX|Dgpm0-)@?BeCZk@v@4?Fp5<0UUTGoC(&3{fTMKx z&e(zy)jlB+#kCNU?7pFaPeEh3?l(ui6O)2O(`Ek*-9ZT}g*+gGz#MQC*nv_4i(__= zIexNp<)Ar#&HTHsC-{1V&B3HRID^CxR0*0Tc8KK7t1b?bc9(}{5VVVi>U&s5K`Z_a z&)R*QUC{j_WKZIyjPO>VWMEe63+bN+(l?@3{5XQM#3JX&%uY`%tZ zUEeVwfw~UN2akGn>>SSGD=Wf1jzzRxK2Dm)6g&{^@d@TiFsFu&RqF)FUc3ktme#Ek zLwX$BBaMg3by8M&E2NV%%Rs5uDY7?5T`>739J zK{Wq-MDVhB0tloCT+Tv3aZxH(4q{-A2wX8I)1d>0@|9{zxjjXrf=!uL*!vpkTs0?j ztP$zavBs(EKZ~=C*Ukx@EJTRN$-?X6hY{foqu0-&t6OzK z#;*Iu@vK9U>t%w~wUsqG(GuLCW}_|`hz1nDRD(&tJ7ZO^go92kUf3}** zO`XAIwU#^jnZvA?(TQk z@Gzfm=W(~6A);6dM@|eta7RAIaPAXhcg~R|5XllyCYw#~T~hp>=*}JNkhQ;ij;x=^ z)GitCdvfWRYWCiIqmAN$(Y{aiFipV_%PQFYnfXLK<)9zPJQo}!oC^=;YE4PyA=$r# z5yaL)BlvJ;&2f-fa~{b&_zo%!{-bluZZVZa8w*Q*uY#w$A7cxM_7^q~>D0Fe>TwPM zbY!i=03zcQTtC6YykNHA`bnO>vDYT4Wv-_Ni<+Q1#U#afF zcpR~N^}KR!S>aI=U+`I?*oN$Uc~J$;!nDTX!R&lVEtaz(khOc6?Wpo+AUCnaj28Ko zIqpt*IUs<4F4b$V&T)$n0CnjEeB;4;jl&a5mNvY%!+rVJ1)8F_b*+jd-#xvp~~CHZ}Lc6y10p}02VafnnPtbs8)6(U22~#eR$gmd24kEPyN_g+PJ}q39q|u%wEO_HH~yiWSz!`}+mC!9mAxn7 zV@rasUXYxS+I(VRR_$1BjIWn4F-Z6J%#MR;gwofWY^cJxUr|#IR#~Ku7dw!1QLD zy19e{J3LE&4Pp$`K^@Vf0hW--BOKfjJq&5Ul)XJ94h99QU=EFA3SkUWhjozaRTgSoCKXK+_JIN^F zPmb*HKU0>7Yx;Cl2jvzJSlv{CU3PD(IJ(26&9q5KJ{eal41U!Q^K(CrsI%V5ys-+z@y)*q_M9%>`t0N|X$@+NUKqH0ZhhlYD+4c(KC5(D2ff4=~$6w+Dp!q*6CmcF4`{6mX23u2RYeI)XJU*1Lu{p=PXay}HA*cN^Cn zIPq(gvZ`h%Eb+CVq6Cg*u9du{A?f|K>r}Lru`NpKT%S?UioYAOb{}}a80JRVlXxj3 zyp{4z8Ms0WHT*Yc7=8yFhyRw0EvSCqD*NFb5o|$$>k+vv!{|F`Jo>k17)A$)hVc%b z``WzO(?WbyhhDV5(>i_3W!Tw9Dvm3`yVwt-elDs_P8LESC3Bb~xSOXwX>x^f3Jb=^ z;h;w>#yuVMlt3y16SHLQwE>*=A@(CN?nH3+bgO@#+#2qWBX9bPxsX-YT#kRK99bd7|3*bj-;bq)DUXoYKo9`QpG zO$qs^9ft+=dSQdVv!(Db1dmzA5zQjtViS*MJkD&Oc>F*M>g%R4JsUj1E)gN26ZGCw ziUK{^LEB-e7%&Bh+*5Hb6vd~UZp4K?ZNul)cu8D+gH;q#w(cUoQBzEpjI z$u{tB*h#LB>GtTWK5+jci#3HTB!d*ympa6~DiJm~V4x;m?)Vq-_Ie@j*=G91rgUBB zT3EorW?W>FV!H)i*xH2oBqw;ZMg%idPIKwm5%>!W0FTF@oGoWZGyemY<0tW zyVpAY*T!oGobc-%Yc?KzvWstY&=trj<4ET}^osILwg6dBlr?&*gPw-Tf&mL%RGjHT z1@i-Mvnj}eSTEsagBb9?(?Pq&I4d1fZ?A@Y*BVl1btl)`>V_lne#?6u<`D+Kvy~~v z3BPYw7QDyrH_;^b59F!_OsP4e%lVO|lh~i&!;XTh0lv+~wC@<>YAd1a=9XeUe$-J) zqmlMKwGEt?OJg+cd;G{i=wKf{_(CdzPb4#LNeA*@c1)zvO8cJLD+=Vl+L$v{iSO%;s@13o zpw-{V(V69`gN@i}`t8ON8aAWWnBQ$I^X9aH=I#59*%ze%Kgh9}y_ti3QElj%^W(;{ z2TohOZvJUw%~7W%nxi{+Qr=5PGPqW@R~ZybK^c~t5bJ~E-3E4w%9EvCI>r4KuAAnC z+`?%r@YE~BUH#z5h7WwV&iJD$ln8+Kc$uhofT;9u_fD=p1G14rTnT8XqkH6RQK`h9 zol4U(wiwc+y*jz%Fe}3fU2P9`^4?BPWE$^%I(e@&RMz7f^pL>z%^@IMk189pUydPh z&~Qlhm$F@KHiC7`7UGb?O>039=uA0r;6n#1e_)O=L5{_k93*+Bq*@ZYA$>SF$B;U0 z(~usLbAVLShvpR%&RG!CVX~*`ql0*MbPn$nFU-W*kL}8Kf9D843et6Lh>LP$CuLal z2#8h!*hegnQ^p8>XKQklAD)`f59^ z=&%w5UYxf{kL#qAgYKnHHMnn@x_BxlxEGwzev*onD7m z0^v6QSqx;l?CxwEUe4|eRUED=7fXx5Nsl*za}o%Eu8nWM3es)o@{ns?5o4s%0(9~5 zd7ZTNZMYG!gbNs)-x+_|COnS>I$j>XfTx&lb)}OJSOZn2g~n!^$~k{pf2kju$VZ_s^G8<1JwX3@3rYNPKe#3y z2EW1&uBnG*f2AK>QxAh*Q<-om-?oOVae(R>r;Oh2POx)GUyZ8xl zHm6$6 zrD?;!`#QyaR?U-yi1hwWaUD?ev?%HKz-&-M%_3?Kc5dy8uBkySxtYR;{cOk)!0v6(*t)b1kJ~)g8B+p> zZp~W)_k2RQTdi$d4GI&b7rg6%z&y|PVrTqQbu~ETH3@;bIokCSv%d}&dSg2lg2}P+ z7MtULYo=;DzT7EKh>0j2u2+Uj^tBs%B@PtDB|%?}14W@g%MR7o;y{V20DZl4SXocF z-+yaZ^6XGr4p;sE3cB$|C!Jm+|4P^Y7sf&MP$3L0ZL#^Aacv+w6QYxE#epI_67=mj zP@*b0e@(5Id9EKDqK3Xd(#XPxqBOBxoLlh0K& zs90P~8O>Ns3LL)3!X1vK;O@&TvT(4pLH;UBuUtIz^IvBfCg7 zL9lN5yH2WF*UN6o_fmd_GHCVbaVR#@Q|kLps*WJhU3>pq4=Xwo+y{%rbBkac=58_B{*Zjl;S`L7Q)XIi~V2)Dx=wBbzUl>W6owmNU(WK6=z6x+ffRv z__Au1LilBK4OzQ;WY_<87rV3E4mgCPxkwlb)X3!bl&GXwkv+SLtFxV9GfeDwrN5=hOrtqkB;w(Kix*VOAFy7 z_6c27m#e+pN++2<0Y~eCg&WY&p4cUxb@1uBn@L&%m_nCN>XL6kc~mSBA9eNQuEm*j z$WO@X;wfF8=Z!Km1iE%=*Wb^85z?j8x?=Xq&^I`HWv6%1T1Jl!%9WIdSAS=8`F4tM zSCS4Z1ZQ@cv5|lcdc` z5D+avcyVqVq$4thJdcH|g|@glJ-Hq3Y^q>m>EtADuAa}c6X!4LcraBMk31!!M09}# z<(d~G3>psDIxw%TU)W_Xknw>|!7BBlE-I~2h65^Swkk~&rYj9ev}h0QUTmA^T2~3_ zHh+n2-Uo`!U)r?e()-9N6p3+Mmo@FUve8FlaQVy}S4ub*|pZ{(&SVH zEUzCLH0ow6++J|$yo?UpVl5$hFG!ciVJ+TmU7Uo;fM6{4 z?On-_SGtXu%M7#l5}dm0PYlJKemoksB)q$_YE67s<~MoGSYMjzrOogPVwD_}TzX-SjQNu`(%58HXNV(lNHzQjLEaETv0 zk`Rt8HHij0IwBl-l+6svF{vT4i@{@RzCd>)#i77Dov_o>g{ny(SGu1W0bSJ-nOlJ< z2Mhn7?25n6U9zPRbgu5HuJ{^RFCr%{pYDpk&fSYfnagJ~bqm8xmGONxlkgk_6y9@E z7QC)=BYevsVp_-jd{@fz2oe!I@e7%xhpi~Fv-Dn+9Ewda*+yuzUdkkPr#%w;%bCTl zntLU?AaL4)AYPR{N|HHZSed_;uoj4)xyG}+ZsQdHxm2($d>!5!iFTMo2G;t`R4BBU zZ}BQw#Tt{-L1QJD{Zf60l2Z-$_ROL*z3}(M%_u>#M(=cuyQ@my61%x9jL_D1W!yaL zt!Pv9UY9siHv8@1HpBZ(FJux1#F=m(%q;j%XhhAl59Mg^O!K57@(;Y6m>*?J6Jyt> zv@icSTV51#U|u>|*iX8spc&^@FlM$6c$HE7w2QXL!ztR(GKPTFf!NRdX=fjXj<`PW z+DJ!%&1C(eY4r~A9Xjx z`q+{!Hvd&QSPHIjU8%lzcVEzeM8j`!?V|nEKHdHHN4Vmow9{W>P1e5Mw9Brc;1(3V zsT+F;G@#Y}x+%x(g-|lszuUk0gG9^$kOR8?r!5djzY2X|x7@05xq-X{WUrS~e(s*w({}lTvYEX?l3=%j9Wu*e-!cyWfueHoNMHcn1ppGQg^V?HH87%*G;;M1wylqmPgb?tPuSb=K9 zKi2Bo!R{I)%1=v&F2h}+3i|X^=#>SyAzVS9k)SoTaP{Yz-Lk^d6<6pDfU^=N)mj*4 zOx59A0cR({flY%02=EX|wQ){26$V)=HwGzs)&99LV}tfpsMdMi|94s#8C^Yz4Bq+O zi)Kgxvr-o{&xZ;`F6{nYvwVa?nTxu`wzw~3ij#?=#G%*4-CNC+BMf>jX-+ga)GAMS zX>&v5P{1L&ObU206;?(C5qn<7MkkkdXWQrk7RsVhZrmLA4Q|N0 zg#(W$o_s3e)^7LZk>!@We$V+fW;RM^eIdXtJGe8fZr*Laz1#Cj7&064O4uFU^6e)s zsE$t1f3HqgD#Ab9+08ec%aZXdm}qqF%HOWi;JZU}AOpt=Q%}Zwx@C!0b_#6&@9kzw zkfZ0C1DwS7B@dB)zfIrB7~J1Y5AKQa{}sI40z2pruO zC)g*4JU!lE4gb(&;8;3%DDL}O2;VBTbq~jV$B6;oABp>3tW`_!{ZU?^Mcc1c7r~9P zAeP5C?v6sJlBQL3dgpOzwtSYDwz{~VTb1xEY012nNIQ~Gq?_P05~#RO&VUo81y6O$ zL#oj^!=>iF&S*ta*_o%im$>dSms}Jn*6C-`U1qFwG*779&&CaSQH@FP94|y-2b?V+ zmYF@@O-0I4$VPp`N)(PsnJ*2@pD*yzHHt*P02&a+T6U~Fe^D_Tnm*{H)cklUeu8le zFZ0q1(k->h4lu>GQGd`RQ}gnb?wEVgah@`!ychjdwh(@z>Q^o&;Ae|p<0OaA3}_m! zcSp-3v3c(28&atk$Ay5T0!mt3xr#K%p}(0Pi$<}X_=eT+t&D0YcyOp_6aTi1QDWys zEFIM4cS3$5Zl1;wdAGaS@>!HBL|X4jY2+Lh8zQ~mOh=Fhwa)mUyNQ})2OsU`ht2Y! ztjkAI7THD=dC=BLS**)W=$Au$z^D!qF0A^Snu{_xBrP0&1?wCR3?1Y%@sLub#fuRwWjXv z>uxTs$%v?Gs=whFTXSW)U%&*LX)E|vN_r*FSdt?j-a^Fh{N4aZ1k*!sdinc!2<0z+ zP~JzG1h*k)vB5g@ql$byu=Zh*;!p8V6ZX`>&OPExgxjv#99G8@cIok6>P4!_m%Ia@ zQ_8+;k9dm5C0wSPwBVM1KKQU(k9Yx?s(W~6do}EDi^Fr|yR^3P<%2!KROUlQ^Rh=% ztt;EGXOBoaWNbZTSoZ1>$&Y+QSR?lCkx4t8_~|0le4xwPCteTu<%c@Sz7*^m4>(z< z7S@%D3UI$3aWKbKfaz-aU#D#l7VO_c`yW#th33@=m)Qpg#KWxtMT91}M)JS}I9Pib zxP#(ZTvMYON&|Xu0w}Dg+!vM(NoakdUMlH&=|kfs2^Fl6y48S(CA2+WgAJ8&cy$PD ze|5ZccmmBG%0bxx9?>IC=|Vrvh2If-b7T*v@WK`rD?oXbCF(hYIIhrx~MKe~s) zT&GuU84$Mkp>rx?ts#pAJY-__#txE|X5lc7H0>$S%5p*a~B z!G%{^NJPaxC-kHyd&xg1kU;x%Vvkt!El!NEeY9*ecT$gt#`2Sb$nxYKk=)NugJS+u zdT8fV4S-&C(-_-Rqo>A>BCYI$(=weC`yFU?g#)N*@*AlL!~~&>mkB4g+F1+PH{qRyy?JYVqQ@DQ@_^ zBz_=q7Q;|q8b6Q-L3~^mKad6nq<(q4@*x-pfmbAR1gdpq4?P=1_pV@V(pWiwkgGgd zs9Y64O4xwu_0>HCXmwl)3o29V3)l2eMWOv2Dl8VkLH=#w?uFpm9?CS^kL7@nR@7DN z*Y(gIxE&e#YbihlHCvT@eYlNs0FOpCN~`cx;0--gwTMmvoRR+_9||_jk&zoYB2C4Z zQsi#x;c|7K8(VCs>gW>JGB@}57eLr#7{hq8TYCKK5g(FW#oWqzgh1i9d$8AZ+8-{? zxQzv!2v#lL-a|PXI~*{58hkbr)cOv#tG=)F+nqgB`4amb)cLMtZ8LW1?s$zZmV@y^ zy?BqGRn%Ev^zXVrWMR`2I^2ujT4@XUP|;D9)*hp!(!z*_EytODGFNdOpb zKg443Q?N_3`olexpNxTnqgr^w1zmmOET|q~S^AMCDus2yqY0WP`p!D8{NiKGjPk_* zhnaqoU_!F=@u(sCeQ75wba|qOiV$2|fnH=G*#GUHOo$9|t%u_xczcS?CiWS;k)3kn zu~Fi}wCWmQ>{Dj7fYw&iL`t-fMH!tGF~m+^$-JBd*Aax6f- zYfXoT7P9}Ibw2+0h7%4V0Lf?jIh2XH7 z@jGi7SFeX#vm^+O!1vb1udZ*90H`eHm*5A^fS_7MAmQG2DC$#F=SOQ!{D79`Pj=!) zKqtyo$o@DC>^#@p2(q1cU|mM9yI8Q$%jpPb{0PNPjU*+k39LoGn6) zfMDSSYbm;oVV^YEB3~PVg!Y|loC^N0W-*#K#QaU=gy@}6y3R5hKo2i+w`Eh^X*U0Eu9cuSJqY!o*TO;$N0p%C_iK_ zWn)pu3*q7T?ae%(ZU)8#9BSpE_nfR-BUo_A+RGj`H-0JQQ8d=j!{_?rN0GA~gfOvdm04}$Jr5#EK zfhL~x-&fcX^Fli@#FcYtj~d6o3koN*)CM_DzThew_<6zM%n;rfcXbN8bjrgNuU(Vi zUZJD*bzpZiuT5~T9wal2*Cn`D51t*r>*vO&Mm>mX;BK&XZ7Ck$Go3bRJlK~)(cWms zEC!Hf7=qqp2O$QOy#38~5W?v=(it#K-~(VH5|LZxnwxWJWJAWcXrrN9=Tbr)(6PF< zh!iFvNd~uKjF;g0o$=Cbwqd=sEAA5`-)=1b?Y7}qXudA@4r@l$+sg~ap%4RKnS_Er zJV+G^N$#{^Mj}Eu&bZ66v>Na2t8WN3VOBVI+oAA7!b*O9sd`U3*kV}D-)q~&I^ja7 z)spFFaGw+A!Wu5Zpia5pKbN-iaC-Bb^dXX!(nR9{yDss<)XVGEHy*UC31ugVgL3dB zMYsPDs|Pk2g~X`i;UoY|WImE$_f{~9$w?^Xe1S21h zuWZE=xsfsAQOHl`?l>Zwjz49U0Qq#JOC!t?;L`~v5R=*FK5iZn#o05~vLR698cj3@ z%5OYtttBWb932i{QK=)>=NwZI3y5wGW^V;seLlhLb0bcdU4?ofK^bEZjZj}q7|GAH|8C0eqM>Ij-o7>#E2pk(&;oC>$-=8b$c4Etpxl_95Tu7w|>6-Kp=B6G$ zjjbfoq_D>C!@081Fi%mFqVv(*8I%yAkReq2SW0Gbu8Jn4VJn(GnHy6GrcNP!YBitt zksJ#}(}c?lQJX(wB}1R<2c>}UbH~Q(iy0tVCt8pzV?+6cjV#y%!x?!E1OW)xL)Kg{*ttBM0CyM%J!eBzIp#eg_Q3_m5TlRQnCZPA^3%~Km(CP@jC z5@`V3FR(t?rPm|~nNH-AYU0D%=Utg%*j%FVVSBn;Z|qg`b{ns_doLxYp)iI{|55Qf z88Bik0EyT4==B$Ix;R2F_w4m=Lq!pcT=(jwEmar7kx;OAFKwhmK8H&5_v!U7Dm5O? zGzypmyZiR~Q_C?}hUfiQbdg&rP<;AY7#;&J2+RYhU&T6!1A6_}Y9Jwbt;T`9{@Yya zh^cEe4(j#an1O)N8#4}0hjwnvI3yJsG}_#lacGKk|7p53T`F?a;6{pv_4*4S^r%Gf z%)lJp>)*|aN40U{5xxE`w0K-)SC8zK*T<0?c4igVP3z;nasE~zaOc<%Y^kL}ha8UT zU9a|drpA^Rrs#x#<_#zBEH$$n%8ifS$URbV#4){)5uk7|Q8>6Bh^``oOyK}kFJ0)Qk;W2;Z^ z^%tupAzN#GMv9a0F|F+Nne3WvjA(;PbdoAcJ*(GL8Mxsc#U>`mKfBlLl1G3_PLO|2 z?=MIbX*VA(-dI2O`vt3h9~sIm&)tZImjeKDCFgBKSK>5-^ZR^h;}_F9&u>JU^N`q{ zT?<~&>$ypBwwr_H>xI4RT+^~~x<$E&i+Z!I`+e~Ptw_~Lq>FpSbKkM4h%`DlsF%!? zCuQI+?Um17lSoyu3-7&(gP*RaVl$-Z=p4yqz2X`2{C!mP*zjK7`w#9IH%*O<>=heZ zVQ`U13UlQ~40CX@2^n1_r+37n%_Jyw8q))O^+t@U+~zP*cFjh%#Y&FXZfuK%iUAhu zIyq8{XWbBEJJt|i-y1u1ZJx~5;M~AT5bgWjnNHv;({2%N>=g%#;}9^zaucsw(`X~; zf=c7&nb(@Nr%YHDkLK3n`*u0RtZIq=-y1Zz&!C>#smLgIURoI<*Np4yhASze= z)kM8EiA7N_J6V}fc@63{nU&xb8BEGl5Di&b-IT(6vcaoz5IhKY6ZcA;0(-5OZx&Qb zWe+%QicY|Rc7qeV-b+s%Xw~o_K`|VxeW%CaSe!w7LnX;{Zlt`~rXsG^XD$qaPR~)E z=gnSuBTznUbYX8b*S?zmZ}*C7jK9s;e#ip8(<{mia#CSS{cf+UddSHMMs4r){*CLq zJp-tV1y{gTj+I)WXa*&CU#?a>xLisMCBGl^(pwq{dQw(r!z)ltNoSb&$ias>Gom6d>nHiO#PwlncjwdmBkWSa5&lfsM>W}U^#r1& z&t*Syp<9ph1*-~Xr^5wR$Zyfs0R&(6nlo+;%2g2sJWxV*)u~VWN@}3%CtOf;VqYh$ zmyrcURjrr5k+w5Jm~!QI-Tp1_V{7$haOU3T1?WCKAKfsZrTe|K`4PI21i}wKfjIP? zUjFD4h#wR@`cJv`kx`&(7Vg}aXWyHYq0lIxmv8LS7t#dywLwR$jen);2P}iwwePPf zsE>;RQ25%5;3m&*eOYQc(A680uzR1sEJu&J(}by$*`qH@t%(y+?Aa$gp{sZlYlT#G zufF8aECdb%xp#&JoX~6^AGp#I8fB~uvkJR!AC>)RkqCu#c(Dlk^?5R04t+;q_wS<` zkTlwA1|QHTZhwq$LNgeL>_8vOyzk}O5X8L2V5@$!)@gLHc_i{#ugkFOk+9%_vTzt?X>#)AO*IPPl9Ns7H%FiQ4a7#x> z3FN`HUg=21LY&dS({FVV@VX}Cs6Gx6@?slQmlHa!@_f5x`M%VcZn>P&pH?GhCs#K5dkXEh*ZPzMb! z?NgVqTB0ifnU(^~&}AIjy3HC0O;7j!@;<(9+G#!l`#X9^ zR?*)OL5^>4aCH^$m1-1pHpY4S#ry;bn(56pl|^({^>JCM0m2&~q7BP=GJi?etoXN2`aV5^1@VbgEAsXLMFLKhUdl% zUG-z)0Ns?oT_x(9l?BSdacGck$uP(v&J_h7rdyTWZh`|GsM~T46f8)maG-9N0jY0q zHnKp4e3G0}cl3!Z?BPsyZO6XE(Q19*&o9a2cCdT)kzHF}_x^cA? zwdMV%3b z=*inhllUxGD{!L#@%dO1#Y*Ad%o}jQ8k4mf~S&rzzg2_cpfJof~WgvL&i@Tlxop*(5Ovng;Ge*WY%a3SE-s8H2T@5 z?FEuii;d@+wq6bqv|i6k!?T#Gy2#YXGRhe1gVbz1`$C`Cu4#rC#MLkMiGtOX6dQ;#ZossV*_JsjtpRmB6ClLF3nEHfU-w^!m&O4SPm| z_J)*nGlOsS@l7^udTC_teV`R6y!bvjIZdx-zZEip`n6@`YAtLU>!*?5Rza!j?Z`c- zja+RYR+@AItwZ?O=sPOZ%86`NaPOw%z~UM=OS$({l$w(PmB4yGKQ@X_VSkXn^N4La z{~_nbVbK?Q=Z>J@5^!`Br6O*eqPzI0j}EY^6)9gWx^TK&DXN7lfB2a5*0E6La+yz3 z$dTp-pNeI0v{6u`(oUt|GtUA(VqIyuV**y(MfqH<65P>CL^HDc!m}-uh-s6aUwX0z ziKuG0zv`p2FY%Ja3tPWtcODC*F3ntuV*4h6AgaJP68ts~w~lgtmq)ZhEx%7t3gN6*`}K`;QI19IK~4LXiOG%Do;*NGL3^+IlPU*atN$9!yPhCLb={8Hvc``gLTNfKaD_5H)@3~HeUn4Ybw)?Lqj}ovAN;-F!^bz z^Xc#eF4dxxByvOoTp1t5Zg6jooJYA)Z?74S7GXyvfN`?~c62HjEY<3bW9IpjqNp7_ z;g6lio5xO~Q|Dr7R!8!z$IYWWu$x775duti9zTz)z7K{pZW+E#a6$?YT^4*|v;(>| zqO^44q6z%8OEf=&_xPQ#6V1^t&Vl zYE=ne;=44Zdt1S4M3<#d;)e(>pBLHE5c2Fx;Ayy zJT5kg1KG9;lW%-IzCLkv%9t;J)Ju7Mo8^DFW*%Lg9;@aIxM*@}r}6dcu1)C;1OK5= zZd{i#dl+)-TBAI%;rf(rG3*k&eDj7B&{a#9Zw2+2^}=}L#tfj_l%^_B4}4Pw&{gZF zCnhSTn=^o_yE1P{83N>W)%x;89X}I-xd13p~qbZY= z0M&GQEX6P`-R#%!aMR=IP~ecBNa+W9Vvy~VDPRDyx)d~?N(X~CU>Z-SSpS9f71d`_ zBnQzsoCJV=KAQ;;y82uuK=8fKr_8_w_>us${6Y#rg2O5OVitnH;Y(TIfWeouz%46P zU&+ECT8LLuR33(RLGW4%HC``)TwYHz%(Sqgz~hY+m&Y`hmkPmjz4T_v9AV(a)p2+r z?X66(zyrK?^LC0j72SV*CllO);N3LmK>h#2>LtHfP}~9EBYtllm!rl76U+c0{CW$} zlJ_$~FNJ!;t>Mtb2brOlLyqyoOwg;~>Ae!L^HE9|&wLX!vh(r0|0`y*5qHb#)3^u7 zL0v$3Ww^i(epv}p`D7lS`CtLL)hK?<3A}I|W4=%4Wi4Y_2Wv-NDe>7nE+&GU4&5Y{ zSe$`~YOCS%d7=(Axg^BFffGDy_j;r7vYxdvaSFutFcbw?h%n??BmCITtaL5MTIG{t4^(oBha5R=$#)Ehhpb`QM?_mHz5*M^LFXaIG7;{pnJRa zi@NX3jguzq*3YRlDKRWxB3)4GwtN4d#|Y7dLP_k=|5q-g%Zwpvd%b7>pQS=W5BKU9 z>gpv*z1cgyH-Viz`^5Lgfx_PGn@q37+oSu*J}a9=-9>r|O7HFN-~X3xpJSleo*mHt z7a3qF=XqcgT7cY<+z#p&cGGKhLyD(*#e5zt^*;x`mdYXhykjo)FsAdYn_8}Drw;AU zJ@FO#VNFatlpCn!;j-6@sW8IlEgaDys@4A^;>XwVZ8W||rpy5|mPf_wmqU}s?dW*T zbzt=v9TPtr9Oz?H=Cl&tak6PwcxL8UK^@;uuZF9wC}>S@Wn;SZgnoMLN_|{jD^6ER zWS7PveN-y0tkF^FV71zg2u_Sw7Kou>!(xo1u79t>;#%0jllo($lN3y}CMT!pOB@L+ zhEr0MHI4!(>!~UBAr6)7!)Z+*8-+YQ-nhgys^%su=^0XNu5n4h*NS^)ym3jRfX3yl z{Q9CgaCQ^prRK*uve)kXAgkzO98s;ZoZIi_LhG1DERAhL|8S~|R|t(do{>9`=a5RA z#sLSVQkC*?!TG81Xc8>^1*yy+{1h{DVLvVAbY0CD?enRUx<3>u+lS5;^iySC8g#ij zUYRb!Z3*Qa;N0rP{n2B8db3$=$#U_$kh9)Jrkf8g>EBBDCwFH)BMGz$m(G9_rDm7) z%WB>{oG21{s$AYLYo41R#k2N`eo>+)4*aA^NArY}@5+AKB}f}x)U>PmX`jx3HiF{V z>Q!60RXwF(^6Gxtf=q%6)?O3RKo2P_$*4A#m3AmquI(4s6NtXjdDApix~@NZf>di` zCIYBP*Eh|DlJ^Y>W1q~09x!!J!i@a9L>8U1nseuWLLSqhL{2hnduzb$9pnbD@oDaWO^XNvIGM z-Pg~RK$&qU8oIxKgbhEHd5lfcKfi)!gi3|R19>Q#5b42wk$0l&XHo`+r^rK6URe;e zrGGfbpsM-wNFEWZIOb8wVe+uZ0OqlD$IjEib?lF)`wK)ufAK_5{yh zLju+QDe1sjNLgJk(z4Uw>3(sOQGQY|EuN8vH$M%UCeL!nXAG~$Hql1!f=am%JU5dj z%{+QO!Gom@M~Ra;Jg;7m10q~cMnZa?z1UNXg{W z4LQGGO?O_TAYA(MT0d2zrm7Q`@W0NhlT=upMR+5ls#5UsW0dpC2 zh0fc_0SIbFC;)k&mgdXpQWE_F5mP*B7 z8B~NUgj$nQ{ezGcV&H2#mgmHe_(VPSZmg8QAD7l&jx_=B{64+mtG>177+z6EGBVVO`C4p-{q4c~z;g z?Qg!%#4v*XdW#=2!)~_ekC|b&*!-uguuC@EbmswSOk=yYWQ)yr8IUV*KkV;HjitZY zH7n@0zu7Gl2T1kTTkM_{7NomJR@kMRZMtVx*ljo4bg!(iP%6H6R@iN~*nFR?urO-- zW`^Bj^Zf>74lOcj+Jm5l4)z~NF@**i=V@@j0Hqe=&43191a%|_4$#q%cwnwx4-OiT ztIX&E=$EjZ6DhcZ2jnU<0}6)QhvaBUg-(YKi2YgL@lL~>j@nc<hy< z_<&rlXF#M#@rbm+RHqLLQ&X6{I5KH`C<^7*8jl)Ch#wFxSbKDmf+C0$KO8fV5VBCS z!Q`nvu>PRY|6hV<0hsTtMWX^qwVG%3s2spTN*wbki423+;tw zynb~iU=^=llN5cL&SDV$n`<*MjG({X;=0VRn{9f1X4ow@zac9uM1D7BhTUTGn=*;v zcNnkVoE3E2-`tXk1El)vEpE*U3(~zUD=ft8w`YZgc>Rv7un@1`nH3h|^}Djd!l>Py z8Fq`!@8Kv+mr#zm2W|0XfGQ-1eqV-5k_Oy!^Qzbdd=A1-Lb)z&NZ!YxnyiQcpjGRk zyk&a=xqpC8{zgEyDy^M{t9K@94=_U!fPXI4Yk1H_AI5!f;7>5k5rJC*rxcdMRo@Q{ zc&`2%huK}nvg8HzbyTz*Jj|*XA+w;eV_`$Elr9-sUf5|Bbny{33K7sHmC{aSI4vfC zA7uv|0bWrp;lT_vVt9X%BK_C^T|pIrUQmIjvI!C*W}P(*{!oTTGvE|y@VKv!U~xj% z8$Q8fM~QGK=AJB93zab#mPNHntsX3{;!(HalN=XIpmHE!o?^u+mJ92uwE$8&!I=Gf z5tKKqgA>`SYlQPOOUr)u!?KHgW?&wLmG#D0xiLN&jICJ%YlLS92ExBiSK;^P28P1F zkJmt^`fMMpT5lU4{aASLn9(H{->F z65OgZLFf8w)wkl=1ooz2Xf_x&-yZmrFq^u066ZTn_OKheyG}>mg$0>MbG9qg%Q!uj zmA3~L$18<8Jwbq>4)yB2flYj9+#>`2zJJ6u8(M=th=S?fAc&UahXemL+@=Q86h9jH zZ($JZH=STNynh@6glEqU&?kOHfa5ofa&;Q-Ut>XhI`F5y7Po@pM+Nbjzq!SeQ;iJ< z=yU&o*_mh{zlchKhPFm=C=Je+{uYMJG;ov-|iFSQU~`^T8iyBIp(_@VfazJdDI z&k`L>G(g`)Co^^p&SzOUeDCi*oRc(Ue((>SR%rwGqrbWBYUQGV`N_}sAJ)T-y9Q|I zL9fwJ?>kxEcNz2=z=hzK>hSQ3HqW~b{+F;yX+7tyx!neT9tVJT`tLsIodoE9Z6kXO zdMEIr+T>)xLhU)|^()G>Ef^m!1%ZX$YcS#oT&rUN_a6LB62-)FxDs1Z+X!DZX$w_{a{7#7>d9t765_mPM5gDsf2LIYOzgEL_!WD3v5%^R6n!rVb5$MyR z8jgAcwhb>zcLL$l{eW^BV2pc)f1I4*F>*N54{AbJ2j{Fo_tFmcj40(~@Xp(_2WjKb zyI3I3c)x?Dq>+{r+$9Xvle>@|E)1 zF^ShnEehMXLbcao65ZqEPpaAq>3+sS&x_t2 z*RD%cBOEjm&h>Fag%e5*D-YETaSGr-Y6ZA4PN5vwn-V7jG6+(*SvIPq;Hs1D@hyW{ zuhDjm1z5T9?Qb3YIn_$?(RMUVV^EBXSK%yzu(){JVD^*mNZXuzzkM+KVS7Zhhwbke zq@0(3uVn{((SnK|?;NC?7!6qHlz|1jYcQb%gTRc3zI!mS+#UJE+E=IC{hq;QPA?!K zwTF7|U^Ax|90F*??i&;bPgqxISlzn`W6Ra8BHcgeIg6d05UA|~gDEAnl+uW0g=Xf1 z&C@Wm`=P=314hX#h^haul&q*_%|u4qg+~UPIgf$ktoWhogh!iJH$~;K<_B2WrN^a2 z^5_~;u)6j{>O3a_Kbc{k6W~*WvaZHw5KQ3qbOvB!7M>a8I}FuiQmeB~Dz)17(^G%1 z@6dmi88s^i&KP1~1t$jKT2BM`oQf1f20eOCq_M6>EaXa;v4_Pc+{=>zD2L1)^ zP9nSkesS>s44eE2afq7r?S}^Mr9pmH*>M%Icn0a^!PuKHsVB6WTUBZpgjWXBE~9~4 z1r7A8gUL5Ja(>Hzzcwg0f)mT?4c6;}w6S4aO&k^{bPU=XEU#2FTuU0HH`(E)BIzWl zL3}G?*J!R7thd=sr#5FMj=_8i2j_c1n7~J{ z_H_euK=!#S2L4#J*1*&@H@R)O+V~A+ix}h+)m^ZD^fVzd!(Tof9EOaAsvDAH1UrFs-X+DulyYIs7d?$H;WEoz7&ELKsqzgOUExoPGR^Z~v zasxIO8S;lD$mNhMEvzds*ES(=b=7C!k;lK!IX9x zqQT+JnA&sTFS`!;-`^FWuCDAh#LIJ6S9F6W!J%Zj`;h+uP`5``N~-T}V|xtoT}`x7<0Mpwa=0{yxxa{=lbLzyO*;N~ z@eoCNXixM)Vzn@Bm)I!)9smp*L`8NATX;qnBn7Yw)~ zc}0TOOC)aO${2VfBQ!G3yuB*MtO|H0eKpHVe=&<5{(4PJ?;_xC>({1mYuZpcaorH* zO*KukVp}Qo;`$-JhAV7e;_+OjZW!XEehzFF!Hq*AhoZGE#N17aIc*USIy3P`~ZHQhC(LP)#C_~&HBU~?vJ1Tdm zj)zCZkI0SPIV2BAg^h2V!0s9n+flv~C$7X?dw;iD!uZBVnlLpu_gFha-y<@;H)djC z$8mm`x<*%8_r*-CC=yHR{+P85!aE$9Ai{0y0p%HeBjd&8CLd(`jx9v@uNmYa8_Afd z?oec)hb@pX7ZIRGhNuV`8$%}$`TnR{5GZFu89OHb*pPU*$~E<3-T!#Z+Ev>eBI%0l ziI}ykL|`VK3@LJq&4{@7r-tUCqE0|@@)#60sLayS`P7>^XGWfp9v5r`)p_#AXQlnq zAK_ouX+M|C8byexY4dz&k?77xjYG#lnY9;&LVMPu(J4 z*>HFa5lTygF}y|s{?Nu0D^B53bcTJC`(e@ts-#6Nw%;1!iV4?p@Y3FiP~IN;6H@mm z5I6CTnj7wS99W-l-7$N2$p0{$7mu5IZ%Aw%#`%Q=3h&2wu_?U4=oG0P^>Bt8?;!)j{z+S4IDbN0!QN_)^dS#J5zs`Z6pZAaRy z$7&%4|5Vu;XD`Nn{EQ8{XE%tEKOf@!w~n%OK?{HVLalGj*Mw3N#`sccp~L{HN|ay4 zXQ84f3g_z~)*ubwvFZ`chv~beLjPun${Nt8$x>P7_}igB5OxCfUu;S>6>F1c@-H_1 zo4?!A&A5H%Hvrl-3Ip){&~{C75h6!i>;R?Cs`o!M-8~;+w|hUb$49wB01KPSk@F}l z;Gb+jydZiKg<*Cc=14N2i&c0AV-Te-S@BqqEjLjcM!O92G9(8ox4G-EKZ~yI1&6DS zh23q~pGB7lOnmoYf9giVTKD5Lu*a}J*B3?NM)n*|eiL)03OigYxz{k8s5mQWaJY%R z)xgAohs>Yb(mun<&x3|hxxsyh&C)1xIENwj8#W6pt)h`Qb^l>A=j9m@CUJoCS)2~x z&j(r_BIiOF;-F#5YNPHuCqnq!!Iro@3&NidvFzJ~AL=^Q9FXC!r(3bhqcQyX z4BMYbu{J}TIc&0v3q!|Y7~m{cDQ)7oZh}9ZZM6~NVfXk7e?MoKmYmo>6+ng0STNkV z!;~SV*`(q|JM$RiJljus0);=HZ#fB_J>l;c4BJf}mzx^S4P6p;j?P`FmtsZ&LwXIOIUSA}DT$Zch+G6p`7v!}iL5qJ_ck z9HvSUWFht}3q#&zjg4BwJLggu)T6qWpQtU?s{>#$@`S2^es}g zkx>ha`-lIDRxA_Bq?+BMzsXLdDZczkGh z`7DuS79Y+lM<0t$HVEbTNM1R{(_|(ef>$K7lFrTDs>fKg;PYortA-o`WOp5dLYpG+in(E$-3_!@MyQHibS6 zclN(H?9bVG@wlm%e7tb)7~tjMOi4Z21QSpe*-RW>XdBI0 z!Mv4{oCslZC*B_BVy(F5bk208-o|hR_fCo;N0GVFcUdb{rkGcS>N;iyc+WE;Bx{#V zwvH}8?|W9OacJDo2PsoZr*IuHe>m)~P}AC?QMiGRhTZCTH|raDSdKdJ0uCIn8Rp;>d1O(H;*TeJv17aU@n-aWSysokSo8gxK2w>(lz8&tw zKgPFT0}rB&Z~xseKVTu+*<_qv^8H?A3BSr4R(DdYtg6SUM z22`{cTOxVw0e^BMcz=z&3%>IR*KA_yBT}I50`4-x6@7j{Jcv{wx$HXfr^KNjZUQd1 z+HHjQ6XPNNeg~*2s;>)n9~rO`A^qC{%K2;cJw|w2OGl)b*mrr|bA(c5*Z^0yyC3%& z>9Ir!WbcvxMJ#J6MRl~OOy0{AsFTH-45;BH2XgCDr$7t-*1FcC7_Xb zqQ0(=*4N3Zu@&BbBtFpxPD))x#m1J^0b|z z`BE(%F)|ue%1z36gU5=ABfTHhDcz%(JD2sX%y9-)sPA_5=n*;%n+X4_ambH1O2>@Q zNvuTBO?HH9+^E~fj;s@t0F4~VY}IVm-ERW-YZZ?hnfOm=3GPie{y(K5(9sh{{z3G} zxB)kyL4hWY#gKDE$HOQBTb(%VUu#oh(E2DEEKi^r;gCxkPAv$ zyGiL^r(yMZT83GnKu;fG|Ib5Hss?bmjy~jj#t83d<{P$6rly1SXExh8@R4VYESsGX zub1$)kh5oN(1EpcMmS-lU2oHx?f9#6N6MnR8^_YHEYAB+F##Z`^GE2iVOK%7GIm@Y zOWULbDGvMV1taMv**1Zf_GLN!wo1jZXHrC@Tdc0KH6BV4_#^@$Wgcv>o>aXaQ{&gCP~6iJkV z2sN+pNW_P-W(^GDm7Xxk2MnMpn!aj8o}7q6NBRSoECg3)Y{-V~*LdQwXk%DlF%3x9 zst}%Ha(jc22jRN>9Y7y`{fM}f-&5-m={K--!-%+2CJPo%;~Vog2V->8$ls%FAt9){ zS>Zy}U~Ifn!%J_cGPHkl{)R!^w~X{+!&ZwoDF?TX(59;M8xC$c*alzIEWuT=w~f$N zV+4SzPT;a!193l5h6JW}@d8mp;?5D;dY2^3shqn;qBS!f)gixk_XzL3 zlaSR!#;AK09f4keTcP)4B!_7CvY%(h3`3hVYE19G5zei`0ujoL*c`4(DLF#2_eVsg zDLyblMInwP3V{~agS@N=rGC`C5f6=si&ElrNh5O}*_0e|sQ2)Qe26(JWG*UH1(XpQ zplXlIkOU~5wu$BE&c-_K@p<6yX+8=ORR!Z}y(**VlErJqGi!QvgExU zLzmPdY>!cSuZ4#&-AfnjnT;~aoKseNWn~*s_8v_xoi^qvd zM%@Z%zfn#L__V-jfQ7Vw_7<$54#?9DKs#`h(%8C}Ax$$pZB^T`deEr2kcdH{CkvsB z`QXviDF!C`kkMR6UX6(cJ`WwGohr@eN)9^I65y~=T1ACF)*&Yem#-Z@njFMYNAynG z5u@Tl0NsuvMW9EH()uvm8jb;9qow1Wqeh!MAS|D zGnx{Y{k9AjN>jl+nWo^_7@fgLJ#_e&8aPf_ofIv0?Ah_7yv>w?feDQhvP}`T>?e-$ z4rvNqu~iYvKTdEs{>#gj*WPfjAEZwM6H}-1Af}`-F((O+3WHB5 zo+f9fnmds1SWw+?x>RcY4K=nLtejq3DUY8qN}F@hl@9IIuYgr%9lRf2Q@FNVDK|Ep zIVz9)rv!Nsaq;+_H9E6(H;nt)Gi0P#sz8u-PKvFCIYwuY#WfcAvGc?j^XGWZt z;-n(D(EQKM5V*?AXG#MEbOnnJ%{VKD ze60vX~A`)bfu%#y+$2A)Yp}+ANAxCU^H$R6`8p*F1O+JCzB?)ar7UB^FT?&iCt(= zhz>7;ZyMzyY3+)dr^X_`c~tI-H%|{_e~Xl<_9fs-Z_PCiLC56lUBa~9mTMk*XyH7( zJ(sF^h``9-F;f~a5AT$-EYgrW%kIiG%Oa$zTtmB`9^e^?lMMGAD4KP@KgjEvxJl@OJ~T?V z5+kU~kJn^6uHxZQbE-w7IVf%ekMM#48^CU;svr;2qcTp@5_f4mHY)6go_-)=vUud9 zR`8p+_$1)tquDNr3^@R{LrI!O@>7XO4FDFK9Ko|O!6FW@fONM*o=aF{g^*~G_5A37 zw$tSR8CJ(KUSOw=Tm@rxW6n{`7qf{zM1hC=rEDwo2ri8H%T1!ffWN|hWvZ*8XR1W# zRbKRmT2miiQ>*I~?F=Dn1NnNB+=5+v!^@SL)o=1L%+_Ey1M`;B8_h9}uhuz| z=I=)TiwCy?z@#uMCcf8+WWj<1pt<;ARBaUqK*NOw`!Oa@j_jH6K?I;bS^l~3)|KDR z^UVbo{P9;fQ{a8T@(!h4=9@G7w$RH(-gQ1@T(N22SyC5txA`W-Z~_M(*6#C#%Y^BO z7qxFPS=b&b0+1~|y`2zckNJNSvOwuLTA+K*7aJ524byOY&F5NGJ-MR8F2Wggf1P79 z_nx0?LtGI+i?Ppq&d%g(n&poq{`5-CMdwK!5#1!pI;8$RfPA@($shKp?!A2PBZU z$RqQ@WaP;_C-dBb?*0K4H#0IbGBPqUGBQqPI)8O41J5JWPwnImO2e~2j6cv3We@RK z8THhq;O%leh=hHCIR2+~vL2vdcQ`kwJ>t_lSxyhefz?%xA7`)@lu5w(0UvqJw8vPN z)dU2&S=?c}cz7}~+f@S?4*5L3#0oKVL$h4`5bUnmeR-rK*w4C8{VZKU) zFz0n5M`H~0N_?x6Fy=E!F^oUZw^oF*fO%%1*d#CPM4`T%A6oA=(xOiPY%1o6kBCl| z!;|QKnR;ChMdB~!X&Cq9s}zyOB_;4cTFD|^+Q|{3_}gJ)3c(OC3YRh0bnLRkynvis z3E#dzO#gBo0U2kgmX;YhS5PPeX+Y~AW*K*44uxF-+#ZA9iwE_ObaIE586}ms9tA?V zpF6oj%i?8d`}J5SD<(+x+4yJaSK|5@p!fqADj!ze5EX9 zzM>O{Pn0f%ggvJgx6;@krYk$~!GCFFUKm!jxN;bm)wW2Jd8?1@-rnj^iv27%UPRH- z*wz7_I$m7FIas1T#E}izAvRFt_F%eNrCTur->KG(K&$F-%z#004o24n%>}&T?np~F zI8f{*HW0%NNII|gA1`;Jqd7D0nrtQm-$%T{Y)p=PNM{^tfS;JW z)+srJP3_09k8CEqepWj_n00U1*0PKtMj}%qN7>vBJ6z1b`k?u7EV@|(lJK%DLO9MW zDZn_Y&-9VtbbiPPygtXUVc%ru12qC>|A1@;lv^Gcfl3Zj---?iR-{az6P@_m>6i_I zpH-ez#)suH`ej2d+caQA3SwPhro7#WJl0CIK%(mTTakBS)Z;=>1pBcGUf)#Yy z=U6T-qD|(3+K!GZQ5^4h9be{%!Q(3u_+8QoW$L;Tb5eJMg^3hQzrxLBSi zBfph&Kp7Ocr~Mt2x_nX@dAnQE_+)0S*VK_ERZN*FWtI`+aAQktQshfyYrEy(p?Q|a~vmXR>q2nI+!AP%M zcueWkGW&B17bej8Pz%sNbx%v^xAKxOGpCpNV}3OvQ#d2iXVd$oQGvvnWfaLR^IzBu zBX1l&4$Ib$L34bTZ>EyxNpHfnQ)zaY<>VHR4|EwKXu)yApI6N(vx2K54jod4^@593 z+AiSmEiL&2dg=BF!zt8tJ_hcEpy&OtFLpC?^sj|qy6DA6?o@P-EOQbU+ z0ajh?zZ1c0qCNP<+M3@F}MT9eP?WV4%r|(FgE8}A?arXJKVcxH7F*5LQRT;U- z)jG)b_EmJz+jT>)ylizDeUhzmVcV0f;}v&}8miI+v8r6#VwymB*0D;n*Jh*f0kG*0 z>erX?X}pueC>|Tw>@$f6L!lpDDX_7Ow()igv>n>Sy1~wAfKL_RBx*Aoi_SceljnU_ zi!vp|$mh_%EoBtXYu7j|x3yFy*83GNux^jrDk=rG)9?gUG0>W6TN$0^gtCk~WyH#5 z8?S`j_Eo82LF4wa_!+JeU_^hh%)ADPm`b*Gx8`i~4(5|lf3`VV{mwG`^)>$DV^FjY0auN4Hd&_8_7jH(Hmc|AjorwF&=tR*TrCiWZo6gsw z>t{d9YrHy)V;Gdj+mFG;eZW-}#x{!m3bd4;>L?Ugup~JVPYs4bLJjs|}e0uw?4>`Dm1C zF!_VRpoVLLpdPMaQ4Bxk8X!_F((v)5r2%SuGdeZM<@T1Pij|;);nIA9t;_g$*JlUt zcF%aN=A>_5qlz1-Z|PoC=i^%BNOC@49+a4@Sp((V=U?j~s@;;qgFt zPP?vV&YR4RX}#Ml}y1AWfB-*9rkr2H*>^iSF&!9ybOVyl}B(-3WYY$lPFj;}V%VFb%$S zE!%}`9`EfvZJ9WF=0GvLv+Fx$nV4pTwz>@>NVL8$qZlBYKz1d;w>1r^Vq@V4e`~ncLIGxy{Nlbce%qb!_6HB*G(!XU#V)Jtmf;$1B+JgWNYNXUVwmSI=h@w&f7Gz zU-syl>)<^t8dluU-D`;{8&@bv_mz{`8wwA6lLL`p_m|TKOp&f66YVTCvK}a>O}m|$ zzO+|uCK&Y~^E|GQ(E$73K`uMBoUA4{LO=AnJyh=THmWlA17y?6lUD%q6|m{$?n^;Y zi8#VrO?5Y;+rN#v+hE|bm-pH)uo^Kc;mchwO1;4rAaqS(|lhHRkO zk*~G%eb&TjT*DK7#4zHc{w=~J-K4Q zKJ1fzoNm+#hdVaGwKI>DljAWy^Hhp(PA_?nmXov8UjR_F1RP*4O zayng#*BC|2Kg+!rad-QnVGYQR`gd59SCrFPl&)7oByl?7ISDFqm`TsE$VjEvs%Rp0 z^N6&uvfO{@fnFs!;$7vg4ci1gFIcN1qz#Y|3KYP8SRb))O}WRLfM|LboN5e9to1B} zM(>nM6c_7t<fAZpsuk9uKSH8 zIuSO3o!C^)hnFTn%9JB-@#b_Y{r#-x9*y2@6{TkD${8qL+by;u* zS>F=9z&gR4Qdh(-N5(U7aCFseE2r;bwcKjq;LzQ4&24z4$kJ_FjQ+V+| z_vFR$_y-8)N?LlAj&mNS^5_I9x_#}WDP z!tu)TZZ&eSgy~~JTr|S1ID2>Yl-mbw*qtaInBIGp*_Tuu+td46P$8(h{pD8tpsWPu z>WlLpS90Xu0hS?=dpYPr6nJ$cILHf4oIh-K{+=%#t-mVur!oBA=phzZsgJ)_l?xOP zCkzWJzQGNu{Uhb%_lP&EQXJ#*Qh8rwvA2kbP%L`&WfoB!8>E3m3I^t1f()EQ)S;Zi zy~LTqE4(Or>!-5t;fu`NSIa%2w7?p^xeeAjxJW0cS1n-$`PZ13cq>h*F~i_~NhpD{ z=5tnmOdAag-$W`VY*1YjD+>HHh z?z<%h(Z+tyhs{+--rRk^#E?hOKj6t-KuM*^qHJV}^8L`q2)$cZn+5e$Aj;}TtPo_7 zt~G+D;pWU>bhFqdANvt$35Aku9eh$kP(lHbiTWvT)`SL{OTUDRf%ApyFwmK9QuvIw z$zjKT2@4LqG=+UQAZil~3$cX$$#l z-$Z4~f#GD9Md$Z7yoHO?qf&h3zAe%5q4;4NIM4Kf%xNCBa7bjoRs_d%x{gHhJD-YD z#JFE*{+HaFM=wQ<3f}jR?M(ZZc&#cWtaDsv&t-24vw!5V@$sF>z=+q(f)PcZ(Ajh0BBR?& z(9NAaUy>+fdj-0sv*#-j#uk+ycJ=6ORcT3#u zooUPCW2sYY?&wTgUSFB82X}V9jshFRXX}V^@VwI|wj-F-_-cspf-icP@9I4CuU;?M zU3dQtss(FyQfJz=4lAY`;n+UkQ+*Q>>7p49I=M5svCg1`tSD1DlgnT2Npf=M0T`0G z0)F>#Pv`$#igTs%&CQWAnbbp7_jdkYr3#nIcUKN$bKl>pZWy5ZJGUq{R+ee$v^ioA zbpAi3x>hRR-F4o8J@~ikJ?#CacDBASg;i2rzmOYwHAP>*x6Wt1Dlh~4Cs4Ql7w&Pw+K1Z7Y zL7UZ?-7_tzo(E_488iU9(3E(PNy6_mj&_~Hp z;pmGxn}KO8T4*@204-*t!LX@NhebZl88RZ>P*}o3rd8Yk@fE5RcI$|bf2pfg7zJ*1 zS!YMk`0&Q;Fg{9N-kH4T-ln*chne&eSm>vCq%$3PaVK@;Z#Q~==uw_u&OFiXk1@G2 zd}3vE15fIZLUGvRKF+YmMDNZy9Po*RzQeFQ+1WgHRKu00^Yf=Vn}^u^;lxnbjy%oj z+y(l7D4qi5pK*5$)dCz?rkW7vSr+(c_Ynu|3^;~Iq!ny+#rh9e5NV{pm!uO5Bq;wJ z3vf(n3FlUJb_Ye9j!8O>G7s@qDFtLYP*JHk3eoZ1YGw->%jyarjJoJoSkswe7L9a> zc`Y_&`W4o8HjkWz_v$M>T*lWiM`MhTGY34&SkHZr;ebx0YqU1_#FnK6%##$n=!k?W0xo5*E4WxkH2UT!>Rl$?k}KB1!^Ycq z2Nf@@QluOG;bVa9tWCVa$ZP0}E|CQRmzs9)u0V$MT0`lBODR=Qp#hN2Yv;}q`0%k7 zh7xG}U98hx^`|q1%WUM`{skY9d-b)k_atIR3E!KD9VL68AG;W*dp~cLT%9CrunU^t z_`xRsfPeACLebtHOh%7(_fRr=w7-X0n4||}$lz*9B$EdM72pvTPiujOCDge-ztq_g zMuZmsR-40Epe+eM!I`=B8340#oVKN1;b#}zUQjRqBx~(NZ zYPHD&N_C`|mT$C_q9H`lQC?SEiw{_Y#pWvzQ9v5Ym!Mcez6ATy;)QvpJy^7RVnP;!}T3i&nfPD92@&~ zRpIlb?0+eIk(7N^@MTi=zXV@dS}GRMe@*I|uU)n?&duQZZ(REk{z?aOzfEd+;Pt1I zvabogOLj_zemT*m-*>jZ@ib*#dpTfw{lM)SmMTmb2*J84Jq(P*F+Z|38XpWgpod!% zQVqe4U6NhBpvlRpFQnbn#S=Az1I+ubFeYhi7dx_LfNTj7IYb-RB{{Gr#2nwncB9!9 z*4Ix+${$i3c5_nx)y2kJy0|u1K_i%>w|23OZ8J(|RJySde>Xw2&TUCeT$>#=F)9Cw z^bNNs<^Mitx+5un$cV-}lk;Tqtl%hK$G+?@p=!Zj+nTh4$v|3I^vUCl&vn z+1!*a_H|m$Z(%?S!Q3ND{+=!z6e+%HCq66rd%N(oNkj!reqR@|sKS$8xD+J7Pg(Bo zLfavG?Z#Ij!YTRy%fF2RA>0E1YiKTg14JN&$Pc<2!mkXbvM?E%8ZK*r6}Ya@IEJO2 zZ!mm_XJ?$(DutDA*x_SI09t?x^i)>bkL5-7?!%wAFqs-zi zuFE48%Y@%ce9D&H3j@NLx3r6AOHa!Op3-So*)qH1%03Z40)`_j_cf~|8LQ)c|HEB8 z!GtkP>Cz)zJO^y*Bn%m^oorI*QEn!BmLqHhKHveDDMycW`9rC*0?(;gq*6LHQ=xz8 z34grH*&fFwR1D_96Mu_(!NPcw`R&z8_5rTiXg<}&b4F~3G0E^e%@Sqn**XxCT6B7& zf9M&WN^vT1jvxuR!9&DnyCi=@VB)S|g=@MD;{lLq@Zzag)t>8;{56Bkij~ZRILRW~ z_F?v_F76OW)E=SE$L~>KQCr=`7mdkAm$Dn9!5M41Bwscl5@tGD*D^z!d6VCheH_MB zK=>VvjN`fzxVRw_-1RnjVK1V3pP(n`#UdXA9UC!tp3k*8vo$#hEzb-ZNO%t69 z!UWuWHsxS~J>P}D?nt2ruqU~WeuoXVvsSs(Cl@M~2NcYFvSKzfRiZR~a#lEE_Q*5HWF)c|qz<1dc z&G{mm1m1}_5Q^>a+EP5BhGv_u3T_A*^(gEtQ7MYWt`f^2;`ASbZy@Yu10YT!>B|9X zQo~0!**xs+`2b^2m&wHd(V1ti^NMr7q@+9y$B^#40CJ$-=ba+ssqf! zINw!@i-~H9JJ`kZSzQC%_Ik)So(c6H=FJ9KiP}#h21QC6pz8|I*RN#?>Hju!wKN<%vIUpz2D?)HJUKqWSEmG`vZJJ{8kr! zw+oBMZzKeB;CH0Wo!OV4=t9Tcu?qyT;*&lFMe95Jxj9_q?TAA}siYjPrqNloc zi@9k`kMGJiF@Sc^Uv?Q%M4oX=(k66`M`One;HLlPuKv3uK|od2?AW}etN$*^5Et~q ztzG@bzq_ww{NL6hS~!Y)VvBIe($3%B)#pLtF=mwnUu_nGJGyqE6)RXt<{H*YF1! zY7idiN?!MP&AcEDhsGc5njG*q6wIJ(!_=lKB<%Ic`TxusbQzl5gpXe z?@A|Aj(qs;I8|8SEzZFq3t0{w#UaKq$OT})FY;Ew_QPT?1!Pz(=}L#KvLKL7f!VGO zM|f`Z=g$!ce`!}M1Y8?SFojICWjx8OYQ+VQ>J%5x<=)OwONjC?cMgqTYeyuGv`4zq z>4t+pg7K&q17lh6Nb9i(gJ@pheCRhU50mHdhzL+NxbETBH;P=Yendshm^h@sUr{^>CKQFi2(_m^?evc=sDK&bp zFDsqd=V`1iNH^~H%mxTp$mR}sW-x{+;AA@J(GZyc?jXw-4tXXMSQv2NnFA+a;jo9a z{PnrQ5f5n)tdXgE$&(2NU+S8dJ#^z+#~>WRD_!YiJT}_!WJ+`GFu0yjq~}$Sl!b^a zKCgN3>QjYOExdLq^}X(qMvceSy}`zGj6SgF>PFT!XNi4M=TSBlOCWQ_$2=X+6$)vq z1(!4|jfK@1JKJw&b zf{!CJh!%MJp~_EK)@@gOs*r6;*VQ6xKIM`0=F7J7vq)1yo>A2)UUr>T5vMMDoH{S_T6+LZH9g9 zQx%TA(7a^yYQC>qF>h2VT^M&EE!NHkF<)96e@~sy-zQa-tHsC((whPJa;3JxFCSFK8@EA^>!aZ;IblZ3e?+zD- zo9J<$TC~>hbaB|omoDGsY05yoJE5uJaE;uggr+cGnwp&46rxT^XbNqNdlH($d}-?5 zczQxn$ezJ`F&1zLW*?Et3=cRebSBTYnB>AkSb&4YW_e^A&Psz^VKz^n zSa~qvFibS4pW~T?b!Pn4Tn~%V?4?3eVjeeSMpN-6q6Kx7GvCvbu*8B3-8)10oG_bP z=;5Qfb9E69L9Cw`zqR@lG074SKk!^1uaK-o#w_*pg`IA-xzwm-9*jEu4CC?( z-S$ZOvWG8pZ-&yn`aa^zy0rJBzO24|9^*b~XQ>&_4v$##wUdu~xK9XAc!(`t_N1rT zVz0hW`LZtU{j@KuZ=Yv8bkMf;Sc2p5>EdD!Be=Qg$XdmXzICIG>yqT0e zyzo|Hc5uRDdl2QYdjvc7WD<8W!SJ_}^1-e5P7?Rf74~it0=n_uOH!@m%X>cwgIsDK zBuS!j>3x`l!?s1?BQ~Yo(x!00H8JYrq^V96q3nOcn^kvh8mksH(x*vU0rVO=;-KBn zlIT-tBhtf1oMO3fXf86;K2I9d{D{UclJj$4CUtCBx-cpYen|FDe3euccox1+lHhFa zo2264RroeZ!l8QD2%qLnwR;qV*dqE;zDsHhYWki<*}+wC31bC6Tu4XX$xSKTACp7~ z$m0F=jTgE1`80!5nK88>M!`*qNboHPB8|Psz1OFjpuHw|IegqjZYKue@X5gVixRpB z5{OGfb1I!f5twk1`=EoWs|OE2At2$uISCJrYY7pg|CS`Y>wEngmbDztyIU_xFerdV zz{AOOTT*oj4JXq?AA7;PFVymNOZnRqk-$eW3|^4G<09W)xOXia*WBsL?%M~m@A73| z3Z)Bwy4#nHr3-(Wbdl#+8cOrfPWE9y1&lG}B660+OQ$o_Jv~Fp zaS@#1%ZK8aKl36xP(}?wEtaP>a+VJPDjn*Fe-Zg{-I5fZv0?uf_)wuX<2bIip>Lms9#o{wL zmk(88{!-u2KzXtPmiZ8%0zz2sL7;gTG}Y!GE`d;d#D_rLg&H0$flz$RBj88_DE-HM z+0X!FKjF#7k%8nXK?Y`1D#r-94 zfQ9)3rE!V}eZ5xn9P;Gj_+qaQ`|?%!BR)F`3B-HAE_=zxG{NZA_hsL_6O>nctpF9= z%B#Ls1fy5q*Gi#W+WU1MAyUg59t30;5pvXrAT=Djh>kU#i@iFIWN9lN_pHh&um&bb zRPjxZksm>Q%hxs#XViFEZSjP!Z5tEYKG`x&-LkhX+4}48W5PS9gu!WfLHJFdcNSz;FL|-)|i4X);*^gF3t5QxyhYeZ5q9tkAIVnTi2J3FWUF(q zDuK7Q_?3?c3mHfz?5}-9SlEdBjgJV6Tt&pUJ|Zk+A>wq4uz?~X`8yxUR^5pEy^mz8 zb0BZvmn;6@Bf>()p+@WDk5&`<`H@eS%?_hB5b4xNgmhDqrk1Y z5qEqyw|mG?Iy6PHx!U3cU-v9V0L6%WbGMQT5@%^PcZ-h#i`L7i(p!BLSh$LU+ggMS zv?I9_edJm-1M2O*S}i7ARtvt)+TtC)QL~VNUc$c9H)<9(;@;&W!lG6Yakq~M3t5Pm z)FN!4h)AC7BiX7Oai{p|wK@kRL(o`l@t$sUl2>{~VDx*t`Mnd$Xh2~@2;P1X;8j1kLafWEC(8n%SZfK%MTwEMFI_HUxjRNAsuvH6=J033zGmIW5NR z+h=Y!x9^YK=x8|4>*kJh)CiZ2hQ)P$OR$Oyx+VC|u`!6ifDOpP7NHdvl|qBS3s{>M zw+OAcq+7yy0`DLw6l1AJ`D%WER1o5_Qivc7gt)vEA_xQ_K3s}Ks1eWm9w~(f6(ZiF zr8sjLMGHJusygT~1|K|L3J=IbyeCTG0eOh`WD*|l8VK*HB>t)W3L!pS5>Zk3Oi4sV z;s)bxsO?o%&{QsQBK&NE#Z117^!*#K^L{fO^F?X^PJ6z z2oSsQyl3)gp5b9(ZGKCO(283V(Qto3wY|_HwBoiz;^7Q_dmNuGo2_ax?Lg1w%}%7iq+VC^e~QQV)55r7l1 z6h`r2BF1o_<4`G#;^AZrpyNm>jN(g)x`ZQmY9Y22*Y}rOj$3>salloK;H$|<902&5 zPX?JNjEsEUM;M{l%JYqu;}(zllqc0|21*|DO*X;=<#{|20p|9bi3o6#^Hw4sNV}dW ziBde7jDp(r?UE?PcYHIIyGz>j-NX)oc6~1q0krG;K1C-?WqtTTi_nT6CZcKW`caF} ziXSHu58CyUL@ttc{j?-X@iU)xWfmyyddfGC2uo?#&wZMakb>*KNX*X!U;15vA!vVQT#R$12yOAQW(YWk}-ge?@M76e@Ij$qB$|{yEgx0%W;c0UQA!e z#5c}7PC8PrmY1yjO=pH*9DA{6V{X=uQAyIkxHBwJ9Dgxg|Kjffx|k(|OIn$57KMs8 zU+i(CP+yFIt=jx8rPu^27Gt)Ao?Fihzj#|IE@Ay9TPL1jf#U5Kdu%A`tXfjKc%h&a@6Z12{oQvI?ZYBj+qq(Ipit~~&U=^5O z3Zu9n5d&AFg{3fxi;^*bj>V-gic2o``kz7AD8`GdB{);Z1!?ISp%<53Oz%m=H9FO1 z)Q(>=)#k~uwET?96sgR^KBdc2VXS?u^By@f{NkfNoom+5N}3yZ>6 zrEi%c6mvmam56CBXsdl{m+FL(UXzFb3)Wl#V%=jKn(TkY^646%}>NVUOlu6jR3>NyIdD%uAl>%XNZ|c{vdQbj&M> z2*BZ26A>VY_q9X>&@rzkB7oWbMlwQb^ij`j;%?$+n8!+Bq(&c4Yy@=Wn~7CmB>h{7 z82FvUi9|7=46eck*<#OsdI5b5RU!f?fv*!0KnZ-4hyY69+e8FV0;dxZUIqWH&F@vPy!=0`p3jZKndJf;odp2xS$faDG>vez}O161BL4#B`_`#g_OYf z3b#XtYf(yILWO&y%t*oYHz($2f?E>v8wrVXEYjmHx61lFF!QIJ7tPCbq`~of=%oTo%7naN3cruTB z>^c|dDO^B9FKJGxpetnH?)hN!e;<{~H}!-&JBPx()j{E&3c9Sw&Qebi-&;X9@Ys3R zWZ^9pxJu~03i7SlnQ&!xHU}>{G-Y#R?sp-;+b$a60hW5ZhCy&6B)p`_RXpgzxH>gD z-BfI1jH#|hhKzs0D$%Aa0AU;EhQ`OT%PQ_V9f$UkN0 zUMH6+^$$j*Zb)ZyGb`vDSsRP#?+@2o&T=(DjbrZYivPRR1-J1VzO9!D=2TpEHZ|Z= z1#>I-u^D++HQti*4RO9~c3#DA&Zb=u&H1rGffYwRG2EC=TrvS| z*Nq$k7c?z*mG587)HeoyfN!$lUaE&N0 zZ=d}u+yQqtAl(V9)i03a%&zvT|wt$?ji$W zSm7E3^YxTxD)?O(A;K|v)aA^Es(v;yX$ZqH$^M*yd(|!SR`8hGS2-9pKUeYpSp0I3 zgDh-LM>I568s2JXRYPwZSRLL{!OuL&#KGBX4syK2)|SaOQ=s22 zwiTZI78_@KTz>doiZ8GvMI~wbqV` z8lo^NT{r_-DVh%)?X2LJg_5x8iJ)C-(kuB9qQQ3LN_WSMOP#eRwiH5ENbmr7Q)+K) zrLj>!@P>mixi4mDS!haO?`MT#EL#>9-9UMuf==+gI03lTf_g$d7+XZ4I?5p{;81Ms zlI($*`opool1%2>5mqub8Ju-ZHrE8NI{Yc9$Jan#s`v+#D+4i|$K~(k7~9kNKc;dS zSXp1GpjYm#A_MW(%vX6qr6=r~q3)g;X$o6|hWUzZS2p?^k%24K#NZu)r7IV}!6%1YHSx+y7i;iJ;2Ndg9mMNQ?^c3(5H@w zj<03?vJPr11iq4=SNzH=*J1tE^7cgqxkg<*4Tnj3`K5mpaLM_K1sI8?hqb~c%`Sai zp&!k1KEGw+e#1&R(tT&KZ`B&gnnc;4WRVVq>yOcbI?WhiSIK-aoBPh+zot}fr@ZQkMHi@EX8QJyc=rI3EjyP6lr}hZHVe|P;Tzd2DLS0 zg&aI~4OrUG@Um2(z zo>Q$$!_v$66T6fA`tYr~Z}0A%U8okg!XfaI6<$$)M|bkV`YPu4#O~}~=^Zl?^l-TD z>dr4ux-7X66-Vms?&L+Lkpj`6!Lc6aYiyjjQGgmT^J7gja7dtbu@P`NUa zhyX86@mqNPg9f-ZME{%;O0o4KqB$$?F{lf5poM-fvyM6d`(L->xzA|JsK>&;Kdfjd z+$89(=mBR%HvWU%$peTKU72dkduo~*HfN~!NP&k!q@g3y@Eo>lp_t~T$-~?>c zEF(!<<7U&8jXBP4+xT-?3pzxX@aA>*zXmI>TN!&^YxSHT)dgT_H8uvrQ;kwGAefxVKIr@Jv-=c=%tLGF&Nc8;Neyv93*2GZJ4mH$2{ z6muC(fhor8LQWgKiWFGSMxCQ$jJP4Jg!HGgrH#(vvhg={_wNLTj7k^kMhpOVyrs)F zCs-Dm4pubJhkOkyGnui4`xz1D5O*tg!NG?R=Y{V49Jb4R39*=z9#Lvv%C&Fu-NgwaD2d#`tD znOOTmvhjseXIuM2a*Vbt^aHHg9m8y)9Sk}7#}VMgb~bk?B*|#b#y{-kq>Xo^JD)(h zL<_CeYh{OoEm@P~rEpP;A)2E0vXePhkypITvCv*kn8_9*(~9Q&YhE^31@f=+G*-g{ zFAAk|b;ZV14zb_~Byhon(+blJ`^4<)(Qx>Tk%<&I=ABj%#N$zuYN)aAP1X0Or{L6f z?@cyReLJSXb%j);LVYWFCk9=^9iBoy!Tt8ttFTUX?~j`v7Z$$&n9YUOAINmB(60eE z>DE){Z+EB5W?Yrv4pGr{C0zMY0I9?fhnJ64&?z`p?1s5|+JDTG z$Ht&v8s(Ev=BQGgVG8D_PL*Nff99PlHr}bwJQL4EXl|K}ejaKFV>ZOge8B_n=wuvs zK(?tVoB6W)Z{nM5D(@>H*6vr`-RFzAK40tAbzggjL6`Z4Iqc|!M#+EcHOu2R zolpVn^+p8v@Kn8<)!*@)j#wF*gMM*ar{$kD#uQ*z;S$o*SL<6uh;E-hgp@8aUWP z+Rd@Ntp|A{Bhut3G_eOc3=wf?(1hXkK_b1k_i*_~yhZO|I+`u7DE*2QxwD6MF%2og zNrJmucl98zVx(J<0(XZ4z;4FG4oz|nfT!T(u=i@+OssoKNQp7HzLNKZl+enPSoOWm zN#HJbALII#x!=P{+~{UF9ECZTxt~QW8TZP@)bRWRVduDpM0y_#J7=)MQ*dg+tTpU5 zy-r%Q_MslyAw)40Mgen%ObZ3hASha5dV&goinBSm9ga>aED~n)@SiP2N}8BW$g z7`>`vH;^!s=2<=TF^NI5U1m0`T*r*F@#gd(A2?1WSTpzxh1yH!`(?(=4VidlI%q`G z4Qy!$46;x3<~f-dEipftiBhpKoXC|0;o5O^P#BT*(XcQi)nH1j$Rbu94!+QsL*OF3 z^s+eY52d=b&=RK>iWFGt)qD}eWnRRvbzn`du)K%%Vh^H6NbBG+^AN`rl!wEG!r+Ok z)Fa_6R?$33C%BI~XR)W?V<9phazfZ)LwdBE;>Vr(%w6t@P%?({15WNbpL9w_tjJTw zpo49ia#!}Wd(iCy&$xu_KOhQ04!O}Xdp0DCH-PR2SA=94V;C**9IFI}SckQ)>_I1D z4jg@SwJOvsmVz>cYIP5N1gdfV9l~OM*#LnONaC6vt`k~~yVgsFMp@Uxe~7D*uqkzj zyFOu|7?>$G{UOy@Gt+hu_T~LuS!B z(xaC*fWT3twiaSdUg|-yhU8JA_`v!!JObDhyxfC65(?8*$Tmg|z7kG8uGTqy@KDN`5tCcxj~l%ew&^ zkM*FC9`C>&59R3UY<;oOH|5`S%2BMyTV6Sep`PHmiIy!-3AXJ_uAOAQM)r{=_S*?M z&css-(L14laIRB8-gS<7q`-TuHyn&*#4Cb^RI#x@KJE8=_)petD(k`+i4RI>5N6kh zJ^X>zcGYOCf8=17>7M2N^yS^aTnI)FZur=-&b!g;8jJNo{u8gTF)5#hGtXj@a}+)c z6|*r--Q`Ys#cpV}nZ6OyO?>WMRq`@)lZ!SL3 z>#$$YbbF~JEM&@^F^P=MB`S=53rQ!QVd#Ct4 z`}0ruhdCXthqAJhUH!4ER|VorU<_M=0HNL#5g{Fw|8``gAKGrTb3#!7dznb5@e z^f|yymCQ<`rfyIX&y2B^?nx*0XbZsn5@B4W+p={OA_~S=vU)Ws;Lfw4PN*b#lHy2v zH~4<==1S*hJ-J|bIuEATHS}o@vig=vGUlZ`e|KoA$XhGPjVTD%G9lfhCWuqX7vKXn z<;=RRvTsaK&9V3&#h@6dCD1ZACRWx{L0P}dLf9#Gq)2XD_N{MbxD{rQ{ZY#8mH(>+ z%|yM#(s{F9nD05e?mH@Z5%rZOgB18z$QFR{R`2hu^xH4o4Hh|5lJ2VXJD2P-BuIBV z1c{^U8F^CW|Jwr2oZSH6M-!7P|Igp7e)zCr%HObhnDO^i4z#GJAL_`F*EGKXnzQNN z%37h+il!4_3D915TwE&6z2mL{6LS&aI?FPC>d>t&~xD z$C{08)2*1qFRrAMNx>1~4IW7SODgFIFBx;G+l&dT6Iax-N_+bo{fbubfFQ^6 zyWDQZUZ~CPJ?t_0Xai|`yh3(A;#u6K>vnT2OOM(V0on9bl_vj}4cQzWuRLZW+I68N zD9--J-C||163=&@aE}UGoI=HucAJnq91f0PPe-?zKxl&?K4l{ghCbjqnRXUyaei7& zI596;FnplUo>9i;8I)r6^6Z&62MT0GB?Tumt0hOeO%qePHu#1hhc6lBpDVR^@WIr| zQlmlxy2@@@yEK6WmS$5%S69+Wew55`bVzRc<)JXi)S6OLRyViSRsec`W46Ao(lUgE zNnz{u)^L5P#wGARzo8VSCTF92#}bmj>$dWrZ1U__a7sH|hvBr|?3vb{f}}#9cP|la zheK$2kRF~vn_- z-@!`v7k)N2IvWq!Qi|1dGkqgS@ZlD9kR{4w%#lj>A%sw2i!Dv=mplr=T?B43OxFc3 zSJGn+f^w}|N<(*;)@sH%%`26^HF@2#LgGq%wUVOdq(xo7IcEj;HCyKrgX^-*V^|*Y zL$kW{>mFxBtQnr-Z#YISl_yuWuJY*L&>?}-=2)dWeo;tfsbq0K{+DcLv9ULm7>cQa z1PUY_sb+I-zfM$oC{%(oM>?)3m;yu+%;7!jVLE(4i>`C4kysy+i3rphG z{R73A78YTP^h32uwy+S`^&geszx2ym+CDBZO~XQTMEXeyjTWK<-D-*ZR1L96ERDC{ zQx;Zn1IB3NKRW{oVI4ZZI)({Ynr<8-GJXzmQjJ&Hx-S)gUdZH|F-h)&HCt= z3MSa;(jB#?7g<+4w%@r20dJw;!&_cgzITsl6fOUQeRKgM9@&QeSV{3tFel|E(9k$k z*f&=3#ZWTu%pS{GC0*KbQ&q{!A*tIO;4EimF!}Jtm$6lJC8>Rs3%VkmA2F_q&Uc#V zXuK!00gu(y-G%w_RqPE)!9ApTxUVjs@A-#xJ`KBQbHScar6RjRtZM<)M7g=jz97!H zYfogh2v?86Kl@bUmMUH$G!lNhV4uctRk4z{R`n-#O365H;|Cb9@wc15t%?mK?tgwn zsy;g^k5@zXgo{rB1{<$#WVEjnt6Jo(7pBt^vyVo;T`tZJtExMz_@L0$ww}nwY5rYRYF}b^n zVtu9GBy*^|c-~E7QL}Slr4bd)Sd**x_75^%bc8aVivAXAx;mACyCmz$9g?ZfPpKjW z#FmbQY$FbWOEN(b-&19K@!~A;WFK7{mDxmT?}eB6Hm}tTet?(;zbLR34fZ;pQLW#$g3St%>(G zk@n2Ny)9`uS)W$LCbCNgMJg`u#>#!Vl2?ZVy${b-m(?U+QgWDeqzJe&2YJu-ZAuJmJ06&)wUnGK>yr$gd+9o#Uts%3Z0si9CC z0A}mFDms4mHv>WXVN3JX1S&NMFxn3DdVyLZ&Y(1zi3`=lIfHUAl*(RQRK-ygNrP*U z%UoG}<}IRlaQw%Tv*{)jUs^>m74aKfRf^b}`DKmUHBG2CfAW=$Ns3$T>n{S1#+#T|m) zI%(JVL={CMJNW|NQv!RQ^l3hsj50Pu3dLbhRZ+-`YjU&ZeY(oFZ=$CWYJ!Twd4`8A zs!1t3C}`Pz){h3NN~5h%dQsGur*YI$&sDLftOP0$vQk-*riP&rS^2DxnRf4G(8~tc^Cdv_WJB>!3|a#9GiJbhmEiX%*!=?F3k6^UqgZ zYLXaP>C|9L>Y&V3>0!B4Zp;?80(8afKBam&;wV43VQWI;3h4!h#zSgkj@cG=$cAkm zVQ`mY!(n^Xg`_UfsH|uHU6;-jF6)OM45ND*hV{j&PH~k2TMNjB+#N167}B9LaQp5~ zk5$IG>?z(=MaSInRT(#!>R^fScUubaYBsq+6Vj6hT-lx^6t?X4x@ZE5apNQ3?(D0g z19f4YZb=LlYH>fWVTptj;(;oPe6(wW7SX3(ILMjgIH2oV&AV6+xp&J>H@gU`8IR;@fjI zzH$bT=D^`Q-r}7&&hKn9ZjSSBo>8IZ0$tPc)|nO>0_2^jQWr^-+<+l@&=P+^*RQ_* zxA-4Z^`kun0H{K0LD$Fm4}JvCGnK13gdO zkc5ww>TzU4bD#Kgq3Tboy3vy1C~J6GK2y6D8_QEr4slMMSwCUaKCkNPsZ&qKFQW66 zMu=F!?u;+}-GvsuYO!1ZZ$MPwjUl|L;p;P#3)EcS_{R*hzvZPgYCY${ZCW=%G=Bdv zzYiKtw|MRpo9p5J3Mu?uY2z+tEU;e)>HGeyy+XjaAN=gHjzrW0Cn&=|`h~?+1myb0 zYWoEVV=Zx&0J3hX<~_GVid`jGp2nV8GazH*svQ;yUH~qzJ>1NJF3ZVGz=sPpC9T;wi@#Y zUQTEnX}c8ethU3o%?4?=%c|cJ4$F0MS2Y>Ly17EWzUR;(SM-m2FYc~pzqZI8?r&-O zMJfj|C3oJWYW6{v!pFHYxte{7rEp==Olcu1ka17-e~l9eAHX!jt@Za-vumw;2go_$*e)a#h zESUHVvaLx+zC%*rY!KJv1=X}U4JSuHm)`TTvap&C!Zd*qRfMjN`bCL2za*T+)zL2{ zDH*idl4^D^$)tDCj`oAOY%HxN@0cd)Kk_~QZHPlVE{kY8U)4CDmq)aT4;Q54;TEF8 ze0?OMpMAB8ettBf0e$#9pC4->AuxX*uciYQH_O;h#q0N=`X{RC_}fIykH{7qDfpfD z;7>*rr-MwFypgy)6`3B^-~k`-1qQe}pb?*Vdb*lE?l4IKA8TVOo%sXCw>(qL&*RFn z3{|OYQA5vG{|X5)D+ncpyM0x)j_jx)H#95USesOW8n^I) z8SBod1oC2il0@h>m>C<`yma?K;||RdFE&OLcZ_o)ChR)gRH|%^iR;lFd<<1%uOOC|k?qf^ae3%oy1!_uJPtC#gI-?8wOJl01iRN}#GXhbl-JRtXVN!VOpjGZ9B1O)+ z|B2SpmTuiqqe{fki574B$$-V8*XDwgyqvXwMqTRd>VIw_k-Eqr*h}Z&B3Eeeo$AZZ zw)DHz{CyU42T9f^Achcwu?}Gc_;T8N)n)`-3?G6DLFPmB!EhHh_;0PrM1`(}mT=eF z2=0vmJX1cX_8neChn9G7RkkkG2)h5nYW2hwIisBp6ZBdCe&|Ofoh4N75Qt_BKK9ZQ zKS-fce5&$El3`7Fyaaw)ZHF<^=$XgiPA3GK*`HPOl@>CCTUHX(!l|<=2r}?_#JY&= zV3fhgcLRSBv1?mK9nbnN&x$}$316|7O|R+^0vqs4QoKI0xsbmO)?VOZQ2%wrREd;9 z>w@hi{2<~Ro+G{n5Sg~dnOx9-_}@m%rby+5EFul5%cYwO2%S#$RvBXRU1Ym$*<*x< zE7mU~e3JZ_Ojc(5kEd>3Gt{9oQFN~S7RB9!2iLuzDaV~@#09svrQ(nBz< zWkbLvbqW;bMnb^S9E#_U@2hHzbCre{V7rz`=S<*8nf^@dSb zKf5ORUM;=4T^mLZa!^wdIXd$qj>!6=u{!H}t_`|_;P zq%Ky)kXJ-ZX0zsqeeB%as*XOV2H(}DEDmC&uT=X7Srf&7Ci$ys_|pWP?+6>yE;rTw zYBhd#846@l7;F5-W4w^&<=PrMrol0QF}cA>p(|Kd^S=l|+Hh1*(VN^r=x&C$VDmlk zL=ONNDhT;QM{Gs!fBL^Jw?%S&&Hp^hy5&L~v+f(`$;6 zS@T8>#eT%hPY#qO*V)mUf28&(UI^T^5FphPZcs>F+WT0|FDNHh=viBv2}bq9Z-|a_ zjUs$7SoCEy9?r5oi5lznOPohcFn(SmVsf&^ zx^PpH2{D^X562IU-?l3g+38{uZF)5 z$c;24b}jmC$boW6ZNa^&C$_U-d=O_zW^rl%{h zjB|4^XNRV8(Do-aUA-9U+s038F7%>YlkEq`T)Dz$H5Fc*fkXiZpqxs;qRdPJ;l7z9qi&F4IsqqQ5^)F`X8-qUtIXrltaEWIef(*)sx}oOgOFYt4 zpUxX-w_H-=W-;`3unLQzcQpProhjsRy~ID+a9lIs9YVz0lJGzoVCXyIO-vY%YvC)> zOd(x&djj*W2!<7h56U!T@3_RHOknX)YV}SZL-3)E@HFYJOFW7TR2I*hyL|!z7-2oA zpeOm5Yh%Lk*Kqj2b@C;i$!KA#)2=C(RJzB_LMDgLJ(u)s32K0E%hpqgdwmiHl@kI@ zru%$@Cs+eB_4oUjE;!862QK;VUJ@DO8jPiCglSTb?>#+uNtqiTK6nLbnCctDG<;)` z%YgJfbV<3df`PeQHaE@30a}+O+G_eGo!zy_+buH^SR{8*&Gd;=>{6^*KBCpyKHEnQ zh224b^c-IWDlTtsf&|9G^XBW++RPwQ7rWw5C>{7u+oZ zY=uIt)Ag;|z}KiR=nC4xi*)td+O(A#8sUYQ)*VJkU)oS*+ckQtUN1sxSVb#EZfhiA z2OtRfn7LCL-6g+qdd_POIOXd)}}ttaA{?3RxYft&YUE z^UlFa{@knA`9R^Hd-eWlyFC24^a7RK=Vz4s>z`9{-@j`+0zPH?h046_KT+mC{XJwt z=l+3{d-wX!nB2SfKb}j;f9`$h;Wp)7V$UJE|9olNc3|C)D75Q9f3P3zRaW0~6!4pK z+cpLbg%0Q9|A^6%dU_u8^nB>)Pg?`st$X$Pnc3H$D_Z;h9nt!mUrK}+=ARIamgr9@G1iJr=%J1`EDgW31P5tiMiGKg4j5~g$&3V$jJX%7n+rR}aZQ2uK zFKyelkV-eUI~V__UJ=dbP#gd=Z3>!b1$r4o zktCkw>lKttL*8BmLB#CW@Gs1T*I_c@-&U=9wT2R4ceQET0MYJmKz{pS#d=tij-u?M zXdV;bc$;6SN-4cHklh9-Y3*v%)0#y@nn;8R*jlnDSks)n( zKu!u1-wt&KYPEOt&-OWD;Ja8Cvb`1PLDE}oaNyo+)BYzNc;kL8=(Tg}M!+{h0JXjV z)(Z&uyc*uwOE)({bClDzJ>#|mQZV?EbpHFgt#gJI>qZ8J{0BPaJe6{FDnIf=oq7%w z&836^$aDrGRR<~)9TVw8ViID zT_~UHgboneo+8oyLZ@{cHl`3b%wGC}|Rd2J?}!MIx7(csbh%{uF+wHYJ* z7M*@UT_XhC!si76h)7*trEehE6d_n5k2RgjqTzO2TZNW0NpPr&}b0j;hZG=`rhZXDg61L&TUuU3)bci?d!o2S;%+nz<7ZgZ4)Tjb6Q=$QnP`vR^jhD*erv7T-~-KECYpHuU75JW7rE8 zrb4cF8~)Y1Eh@QoZDC>P)gJ%vjYeauREJi>*62#9su4-a#E*Tisfyc%sqQY$bVOW z_XK!ffDd#T?AeF=T_TJ^NIrM0@s`&ar!TN~c>r`&`KVLVzy? z_)37U1^7nSai03B3s>E5CHu4h-wE)&06z%uqX0Ly6Qe--ev?iy`#x5uO5exnlxW|_ z>m0l96Lh-O_nX_PCH)owZqZ}*ry0iC?K)8=${kYaodVn?z}*5&5@50b zQv|q2SI8oFuVmaO!2KEn1?&O+%Mh>!1$U~>{e>F2M!38upKZJW-C=??O@QeF%n)Fv z0J8*`Ex;TB<_a)RfcXL}5MZGIi`t2Iq#bE{wZJTv{3QY`6=0bF%LRB?fJX#)RDj0> zcwB%d1b9+_rv!LffM*1FR)7@(JSV_P%}OOBt8_vrBdc|qAtP&aqR7ZvsdSwH>jl^# zz(xT!39wm!=fet{`8;%sPHBtY_^tZq`QUG-&*3qI^97x(_DtJ!0$JeO^-s3IU(~-Z zsF(O~x_NYm&VY3lPjK@)bxKD*T|^DBO9h#L-T^qtVF0g5=Ic81r&vg?cFeya2uB4tCctrB z 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 VoS&%78u1sZu~{?AL_BITS;\n// @ts-ignore: decorator\n@inline export const AL_MASK: usize = AL_SIZE - 1;\n\n// Extra debugging\n\n// @ts-ignore: decorator\n@inline export const DEBUG = true;\n// @ts-ignore: decorator\n@inline export const TRACE = false;\n// @ts-ignore: decorator\n@inline export const RTRACE = isDefined(ASC_RTRACE);\n// @ts-ignore: decorator\n@inline export const PROFILE = isDefined(ASC_PROFILE);\n\n// Memory manager\n\n// ╒════════════ Memory manager block layout (32-bit) ═════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤\n// │ MM info │ -4\n// ╞>ptr═══════════════════════════════════════════════════════════╡\n// │ ... │\n@unmanaged export class BLOCK {\n /** Memory manager info. */\n mmInfo: usize;\n}\n\n/** Overhead of a memory manager block. */\n// @ts-ignore: decorator\n@inline export const BLOCK_OVERHEAD: usize = offsetof();\n\n/** Maximum size of a memory manager block's payload. */\n// @ts-ignore: decorator\n@inline export const BLOCK_MAXSIZE: usize = (1 << 30) - BLOCK_OVERHEAD;\n\n// Garbage collector\n\n// ╒══════════ Garbage collector object layout (32-bit) ═══════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤\n// │ Memory manager block │ -20\n// ╞═══════════════════════════════════════════════════════════════╡\n// │ GC info │ -16\n// ├───────────────────────────────────────────────────────────────┤\n// │ GC info │ -12\n// ├───────────────────────────────────────────────────────────────┤\n// │ RT id │ -8\n// ├───────────────────────────────────────────────────────────────┤\n// │ RT size │ -4\n// ╞>ptr═══════════════════════════════════════════════════════════╡\n// │ ... │\n@unmanaged export class OBJECT extends BLOCK {\n /** Garbage collector info. */\n gcInfo: u32;\n /** Garbage collector info. */\n gcInfo2: u32;\n /** Runtime class id. */\n rtId: u32;\n /** Runtime object size. */\n rtSize: u32;\n}\n\n/** Overhead of a garbage collector object. Excludes memory manager block overhead. */\n// @ts-ignore: decorator\n@inline export const OBJECT_OVERHEAD: usize = (offsetof() - BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK;\n\n/** Maximum size of a garbage collector object's payload. */\n// @ts-ignore: decorator\n@inline export const OBJECT_MAXSIZE: usize = BLOCK_MAXSIZE - OBJECT_OVERHEAD;\n\n/** Total of memory manager and garbage collector overhead. */\n// @ts-ignore: decorator\n@inline export const TOTAL_OVERHEAD: usize = BLOCK_OVERHEAD + OBJECT_OVERHEAD;\n","import { AL_BITS, AL_SIZE, AL_MASK, DEBUG, BLOCK, BLOCK_OVERHEAD, BLOCK_MAXSIZE } from \"./common\";\nimport { oninit, onalloc, onresize, onmove, onfree } from \"./rtrace\";\nimport { E_ALLOCATION_TOO_LARGE } from \"../util/error\";\n\n// === The TLSF (Two-Level Segregate Fit) memory allocator ===\n// see: http://www.gii.upv.es/tlsf/\n\n// - `ffs(x)` is equivalent to `ctz(x)` with x != 0\n// - `fls(x)` is equivalent to `sizeof(x) * 8 - clz(x) - 1`\n\n// ╒══════════════ Block size interpretation (32-bit) ═════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┼─┴─┴─┴─╫─┴─┴─┴─┤\n// │ | FL │ SB = SL + AL │ ◄─ usize\n// └───────────────────────────────────────────────┴───────╨───────┘\n// FL: first level, SL: second level, AL: alignment, SB: small block\n\n// @ts-ignore: decorator\n@inline const SL_BITS: u32 = 4;\n// @ts-ignore: decorator\n@inline const SL_SIZE: u32 = 1 << SL_BITS;\n\n// @ts-ignore: decorator\n@inline const SB_BITS: u32 = SL_BITS + AL_BITS;\n// @ts-ignore: decorator\n@inline const SB_SIZE: u32 = 1 << SB_BITS;\n\n// @ts-ignore: decorator\n@inline const FL_BITS: u32 = 31 - SB_BITS;\n\n// [00]: < 256B (SB) [12]: < 1M\n// [01]: < 512B [13]: < 2M\n// [02]: < 1K [14]: < 4M\n// [03]: < 2K [15]: < 8M\n// [04]: < 4K [16]: < 16M\n// [05]: < 8K [17]: < 32M\n// [06]: < 16K [18]: < 64M\n// [07]: < 32K [19]: < 128M\n// [08]: < 64K [20]: < 256M\n// [09]: < 128K [21]: < 512M\n// [10]: < 256K [22]: <= 1G - OVERHEAD\n// [11]: < 512K\n// VMs limit to 2GB total (currently), making one 1G block max (or three 512M etc.) due to block overhead\n\n// Tags stored in otherwise unused alignment bits\n\n// @ts-ignore: decorator\n@inline const FREE: usize = 1 << 0;\n// @ts-ignore: decorator\n@inline const LEFTFREE: usize = 1 << 1;\n// @ts-ignore: decorator\n@inline const TAGS_MASK: usize = FREE | LEFTFREE; // <= AL_MASK\n\n// ╒════════════════════ Block layout (32-bit) ════════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┼─┼─┤ ┐\n// │ size │L│F│ ◄─┐ info overhead\n// ╞>ptr═══════════════════════════════════════════════════════╧═╧═╡ │ ┘\n// │ if free: ◄ prev │ ◄─┤ usize\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ if free: next ► │ ◄─┤\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ ... │ │ >= 0\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ if free: back ▲ │ ◄─┘\n// └───────────────────────────────────────────────────────────────┘ >= MIN SIZE\n// F: FREE, L: LEFTFREE\n@unmanaged export class Block extends BLOCK {\n\n /** Previous free block, if any. Only valid if free, otherwise part of payload. */\n prev: Block | null;\n /** Next free block, if any. Only valid if free, otherwise part of payload. */\n next: Block | null;\n\n // If the block is free, there is a 'back'reference at its end pointing at its start.\n}\n\n// Block constants. A block must have a minimum size of three pointers so it can hold `prev`,\n// `next` and `back` if free.\n\n// @ts-ignore: decorator\n@inline const BLOCK_MINSIZE: usize = ((3 * sizeof() + BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK) - BLOCK_OVERHEAD; // prev + next + back\n// @ts-ignore: decorator\n// @inline const BLOCK_MAXSIZE: usize = 1 << (FL_BITS + SB_BITS - 1); // exclusive, lives in common.ts\n\n/** Gets the left block of a block. Only valid if the left block is free. */\n// @ts-ignore: decorator\n@inline function GETFREELEFT(block: Block): Block {\n return load(changetype(block) - sizeof());\n}\n\n/** Gets the right block of a block by advancing to the right by its size. */\n// @ts-ignore: decorator\n@inline function GETRIGHT(block: Block): Block {\n return changetype(changetype(block) + BLOCK_OVERHEAD + (block.mmInfo & ~TAGS_MASK));\n}\n\n// ╒═════════════════════ Root layout (32-bit) ════════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤ ┐\n// │ 0 | flMap S│ ◄────┐\n// ╞═══════════════════════════════════════════════════════════════╡ │\n// │ slMap[0] S │ ◄─┐ │\n// ├───────────────────────────────────────────────────────────────┤ │ │\n// │ slMap[1] │ ◄─┤ │\n// ├───────────────────────────────────────────────────────────────┤ u32 │\n// │ slMap[22] │ ◄─┘ │\n// ╞═══════════════════════════════════════════════════════════════╡ usize\n// │ head[0] │ ◄────┤\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ ... │ ◄────┤\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ head[367] │ ◄────┤\n// ╞═══════════════════════════════════════════════════════════════╡ │\n// │ tail │ ◄────┘\n// └───────────────────────────────────────────────────────────────┘ SIZE ┘\n// S: Small blocks map\n@unmanaged class Root {\n /** First level bitmap. */\n flMap: usize;\n}\n\n// Root constants. Where stuff is stored inside of the root structure.\n\n// @ts-ignore: decorator\n@inline const SL_START: usize = sizeof();\n// @ts-ignore: decorator\n@inline const SL_END: usize = SL_START + (FL_BITS << alignof());\n// @ts-ignore: decorator\n@inline const HL_START: usize = (SL_END + AL_MASK) & ~AL_MASK;\n// @ts-ignore: decorator\n@inline const HL_END: usize = HL_START + FL_BITS * SL_SIZE * sizeof();\n// @ts-ignore: decorator\n@inline const ROOT_SIZE: usize = HL_END + sizeof();\n\n// @ts-ignore: decorator\n@lazy export let ROOT: Root = changetype(0); // unsafe initializion below\n\n/** Gets the second level map of the specified first level. */\n// @ts-ignore: decorator\n@inline function GETSL(root: Root, fl: usize): u32 {\n return load(\n changetype(root) + (fl << alignof()),\n SL_START\n );\n}\n\n/** Sets the second level map of the specified first level. */\n// @ts-ignore: decorator\n@inline function SETSL(root: Root, fl: usize, slMap: u32): void {\n store(\n changetype(root) + (fl << alignof()),\n slMap,\n SL_START\n );\n}\n\n/** Gets the head of the free list for the specified combination of first and second level. */\n// @ts-ignore: decorator\n@inline function GETHEAD(root: Root, fl: usize, sl: u32): Block | null {\n return load(\n changetype(root) + (((fl << SL_BITS) + sl) << alignof()),\n HL_START\n );\n}\n\n/** Sets the head of the free list for the specified combination of first and second level. */\n// @ts-ignore: decorator\n@inline function SETHEAD(root: Root, fl: usize, sl: u32, head: Block | null): void {\n store(\n changetype(root) + (((fl << SL_BITS) + sl) << alignof()),\n head,\n HL_START\n );\n}\n\n/** Gets the tail block.. */\n// @ts-ignore: decorator\n@inline function GETTAIL(root: Root): Block {\n return load(\n changetype(root),\n HL_END\n );\n}\n\n/** Sets the tail block. */\n// @ts-ignore: decorator\n@inline function SETTAIL(root: Root, tail: Block): void {\n store(\n changetype(root),\n tail,\n HL_END\n );\n}\n\n/** Inserts a previously used block back into the free list. */\nfunction insertBlock(root: Root, block: Block): void {\n if (DEBUG) assert(block); // cannot be null\n let blockInfo = block.mmInfo;\n if (DEBUG) assert(blockInfo & FREE); // must be free\n\n let right = GETRIGHT(block);\n let rightInfo = right.mmInfo;\n\n // merge with right block if also free\n if (rightInfo & FREE) {\n removeBlock(root, right);\n block.mmInfo = blockInfo = blockInfo + BLOCK_OVERHEAD + (rightInfo & ~TAGS_MASK); // keep block tags\n right = GETRIGHT(block);\n rightInfo = right.mmInfo;\n // 'back' is set below\n }\n\n // merge with left block if also free\n if (blockInfo & LEFTFREE) {\n let left = GETFREELEFT(block);\n let leftInfo = left.mmInfo;\n if (DEBUG) assert(leftInfo & FREE); // must be free according to right tags\n removeBlock(root, left);\n block = left;\n block.mmInfo = blockInfo = leftInfo + BLOCK_OVERHEAD + (blockInfo & ~TAGS_MASK); // keep left tags\n // 'back' is set below\n }\n\n right.mmInfo = rightInfo | LEFTFREE;\n // reference to right is no longer used now, hence rightInfo is not synced\n\n // we now know the size of the block\n let size = blockInfo & ~TAGS_MASK;\n if (DEBUG) assert(size >= BLOCK_MINSIZE); // must be a valid size\n if (DEBUG) assert(changetype(block) + BLOCK_OVERHEAD + size == changetype(right)); // must match\n\n // set 'back' to itself at the end of block\n store(changetype(right) - sizeof(), block);\n\n // mapping_insert\n let fl: usize, sl: u32;\n if (size < SB_SIZE) {\n fl = 0;\n sl = (size >> AL_BITS);\n } else {\n const inv: usize = sizeof() * 8 - 1;\n let boundedSize = min(size, BLOCK_MAXSIZE);\n fl = inv - clz(boundedSize);\n sl = ((boundedSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));\n fl -= SB_BITS - 1;\n }\n if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range\n\n // perform insertion\n let head = GETHEAD(root, fl, sl);\n block.prev = null;\n block.next = head;\n if (head) head.prev = block;\n SETHEAD(root, fl, sl, block);\n\n // update first and second level maps\n root.flMap |= (1 << fl);\n SETSL(root, fl, GETSL(root, fl) | (1 << sl));\n}\n\n/** Removes a free block from internal lists. */\nfunction removeBlock(root: Root, block: Block): void {\n let blockInfo = block.mmInfo;\n if (DEBUG) assert(blockInfo & FREE); // must be free\n let size = blockInfo & ~TAGS_MASK;\n if (DEBUG) assert(size >= BLOCK_MINSIZE); // must be valid\n\n // mapping_insert\n let fl: usize, sl: u32;\n if (size < SB_SIZE) {\n fl = 0;\n sl = (size >> AL_BITS);\n } else {\n const inv: usize = sizeof() * 8 - 1;\n let boundedSize = min(size, BLOCK_MAXSIZE);\n fl = inv - clz(boundedSize);\n sl = ((boundedSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));\n fl -= SB_BITS - 1;\n }\n if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range\n\n // link previous and next free block\n let prev = block.prev;\n let next = block.next;\n if (prev) prev.next = next;\n if (next) next.prev = prev;\n\n // update head if we are removing it\n if (block == GETHEAD(root, fl, sl)) {\n SETHEAD(root, fl, sl, next);\n\n // clear second level map if head is empty now\n if (!next) {\n let slMap = GETSL(root, fl);\n SETSL(root, fl, slMap &= ~(1 << sl));\n\n // clear first level map if second level is empty now\n if (!slMap) root.flMap &= ~(1 << fl);\n }\n }\n // note: does not alter left/back because it is likely that splitting\n // is performed afterwards, invalidating those changes. so, the caller\n // must perform those updates.\n}\n\n/** Searches for a free block of at least the specified size. */\nfunction searchBlock(root: Root, size: usize): Block | null {\n // size was already asserted by caller\n\n // mapping_search\n let fl: usize, sl: u32;\n if (size < SB_SIZE) {\n fl = 0;\n sl = (size >> AL_BITS);\n } else {\n const halfMaxSize = BLOCK_MAXSIZE >> 1; // don't round last fl\n const inv: usize = sizeof() * 8 - 1;\n const invRound = inv - SL_BITS;\n let requestSize = size < halfMaxSize\n ? size + (1 << (invRound - clz(size))) - 1\n : size;\n fl = inv - clz(requestSize);\n sl = ((requestSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));\n fl -= SB_BITS - 1;\n }\n if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range\n\n // search second level\n let slMap = GETSL(root, fl) & (~0 << sl);\n let head: Block | null = null;\n if (!slMap) {\n // search next larger first level\n let flMap = root.flMap & (~0 << (fl + 1));\n if (!flMap) {\n head = null;\n } else {\n fl = ctz(flMap);\n slMap = GETSL(root, fl);\n if (DEBUG) assert(slMap); // can't be zero if fl points here\n head = GETHEAD(root, fl, ctz(slMap));\n }\n } else {\n head = GETHEAD(root, fl, ctz(slMap));\n }\n return head;\n}\n\n/** Prepares the specified block before (re-)use, possibly splitting it. */\nfunction prepareBlock(root: Root, block: Block, size: usize): void {\n // size was already asserted by caller\n\n let blockInfo = block.mmInfo;\n if (DEBUG) assert(!((size + BLOCK_OVERHEAD) & AL_MASK)); // size must be aligned so the new block is\n\n // split if the block can hold another MINSIZE block incl. overhead\n let remaining = (blockInfo & ~TAGS_MASK) - size;\n if (remaining >= BLOCK_OVERHEAD + BLOCK_MINSIZE) {\n block.mmInfo = size | (blockInfo & LEFTFREE); // also discards FREE\n\n let spare = changetype(changetype(block) + BLOCK_OVERHEAD + size);\n spare.mmInfo = (remaining - BLOCK_OVERHEAD) | FREE; // not LEFTFREE\n insertBlock(root, spare); // also sets 'back'\n\n // otherwise tag block as no longer FREE and right as no longer LEFTFREE\n } else {\n block.mmInfo = blockInfo & ~FREE;\n GETRIGHT(block).mmInfo &= ~LEFTFREE;\n }\n}\n\n/** Adds more memory to the pool. */\nfunction addMemory(root: Root, start: usize, end: usize): bool {\n if (DEBUG) assert(start <= end); // must be valid\n start = ((start + BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK) - BLOCK_OVERHEAD;\n end &= ~AL_MASK;\n\n let tail = GETTAIL(root);\n let tailInfo: usize = 0;\n if (tail) { // more memory\n if (DEBUG) assert(start >= changetype(tail) + BLOCK_OVERHEAD);\n\n // merge with current tail if adjacent\n const offsetToTail = AL_SIZE;\n if (start - offsetToTail == changetype(tail)) {\n start -= offsetToTail;\n tailInfo = tail.mmInfo;\n } else {\n // We don't do this, but a user might `memory.grow` manually\n // leading to non-adjacent pages managed by TLSF.\n }\n\n } else if (DEBUG) { // first memory\n assert(start >= changetype(root) + ROOT_SIZE); // starts after root\n }\n\n // check if size is large enough for a free block and the tail block\n let size = end - start;\n if (size < BLOCK_OVERHEAD + BLOCK_MINSIZE + BLOCK_OVERHEAD) {\n return false;\n }\n\n // left size is total minus its own and the zero-length tail's header\n let leftSize = size - 2 * BLOCK_OVERHEAD;\n let left = changetype(start);\n left.mmInfo = leftSize | FREE | (tailInfo & LEFTFREE);\n left.prev = null;\n left.next = null;\n\n // tail is a zero-length used block\n tail = changetype(start + BLOCK_OVERHEAD + leftSize);\n tail.mmInfo = 0 | LEFTFREE;\n SETTAIL(root, tail);\n\n insertBlock(root, left); // also merges with free left before tail / sets 'back'\n\n return true;\n}\n\n/** Grows memory to fit at least another block of the specified size. */\nfunction growMemory(root: Root, size: usize): void {\n if (ASC_LOW_MEMORY_LIMIT) {\n unreachable();\n return;\n }\n // Here, both rounding performed in searchBlock ...\n const halfMaxSize = BLOCK_MAXSIZE >> 1;\n if (size < halfMaxSize) { // don't round last fl\n const invRound = (sizeof() * 8 - 1) - SL_BITS;\n size += (1 << (invRound - clz(size))) - 1;\n }\n // and additional BLOCK_OVERHEAD must be taken into account. If we are going\n // to merge with the tail block, that's one time, otherwise it's two times.\n let pagesBefore = memory.size();\n size += BLOCK_OVERHEAD << usize((pagesBefore << 16) - BLOCK_OVERHEAD != changetype(GETTAIL(root)));\n let pagesNeeded = (((size + 0xffff) & ~0xffff) >>> 16);\n let pagesWanted = max(pagesBefore, pagesNeeded); // double memory\n if (memory.grow(pagesWanted) < 0) {\n if (memory.grow(pagesNeeded) < 0) unreachable();\n }\n let pagesAfter = memory.size();\n addMemory(root, pagesBefore << 16, pagesAfter << 16);\n}\n\n/** Computes the size (excl. header) of a block. */\nfunction computeSize(size: usize): usize {\n // Size must be large enough and aligned minus preceeding overhead\n return size <= BLOCK_MINSIZE\n ? BLOCK_MINSIZE\n : ((size + BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK) - BLOCK_OVERHEAD;\n}\n\n/** Prepares and checks an allocation size. */\nfunction prepareSize(size: usize): usize {\n if (size > BLOCK_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);\n return computeSize(size);\n}\n\n/** Initializes the root structure. */\nfunction initialize(): void {\n if (isDefined(ASC_RTRACE)) oninit(__heap_base);\n let rootOffset = (__heap_base + AL_MASK) & ~AL_MASK;\n let pagesBefore = memory.size();\n let pagesNeeded = ((((rootOffset + ROOT_SIZE) + 0xffff) & ~0xffff) >>> 16);\n if (pagesNeeded > pagesBefore && memory.grow(pagesNeeded - pagesBefore) < 0) unreachable();\n let root = changetype(rootOffset);\n root.flMap = 0;\n SETTAIL(root, changetype(0));\n for (let fl: usize = 0; fl < FL_BITS; ++fl) {\n SETSL(root, fl, 0);\n for (let sl: u32 = 0; sl < SL_SIZE; ++sl) {\n SETHEAD(root, fl, sl, null);\n }\n }\n let memStart = rootOffset + ROOT_SIZE;\n if (ASC_LOW_MEMORY_LIMIT) {\n const memEnd = ASC_LOW_MEMORY_LIMIT & ~AL_MASK;\n if (memStart <= memEnd) addMemory(root, memStart, memEnd);\n else unreachable(); // low memory limit already exceeded\n } else {\n addMemory(root, memStart, memory.size() << 16);\n }\n ROOT = root;\n}\n\n/** Allocates a block of the specified size. */\nexport function allocateBlock(root: Root, size: usize): Block {\n let payloadSize = prepareSize(size);\n let block = searchBlock(root, payloadSize);\n if (!block) {\n growMemory(root, payloadSize);\n block = changetype(searchBlock(root, payloadSize));\n if (DEBUG) assert(block); // must be found now\n }\n if (DEBUG) assert((block.mmInfo & ~TAGS_MASK) >= payloadSize); // must fit\n removeBlock(root, block);\n prepareBlock(root, block, payloadSize);\n if (isDefined(ASC_RTRACE)) onalloc(block);\n return block;\n}\n\n/** Reallocates a block to the specified size. */\nexport function reallocateBlock(root: Root, block: Block, size: usize): Block {\n let payloadSize = prepareSize(size);\n let blockInfo = block.mmInfo;\n let blockSize = blockInfo & ~TAGS_MASK;\n\n // possibly split and update runtime size if it still fits\n if (payloadSize <= blockSize) {\n prepareBlock(root, block, payloadSize);\n if (isDefined(ASC_RTRACE)) {\n if (payloadSize != blockSize) onresize(block, BLOCK_OVERHEAD + blockSize);\n }\n return block;\n }\n\n // merge with right free block if merger is large enough\n let right = GETRIGHT(block);\n let rightInfo = right.mmInfo;\n if (rightInfo & FREE) {\n let mergeSize = blockSize + BLOCK_OVERHEAD + (rightInfo & ~TAGS_MASK);\n if (mergeSize >= payloadSize) {\n removeBlock(root, right);\n block.mmInfo = (blockInfo & TAGS_MASK) | mergeSize;\n prepareBlock(root, block, payloadSize);\n if (isDefined(ASC_RTRACE)) onresize(block, BLOCK_OVERHEAD + blockSize);\n return block;\n }\n }\n\n // otherwise move the block\n return moveBlock(root, block, size);\n}\n\n/** Moves a block to a new one of the specified size. */\nfunction moveBlock(root: Root, block: Block, newSize: usize): Block {\n let newBlock = allocateBlock(root, newSize);\n memory.copy(changetype(newBlock) + BLOCK_OVERHEAD, changetype(block) + BLOCK_OVERHEAD, block.mmInfo & ~TAGS_MASK);\n if (changetype(block) >= __heap_base) {\n if (isDefined(ASC_RTRACE)) onmove(block, newBlock);\n freeBlock(root, block);\n }\n return newBlock;\n}\n\n/** Frees a block. */\nexport function freeBlock(root: Root, block: Block): void {\n if (isDefined(ASC_RTRACE)) onfree(block);\n block.mmInfo = block.mmInfo | FREE;\n insertBlock(root, block);\n}\n\n/** Checks that a used block is valid to be freed or reallocated. */\nfunction checkUsedBlock(ptr: usize): Block {\n let block = changetype(ptr - BLOCK_OVERHEAD);\n assert(\n ptr != 0 && !(ptr & AL_MASK) && // must exist and be aligned\n !(block.mmInfo & FREE) // must be used\n );\n return block;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __alloc(size: usize): usize {\n if (!ROOT) initialize();\n return changetype(allocateBlock(ROOT, size)) + BLOCK_OVERHEAD;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __realloc(ptr: usize, size: usize): usize {\n if (!ROOT) initialize();\n return (ptr < __heap_base\n ? changetype(moveBlock(ROOT, checkUsedBlock(ptr), size))\n : changetype(reallocateBlock(ROOT, checkUsedBlock(ptr), size))\n ) + BLOCK_OVERHEAD;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __free(ptr: usize): void {\n if (ptr < __heap_base) return;\n if (!ROOT) initialize();\n freeBlock(ROOT, checkUsedBlock(ptr));\n}\n","// This file is shared with the compiler and must remain portable\n\n// ╒═══════════════════ Typeinfo interpretation ═══════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤ ◄─ __rtti_base\n// │ count │\n// ╞═══════════════════════════════════════════════════════════════╡ ┐\n// │ Typeinfo#flags [id=0] │ id < count\n// ├───────────────────────────────────────────────────────────────┤\n// │ ... │\n\n/** Runtime type information data structure. */\n@unmanaged\nexport class Typeinfo {\n /** Flags describing the shape of this class type. */\n flags: TypeinfoFlags = TypeinfoFlags.NONE;\n}\n\n/** Runtime type information flags. */\nexport const enum TypeinfoFlags {\n /** No specific flags. */\n NONE = 0,\n /** Type is an `ArrayBufferView`. */\n ARRAYBUFFERVIEW = 1 << 0,\n /** Type is an `Array`. */\n ARRAY = 1 << 1,\n /** Type is a `StaticArray`. */\n STATICARRAY = 1 << 2,\n /** Type is a `Set`. */\n SET = 1 << 3,\n /** Type is a `Map`. */\n MAP = 1 << 4,\n /** Type has no outgoing pointers. */\n POINTERFREE = 1 << 5,\n /** Value alignment of 1 byte. */\n VALUE_ALIGN_0 = 1 << 6,\n /** Value alignment of 2 bytes. */\n VALUE_ALIGN_1 = 1 << 7,\n /** Value alignment of 4 bytes. */\n VALUE_ALIGN_2 = 1 << 8,\n /** Value alignment of 8 bytes. */\n VALUE_ALIGN_3 = 1 << 9,\n /** Value alignment of 16 bytes. */\n VALUE_ALIGN_4 = 1 << 10,\n /** Value is a signed type. */\n VALUE_SIGNED = 1 << 11,\n /** Value is a float type. */\n VALUE_FLOAT = 1 << 12,\n /** Value type is nullable. */\n VALUE_NULLABLE = 1 << 13,\n /** Value type is managed. */\n VALUE_MANAGED = 1 << 14,\n /** Key alignment of 1 byte. */\n KEY_ALIGN_0 = 1 << 15,\n /** Key alignment of 2 bytes. */\n KEY_ALIGN_1 = 1 << 16,\n /** Key alignment of 4 bytes. */\n KEY_ALIGN_2 = 1 << 17,\n /** Key alignment of 8 bytes. */\n KEY_ALIGN_3 = 1 << 18,\n /** Key alignment of 16 bytes. */\n KEY_ALIGN_4 = 1 << 19,\n /** Key is a signed type. */\n KEY_SIGNED = 1 << 20,\n /** Key is a float type. */\n KEY_FLOAT = 1 << 21,\n /** Key type is nullable. */\n KEY_NULLABLE = 1 << 22,\n /** Key type is managed. */\n KEY_MANAGED = 1 << 23\n}\n","import { BLOCK, BLOCK_OVERHEAD, OBJECT_OVERHEAD, OBJECT_MAXSIZE, TOTAL_OVERHEAD, DEBUG, TRACE, RTRACE, PROFILE } from \"./common\";\nimport { onvisit, oncollect, oninterrupt, onyield } from \"./rtrace\";\nimport { TypeinfoFlags } from \"../shared/typeinfo\";\nimport { E_ALLOCATION_TOO_LARGE, E_ALREADY_PINNED, E_NOT_PINNED } from \"../util/error\";\n\n// === ITCMS: An incremental Tri-Color Mark & Sweep garbage collector ===\n// Adapted from Bach Le's μgc, see: https://github.com/bullno1/ugc\n\n// ╒═════════════╤══════════════ Colors ═══════════════════════════╕\n// │ Color │ Meaning │\n// ├─────────────┼─────────────────────────────────────────────────┤\n// │ WHITE* │ Unprocessed │\n// │ BLACK* │ Processed │\n// │ GRAY │ Processed with unprocessed children │\n// │ TRANSPARENT │ Manually pinned (always reachable) │\n// └─────────────┴─────────────────────────────────────────────────┘\n// * flipped between cycles\n\n// @ts-ignore: decorator\n@lazy let white = 0;\n// @ts-ignore: decorator\n@inline const gray = 2;\n// @ts-ignore: decorator\n@inline const transparent = 3;\n// @ts-ignore: decorator\n@inline const COLOR_MASK = 3;\n\n/** Size in memory of all objects currently managed by the GC. */\n// @ts-ignore: decorator\n@lazy let total: usize = 0;\n\n/** Currently transitioning from SWEEP to MARK state. */\n// @ts-ignore: decorator\n@inline const STATE_IDLE = 0;\n/** Currently marking reachable objects. */\n// @ts-ignore: decorator\n@inline const STATE_MARK = 1;\n/** Currently sweeping unreachable objects. */\n// @ts-ignore: decorator\n@inline const STATE_SWEEP = 2;\n/** Current collector state. */\n// @ts-ignore: decorator\n@lazy let state = STATE_IDLE;\n\n// @ts-ignore: decorator\n@lazy let fromSpace = initLazy(changetype(memory.data(offsetof())));\n// @ts-ignore: decorator\n@lazy let toSpace = initLazy(changetype(memory.data(offsetof())));\n// @ts-ignore: decorator\n@lazy let pinSpace = initLazy(changetype(memory.data(offsetof())));\n// @ts-ignore: decorator\n@lazy let iter: Object = changetype(0); // unsafe initializion below\n\nfunction initLazy(space: Object): Object {\n space.nextWithColor = changetype(space);\n space.prev = space;\n return space;\n}\n\n/** Visit cookie indicating scanning of an object. */\n// @ts-ignore: decorator\n@inline const VISIT_SCAN = 0;\n\n// ╒═══════════════ Managed object layout (32-bit) ════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤\n// │ Memory manager block │\n// ╞═══════════════════════════════════════════════════════════╤═══╡\n// │ next │ C │ = nextWithColor\n// ├───────────────────────────────────────────────────────────┴───┤\n// │ prev │\n// ├───────────────────────────────────────────────────────────────┤\n// │ rtId │\n// ├───────────────────────────────────────────────────────────────┤\n// │ rtSize │\n// ╞>ptr═══════════════════════════════════════════════════════════╡\n// │ ... │\n// C: color\n\n/** Represents a managed object in memory, consisting of a header followed by the object's data. */\n@unmanaged class Object extends BLOCK {\n /** Pointer to the next object with color flags stored in the alignment bits. */\n nextWithColor: usize; // *u32\n /** Pointer to the previous object. */\n prev: Object; // *u32\n /** Runtime id. */\n rtId: u32;\n /** Runtime size. */\n rtSize: u32;\n\n /** Gets the pointer to the next object. */\n get next(): Object {\n return changetype(this.nextWithColor & ~COLOR_MASK);\n }\n\n /** Sets the pointer to the next object. */\n set next(obj: Object) {\n this.nextWithColor = changetype(obj) | (this.nextWithColor & COLOR_MASK);\n }\n\n /** Gets this object's color. */\n get color(): i32 {\n return i32(this.nextWithColor & COLOR_MASK);\n }\n\n /** Sets this object's color. */\n set color(color: i32) {\n this.nextWithColor = (this.nextWithColor & ~COLOR_MASK) | color;\n }\n\n /** Gets the size of this object in memory. */\n get size(): usize {\n return BLOCK_OVERHEAD + (this.mmInfo & ~3);\n }\n\n /** Tests if this object is pointerfree. */\n get isPointerfree(): bool {\n let rtId = this.rtId;\n // 0: Object, 1: ArrayBuffer, 2: String\n return rtId <= idof() || (__typeinfo(rtId) & TypeinfoFlags.POINTERFREE) != 0;\n }\n\n /** Unlinks this object from its list. */\n unlink(): void {\n let next = this.next;\n if (next == null) {\n if (DEBUG) assert(this.prev == null && changetype(this) < __heap_base);\n return; // static data not yet linked\n }\n let prev = this.prev;\n if (DEBUG) assert(prev);\n next.prev = prev;\n prev.next = next;\n }\n\n /** Links this object to the specified list, with the given color. */\n linkTo(list: Object, withColor: i32): void {\n let prev = list.prev;\n this.nextWithColor = changetype(list) | withColor;\n this.prev = prev;\n prev.next = this;\n list.prev = this;\n }\n\n /** Marks this object as gray, that is reachable with unscanned children. */\n makeGray(): void {\n if (this == iter) iter = assert(this.prev);\n this.unlink();\n this.linkTo(toSpace, this.isPointerfree ? i32(!white) : gray);\n }\n}\n\n/** Visits all objects considered to be program roots. */\nfunction visitRoots(cookie: u32): void {\n __visit_globals(cookie);\n let pn = pinSpace;\n let iter = pn.next;\n while (iter != pn) {\n if (DEBUG) assert(iter.color == transparent);\n __visit_members(changetype(iter) + TOTAL_OVERHEAD, cookie);\n iter = iter.next;\n }\n}\n\n/** Visits all objects on the stack. */\nfunction visitStack(cookie: u32): void {\n let ptr = __stack_pointer;\n while (ptr < __heap_base) {\n __visit(load(ptr), cookie);\n ptr += sizeof();\n }\n}\n\n/** Performs a single step according to the current state. */\nfunction step(): usize {\n // Magic constants responsible for pause times. Obtained experimentally\n // using the compiler compiling itself. 2048 budget pro run by default.\n const MARKCOST = isDefined(ASC_GC_MARKCOST) ? ASC_GC_MARKCOST : 1;\n const SWEEPCOST = isDefined(ASC_GC_SWEEPCOST) ? ASC_GC_SWEEPCOST : 10;\n let obj: Object;\n switch (state) {\n case STATE_IDLE: {\n state = STATE_MARK;\n visitCount = 0;\n visitRoots(VISIT_SCAN);\n iter = toSpace;\n return visitCount * MARKCOST;\n }\n case STATE_MARK: {\n let black = i32(!white);\n obj = iter.next;\n while (obj != toSpace) {\n iter = obj;\n if (obj.color != black) { // skip already-blacks (pointerfree)\n obj.color = black;\n visitCount = 0;\n __visit_members(changetype(obj) + TOTAL_OVERHEAD, VISIT_SCAN);\n return visitCount * MARKCOST;\n }\n obj = obj.next;\n }\n visitCount = 0;\n visitRoots(VISIT_SCAN);\n obj = iter.next;\n if (obj == toSpace) {\n visitStack(VISIT_SCAN);\n obj = iter.next;\n while (obj != toSpace) {\n if (obj.color != black) {\n obj.color = black;\n __visit_members(changetype(obj) + TOTAL_OVERHEAD, VISIT_SCAN);\n }\n obj = obj.next;\n }\n let from = fromSpace;\n fromSpace = toSpace;\n toSpace = from;\n white = black;\n iter = from.next;\n state = STATE_SWEEP;\n }\n return visitCount * MARKCOST;\n }\n case STATE_SWEEP: {\n obj = iter;\n if (obj != toSpace) {\n iter = obj.next;\n if (DEBUG) assert(obj.color == i32(!white)); // old white\n free(obj);\n return SWEEPCOST;\n }\n toSpace.nextWithColor = changetype(toSpace);\n toSpace.prev = toSpace;\n state = STATE_IDLE;\n break;\n }\n }\n return 0;\n}\n\n/** Frees an object. */\nfunction free(obj: Object): void {\n if (changetype(obj) < __heap_base) {\n obj.nextWithColor = 0; // may become linked again\n obj.prev = changetype(0);\n } else {\n total -= obj.size;\n if (isDefined(__finalize)) {\n __finalize(changetype(obj) + TOTAL_OVERHEAD);\n }\n __free(changetype(obj) + BLOCK_OVERHEAD);\n }\n}\n\n// Garbage collector interface\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __new(size: usize, id: i32): usize {\n if (size >= OBJECT_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);\n if (total >= threshold) interrupt();\n let obj = changetype(__alloc(OBJECT_OVERHEAD + size) - BLOCK_OVERHEAD);\n obj.rtId = id;\n obj.rtSize = size;\n obj.linkTo(fromSpace, white); // inits next/prev\n total += obj.size;\n let ptr = changetype(obj) + TOTAL_OVERHEAD;\n // may be visited before being fully initialized, so must fill\n memory.fill(ptr, 0, size);\n return ptr;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __renew(oldPtr: usize, size: usize): usize {\n let oldObj = changetype(oldPtr - TOTAL_OVERHEAD);\n // Update object size if its block is large enough\n if (size <= (oldObj.mmInfo & ~3) - OBJECT_OVERHEAD) {\n oldObj.rtSize = size;\n return oldPtr;\n }\n // If not the same object anymore, we have to move it move it due to the\n // shadow stack potentially still referencing the old object\n let newPtr = __new(size, oldObj.rtId);\n memory.copy(newPtr, oldPtr, min(size, oldObj.rtSize));\n return newPtr;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void {\n // Write barrier is unnecessary if non-incremental\n if (!childPtr) return;\n if (DEBUG) assert(parentPtr);\n let child = changetype(childPtr - TOTAL_OVERHEAD);\n if (child.color == white) {\n let parent = changetype(parentPtr - TOTAL_OVERHEAD);\n let parentColor = parent.color;\n if (parentColor == i32(!white)) {\n // Maintain the invariant that no black object may point to a white object.\n if (expectMultiple) {\n // Move the barrier \"backward\". Suitable for containers receiving multiple stores.\n // Avoids a barrier for subsequent objects stored into the same container.\n parent.makeGray();\n } else {\n // Move the barrier \"forward\". Suitable for objects receiving isolated stores.\n child.makeGray();\n }\n } else if (parentColor == transparent && state == STATE_MARK) {\n // Pinned objects are considered 'black' during the mark phase.\n child.makeGray();\n }\n }\n}\n\n// @ts-ignore: decorator\n@lazy let visitCount = 0;\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __visit(ptr: usize, cookie: i32): void {\n if (!ptr) return;\n let obj = changetype(ptr - TOTAL_OVERHEAD);\n if (RTRACE) if (!onvisit(obj)) return;\n if (obj.color == white) {\n obj.makeGray();\n ++visitCount;\n }\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __pin(ptr: usize): usize {\n if (ptr) {\n let obj = changetype(ptr - TOTAL_OVERHEAD);\n if (obj.color == transparent) {\n throw new Error(E_ALREADY_PINNED);\n }\n obj.unlink(); // from fromSpace\n obj.linkTo(pinSpace, transparent);\n }\n return ptr;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __unpin(ptr: usize): void {\n if (!ptr) return;\n let obj = changetype(ptr - TOTAL_OVERHEAD);\n if (obj.color != transparent) {\n throw new Error(E_NOT_PINNED);\n }\n if (state == STATE_MARK) {\n // We may be right at the point after marking roots for the second time and\n // entering the sweep phase, in which case the object would be missed if it\n // is not only pinned but also a root. Make sure it isn't missed.\n obj.makeGray();\n } else {\n obj.unlink();\n obj.linkTo(fromSpace, white);\n }\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __collect(): void {\n if (TRACE) trace(\"GC (full) at\", 1, total);\n if (state > STATE_IDLE) {\n // finish current cycle\n while (state != STATE_IDLE) step();\n }\n // perform a full cycle\n step();\n while (state != STATE_IDLE) step();\n threshold = (total * IDLEFACTOR / 100) + GRANULARITY;\n if (TRACE) trace(\"GC (full) done at cur/max\", 2, total, memory.size() << 16);\n if (RTRACE || PROFILE) oncollect(total);\n}\n\n// Garbage collector automation\n\n/** How often to interrupt. The default of 1024 means \"interrupt each 1024 bytes allocated\". */\n// @ts-ignore: decorator\n@inline const GRANULARITY: usize = isDefined(ASC_GC_GRANULARITY) ? ASC_GC_GRANULARITY : 1024;\n/** How long to interrupt. The default of 200% means \"run at double the speed of allocations\". */\n// @ts-ignore: decorator\n@inline const STEPFACTOR: usize = isDefined(ASC_GC_SWEEPFACTOR) ? ASC_GC_SWEEPFACTOR : 200;\n/** How long to idle. The default of 200% means \"wait for memory to double before kicking in again\". */\n// @ts-ignore: decorator\n@inline const IDLEFACTOR: usize = isDefined(ASC_GC_IDLEFACTOR) ? ASC_GC_IDLEFACTOR : 200;\n\n/** Threshold of memory used by objects to exceed before interrupting again. */\n// @ts-ignore: decorator\n@lazy let threshold: usize = ((memory.size() << 16) - __heap_base) >> 1;\n\n/** Performs a reasonable amount of incremental GC steps. */\nfunction interrupt(): void {\n if (PROFILE) oninterrupt(total);\n if (TRACE) trace(\"GC (auto) at\", 1, total);\n let budget: isize = GRANULARITY * STEPFACTOR / 100;\n do {\n budget -= step();\n if (state == STATE_IDLE) {\n if (TRACE) trace(\"└ GC (auto) done at cur/max\", 2, total, memory.size() << 16);\n threshold = (total * IDLEFACTOR / 100) + GRANULARITY;\n if (PROFILE) onyield(total);\n return;\n }\n } while (budget > 0);\n if (TRACE) trace(\"└ GC (auto) ongoing at\", 1, total);\n threshold = total + GRANULARITY * usize(total - threshold < GRANULARITY);\n if (PROFILE) onyield(total);\n}\n","/**\n * @fileoverview 64-bit integer glue code for WebAssembly.\n * @license Apache-2.0\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n// @ts-ignore: decorator\n@global const i64_zero: i64 = 0;\n\n// @ts-ignore: decorator\n@global const i64_one: i64 = 1;\n\n// @ts-ignore: decorator\n@global const i64_neg_one: i64 = -1;\n\n// @ts-ignore: decorator\n@global const i64_minimum: i64 = i64.MIN_VALUE;\n\n// @ts-ignore: decorator\n@global const i64_maximum: i64 = i64.MAX_VALUE;\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is(value: T): bool {\n return isInteger() && sizeof() == 8;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_new(lo: i32, hi: i32 = 0): i64 {\n return lo | (hi << 32);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_low(value: i64): i32 {\n return value;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_not(value: i64): i64 {\n return ~value;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_neg(value: i64): i64 {\n return -value;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_clz(value: i64): i32 {\n return clz(value);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_ctz(value: i64): i32 {\n return ctz(value);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_high(value: i64): i32 {\n return (value >>> 32);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_add(left: i64, right: i64): i64 {\n return left + right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_sub(left: i64, right: i64): i64 {\n return left - right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_mul(left: i64, right: i64): i64 {\n return left * right;\n}\n\n// @ts-ignore: decorator\n@global\nfunction i64_pow(left: i64, right: i64): i64 {\n if (right <= 0) {\n if (left == -1) return select(-1, 1, right & 1);\n return i64(right == 0) | i64(left == 1);\n }\n if (right == 1) return left;\n if (right == 2) return left * left;\n let result: i64 = 1;\n while (right) {\n if (right & 1) result *= left;\n right >>>= 1;\n left *= left;\n }\n return result;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_div(left: i64, right: i64): i64 {\n return left / right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_div_u(left: i64, right: i64): i64 {\n return left / right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_rem(left: i64, right: i64): i64 {\n return left % right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_rem_u(left: i64, right: i64): i64 {\n return left % right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_and(left: i64, right: i64): i64 {\n return left & right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_or(left: i64, right: i64): i64 {\n return left | right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_xor(left: i64, right: i64): i64 {\n return left ^ right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_shl(left: i64, right: i64): i64 {\n return left << right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_shr(left: i64, right: i64): i64 {\n return left >> right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_shr_u(left: i64, right: i64): i64 {\n return left >>> right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_eq(left: i64, right: i64): bool {\n return left == right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_ne(left: i64, right: i64): bool {\n return left != right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_ge(left: i64, right: i64): bool {\n return left >= right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_ge_u(left: i64, right: i64): bool {\n return left >= right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_gt(left: i64, right: i64): bool {\n return left > right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_gt_u(left: i64, right: i64): bool {\n return left > right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_le(left: i64, right: i64): bool {\n return left <= right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_le_u(left: i64, right: i64): bool {\n return left <= right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_lt(left: i64, right: i64): bool {\n return left < right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_lt_u(left: i64, right: i64): bool {\n return left < right;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_align(value: i64, alignment: i64): i64 {\n let mask: i64 = alignment - 1;\n assert(alignment && (alignment & mask) == 0);\n return (value + mask) & ~mask;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_signbit(value: i64): bool {\n return (value >>> 63);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_i8(value: i64): bool {\n return value >= i8.MIN_VALUE && value <= i8.MAX_VALUE;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_i16(value: i64): bool {\n return value >= i16.MIN_VALUE && value <= i16.MAX_VALUE;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_i32(value: i64): bool {\n return value >= i32.MIN_VALUE && value <= i32.MAX_VALUE;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_u8(value: i64): bool {\n return value <= u8.MAX_VALUE;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_u16(value: i64): bool {\n return value <= u16.MAX_VALUE;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_u32(value: i64): bool {\n return value <= u32.MAX_VALUE;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_bool(value: i64): bool {\n return (value & ~1) == 0;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_f32(value: i64): bool {\n return value >= f32.MIN_SAFE_INTEGER && value <= f32.MAX_SAFE_INTEGER;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_is_f64(value: i64): bool {\n return value >= f64.MIN_SAFE_INTEGER && value <= f64.MAX_SAFE_INTEGER;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_to_f32(value: i64): f32 {\n return value;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_to_f64(value: i64): f64 {\n return value;\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_to_string(value: i64, unsigned: bool = false): string {\n return unsigned ? u64(value).toString() : value.toString();\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_clone(value: i64): i64 {\n return value;\n}\n","import { strtol, strtod, strtob } from \"./util/string\";\n\ntype auto = i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isBoolean(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isInteger(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isSigned(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isFloat(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isVector(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isReference(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isString(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isArray(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isArrayLike(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isFunction(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isNullable(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isDefined(expression: auto): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isConstant(expression: auto): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isManaged(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isVoid(): bool;\n\n// @ts-ignore\n@builtin\nexport declare function lengthof(func?: T): i32;\n\n// @ts-ignore\n@builtin\nexport declare function bswap(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function clz(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function ctz(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function popcnt(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function rotl(value: T, shift: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function rotr(value: T, shift: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function abs(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function max(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function min(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function ceil(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function floor(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function copysign(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function nearest(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function reinterpret(value: number): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function sqrt(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function trunc(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function add(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function sub(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function mul(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function div(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function eq(left: T, right: T): i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function ne(left: T, right: T): i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function rem(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function store(ptr: usize, value: auto, immOffset?: usize, immAlign?: usize): void;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function sizeof(): usize; // | u32 / u64\n\n// @ts-ignore: decorator\n@builtin\nexport declare function alignof(): usize; // | u32 / u64\n\n// @ts-ignore: decorator\n@builtin\nexport declare function offsetof(fieldName?: string): usize; // | u32 / u64\n\n// @ts-ignore: decorator\n@builtin\nexport declare function idof(): u32;\n\n// @ts-ignore\n@builtin\nexport declare function nameof(): string;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function select(ifTrue: T, ifFalse: T, condition: bool): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function unreachable(): auto;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function changetype(value: auto): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function assert(isTrueish: T, message?: string): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function unchecked(expr: T): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function call_indirect(index: u32, ...args: auto[]): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function instantiate(...args: auto[]): T;\n\nexport namespace atomic {\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load(ptr: usize, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: T, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg(ptr: usize, expected: T, replacement: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function wait(ptr: usize, expected: T, timeout: i64): AtomicWaitResult;\n\n // @ts-ignore: decorator\n @builtin\n export declare function notify(ptr: usize, count: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function fence(): void;\n}\n\n// @ts-ignore: decorator\n@lazy\nexport const enum AtomicWaitResult {\n OK = 0,\n NOT_EQUAL = 1,\n TIMED_OUT = 2\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i8(value: auto): i8;\n\nexport namespace i8 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i8 = -128;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i8 = 127;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i8 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i16(value: auto): i16;\n\nexport namespace i16 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i16 = -32768;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i16 = 32767;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i16 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i32(value: auto): i32;\n\nexport namespace i32 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i32 = -2147483648;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i32 = 2147483647;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i32 {\n return strtol(value, radix);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function clz(value: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ctz(value: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(value: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_s(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_u(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotl(value: i32, shift: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotr(value: i32, shift: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_s(left: i32, right: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_u(left: u32, right: u32): u32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_f32(value: f32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_s(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_s(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void;\n\n export namespace atomic {\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i32, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i32, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i32, immOffset?: usize): void;\n\n export namespace rmw8 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i32, replacement: i32, immOffset?: usize): i32;\n }\n\n export namespace rmw16 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i32, replacement: i32, immOffset?: usize): i32;\n }\n\n export namespace rmw {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg(ptr: usize, expected: i32, replacement: i32, immOffset?: usize): i32;\n }\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i64(value: auto): i64;\n\nexport namespace i64 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i64 = -9223372036854775808;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i64 = 9223372036854775807;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i64 {\n return strtol(value, radix);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function clz(value: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ctz(value: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_s(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_u(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_s(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_s(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32_s(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32_u(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(value: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotl(value: i64, shift: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotr(value: i64, shift: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: i64, right:i64): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: i64, right:i64): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_s(left: i64, right: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_u(left: u64, right: u64): u64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_f64(value: f64): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store32(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n export namespace atomic {\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32_u(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i64, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i64, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store32(ptr: usize, value: i64, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i64, immOffset?: usize): void;\n\n export namespace rmw8 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n\n export namespace rmw16 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n\n export namespace rmw32 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n\n export namespace rmw {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isize(value: auto): isize;\n\nexport namespace isize {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: isize = sizeof() == sizeof()\n ? -2147483648\n : -9223372036854775808;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: isize = sizeof() == sizeof()\n ? 2147483647\n : 9223372036854775807;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): isize {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u8(value: auto): u8;\n\nexport namespace u8 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u8 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u8 = 255;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u8 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u16(value: auto): u16;\n\nexport namespace u16 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u16 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u16 = 65535;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u16 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u32(value: auto): u32;\n\nexport namespace u32 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u32 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u32 = 4294967295;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u32 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u64(value: auto): u64;\n\nexport namespace u64 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u64 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u64 = 18446744073709551615;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u64 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function usize(value: auto): usize;\n\nexport namespace usize {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: usize = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: usize = sizeof() == sizeof()\n ? 4294967295\n : 18446744073709551615;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): usize {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function bool(value: auto): bool;\n\nexport namespace bool {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: bool = false;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: bool = true;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string): bool {\n return strtob(value);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f32(value: auto): f32;\n\nexport namespace f32 {\n\n // @ts-ignore: decorator\n @lazy\n export const EPSILON = reinterpret(0x34000000); // 0x1p-23f\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE = reinterpret(0x00000001); // 0x0.000001p+0f\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE = reinterpret(0x7F7FFFFF); // 0x1.fffffep+127f\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_NORMAL_VALUE = reinterpret(0x00800000); // 0x1p-126f\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_SAFE_INTEGER: f32 = -16777215;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_SAFE_INTEGER: f32 = 16777215;\n\n // @ts-ignore: decorator\n @lazy\n export const POSITIVE_INFINITY: f32 = Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NEGATIVE_INFINITY: f32 = -Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NaN: f32 = 0.0 / 0.0;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string): f32 {\n return strtod(value);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function copysign(x: f32, y: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_i32(value: i32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(value: f32): f32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: f32, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: f32, right: f32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: f32, right: f32): i32;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f64(value: auto): f64;\n\nexport namespace f64 {\n\n // @ts-ignore: decorator\n @lazy\n export const EPSILON = reinterpret(0x3CB0000000000000); // 0x1p-52\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE = reinterpret(0x0000000000000001); // 0x0.0000000000001p+0\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE = reinterpret(0x7FEFFFFFFFFFFFFF); // 0x1.fffffffffffffp+1023\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_NORMAL_VALUE = reinterpret(0x0010000000000000); // 0x1p-1022\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_SAFE_INTEGER: f64 = -9007199254740991;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_SAFE_INTEGER: f64 = 9007199254740991;\n\n // @ts-ignore: decorator\n @lazy\n export const POSITIVE_INFINITY: f64 = Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NEGATIVE_INFINITY: f64 = -Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NaN: f64 = 0.0 / 0.0;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string): f64 {\n return strtod(value);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function copysign(x: f64, y: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_i64(value: i64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(value: f64): f64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: f64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: f64, right: f64): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: f64, right: f64): i32;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function v128(\n a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8,\n i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8\n): v128;\n\nexport namespace v128 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: T): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: T): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, ...lanes: u8[]): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_ext(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_zero(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_lane(ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store_lane(ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8x8_s(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8x8_u(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16x4_s(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16x4_u(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32x2_s(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32x2_u(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_splat(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load8_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load16_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load32_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load64_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load32_zero(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load64_zero(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load8_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load16_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load32_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load64_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store32_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store64_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: v128, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(a: v128, b: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function andnot(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function not(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitselect(v1: v128, v2: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function any_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmin(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmax(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function dot(a: v128, b: v128): v128; // i16 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function avgr(a: v128, b: v128): v128; // u8, u16 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_low(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function demote_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function promote_low(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function q15mulr_sat(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i8x16(\n a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8,\n i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8\n): v128;\n\nexport namespace i8x16 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_s(x: v128, idx: u8): i8;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_u(x: v128, idx: u8): u8;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function avgr_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i16x8_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(\n a: v128, b: v128,\n l0: u8, l1: u8, l2: u8, l3: u8, l4: u8, l5: u8, l6: u8, l7: u8,\n l8: u8, l9: u8, l10: u8, l11: u8, l12: u8, l13: u8, l14: u8, l15: u8\n ): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i16x8(a: i16, b: i16, c: i16, d: i16, e: i16, f: i16, g: i16, h: i16): v128;\n\nexport namespace i16x8 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i16): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_s(x: v128, idx: u8): i16;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_u(x: v128, idx: u8): u16;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i16): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function avgr_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i32x4_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i32x4_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i8x16_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i8x16_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i8x16_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i8x16_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i8x16_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i8x16_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function q15mulr_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i8x16_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i8x16_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i8x16_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i8x16_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(\n a: v128, b: v128,\n l0: u8, l1: u8, l2: u8, l3: u8, l4: u8, l5: u8, l6: u8, l7: u8\n ): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i32x4(a: i32, b: i32, c: i32, d: i32): v128;\n\nexport namespace i32x4 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function dot_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f64x2_s_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f64x2_u_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i16x8_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i16x8_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i16x8_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i16x8_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i16x8_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i16x8_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i16x8_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i16x8_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8, l2: u8, l3: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i64x2(a: i64, b: i64): v128;\n\nexport namespace i64x2 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i32x4_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i32x4_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i32x4_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i32x4_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f32x4(a: f32, b: f32, c: f32, d: f32): v128;\n\nexport namespace f32x4 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: f32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: f32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmin(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmax(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function demote_f64x2_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8, l2: u8, l3: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f64x2(a: f64, b: f64): v128;\n\nexport namespace f64x2 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: f64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: f64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmin(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmax(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_low_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_low_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function promote_low_f32x4(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n}\n\n@final\nexport abstract class i31 { // FIXME: usage of 'new' requires a class :(\n\n // @ts-ignore: decorator\n @builtin\n static new(value: i32): i31ref { return changetype(unreachable()); }\n\n // @ts-ignore: decorator\n @builtin\n static get(i31expr: i31ref): i32 { return unreachable(); }\n}\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n// @ts-ignore: decorator\n@external(\"env\", \"abort\")\n@external.js(\"throw Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);\")\ndeclare function abort(\n message?: string | null,\n fileName?: string | null,\n lineNumber?: u32,\n columnNumber?: u32\n): void;\n\n// @ts-ignore: decorator\n@external(\"env\", \"trace\")\n@external.js(\"console.log(message, ...[a0, a1, a2, a3, a4].slice(0, n));\")\ndeclare function trace(\n message: string,\n n?: i32,\n a0?: f64,\n a1?: f64,\n a2?: f64,\n a3?: f64,\n a4?: f64\n): void;\n\n// @ts-ignore: decorator\n@external(\"env\", \"seed\")\n@external.js(\"return Date.now() * Math.random();\")\ndeclare function seed(): f64;\n\n/* eslint-enable @typescript-eslint/no-unused-vars */\n","/**\n * @fileoverview Common constants used by various parts of the compiler.\n * @license Apache-2.0\n */\n\n/** Indicates traits of a {@link Node} or {@link Element}. */\nexport const enum CommonFlags {\n /** No flags set. */\n None = 0,\n\n // Basic modifiers\n\n /** Has an `import` modifier. */\n Import = 1 << 0,\n /** Has an `export` modifier. */\n Export = 1 << 1,\n /** Has a `declare` modifier. */\n Declare = 1 << 2,\n /** Has a `const` modifier. */\n Const = 1 << 3,\n /** Has a `let` modifier. */\n Let = 1 << 4,\n /** Has a `static` modifier. */\n Static = 1 << 5,\n /** Has a `readonly` modifier. */\n Readonly = 1 << 6,\n /** Has an `abstract` modifier. */\n Abstract = 1 << 7,\n /** Has a `public` modifier. */\n Public = 1 << 8,\n /** Has a `private` modifier. */\n Private = 1 << 9,\n /** Has a `protected` modifier. */\n Protected = 1 << 10,\n /** Has a `get` modifier. */\n Get = 1 << 11,\n /** Has a `set` modifier. */\n Set = 1 << 12,\n /** Has a `override` modifier. */\n Override = 1 << 13,\n\n /** Has a definite assignment assertion `!` as in `x!: i32;`. */\n DefinitelyAssigned = 1 << 14,\n\n // Extended modifiers usually derived from basic modifiers\n\n /** Is ambient, that is either declared or nested in a declared element. */\n Ambient = 1 << 15,\n /** Is generic. */\n Generic = 1 << 16,\n /** Is part of a generic context. */\n GenericContext = 1 << 17,\n /** Is an instance member. */\n Instance = 1 << 18,\n /** Is a constructor. */\n Constructor = 1 << 19,\n /** Is a module export. */\n ModuleExport = 1 << 20,\n /** Is a module import. */\n ModuleImport = 1 << 21,\n\n // Compilation states\n\n /** Is resolved. */\n Resolved = 1 << 22,\n /** Is compiled. */\n Compiled = 1 << 23,\n /** Did error. */\n Errored = 1 << 24,\n /** Has a constant value and is therefore inlined. */\n Inlined = 1 << 25,\n /** Is scoped. */\n Scoped = 1 << 26,\n /** Is a stub. */\n Stub = 1 << 27,\n /** Is an overridden method. */\n Overridden = 1 << 28,\n /** Is (part of) a closure. */\n Closure = 1 << 29,\n\n // Other\n\n /** Is quoted. */\n Quoted = 1 << 30\n}\n\n/** Path delimiter inserted between file system levels. */\nexport const PATH_DELIMITER = \"/\";\n/** Substitution used to indicate the parent directory. */\nexport const PARENT_SUBST = \"..\";\n/** Function name prefix used for getters. */\nexport const GETTER_PREFIX = \"get:\";\n/** Function name prefix used for setters. */\nexport const SETTER_PREFIX = \"set:\";\n/** Delimiter used between class names and instance members. */\nexport const INSTANCE_DELIMITER = \"#\";\n/** Delimiter used between class and namespace names and static members. */\nexport const STATIC_DELIMITER = \".\";\n/** Delimiter used between a function and its inner elements. */\nexport const INNER_DELIMITER = \"~\";\n/** Substitution used to indicate a library directory. */\nexport const LIBRARY_SUBST = \"~lib\";\n/** Library directory prefix. */\nexport const LIBRARY_PREFIX = LIBRARY_SUBST + PATH_DELIMITER;\n/** Path index suffix. */\nexport const INDEX_SUFFIX = PATH_DELIMITER + \"index\";\n/** Stub function delimiter. */\nexport const STUB_DELIMITER = \"@\";\n\n/** Common names. */\nexport namespace CommonNames {\n // special\n export const Empty = \"\";\n // types\n export const i8 = \"i8\";\n export const i16 = \"i16\";\n export const i32 = \"i32\";\n export const i64 = \"i64\";\n export const isize = \"isize\";\n export const u8 = \"u8\";\n export const u16 = \"u16\";\n export const u32 = \"u32\";\n export const u64 = \"u64\";\n export const usize = \"usize\";\n export const bool = \"bool\";\n export const f32 = \"f32\";\n export const f64 = \"f64\";\n export const v128 = \"v128\";\n export const funcref = \"funcref\";\n export const externref = \"externref\";\n export const anyref = \"anyref\";\n export const eqref = \"eqref\";\n export const structref = \"structref\";\n export const arrayref = \"arrayref\";\n export const i31ref = \"i31ref\";\n export const stringref = \"stringref\";\n export const stringview_wtf8 = \"stringview_wtf8\";\n export const stringview_wtf16 = \"stringview_wtf16\";\n export const stringview_iter = \"stringview_iter\";\n export const i8x16 = \"i8x16\";\n export const u8x16 = \"u8x16\";\n export const i16x8 = \"i16x8\";\n export const u16x8 = \"u16x8\";\n export const i32x4 = \"i32x4\";\n export const u32x4 = \"u32x4\";\n export const i64x2 = \"i64x2\";\n export const u64x2 = \"u64x2\";\n export const f32x4 = \"f32x4\";\n export const f64x2 = \"f64x2\";\n export const void_ = \"void\";\n export const number = \"number\";\n export const boolean = \"boolean\";\n export const string = \"string\";\n export const native = \"native\";\n export const indexof = \"indexof\";\n export const valueof = \"valueof\";\n export const returnof = \"returnof\";\n export const nonnull = \"nonnull\";\n // aliases\n export const null_ = \"null\";\n export const true_ = \"true\";\n export const false_ = \"false\";\n // objects\n export const this_ = \"this\";\n export const super_ = \"super\";\n export const constructor = \"constructor\";\n // constants\n export const ASC_TARGET = \"ASC_TARGET\";\n export const ASC_RUNTIME = \"ASC_RUNTIME\";\n export const ASC_NO_ASSERT = \"ASC_NO_ASSERT\";\n export const ASC_MEMORY_BASE = \"ASC_MEMORY_BASE\";\n export const ASC_TABLE_BASE = \"ASC_TABLE_BASE\";\n export const ASC_OPTIMIZE_LEVEL = \"ASC_OPTIMIZE_LEVEL\";\n export const ASC_SHRINK_LEVEL = \"ASC_SHRINK_LEVEL\";\n export const ASC_LOW_MEMORY_LIMIT = \"ASC_LOW_MEMORY_LIMIT\";\n export const ASC_EXPORT_RUNTIME = \"ASC_EXPORT_RUNTIME\";\n export const ASC_FEATURE_SIGN_EXTENSION = \"ASC_FEATURE_SIGN_EXTENSION\";\n export const ASC_FEATURE_MUTABLE_GLOBALS = \"ASC_FEATURE_MUTABLE_GLOBALS\";\n export const ASC_FEATURE_NONTRAPPING_F2I = \"ASC_FEATURE_NONTRAPPING_F2I\";\n export const ASC_FEATURE_BULK_MEMORY = \"ASC_FEATURE_BULK_MEMORY\";\n export const ASC_FEATURE_SIMD = \"ASC_FEATURE_SIMD\";\n export const ASC_FEATURE_THREADS = \"ASC_FEATURE_THREADS\";\n export const ASC_FEATURE_EXCEPTION_HANDLING = \"ASC_FEATURE_EXCEPTION_HANDLING\";\n export const ASC_FEATURE_TAIL_CALLS = \"ASC_FEATURE_TAIL_CALLS\";\n export const ASC_FEATURE_REFERENCE_TYPES = \"ASC_FEATURE_REFERENCE_TYPES\";\n export const ASC_FEATURE_MULTI_VALUE = \"ASC_FEATURE_MULTI_VALUE\";\n export const ASC_FEATURE_GC = \"ASC_FEATURE_GC\";\n export const ASC_FEATURE_MEMORY64 = \"ASC_FEATURE_MEMORY64\";\n export const ASC_FEATURE_RELAXED_SIMD = \"ASC_FEATURE_RELAXED_SIMD\";\n export const ASC_FEATURE_EXTENDED_CONST = \"ASC_FEATURE_EXTENDED_CONST\";\n export const ASC_FEATURE_STRINGREF = \"ASC_FEATURE_STRINGREF\";\n export const ASC_VERSION_MAJOR = \"ASC_VERSION_MAJOR\";\n export const ASC_VERSION_MINOR = \"ASC_VERSION_MINOR\";\n export const ASC_VERSION_PATCH = \"ASC_VERSION_PATCH\";\n // classes\n export const I8 = \"I8\";\n export const I16 = \"I16\";\n export const I32 = \"I32\";\n export const I64 = \"I64\";\n export const Isize = \"Isize\";\n export const U8 = \"U8\";\n export const U16 = \"U16\";\n export const U32 = \"U32\";\n export const U64 = \"U64\";\n export const Usize = \"Usize\";\n export const Bool = \"Bool\";\n export const F32 = \"F32\";\n export const F64 = \"F64\";\n export const V128 = \"V128\";\n export const Funcref = \"Funcref\";\n export const Externref = \"Externref\";\n export const Anyref = \"Anyref\";\n export const Eqref = \"Eqref\";\n export const Structref = \"Structref\";\n export const Arrayref = \"Arrayref\";\n export const I31ref = \"I31ref\";\n export const String = \"String\";\n export const RegExp = \"RegExp\";\n export const Object = \"Object\";\n export const Array = \"Array\";\n export const StaticArray = \"StaticArray\";\n export const Set = \"Set\";\n export const Map = \"Map\";\n export const Function = \"Function\";\n export const ArrayBufferView = \"ArrayBufferView\";\n export const ArrayBuffer = \"ArrayBuffer\";\n export const Math = \"Math\";\n export const Mathf = \"Mathf\";\n export const NativeMath = \"NativeMath\";\n export const NativeMathf = \"NativeMathf\";\n export const Int8Array = \"Int8Array\";\n export const Int16Array = \"Int16Array\";\n export const Int32Array = \"Int32Array\";\n export const Int64Array = \"Int64Array\";\n export const Uint8Array = \"Uint8Array\";\n export const Uint8ClampedArray = \"Uint8ClampedArray\";\n export const Uint16Array = \"Uint16Array\";\n export const Uint32Array = \"Uint32Array\";\n export const Uint64Array = \"Uint64Array\";\n export const Float32Array = \"Float32Array\";\n export const Float64Array = \"Float64Array\";\n export const TemplateStringsArray = \"TemplateStringsArray\";\n export const Error = \"Error\";\n // runtime\n export const abort = \"abort\";\n export const trace = \"trace\";\n export const seed = \"seed\";\n export const pow = \"pow\";\n export const ipow32 = \"ipow32\";\n export const ipow64 = \"ipow64\";\n export const mod = \"mod\";\n export const alloc = \"__alloc\";\n export const realloc = \"__realloc\";\n export const free = \"__free\";\n export const new_ = \"__new\";\n export const renew = \"__renew\";\n export const link = \"__link\";\n export const collect = \"__collect\";\n export const visit = \"__visit\";\n export const newBuffer = \"__newBuffer\";\n export const newArray = \"__newArray\";\n export const BLOCK = \"~lib/rt/common/BLOCK\";\n export const OBJECT = \"~lib/rt/common/OBJECT\";\n // memory & table\n export const DefaultMemory = \"0\";\n export const DefaultTable = \"0\";\n}\n\n// shared\nexport { Feature, featureToString } from \"../std/assembly/shared/feature\";\nexport { Target } from \"../std/assembly/shared/target\";\nexport { Runtime } from \"../std/assembly/shared/runtime\";\nexport { Typeinfo, TypeinfoFlags } from \"../std/assembly/shared/typeinfo\";\n","/// \n\nimport { idof } from \"../builtins\";\nimport { CharCode } from \"./string\";\n\n// @ts-ignore: decorator\n@inline\nexport const MAX_DOUBLE_LENGTH = 28;\n\n// @ts-ignore: decorator\n@lazy @inline const POWERS10 = memory.data([\n 1,\n 10,\n 100,\n 1000,\n 10000,\n 100000,\n 1000000,\n 10000000,\n 100000000,\n 1000000000\n]);\n\n/*\n Lookup table for pairwise char codes in range [0-99]\n\n \"00\", \"01\", \"02\", \"03\", \"04\", \"05\", \"06\", \"07\", \"08\", \"09\",\n \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\",\n \"20\", \"21\", \"22\", \"23\", \"24\", \"25\", \"26\", \"27\", \"28\", \"29\",\n \"30\", \"31\", \"32\", \"33\", \"34\", \"35\", \"36\", \"37\", \"38\", \"39\",\n \"40\", \"41\", \"42\", \"43\", \"44\", \"45\", \"46\", \"47\", \"48\", \"49\",\n \"50\", \"51\", \"52\", \"53\", \"54\", \"55\", \"56\", \"57\", \"58\", \"59\",\n \"60\", \"61\", \"62\", \"63\", \"64\", \"65\", \"66\", \"67\", \"68\", \"69\",\n \"70\", \"71\", \"72\", \"73\", \"74\", \"75\", \"76\", \"77\", \"78\", \"79\",\n \"80\", \"81\", \"82\", \"83\", \"84\", \"85\", \"86\", \"87\", \"88\", \"89\",\n \"90\", \"91\", \"92\", \"93\", \"94\", \"95\", \"96\", \"97\", \"98\", \"99\"\n*/\n// @ts-ignore: decorator\n@lazy @inline const DIGITS = memory.data([\n 0x00300030, 0x00310030, 0x00320030, 0x00330030, 0x00340030,\n 0x00350030, 0x00360030, 0x00370030, 0x00380030, 0x00390030,\n 0x00300031, 0x00310031, 0x00320031, 0x00330031, 0x00340031,\n 0x00350031, 0x00360031, 0x00370031, 0x00380031, 0x00390031,\n 0x00300032, 0x00310032, 0x00320032, 0x00330032, 0x00340032,\n 0x00350032, 0x00360032, 0x00370032, 0x00380032, 0x00390032,\n 0x00300033, 0x00310033, 0x00320033, 0x00330033, 0x00340033,\n 0x00350033, 0x00360033, 0x00370033, 0x00380033, 0x00390033,\n 0x00300034, 0x00310034, 0x00320034, 0x00330034, 0x00340034,\n 0x00350034, 0x00360034, 0x00370034, 0x00380034, 0x00390034,\n 0x00300035, 0x00310035, 0x00320035, 0x00330035, 0x00340035,\n 0x00350035, 0x00360035, 0x00370035, 0x00380035, 0x00390035,\n 0x00300036, 0x00310036, 0x00320036, 0x00330036, 0x00340036,\n 0x00350036, 0x00360036, 0x00370036, 0x00380036, 0x00390036,\n 0x00300037, 0x00310037, 0x00320037, 0x00330037, 0x00340037,\n 0x00350037, 0x00360037, 0x00370037, 0x00380037, 0x00390037,\n 0x00300038, 0x00310038, 0x00320038, 0x00330038, 0x00340038,\n 0x00350038, 0x00360038, 0x00370038, 0x00380038, 0x00390038,\n 0x00300039, 0x00310039, 0x00320039, 0x00330039, 0x00340039,\n 0x00350039, 0x00360039, 0x00370039, 0x00380039, 0x00390039\n]);\n\n// Lookup table for pairwise char codes in range [0x00-0xFF]\n// @ts-ignore: decorator\n@lazy @inline const HEX_DIGITS =\n\"000102030405060708090a0b0c0d0e0f\\\n101112131415161718191a1b1c1d1e1f\\\n202122232425262728292a2b2c2d2e2f\\\n303132333435363738393a3b3c3d3e3f\\\n404142434445464748494a4b4c4d4e4f\\\n505152535455565758595a5b5c5d5e5f\\\n606162636465666768696a6b6c6d6e6f\\\n707172737475767778797a7b7c7d7e7f\\\n808182838485868788898a8b8c8d8e8f\\\n909192939495969798999a9b9c9d9e9f\\\na0a1a2a3a4a5a6a7a8a9aaabacadaeaf\\\nb0b1b2b3b4b5b6b7b8b9babbbcbdbebf\\\nc0c1c2c3c4c5c6c7c8c9cacbcccdcecf\\\nd0d1d2d3d4d5d6d7d8d9dadbdcdddedf\\\ne0e1e2e3e4e5e6e7e8e9eaebecedeeef\\\nf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\";\n\n// @ts-ignore: decorator\n@lazy @inline const ANY_DIGITS = \"0123456789abcdefghijklmnopqrstuvwxyz\";\n\n// @ts-ignore: decorator\n@lazy @inline const EXP_POWERS = memory.data([/* eslint-disable indent */\n -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,\n -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,\n -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,\n -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,\n -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,\n 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,\n 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,\n 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,\n 907, 933, 960, 986, 1013, 1039, 1066\n/* eslint-enable indent */]);\n\n// 1e-348, 1e-340, ..., 1e340\n// @ts-ignore: decorator\n@lazy @inline const FRC_POWERS = memory.data([\n 0xFA8FD5A0081C0288, 0xBAAEE17FA23EBF76, 0x8B16FB203055AC76, 0xCF42894A5DCE35EA,\n 0x9A6BB0AA55653B2D, 0xE61ACF033D1A45DF, 0xAB70FE17C79AC6CA, 0xFF77B1FCBEBCDC4F,\n 0xBE5691EF416BD60C, 0x8DD01FAD907FFC3C, 0xD3515C2831559A83, 0x9D71AC8FADA6C9B5,\n 0xEA9C227723EE8BCB, 0xAECC49914078536D, 0x823C12795DB6CE57, 0xC21094364DFB5637,\n 0x9096EA6F3848984F, 0xD77485CB25823AC7, 0xA086CFCD97BF97F4, 0xEF340A98172AACE5,\n 0xB23867FB2A35B28E, 0x84C8D4DFD2C63F3B, 0xC5DD44271AD3CDBA, 0x936B9FCEBB25C996,\n 0xDBAC6C247D62A584, 0xA3AB66580D5FDAF6, 0xF3E2F893DEC3F126, 0xB5B5ADA8AAFF80B8,\n 0x87625F056C7C4A8B, 0xC9BCFF6034C13053, 0x964E858C91BA2655, 0xDFF9772470297EBD,\n 0xA6DFBD9FB8E5B88F, 0xF8A95FCF88747D94, 0xB94470938FA89BCF, 0x8A08F0F8BF0F156B,\n 0xCDB02555653131B6, 0x993FE2C6D07B7FAC, 0xE45C10C42A2B3B06, 0xAA242499697392D3,\n 0xFD87B5F28300CA0E, 0xBCE5086492111AEB, 0x8CBCCC096F5088CC, 0xD1B71758E219652C,\n 0x9C40000000000000, 0xE8D4A51000000000, 0xAD78EBC5AC620000, 0x813F3978F8940984,\n 0xC097CE7BC90715B3, 0x8F7E32CE7BEA5C70, 0xD5D238A4ABE98068, 0x9F4F2726179A2245,\n 0xED63A231D4C4FB27, 0xB0DE65388CC8ADA8, 0x83C7088E1AAB65DB, 0xC45D1DF942711D9A,\n 0x924D692CA61BE758, 0xDA01EE641A708DEA, 0xA26DA3999AEF774A, 0xF209787BB47D6B85,\n 0xB454E4A179DD1877, 0x865B86925B9BC5C2, 0xC83553C5C8965D3D, 0x952AB45CFA97A0B3,\n 0xDE469FBD99A05FE3, 0xA59BC234DB398C25, 0xF6C69A72A3989F5C, 0xB7DCBF5354E9BECE,\n 0x88FCF317F22241E2, 0xCC20CE9BD35C78A5, 0x98165AF37B2153DF, 0xE2A0B5DC971F303A,\n 0xA8D9D1535CE3B396, 0xFB9B7CD9A4A7443C, 0xBB764C4CA7A44410, 0x8BAB8EEFB6409C1A,\n 0xD01FEF10A657842C, 0x9B10A4E5E9913129, 0xE7109BFBA19C0C9D, 0xAC2820D9623BF429,\n 0x80444B5E7AA7CF85, 0xBF21E44003ACDD2D, 0x8E679C2F5E44FF8F, 0xD433179D9C8CB841,\n 0x9E19DB92B4E31BA9, 0xEB96BF6EBADF77D9, 0xAF87023B9BF0EE6B\n]);\n\n// @ts-ignore: decorator\n@inline\nexport function isPowerOf2(value: T): bool {\n return popcnt(value) == 1;\n}\n\n// Count number of decimals for u32 values\n// In our case input value always non-zero so we can simplify some parts\nexport function decimalCount32(value: u32): u32 {\n if (value < 100000) {\n if (value < 100) {\n return 1 + u32(value >= 10);\n } else {\n return 3 + u32(value >= 10000) + u32(value >= 1000);\n }\n } else {\n if (value < 10000000) {\n return 6 + u32(value >= 1000000);\n } else {\n return 8 + u32(value >= 1000000000) + u32(value >= 100000000);\n }\n }\n}\n\n// Count number of decimals for u64 values\n// In our case input value always greater than 2^32-1 so we can skip some parts\nexport function decimalCount64High(value: u64): u32 {\n if (value < 1000000000000000) {\n if (value < 1000000000000) {\n return 10 + u32(value >= 100000000000) + u32(value >= 10000000000);\n } else {\n return 13 + u32(value >= 100000000000000) + u32(value >= 10000000000000);\n }\n } else {\n if (value < 100000000000000000) {\n return 16 + u32(value >= 10000000000000000);\n } else {\n return 18 + u32(value >= 10000000000000000000) + u32(value >= 1000000000000000000);\n }\n }\n}\n\nfunction ulog_base(num: u64, base: i32): u32 {\n if (isPowerOf2(base)) {\n return (63 - clz(num)) / (31 - clz(base)) + 1;\n }\n let b64 = u64(base), b = b64, e: u32 = 1;\n while (num >= b) {\n num /= b;\n b *= b;\n e <<= 1;\n }\n while (num >= 1) {\n num /= b64;\n e++;\n }\n return e - 1;\n}\n\nfunction utoa32_dec_lut(buffer: usize, num: u32, offset: usize): void {\n while (num >= 10000) {\n // in most VMs i32/u32 div and modulo by constant can be shared and simplificate\n let t = num / 10000;\n let r = num % 10000;\n num = t;\n\n let d1 = r / 100;\n let d2 = r % 100;\n\n let digits1 = load(DIGITS + (d1 << alignof()));\n let digits2 = load(DIGITS + (d2 << alignof()));\n\n offset -= 4;\n store(buffer + (offset << 1), digits1 | (digits2 << 32));\n }\n\n if (num >= 100) {\n let t = num / 100;\n let d1 = num % 100;\n num = t;\n offset -= 2;\n let digits = load(DIGITS + (d1 << alignof()));\n store(buffer + (offset << 1), digits);\n }\n\n if (num >= 10) {\n offset -= 2;\n let digits = load(DIGITS + (num << alignof()));\n store(buffer + (offset << 1), digits);\n } else {\n offset -= 1;\n let digit = CharCode._0 + num;\n store(buffer + (offset << 1), digit);\n }\n}\n\nfunction utoa64_dec_lut(buffer: usize, num: u64, offset: usize): void {\n while (num >= 100000000) {\n let t = num / 100000000;\n let r = (num - t * 100000000);\n num = t;\n\n let b = r / 10000;\n let c = r % 10000;\n\n let b1 = b / 100;\n let b2 = b % 100;\n let c1 = c / 100;\n let c2 = c % 100;\n\n let digits1 = load(DIGITS + (c1 << alignof()));\n let digits2 = load(DIGITS + (c2 << alignof()));\n\n offset -= 4;\n store(buffer + (offset << 1), digits1 | (digits2 << 32));\n\n digits1 = load(DIGITS + (b1 << alignof()));\n digits2 = load(DIGITS + (b2 << alignof()));\n\n offset -= 4;\n store(buffer + (offset << 1), digits1 | (digits2 << 32));\n }\n\n utoa32_dec_lut(buffer, num, offset);\n}\n\nfunction utoa_hex_lut(buffer: usize, num: u64, offset: usize): void {\n const lut = changetype(HEX_DIGITS);\n while (offset >= 2) {\n offset -= 2;\n store(\n buffer + (offset << 1),\n load(lut + ((num & 0xFF) << alignof()))\n );\n num >>= 8;\n }\n if (offset & 1) {\n store(buffer, load(lut + (num << 6)));\n }\n}\n\nfunction utoa_dec_simple(buffer: usize, num: T, offset: usize): void {\n do {\n let t = num / 10;\n let r = (num % 10);\n num = changetype(t);\n offset--;\n store(buffer + (offset << 1), CharCode._0 + r);\n } while (num);\n}\n\nfunction utoa_hex_simple(buffer: usize, num: T, offset: usize): void {\n do {\n let d = num & 0x0F | CharCode._0;\n d += select(0x27, 0, d > CharCode._9);\n offset--;\n store(buffer + (offset << 1), d);\n // @ts-ignore: type\n num >>= 4;\n } while (num);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function utoa32_dec_core(buffer: usize, num: u32, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_dec_simple(buffer, num, offset);\n } else {\n utoa32_dec_lut(buffer, num, offset);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction utoa32_hex_core(buffer: usize, num: u32, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_hex_simple(buffer, num, offset);\n } else {\n utoa_hex_lut(buffer, num, offset);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction utoa64_dec_core(buffer: usize, num: u64, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_dec_simple(buffer, num, offset);\n } else {\n utoa64_dec_lut(buffer, num, offset);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction utoa64_hex_core(buffer: usize, num: u64, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_hex_simple(buffer, num, offset);\n } else {\n utoa_hex_lut(buffer, num, offset);\n }\n}\n\nfunction utoa64_any_core(buffer: usize, num: u64, offset: usize, radix: i32): void {\n const lut = changetype(ANY_DIGITS);\n let base = u64(radix);\n if ((radix & (radix - 1)) == 0) { // for radix which pow of two\n let shift = u64(ctz(radix) & 7);\n let mask = base - 1;\n do {\n offset--;\n store(buffer + (offset << 1), load(lut + (usize(num & mask) << 1)));\n num >>= shift;\n } while (num);\n } else {\n do {\n offset--;\n let q = num / base;\n store(buffer + (offset << 1), load(lut + (usize(num - q * base) << 1)));\n num = q;\n } while (num);\n }\n}\n\nexport function utoa32(value: u32, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n let out: String;\n\n if (radix == 10) {\n let decimals = decimalCount32(value);\n out = changetype(__new(decimals << 1, idof()));\n utoa32_dec_core(changetype(out), value, decimals);\n } else if (radix == 16) {\n let decimals = (31 - clz(value) >> 2) + 1;\n out = changetype(__new(decimals << 1, idof()));\n utoa32_hex_core(changetype(out), value, decimals);\n } else {\n let decimals = ulog_base(value, radix);\n out = changetype(__new(decimals << 1, idof()));\n utoa64_any_core(changetype(out), value, decimals, radix);\n }\n return out;\n}\n\nexport function itoa32(value: i32, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n\n let sign = (value >>> 31) << 1;\n if (sign) value = -value;\n let out: String;\n\n if (radix == 10) {\n let decimals = decimalCount32(value);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa32_dec_core(changetype(out) + sign, value, decimals);\n } else if (radix == 16) {\n let decimals = (31 - clz(value) >> 2) + 1;\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa32_hex_core(changetype(out) + sign, value, decimals);\n } else {\n let val32 = u32(value);\n let decimals = ulog_base(val32, radix);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_any_core(changetype(out) + sign, val32, decimals, radix);\n }\n if (sign) store(changetype(out), CharCode.MINUS);\n return out;\n}\n\nexport function utoa64(value: u64, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n let out: String;\n\n if (radix == 10) {\n if (value <= u32.MAX_VALUE) {\n let val32 = value;\n let decimals = decimalCount32(val32);\n out = changetype(__new(decimals << 1, idof()));\n utoa32_dec_core(changetype(out), val32, decimals);\n } else {\n let decimals = decimalCount64High(value);\n out = changetype(__new(decimals << 1, idof()));\n utoa64_dec_core(changetype(out), value, decimals);\n }\n } else if (radix == 16) {\n let decimals = (63 - u32(clz(value)) >> 2) + 1;\n out = changetype(__new(decimals << 1, idof()));\n utoa64_hex_core(changetype(out), value, decimals);\n } else {\n let decimals = ulog_base(value, radix);\n out = changetype(__new(decimals << 1, idof()));\n utoa64_any_core(changetype(out), value, decimals, radix);\n }\n return out;\n}\n\nexport function itoa64(value: i64, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n\n let sign = u32(value >>> 63) << 1;\n if (sign) value = -value;\n let out: String;\n\n if (radix == 10) {\n if (value <= u32.MAX_VALUE) {\n let val32 = value;\n let decimals = decimalCount32(val32);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa32_dec_core(changetype(out) + sign, val32, decimals);\n } else {\n let decimals = decimalCount64High(value);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_dec_core(changetype(out) + sign, value, decimals);\n }\n } else if (radix == 16) {\n let decimals = (63 - u32(clz(value)) >> 2) + 1;\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_hex_core(changetype(out) + sign, value, decimals);\n } else {\n let decimals = ulog_base(value, radix);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_any_core(changetype(out) + sign, value, decimals, radix);\n }\n if (sign) store(changetype(out), CharCode.MINUS);\n return out;\n}\n\n// @ts-ignore: decorator\n@lazy let _K: i32 = 0;\n\n// // @ts-ignore: decorator\n// @lazy\n// let _frc: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _exp: i32 = 0;\n\n// @ts-ignore: decorator\n@lazy let _frc_minus: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _frc_plus: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _frc_pow: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _exp_pow: i32 = 0;\n\n// @ts-ignore: decorator\n@inline\nfunction umul64f(u: u64, v: u64): u64 {\n let u0 = u & 0xFFFFFFFF;\n let v0 = v & 0xFFFFFFFF;\n\n let u1 = u >> 32;\n let v1 = v >> 32;\n\n let l = u0 * v0;\n let t = u1 * v0 + (l >> 32);\n let w = u0 * v1 + (t & 0xFFFFFFFF);\n\n w += 0x7FFFFFFF; // rounding\n\n t >>= 32;\n w >>= 32;\n\n return u1 * v1 + t + w;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction umul64e(e1: i32, e2: i32): i32 {\n return e1 + e2 + 64; // where 64 is significand size\n}\n\n// @ts-ignore: decorator\n@inline\nfunction normalizedBoundaries(f: u64, e: i32): void {\n let frc = (f << 1) + 1;\n let exp = e - 1;\n let off = clz(frc);\n frc <<= off;\n exp -= off;\n\n let m = 1 + i32(f == 0x0010000000000000);\n\n _frc_plus = frc;\n _frc_minus = ((f << m) - 1) << e - m - exp;\n _exp = exp;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction grisuRound(buffer: usize, len: i32, delta: u64, rest: u64, ten_kappa: u64, wp_w: u64): void {\n let lastp = buffer + ((len - 1) << 1);\n let digit = load(lastp);\n while (\n rest < wp_w &&\n delta - rest >= ten_kappa && (\n rest + ten_kappa < wp_w ||\n wp_w - rest > rest + ten_kappa - wp_w\n )\n ) {\n --digit;\n rest += ten_kappa;\n }\n store(lastp, digit);\n}\n\n// @ts-ignore: decorator\n@inline\nfunction getCachedPower(minExp: i32): void {\n const c = reinterpret(0x3FD34413509F79FE); // 1 / lg(10) = 0.30102999566398114\n let dk = (-61 - minExp) * c + 347;\t // dk must be positive, so can do ceiling in positive\n let k = dk;\n k += i32(k != dk); // conversion with ceil\n\n let index = (k >> 3) + 1;\n _K = 348 - (index << 3);\t// decimal exponent no need lookup table\n _frc_pow = load(FRC_POWERS + (index << alignof()));\n _exp_pow = load(EXP_POWERS + (index << alignof()));\n}\n\n// @ts-ignore: decorator\n@inline\nfunction grisu2(value: f64, buffer: usize, sign: i32): i32 {\n\n // frexp routine\n let uv = reinterpret(value);\n let exp = i32((uv & 0x7FF0000000000000) >>> 52);\n let sid = uv & 0x000FFFFFFFFFFFFF;\n let frc = (u64(exp != 0) << 52) + sid;\n exp = select(exp, 1, exp) - (0x3FF + 52);\n\n normalizedBoundaries(frc, exp);\n getCachedPower(_exp);\n\n // normalize\n let off = clz(frc);\n frc <<= off;\n exp -= off;\n\n let frc_pow = _frc_pow;\n let exp_pow = _exp_pow;\n\n let w_frc = umul64f(frc, frc_pow);\n let w_exp = umul64e(exp, exp_pow);\n\n let wp_frc = umul64f(_frc_plus, frc_pow) - 1;\n let wp_exp = umul64e(_exp, exp_pow);\n\n let wm_frc = umul64f(_frc_minus, frc_pow) + 1;\n let delta = wp_frc - wm_frc;\n\n return genDigits(buffer, w_frc, w_exp, wp_frc, wp_exp, delta, sign);\n}\n\nfunction genDigits(buffer: usize, w_frc: u64, w_exp: i32, mp_frc: u64, mp_exp: i32, delta: u64, sign: i32): i32 {\n let one_exp = -mp_exp;\n let one_frc = (1) << one_exp;\n let mask = one_frc - 1;\n\n let wp_w_frc = mp_frc - w_frc;\n\n let p1 = u32(mp_frc >> one_exp);\n let p2 = mp_frc & mask;\n\n let kappa = decimalCount32(p1);\n let len = sign;\n\n while (kappa > 0) {\n let d: u32;\n switch (kappa) {\n case 10: { d = p1 / 1000000000; p1 %= 1000000000; break; }\n case 9: { d = p1 / 100000000; p1 %= 100000000; break; }\n case 8: { d = p1 / 10000000; p1 %= 10000000; break; }\n case 7: { d = p1 / 1000000; p1 %= 1000000; break; }\n case 6: { d = p1 / 100000; p1 %= 100000; break; }\n case 5: { d = p1 / 10000; p1 %= 10000; break; }\n case 4: { d = p1 / 1000; p1 %= 1000; break; }\n case 3: { d = p1 / 100; p1 %= 100; break; }\n case 2: { d = p1 / 10; p1 %= 10; break; }\n case 1: { d = p1; p1 = 0; break; }\n default: { d = 0; break; }\n }\n\n if (d | len) store(buffer + (len++ << 1), CharCode._0 + d);\n\n --kappa;\n let tmp = ((p1) << one_exp) + p2;\n if (tmp <= delta) {\n _K += kappa;\n grisuRound(buffer, len, delta, tmp, load(POWERS10 + (kappa << alignof())) << one_exp, wp_w_frc);\n return len;\n }\n }\n\n while (true) {\n p2 *= 10;\n delta *= 10;\n\n let d = p2 >> one_exp;\n if (d | len) store(buffer + (len++ << 1), CharCode._0 + d);\n\n p2 &= mask;\n --kappa;\n if (p2 < delta) {\n _K += kappa;\n wp_w_frc *= load(POWERS10 + (-kappa << alignof()));\n grisuRound(buffer, len, delta, p2, one_frc, wp_w_frc);\n return len;\n }\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction genExponent(buffer: usize, k: i32): i32 {\n let sign = k < 0;\n if (sign) k = -k;\n let decimals = decimalCount32(k) + 1;\n utoa32_dec_core(buffer, k, decimals);\n store(buffer, select(CharCode.MINUS, CharCode.PLUS, sign));\n return decimals;\n}\n\nfunction prettify(buffer: usize, length: i32, k: i32): i32 {\n if (!k) {\n store(buffer + (length << 1), CharCode.DOT | (CharCode._0 << 16));\n return length + 2;\n }\n\n let kk = length + k;\n if (length <= kk && kk <= 21) {\n // 1234e7 -> 12340000000\n for (let i = length; i < kk; ++i) {\n store(buffer + (i << 1), CharCode._0);\n }\n store(buffer + (kk << 1), CharCode.DOT | (CharCode._0 << 16));\n return kk + 2;\n } else if (kk > 0 && kk <= 21) {\n // 1234e-2 -> 12.34\n let ptr = buffer + (kk << 1);\n memory.copy(\n ptr + 2,\n ptr,\n -k << 1\n );\n store(buffer + (kk << 1), CharCode.DOT);\n return length + 1;\n } else if (-6 < kk && kk <= 0) {\n // 1234e-6 -> 0.001234\n let offset = 2 - kk;\n memory.copy(\n buffer + (offset << 1),\n buffer,\n length << 1\n );\n store(buffer, CharCode._0 | (CharCode.DOT << 16));\n for (let i = 2; i < offset; ++i) {\n store(buffer + (i << 1), CharCode._0);\n }\n return length + offset;\n } else if (length == 1) {\n // 1e30\n store(buffer, CharCode.e, 2);\n length = genExponent(buffer + 4, kk - 1);\n return length + 2;\n } else {\n let len = length << 1;\n memory.copy(\n buffer + 4,\n buffer + 2,\n len - 2\n );\n store(buffer, CharCode.DOT, 2);\n store(buffer + len, CharCode.e, 2);\n length += genExponent(buffer + len + 4, kk - 1);\n return length + 2;\n }\n}\n\nfunction dtoa_core(buffer: usize, value: f64): i32 {\n let sign = i32(value < 0);\n if (sign) {\n value = -value;\n store(buffer, CharCode.MINUS);\n }\n // assert(value > 0 && value <= 1.7976931348623157e308);\n let len = grisu2(value, buffer, sign);\n len = prettify(buffer + (sign << 1), len - sign, _K);\n return len + sign;\n}\n\n// @ts-ignore: decorator\n@lazy @inline const dtoa_buf = memory.data(MAX_DOUBLE_LENGTH << 1);\n\nexport function dtoa(value: f64): String {\n if (value == 0) return \"0.0\";\n if (!isFinite(value)) {\n if (isNaN(value)) return \"NaN\";\n return select(\"-Infinity\", \"Infinity\", value < 0);\n }\n let size = dtoa_core(dtoa_buf, value) << 1;\n let result = changetype(__new(size, idof()));\n memory.copy(changetype(result), dtoa_buf, size);\n return result;\n}\n\nexport function itoa_buffered(buffer: usize, value: T): u32 {\n let sign: u32 = 0;\n if (isSigned()) {\n sign = u32(value < 0);\n if (sign) {\n if (sizeof() == 1) {\n if (value == -0x80) {\n // -0x80 -> -128\n store(buffer,\n CharCode.MINUS |\n (CharCode._0 + 1) << 16 |\n (CharCode._0 + 2) << 32 |\n (CharCode._0 + 8) << 48\n );\n return 4;\n }\n }\n if (sizeof() == 2) {\n if (value == -0x8000) {\n // -0x8000 -> -32768\n store(buffer,\n CharCode.MINUS |\n (CharCode._0 + 3) << 16 |\n (CharCode._0 + 2) << 32 |\n (CharCode._0 + 7) << 48\n ); // -327\n store(buffer + 8,\n (CharCode._0 + 6) << 0 |\n (CharCode._0 + 8) << 16\n ); // 68\n return 6;\n }\n }\n store(buffer, CharCode.MINUS);\n // @ts-ignore\n value = -value;\n }\n }\n let dest = buffer + (sign << 1);\n if (ASC_SHRINK_LEVEL <= 1) {\n if (isSigned()) {\n if (sizeof() <= 4) {\n if (value < 10) {\n store(dest, value | CharCode._0);\n return 1 + sign;\n }\n } else {\n if (value < 10) {\n store(dest, value | CharCode._0);\n return 1 + sign;\n }\n }\n } else {\n if (value < 10) {\n store(buffer, value | CharCode._0);\n return 1;\n }\n }\n }\n let decimals: u32 = 0;\n if (sizeof() <= 4) {\n let val32 = value;\n decimals = decimalCount32(val32);\n utoa32_dec_core(dest, val32, decimals);\n } else {\n if (value <= u32.MAX_VALUE) {\n let val32 = value;\n decimals = decimalCount32(val32);\n utoa32_dec_core(dest, val32, decimals);\n } else {\n let val64 = value;\n decimals = decimalCount64High(val64);\n utoa64_dec_core(dest, val64, decimals);\n }\n }\n return sign + decimals;\n}\n\nexport function dtoa_buffered(buffer: usize, value: f64): u32 {\n if (value == 0) {\n store(buffer, CharCode._0);\n store(buffer, CharCode.DOT, 2);\n store(buffer, CharCode._0, 4);\n return 3;\n }\n if (!isFinite(value)) {\n if (isNaN(value)) {\n store(buffer, CharCode.N);\n store(buffer, CharCode.a, 2);\n store(buffer, CharCode.N, 4);\n return 3;\n } else {\n let sign = value < 0;\n if (sign) {\n store(buffer, CharCode.MINUS); // -\n buffer += 2;\n }\n store(buffer, 0x690066006E0049, 0); // ifnI\n store(buffer, 0x7900740069006E, 8); // ytin\n return 8 + u32(sign);\n }\n }\n return dtoa_core(buffer, value);\n}\n","//\n// Lookup data for exp2f\n//\n\n// @ts-ignore: decorator\n@inline const EXP2F_TABLE_BITS = 5;\n\n// @ts-ignore: decorator\n@lazy @inline const EXP2F_DATA_TAB = memory.data([\n // exp2f_data_tab[i] = uint(2^(i/N)) - (i << 52-BITS)\n // used for computing 2^(k/N) for an int |k| < 150 N as\n // double(tab[k%N] + (k << 52-BITS))\n 0x3FF0000000000000, 0x3FEFD9B0D3158574, 0x3FEFB5586CF9890F, 0x3FEF9301D0125B51,\n 0x3FEF72B83C7D517B, 0x3FEF54873168B9AA, 0x3FEF387A6E756238, 0x3FEF1E9DF51FDEE1,\n 0x3FEF06FE0A31B715, 0x3FEEF1A7373AA9CB, 0x3FEEDEA64C123422, 0x3FEECE086061892D,\n 0x3FEEBFDAD5362A27, 0x3FEEB42B569D4F82, 0x3FEEAB07DD485429, 0x3FEEA47EB03A5585,\n 0x3FEEA09E667F3BCD, 0x3FEE9F75E8EC5F74, 0x3FEEA11473EB0187, 0x3FEEA589994CCE13,\n 0x3FEEACE5422AA0DB, 0x3FEEB737B0CDC5E5, 0x3FEEC49182A3F090, 0x3FEED503B23E255D,\n 0x3FEEE89F995AD3AD, 0x3FEEFF76F2FB5E47, 0x3FEF199BDD85529C, 0x3FEF3720DCEF9069,\n 0x3FEF5818DCFBA487, 0x3FEF7C97337B9B5F, 0x3FEFA4AFA2A490DA, 0x3FEFD0765B6E4540\n]);\n\n// ULP error: 0.502 (nearest rounding.)\n// Relative error: 1.69 * 2^-34 in [-1/64, 1/64] (before rounding.)\n// Wrong count: 168353 (all nearest rounding wrong results with fma.)\n// @ts-ignore: decorator\n@inline\nexport function exp2f_lut(x: f32): f32 {\n const\n N = 1 << EXP2F_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000) / N, // 0x1.8p+52\n Ox127f = reinterpret(0x7F000000);\n\n const\n C0 = reinterpret(0x3FAC6AF84B912394), // 0x1.c6af84b912394p-5\n C1 = reinterpret(0x3FCEBFCE50FAC4F3), // 0x1.ebfce50fac4f3p-3\n C2 = reinterpret(0x3FE62E42FF0C52D6); // 0x1.62e42ff0c52d6p-1\n\n let xd = x;\n let ix = reinterpret(x);\n let ux = ix >> 20 & 0x7FF;\n if (ux >= 0x430) {\n // |x| >= 128 or x is nan.\n if (ix == 0xFF800000) return 0; // x == -Inf -> 0\n if (ux >= 0x7F8) return x + x; // x == Inf/NaN -> Inf/NaN\n if (x > 0) return x * Ox127f; // x > 0 -> HugeVal (Owerflow)\n if (x <= -150) return 0; // x <= -150 -> 0 (Underflow)\n }\n\n // x = k/N + r with r in [-1/(2N), 1/(2N)] and int k.\n let kd = xd + shift;\n let ki = reinterpret(kd);\n let r = xd - (kd - shift);\n let t: u64, y: f64, s: f64;\n\n // exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1)\n t = load(EXP2F_DATA_TAB + ((ki & N_MASK) << alignof()));\n t += ki << (52 - EXP2F_TABLE_BITS);\n s = reinterpret(t);\n y = C2 * r + 1;\n y += (C0 * r + C1) * (r * r);\n y *= s;\n\n return y;\n}\n\n// ULP error: 0.502 (nearest rounding.)\n// Relative error: 1.69 * 2^-34 in [-ln2/64, ln2/64] (before rounding.)\n// Wrong count: 170635 (all nearest rounding wrong results with fma.)\n// @ts-ignore: decorator\n@inline\nexport function expf_lut(x: f32): f32 {\n const\n N = 1 << EXP2F_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000), // 0x1.8p+52\n InvLn2N = reinterpret(0x3FF71547652B82FE) * N, // 0x1.71547652b82fep+0\n Ox1p127f = reinterpret(0x7F000000);\n\n const\n C0 = reinterpret(0x3FAC6AF84B912394) / N / N / N, // 0x1.c6af84b912394p-5\n C1 = reinterpret(0x3FCEBFCE50FAC4F3) / N / N, // 0x1.ebfce50fac4f3p-3\n C2 = reinterpret(0x3FE62E42FF0C52D6) / N; // 0x1.62e42ff0c52d6p-1\n\n let xd = x;\n let ix = reinterpret(x);\n let ux = ix >> 20 & 0x7FF;\n if (ux >= 0x42B) {\n // |x| >= 88 or x is nan.\n if (ix == 0xFF800000) return 0; // x == -Inf -> 0\n if (ux >= 0x7F8) return x + x; // x == Inf/NaN -> Inf/NaN\n if (x > reinterpret(0x42B17217)) return x * Ox1p127f; // x > log(0x1p128) ~= 88.72 -> HugeVal (Owerflow)\n if (x < reinterpret(0xC2CFF1B4)) return 0; // x < log(0x1p-150) ~= -103.97 -> 0 (Underflow)\n }\n\n // x*N/Ln2 = k + r with r in [-1/2, 1/2] and int k.\n let z = InvLn2N * xd;\n\n // Round and convert z to int, the result is in [-150*N, 128*N] and\n // ideally ties-to-even rule is used, otherwise the magnitude of r\n // can be bigger which gives larger approximation error.\n let kd = (z + shift);\n let ki = reinterpret(kd);\n let r = z - (kd - shift);\n let s: f64, y: f64, t: u64;\n\n // exp(x) = 2^(k/N) * 2^(r/N) ~= s * (C0*r^3 + C1*r^2 + C2*r + 1)\n t = load(EXP2F_DATA_TAB + ((ki & N_MASK) << alignof()));\n t += ki << (52 - EXP2F_TABLE_BITS);\n s = reinterpret(t);\n z = C0 * r + C1;\n y = C2 * r + 1;\n y += z * (r * r);\n y *= s;\n\n return y;\n}\n\n//\n// Lookup data for log2f\n//\n\n// @ts-ignore: decorator\n@inline const LOG2F_TABLE_BITS = 4;\n\n// @ts-ignore: decorator\n@lazy @inline const LOG2F_DATA_TAB = memory.data([\n 0x3FF661EC79F8F3BE, 0xBFDEFEC65B963019, // 0x1.661ec79f8f3bep+0, -0x1.efec65b963019p-2,\n 0x3FF571ED4AAF883D, 0xBFDB0B6832D4FCA4, // 0x1.571ed4aaf883dp+0, -0x1.b0b6832d4fca4p-2,\n 0x3FF49539F0F010B0, 0xBFD7418B0A1FB77B, // 0x1.49539f0f010bp+0 , -0x1.7418b0a1fb77bp-2,\n 0x3FF3C995B0B80385, 0xBFD39DE91A6DCF7B, // 0x1.3c995b0b80385p+0, -0x1.39de91a6dcf7bp-2,\n 0x3FF30D190C8864A5, 0xBFD01D9BF3F2B631, // 0x1.30d190c8864a5p+0, -0x1.01d9bf3f2b631p-2,\n 0x3FF25E227B0B8EA0, 0xBFC97C1D1B3B7AF0, // 0x1.25e227b0b8eap+0 , -0x1.97c1d1b3b7afp-3 ,\n 0x3FF1BB4A4A1A343F, 0xBFC2F9E393AF3C9F, // 0x1.1bb4a4a1a343fp+0, -0x1.2f9e393af3c9fp-3,\n 0x3FF12358F08AE5BA, 0xBFB960CBBF788D5C, // 0x1.12358f08ae5bap+0, -0x1.960cbbf788d5cp-4,\n 0x3FF0953F419900A7, 0xBFAA6F9DB6475FCE, // 0x1.0953f419900a7p+0, -0x1.a6f9db6475fcep-5,\n 0x3FF0000000000000, 0, // 0x1p+0, 0x0,\n 0x3FEE608CFD9A47AC, 0x3FB338CA9F24F53D, // 0x1.e608cfd9a47acp-1, 0x1.338ca9f24f53dp-4,\n 0x3FECA4B31F026AA0, 0x3FC476A9543891BA, // 0x1.ca4b31f026aap-1 , 0x1.476a9543891bap-3,\n 0x3FEB2036576AFCE6, 0x3FCE840B4AC4E4D2, // 0x1.b2036576afce6p-1, 0x1.e840b4ac4e4d2p-3,\n 0x3FE9C2D163A1AA2D, 0x3FD40645F0C6651C, // 0x1.9c2d163a1aa2dp-1, 0x1.40645f0c6651cp-2,\n 0x3FE886E6037841ED, 0x3FD88E9C2C1B9FF8, // 0x1.886e6037841edp-1, 0x1.88e9c2c1b9ff8p-2,\n 0x3FE767DCF5534862, 0x3FDCE0A44EB17BCC // 0x1.767dcf5534862p-1, 0x1.ce0a44eb17bccp-2\n]);\n\n// ULP error: 0.752 (nearest rounding.)\n// Relative error: 1.9 * 2^-26 (before rounding.)\n// @ts-ignore: decorator\n@inline\nexport function log2f_lut(x: f32): f32 {\n const\n N_MASK = (1 << LOG2F_TABLE_BITS) - 1,\n Ox1p23f = reinterpret(0x4B000000); // 0x1p23f\n\n const\n A0 = reinterpret(0xBFD712B6F70A7E4D), // -0x1.712b6f70a7e4dp-2\n A1 = reinterpret(0x3FDECABF496832E0), // 0x1.ecabf496832ep-2\n A2 = reinterpret(0xBFE715479FFAE3DE), // -0x1.715479ffae3dep-1\n A3 = reinterpret(0x3FF715475F35C8B8); // 0x1.715475f35c8b8p0\n\n let ux = reinterpret(x);\n // Fix sign of zero with downward rounding when x==1.\n // if (WANT_ROUNDING && predict_false(ix == 0x3f800000)) return 0;\n if (ux - 0x00800000 >= 0x7F800000 - 0x00800000) {\n // x < 0x1p-126 or inf or nan.\n if (ux * 2 == 0) return -Infinity;\n if (ux == 0x7F800000) return x; // log2(inf) == inf.\n if ((ux >> 31) || ux * 2 >= 0xFF000000) return (x - x) / (x - x);\n // x is subnormal, normalize it.\n ux = reinterpret(x * Ox1p23f);\n ux -= 23 << 23;\n }\n // x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ux - 0x3F330000;\n let i = (tmp >> (23 - LOG2F_TABLE_BITS)) & N_MASK;\n let top = tmp & 0xFF800000;\n let iz = ux - top;\n let k = tmp >> 23;\n\n let invc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 0 << alignof());\n let logc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 1 << alignof());\n let z = reinterpret(iz);\n\n // log2(x) = log1p(z/c-1)/ln2 + log2(c) + k\n let r = z * invc - 1;\n let y0 = logc + k;\n\n // Pipelined polynomial evaluation to approximate log1p(r)/ln2.\n let y = A1 * r + A2;\n let p = A3 * r + y0;\n let r2 = r * r;\n y += A0 * r2;\n y = y * r2 + p;\n\n return y;\n}\n\n//\n// Lookup data for logf. See: https://git.musl-libc.org/cgit/musl/tree/src/math/logf.c\n//\n\n// @ts-ignore: decorator\n@inline const LOGF_TABLE_BITS = 4;\n\n// @ts-ignore: decorator\n@lazy @inline const LOGF_DATA_TAB = memory.data([\n 0x3FF661EC79F8F3BE, 0xBFD57BF7808CAADE, // 0x1.661ec79f8f3bep+0, -0x1.57bf7808caadep-2,\n 0x3FF571ED4AAF883D, 0xBFD2BEF0A7C06DDB, // 0x1.571ed4aaf883dp+0, -0x1.2bef0a7c06ddbp-2,\n 0x3FF49539F0F010B0, 0xBFD01EAE7F513A67, // 0x1.49539f0f010bp+0 , -0x1.01eae7f513a67p-2,\n 0x3FF3C995B0B80385, 0xBFCB31D8A68224E9, // 0x1.3c995b0b80385p+0, -0x1.b31d8a68224e9p-3,\n 0x3FF30D190C8864A5, 0xBFC6574F0AC07758, // 0x1.30d190c8864a5p+0, -0x1.6574f0ac07758p-3,\n 0x3FF25E227B0B8EA0, 0xBFC1AA2BC79C8100, // 0x1.25e227b0b8eap+0 , -0x1.1aa2bc79c81p-3 ,\n 0x3FF1BB4A4A1A343F, 0xBFBA4E76CE8C0E5E, // 0x1.1bb4a4a1a343fp+0, -0x1.a4e76ce8c0e5ep-4,\n 0x3FF12358F08AE5BA, 0xBFB1973C5A611CCC, // 0x1.12358f08ae5bap+0, -0x1.1973c5a611cccp-4,\n 0x3FF0953F419900A7, 0xBFA252F438E10C1E, // 0x1.0953f419900a7p+0, -0x1.252f438e10c1ep-5,\n 0x3FF0000000000000, 0, // 0x1p+0, 0,\n 0x3FEE608CFD9A47AC, 0x3FAAA5AA5DF25984, // 0x1.e608cfd9a47acp-1, 0x1.aa5aa5df25984p-5,\n 0x3FECA4B31F026AA0, 0x3FBC5E53AA362EB4, // 0x1.ca4b31f026aap-1 , 0x1.c5e53aa362eb4p-4,\n 0x3FEB2036576AFCE6, 0x3FC526E57720DB08, // 0x1.b2036576afce6p-1, 0x1.526e57720db08p-3,\n 0x3FE9C2D163A1AA2D, 0x3FCBC2860D224770, // 0x1.9c2d163a1aa2dp-1, 0x1.bc2860d22477p-3 ,\n 0x3FE886E6037841ED, 0x3FD1058BC8A07EE1, // 0x1.886e6037841edp-1, 0x1.1058bc8a07ee1p-2,\n 0x3FE767DCF5534862, 0x3FD4043057B6EE09 // 0x1.767dcf5534862p-1, 0x1.4043057b6ee09p-2\n]);\n\n// ULP error: 0.818 (nearest rounding.)\n// Relative error: 1.957 * 2^-26 (before rounding.)\n// @ts-ignore: decorator\n@inline\nexport function logf_lut(x: f32): f32 {\n const\n N_MASK = (1 << LOGF_TABLE_BITS) - 1,\n Ox1p23f = reinterpret(0x4B000000); // 0x1p23f\n\n const\n Ln2 = reinterpret(0x3FE62E42FEFA39EF), // 0x1.62e42fefa39efp-1;\n A0 = reinterpret(0xBFD00EA348B88334), // -0x1.00ea348b88334p-2\n A1 = reinterpret(0x3FD5575B0BE00B6A), // 0x1.5575b0be00b6ap-2\n A2 = reinterpret(0xBFDFFFFEF20A4123); // -0x1.ffffef20a4123p-2\n\n let ux = reinterpret(x);\n // Fix sign of zero with downward rounding when x==1.\n // if (WANT_ROUNDING && ux == 0x3f800000) return 0;\n if (ux - 0x00800000 >= 0x7F800000 - 0x00800000) {\n // x < 0x1p-126 or inf or nan.\n if ((ux << 1) == 0) return -Infinity;\n if (ux == 0x7F800000) return x; // log(inf) == inf.\n if ((ux >> 31) || (ux << 1) >= 0xFF000000) return (x - x) / (x - x);\n // x is subnormal, normalize it.\n ux = reinterpret(x * Ox1p23f);\n ux -= 23 << 23;\n }\n // x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ux - 0x3F330000;\n let i = (tmp >> (23 - LOGF_TABLE_BITS)) & N_MASK;\n let k = tmp >> 23;\n let iz = ux - (tmp & 0x1FF << 23);\n\n let invc = load(LOGF_DATA_TAB + (i << (1 + alignof())), 0 << alignof());\n let logc = load(LOGF_DATA_TAB + (i << (1 + alignof())), 1 << alignof());\n\n let z = reinterpret(iz);\n\n // log(x) = log1p(z/c-1) + log(c) + k*Ln2\n let r = z * invc - 1;\n let y0 = logc + k * Ln2;\n\n // Pipelined polynomial evaluation to approximate log1p(r).\n let r2 = r * r;\n let y = A1 * r + A2;\n y += A0 * r2;\n y = y * r2 + (y0 + r);\n\n return y;\n}\n\n//\n// Lookup data for powf. See: https://git.musl-libc.org/cgit/musl/tree/src/math/powf.c\n//\n\n// @ts-ignore: decorator\n@inline\nfunction zeroinfnanf(ux: u32): bool {\n return (ux << 1) - 1 >= (0x7f800000 << 1) - 1;\n}\n\n// Returns 0 if not int, 1 if odd int, 2 if even int. The argument is\n// the bit representation of a non-zero finite floating-point value.\n// @ts-ignore: decorator\n@inline\nfunction checkintf(iy: u32): i32 {\n let e = iy >> 23 & 0xFF;\n if (e < 0x7F ) return 0;\n if (e > 0x7F + 23) return 2;\n e = 1 << (0x7F + 23 - e);\n if (iy & (e - 1)) return 0;\n if (iy & e ) return 1;\n return 2;\n}\n\n// Subnormal input is normalized so ix has negative biased exponent.\n// Output is multiplied by N (POWF_SCALE) if TOINT_INTRINICS is set.\n// @ts-ignore: decorator\n@inline\nfunction log2f_inline(ux: u32): f64 {\n const N_MASK = (1 << LOG2F_TABLE_BITS) - 1;\n\n const\n A0 = reinterpret(0x3FD27616C9496E0B), // 0x1.27616c9496e0bp-2\n A1 = reinterpret(0xBFD71969A075C67A), // -0x1.71969a075c67ap-2\n A2 = reinterpret(0x3FDEC70A6CA7BADD), // 0x1.ec70a6ca7baddp-2\n A3 = reinterpret(0xBFE7154748BEF6C8), // -0x1.7154748bef6c8p-1\n A4 = reinterpret(0x3FF71547652AB82B); // 0x1.71547652ab82bp+0\n\n // x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ux - 0x3F330000;\n let i = usize((tmp >> (23 - LOG2F_TABLE_BITS)) & N_MASK);\n let top = tmp & 0xFF800000;\n let uz = ux - top;\n let k = top >> 23;\n\n let invc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 0 << alignof());\n let logc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 1 << alignof());\n let z = reinterpret(uz);\n\n // log2(x) = log1p(z/c-1)/ln2 + log2(c) + k\n let r = z * invc - 1;\n let y0 = logc + k;\n\n // Pipelined polynomial evaluation to approximate log1p(r)/ln2.\n let y = A0 * r + A1;\n let p = A2 * r + A3;\n let q = A4 * r + y0;\n\n r *= r;\n q += p * r;\n y = y * (r * r) + q;\n\n return y;\n}\n\n// The output of log2 and thus the input of exp2 is either scaled by N\n// (in case of fast toint intrinsics) or not. The unscaled xd must be\n// in [-1021,1023], sign_bias sets the sign of the result.\n// @ts-ignore: decorator\n@inline\nfunction exp2f_inline(xd: f64, signBias: u32): f32 {\n const\n N = 1 << EXP2F_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000) / N; // 0x1.8p+52\n\n const\n C0 = reinterpret(0x3FAC6AF84B912394), // 0x1.c6af84b912394p-5\n C1 = reinterpret(0x3FCEBFCE50FAC4F3), // 0x1.ebfce50fac4f3p-3\n C2 = reinterpret(0x3FE62E42FF0C52D6); // 0x1.62e42ff0c52d6p-1\n\n // x = k/N + r with r in [-1/(2N), 1/(2N)]\n let kd = (xd + shift);\n let ki = reinterpret(kd);\n let r = xd - (kd - shift);\n let t: u64, z: f64, y: f64, s: f64;\n\n // exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1)\n t = load(EXP2F_DATA_TAB + ((ki & N_MASK) << alignof()));\n t += (ki + signBias) << (52 - EXP2F_TABLE_BITS);\n s = reinterpret(t);\n z = C0 * r + C1;\n y = C2 * r + 1;\n y += z * (r * r);\n y *= s;\n return y;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction xflowf(sign: u32, y: f32): f32 {\n return select(-y, y, sign) * y;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction oflowf(sign: u32): f32 {\n return xflowf(sign, reinterpret(0x70000000)); // 0x1p97f\n}\n\n// @ts-ignore: decorator\n@inline\nfunction uflowf(sign: u32): f32 {\n return xflowf(sign, reinterpret(0x10000000)); // 0x1p-95f\n}\n\n// @ts-ignore: decorator\n@inline\nexport function powf_lut(x: f32, y: f32): f32 {\n const\n Ox1p23f = reinterpret(0x4B000000), // 0x1p23f\n UPPER_LIMIT = reinterpret(0x405FFFFFFFD1D571), // 0x1.fffffffd1d571p+6\n LOWER_LIMIT = -150.0,\n SIGN_BIAS = 1 << (EXP2F_TABLE_BITS + 11);\n\n let signBias: u32 = 0;\n let ix = reinterpret(x);\n let iy = reinterpret(y);\n let ny = 0;\n\n if (i32(ix - 0x00800000 >= 0x7f800000 - 0x00800000) | (ny = i32(zeroinfnanf(iy)))) {\n // Either (x < 0x1p-126 or inf or nan) or (y is 0 or inf or nan).\n if (ny) {\n if ((iy << 1) == 0) return 1.0;\n if (ix == 0x3F800000) return NaN; // original: 1.0\n if ((ix << 1) > (0x7F800000 << 1) || (iy << 1) > (0x7F800000 << 1)) return x + y;\n if ((ix << 1) == (0x3F800000 << 1)) return NaN; // original: 1.0\n if (((ix << 1) < (0x3F800000 << 1)) == !(iy >> 31)) return 0; // |x| < 1 && y==inf or |x| > 1 && y==-inf.\n return y * y;\n }\n if (zeroinfnanf(ix)) {\n let x2 = x * x;\n if ((ix >> 31) && checkintf(iy) == 1) x2 = -x2;\n return iy < 0 ? 1 / x2 : x2;\n }\n // x and y are non-zero finite.\n if (ix < 0) {\n // Finite x < 0.\n let yint = checkintf(iy);\n if (yint == 0) return (x - x) / (x - x);\n if (yint == 1) signBias = SIGN_BIAS;\n ix &= 0x7FFFFFFF;\n }\n if (ix < 0x00800000) {\n // Normalize subnormal x so exponent becomes negative.\n ix = reinterpret(x * Ox1p23f);\n ix &= 0x7FFFFFFF;\n ix -= 23 << 23;\n }\n }\n let logx = log2f_inline(ix);\n let ylogx = y * logx; // cannot overflow, y is single prec.\n if ((reinterpret(ylogx) >> 47 & 0xFFFF) >= 0x80BF) { // reinterpret(126.0) >> 47\n // |y * log(x)| >= 126\n if (ylogx > UPPER_LIMIT) return oflowf(signBias); // overflow\n if (ylogx <= LOWER_LIMIT) return uflowf(signBias); // underflow\n }\n return exp2f_inline(ylogx, signBias);\n}\n\n//\n// Lookup data for exp. See: https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c\n//\n\n// @ts-ignore: decorator\n@inline const EXP_TABLE_BITS = 7;\n\n// @ts-ignore: decorator\n@lazy @inline const EXP_DATA_TAB = memory.data([\n 0x0000000000000000, 0x3FF0000000000000,\n 0x3C9B3B4F1A88BF6E, 0x3FEFF63DA9FB3335,\n 0xBC7160139CD8DC5D, 0x3FEFEC9A3E778061,\n 0xBC905E7A108766D1, 0x3FEFE315E86E7F85,\n 0x3C8CD2523567F613, 0x3FEFD9B0D3158574,\n 0xBC8BCE8023F98EFA, 0x3FEFD06B29DDF6DE,\n 0x3C60F74E61E6C861, 0x3FEFC74518759BC8,\n 0x3C90A3E45B33D399, 0x3FEFBE3ECAC6F383,\n 0x3C979AA65D837B6D, 0x3FEFB5586CF9890F,\n 0x3C8EB51A92FDEFFC, 0x3FEFAC922B7247F7,\n 0x3C3EBE3D702F9CD1, 0x3FEFA3EC32D3D1A2,\n 0xBC6A033489906E0B, 0x3FEF9B66AFFED31B,\n 0xBC9556522A2FBD0E, 0x3FEF9301D0125B51,\n 0xBC5080EF8C4EEA55, 0x3FEF8ABDC06C31CC,\n 0xBC91C923B9D5F416, 0x3FEF829AAEA92DE0,\n 0x3C80D3E3E95C55AF, 0x3FEF7A98C8A58E51,\n 0xBC801B15EAA59348, 0x3FEF72B83C7D517B,\n 0xBC8F1FF055DE323D, 0x3FEF6AF9388C8DEA,\n 0x3C8B898C3F1353BF, 0x3FEF635BEB6FCB75,\n 0xBC96D99C7611EB26, 0x3FEF5BE084045CD4,\n 0x3C9AECF73E3A2F60, 0x3FEF54873168B9AA,\n 0xBC8FE782CB86389D, 0x3FEF4D5022FCD91D,\n 0x3C8A6F4144A6C38D, 0x3FEF463B88628CD6,\n 0x3C807A05B0E4047D, 0x3FEF3F49917DDC96,\n 0x3C968EFDE3A8A894, 0x3FEF387A6E756238,\n 0x3C875E18F274487D, 0x3FEF31CE4FB2A63F,\n 0x3C80472B981FE7F2, 0x3FEF2B4565E27CDD,\n 0xBC96B87B3F71085E, 0x3FEF24DFE1F56381,\n 0x3C82F7E16D09AB31, 0x3FEF1E9DF51FDEE1,\n 0xBC3D219B1A6FBFFA, 0x3FEF187FD0DAD990,\n 0x3C8B3782720C0AB4, 0x3FEF1285A6E4030B,\n 0x3C6E149289CECB8F, 0x3FEF0CAFA93E2F56,\n 0x3C834D754DB0ABB6, 0x3FEF06FE0A31B715,\n 0x3C864201E2AC744C, 0x3FEF0170FC4CD831,\n 0x3C8FDD395DD3F84A, 0x3FEEFC08B26416FF,\n 0xBC86A3803B8E5B04, 0x3FEEF6C55F929FF1,\n 0xBC924AEDCC4B5068, 0x3FEEF1A7373AA9CB,\n 0xBC9907F81B512D8E, 0x3FEEECAE6D05D866,\n 0xBC71D1E83E9436D2, 0x3FEEE7DB34E59FF7,\n 0xBC991919B3CE1B15, 0x3FEEE32DC313A8E5,\n 0x3C859F48A72A4C6D, 0x3FEEDEA64C123422,\n 0xBC9312607A28698A, 0x3FEEDA4504AC801C,\n 0xBC58A78F4817895B, 0x3FEED60A21F72E2A,\n 0xBC7C2C9B67499A1B, 0x3FEED1F5D950A897,\n 0x3C4363ED60C2AC11, 0x3FEECE086061892D,\n 0x3C9666093B0664EF, 0x3FEECA41ED1D0057,\n 0x3C6ECCE1DAA10379, 0x3FEEC6A2B5C13CD0,\n 0x3C93FF8E3F0F1230, 0x3FEEC32AF0D7D3DE,\n 0x3C7690CEBB7AAFB0, 0x3FEEBFDAD5362A27,\n 0x3C931DBDEB54E077, 0x3FEEBCB299FDDD0D,\n 0xBC8F94340071A38E, 0x3FEEB9B2769D2CA7,\n 0xBC87DECCDC93A349, 0x3FEEB6DAA2CF6642,\n 0xBC78DEC6BD0F385F, 0x3FEEB42B569D4F82,\n 0xBC861246EC7B5CF6, 0x3FEEB1A4CA5D920F,\n 0x3C93350518FDD78E, 0x3FEEAF4736B527DA,\n 0x3C7B98B72F8A9B05, 0x3FEEAD12D497C7FD,\n 0x3C9063E1E21C5409, 0x3FEEAB07DD485429,\n 0x3C34C7855019C6EA, 0x3FEEA9268A5946B7,\n 0x3C9432E62B64C035, 0x3FEEA76F15AD2148,\n 0xBC8CE44A6199769F, 0x3FEEA5E1B976DC09,\n 0xBC8C33C53BEF4DA8, 0x3FEEA47EB03A5585,\n 0xBC845378892BE9AE, 0x3FEEA34634CCC320,\n 0xBC93CEDD78565858, 0x3FEEA23882552225,\n 0x3C5710AA807E1964, 0x3FEEA155D44CA973,\n 0xBC93B3EFBF5E2228, 0x3FEEA09E667F3BCD,\n 0xBC6A12AD8734B982, 0x3FEEA012750BDABF,\n 0xBC6367EFB86DA9EE, 0x3FEE9FB23C651A2F,\n 0xBC80DC3D54E08851, 0x3FEE9F7DF9519484,\n 0xBC781F647E5A3ECF, 0x3FEE9F75E8EC5F74,\n 0xBC86EE4AC08B7DB0, 0x3FEE9F9A48A58174,\n 0xBC8619321E55E68A, 0x3FEE9FEB564267C9,\n 0x3C909CCB5E09D4D3, 0x3FEEA0694FDE5D3F,\n 0xBC7B32DCB94DA51D, 0x3FEEA11473EB0187,\n 0x3C94ECFD5467C06B, 0x3FEEA1ED0130C132,\n 0x3C65EBE1ABD66C55, 0x3FEEA2F336CF4E62,\n 0xBC88A1C52FB3CF42, 0x3FEEA427543E1A12,\n 0xBC9369B6F13B3734, 0x3FEEA589994CCE13,\n 0xBC805E843A19FF1E, 0x3FEEA71A4623C7AD,\n 0xBC94D450D872576E, 0x3FEEA8D99B4492ED,\n 0x3C90AD675B0E8A00, 0x3FEEAAC7D98A6699,\n 0x3C8DB72FC1F0EAB4, 0x3FEEACE5422AA0DB,\n 0xBC65B6609CC5E7FF, 0x3FEEAF3216B5448C,\n 0x3C7BF68359F35F44, 0x3FEEB1AE99157736,\n 0xBC93091FA71E3D83, 0x3FEEB45B0B91FFC6,\n 0xBC5DA9B88B6C1E29, 0x3FEEB737B0CDC5E5,\n 0xBC6C23F97C90B959, 0x3FEEBA44CBC8520F,\n 0xBC92434322F4F9AA, 0x3FEEBD829FDE4E50,\n 0xBC85CA6CD7668E4B, 0x3FEEC0F170CA07BA,\n 0x3C71AFFC2B91CE27, 0x3FEEC49182A3F090,\n 0x3C6DD235E10A73BB, 0x3FEEC86319E32323,\n 0xBC87C50422622263, 0x3FEECC667B5DE565,\n 0x3C8B1C86E3E231D5, 0x3FEED09BEC4A2D33,\n 0xBC91BBD1D3BCBB15, 0x3FEED503B23E255D,\n 0x3C90CC319CEE31D2, 0x3FEED99E1330B358,\n 0x3C8469846E735AB3, 0x3FEEDE6B5579FDBF,\n 0xBC82DFCD978E9DB4, 0x3FEEE36BBFD3F37A,\n 0x3C8C1A7792CB3387, 0x3FEEE89F995AD3AD,\n 0xBC907B8F4AD1D9FA, 0x3FEEEE07298DB666,\n 0xBC55C3D956DCAEBA, 0x3FEEF3A2B84F15FB,\n 0xBC90A40E3DA6F640, 0x3FEEF9728DE5593A,\n 0xBC68D6F438AD9334, 0x3FEEFF76F2FB5E47,\n 0xBC91EEE26B588A35, 0x3FEF05B030A1064A,\n 0x3C74FFD70A5FDDCD, 0x3FEF0C1E904BC1D2,\n 0xBC91BDFBFA9298AC, 0x3FEF12C25BD71E09,\n 0x3C736EAE30AF0CB3, 0x3FEF199BDD85529C,\n 0x3C8EE3325C9FFD94, 0x3FEF20AB5FFFD07A,\n 0x3C84E08FD10959AC, 0x3FEF27F12E57D14B,\n 0x3C63CDAF384E1A67, 0x3FEF2F6D9406E7B5,\n 0x3C676B2C6C921968, 0x3FEF3720DCEF9069,\n 0xBC808A1883CCB5D2, 0x3FEF3F0B555DC3FA,\n 0xBC8FAD5D3FFFFA6F, 0x3FEF472D4A07897C,\n 0xBC900DAE3875A949, 0x3FEF4F87080D89F2,\n 0x3C74A385A63D07A7, 0x3FEF5818DCFBA487,\n 0xBC82919E2040220F, 0x3FEF60E316C98398,\n 0x3C8E5A50D5C192AC, 0x3FEF69E603DB3285,\n 0x3C843A59AC016B4B, 0x3FEF7321F301B460,\n 0xBC82D52107B43E1F, 0x3FEF7C97337B9B5F,\n 0xBC892AB93B470DC9, 0x3FEF864614F5A129,\n 0x3C74B604603A88D3, 0x3FEF902EE78B3FF6,\n 0x3C83C5EC519D7271, 0x3FEF9A51FBC74C83,\n 0xBC8FF7128FD391F0, 0x3FEFA4AFA2A490DA,\n 0xBC8DAE98E223747D, 0x3FEFAF482D8E67F1,\n 0x3C8EC3BC41AA2008, 0x3FEFBA1BEE615A27,\n 0x3C842B94C3A9EB32, 0x3FEFC52B376BBA97,\n 0x3C8A64A931D185EE, 0x3FEFD0765B6E4540,\n 0xBC8E37BAE43BE3ED, 0x3FEFDBFDAD9CBE14,\n 0x3C77893B4D91CD9D, 0x3FEFE7C1819E90D8,\n 0x3C5305C14160CC89, 0x3FEFF3C22B8F71F1\n]);\n\n// Handle cases that may overflow or underflow when computing the result that\n// is scale*(1+TMP) without intermediate rounding. The bit representation of\n// scale is in SBITS, however it has a computed exponent that may have\n// overflown into the sign bit so that needs to be adjusted before using it as\n// a double. (int32_t)KI is the k used in the argument reduction and exponent\n// adjustment of scale, positive k here means the result may overflow and\n// negative k means the result may underflow.\n// @ts-ignore: decorator\n@inline\nfunction specialcase(tmp: f64, sbits: u64, ki: u64): f64 {\n const\n Ox1p_1022 = reinterpret(0x0010000000000000), // 0x1p-1022\n Ox1p1009 = reinterpret(0x7F00000000000000); // 0x1p1009\n\n let scale: f64;\n if (!(ki & 0x80000000)) {\n // k > 0, the exponent of scale might have overflowed by <= 460.\n sbits -= u64(1009) << 52;\n scale = reinterpret(sbits);\n return Ox1p1009 * (scale + scale * tmp); // 0x1p1009\n }\n // k < 0, need special care in the subnormal range.\n sbits += u64(1022) << 52;\n // Note: sbits is signed scale.\n scale = reinterpret(sbits);\n let y = scale + scale * tmp;\n if (abs(y) < 1.0) {\n // Round y to the right precision before scaling it into the subnormal\n // range to avoid double rounding that can cause 0.5+E/2 ulp error where\n // E is the worst-case ulp error outside the subnormal range. So this\n // is only useful if the goal is better than 1 ulp worst-case error.\n let one = copysign(1.0, y);\n let lo = scale - y + scale * tmp;\n let hi = one + y;\n lo = one - hi + y + lo;\n y = (hi + lo) - one;\n // Fix the sign of 0.\n if (y == 0.0) y = reinterpret(sbits & 0x8000000000000000);\n }\n return y * Ox1p_1022;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function exp_lut(x: f64): f64 {\n const\n N = 1 << EXP_TABLE_BITS,\n N_MASK = N - 1;\n\n const\n InvLn2N = reinterpret(0x3FF71547652B82FE) * N, // 0x1.71547652b82fep0\n NegLn2hiN = reinterpret(0xBF762E42FEFA0000), // -0x1.62e42fefa0000p-8\n NegLn2loN = reinterpret(0xBD0CF79ABC9E3B3A), // -0x1.cf79abc9e3b3ap-47\n shift = reinterpret(0x4338000000000000); // 0x1.8p52;\n\n const\n C2 = reinterpret(0x3FDFFFFFFFFFFDBD), // __exp_data.poly[0] (0x1.ffffffffffdbdp-2)\n C3 = reinterpret(0x3FC555555555543C), // __exp_data.poly[1] (0x1.555555555543cp-3)\n C4 = reinterpret(0x3FA55555CF172B91), // __exp_data.poly[2] (0x1.55555cf172b91p-5)\n C5 = reinterpret(0x3F81111167A4D017); // __exp_data.poly[3] (0x1.1111167a4d017p-7)\n\n let ux = reinterpret(x);\n let abstop = u32(ux >> 52) & 0x7FF;\n if (abstop - 0x3C9 >= 0x03F) {\n if (abstop - 0x3C9 >= 0x80000000) return 1;\n if (abstop >= 0x409) {\n if (ux == 0xFFF0000000000000) return 0;\n if (abstop >= 0x7FF) {\n return 1.0 + x;\n } else {\n return select(0, Infinity, ux < 0);\n }\n }\n // Large x is special cased below.\n abstop = 0;\n }\n\n // exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]\n // x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]\n let z = InvLn2N * x;\n // #if TOINT_INTRINSICS\n // \tkd = roundtoint(z);\n // \tki = converttoint(z);\n // #elif EXP_USE_TOINT_NARROW\n // \t// z - kd is in [-0.5-2^-16, 0.5] in all rounding modes.\n // let kd = z + shift;\n // let ki = reinterpret(kd) >> 16;\n // let kd = ki;\n // #else\n // z - kd is in [-1, 1] in non-nearest rounding modes.\n let kd = z + shift;\n let ki = reinterpret(kd);\n kd -= shift;\n // #endif\n let r = x + kd * NegLn2hiN + kd * NegLn2loN;\n // 2^(k/N) ~= scale * (1 + tail).\n let idx = usize((ki & N_MASK) << 1);\n let top = ki << (52 - EXP_TABLE_BITS);\n\n let tail = reinterpret(load(EXP_DATA_TAB + (idx << alignof()))); // T[idx]\n // This is only a valid scale when -1023*N < k < 1024*N\n let sbits = load(EXP_DATA_TAB + (idx << alignof()), 1 << alignof()) + top; // T[idx + 1]\n // exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1).\n // Evaluation is optimized assuming superscalar pipelined execution.\n let r2 = r * r;\n // Without fma the worst case error is 0.25/N ulp larger.\n // Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp.\n let tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n if (abstop == 0) return specialcase(tmp, sbits, ki);\n let scale = reinterpret(sbits);\n // Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there\n // is no spurious underflow here even without fma.\n return scale + scale * tmp;\n}\n\n//\n// Lookup data for exp2. See: https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c\n//\n\n// Handle cases that may overflow or underflow when computing the result that\n// is scale*(1+TMP) without intermediate rounding. The bit representation of\n// scale is in SBITS, however it has a computed exponent that may have\n// overflown into the sign bit so that needs to be adjusted before using it as\n// a double. (int32_t)KI is the k used in the argument reduction and exponent\n// adjustment of scale, positive k here means the result may overflow and\n// negative k means the result may underflow.\n// @ts-ignore: decorator\n@inline\nfunction specialcase2(tmp: f64, sbits: u64, ki: u64): f64 {\n const Ox1p_1022 = reinterpret(0x10000000000000); // 0x1p-1022\n let scale: f64;\n if ((ki & 0x80000000) == 0) {\n // k > 0, the exponent of scale might have overflowed by 1\n sbits -= u64(1) << 52;\n scale = reinterpret(sbits);\n return 2 * (scale * tmp + scale);\n }\n // k < 0, need special care in the subnormal range\n sbits += u64(1022) << 52;\n scale = reinterpret(sbits);\n let y = scale * tmp + scale;\n if (y < 1.0) {\n // Round y to the right precision before scaling it into the subnormal\n // range to avoid double rounding that can cause 0.5+E/2 ulp error where\n // E is the worst-case ulp error outside the subnormal range. So this\n // is only useful if the goal is better than 1 ulp worst-case error.\n let hi: f64, lo: f64;\n lo = scale - y + scale * tmp;\n hi = 1.0 + y;\n lo = 1.0 - hi + y + lo;\n y = (hi + lo) - 1.0;\n }\n return y * Ox1p_1022;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function exp2_lut(x: f64): f64 {\n const\n N = 1 << EXP_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000) / N; // 0x1.8p52\n\n const\n C1 = reinterpret(0x3FE62E42FEFA39EF), // 0x1.62e42fefa39efp-1\n C2 = reinterpret(0x3FCEBFBDFF82C424), // 0x1.ebfbdff82c424p-3\n C3 = reinterpret(0x3FAC6B08D70CF4B5), // 0x1.c6b08d70cf4b5p-5\n C4 = reinterpret(0x3F83B2ABD24650CC), // 0x1.3b2abd24650ccp-7\n C5 = reinterpret(0x3F55D7E09B4E3A84); // 0x1.5d7e09b4e3a84p-10\n\n let ux = reinterpret(x);\n let abstop = u32(ux >> 52) & 0x7ff;\n if (abstop - 0x3C9 >= 0x03F) {\n if (abstop - 0x3C9 >= 0x80000000) return 1.0;\n if (abstop >= 0x409) {\n if (ux == 0xFFF0000000000000) return 0;\n if (abstop >= 0x7FF) return 1.0 + x;\n if (ux >= 0) return Infinity;\n else if (ux >= 0xC090CC0000000000) return 0;\n }\n if ((ux << 1) > 0x811A000000000000) abstop = 0; // Large x is special cased below.\n }\n\n // exp2(x) = 2^(k/N) * 2^r, with 2^r in [2^(-1/2N),2^(1/2N)].\n // x = k/N + r, with int k and r in [-1/2N, 1/2N]\n let kd = x + shift;\n let ki = reinterpret(kd);\n kd -= shift; // k/N for int k\n let r = x - kd;\n // 2^(k/N) ~= scale * (1 + tail)\n let idx = usize((ki & N_MASK) << 1);\n let top = ki << (52 - EXP_TABLE_BITS);\n\n let tail = reinterpret(load(EXP_DATA_TAB + (idx << alignof()), 0 << alignof())); // T[idx])\n // This is only a valid scale when -1023*N < k < 1024*N\n let sbits = load(EXP_DATA_TAB + (idx << alignof()), 1 << alignof()) + top; // T[idx + 1]\n // exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1).\n // Evaluation is optimized assuming superscalar pipelined execution\n let r2 = r * r;\n // Without fma the worst case error is 0.5/N ulp larger.\n // Worst case error is less than 0.5+0.86/N+(abs poly error * 2^53) ulp.\n let tmp = tail + r * C1 + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n if (abstop == 0) return specialcase2(tmp, sbits, ki);\n let scale = reinterpret(sbits);\n // Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there\n // is no spurious underflow here even without fma.\n return scale * tmp + scale;\n}\n\n//\n// Lookup data for log2. See: https://git.musl-libc.org/cgit/musl/tree/src/math/log2.c\n//\n\n// @ts-ignore: decorator\n@inline const LOG2_TABLE_BITS = 6;\n\n/* Algorithm:\n\n x = 2^k z\n log2(x) = k + log2(c) + log2(z/c)\n log2(z/c) = poly(z/c - 1)\n\nwhere z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls\ninto the ith one, then table entries are computed as\n\n tab[i].invc = 1/c\n tab[i].logc = (double)log2(c)\n tab2[i].chi = (double)c\n tab2[i].clo = (double)(c - (double)c)\n\nwhere c is near the center of the subinterval and is chosen by trying +-2^29\nfloating point invc candidates around 1/center and selecting one for which\n\n 1) the rounding error in 0x1.8p10 + logc is 0,\n 2) the rounding error in z - chi - clo is < 0x1p-64 and\n 3) the rounding error in (double)log2(c) is minimized (< 0x1p-68).\n\nNote: 1) ensures that k + logc can be computed without rounding error, 2)\nensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to a\nsingle rounding error when there is no fast fma for z*invc - 1, 3) ensures\nthat logc + poly(z/c - 1) has small error, however near x == 1 when\n|log2(x)| < 0x1p-4, this is not enough so that is special cased. */\n\n// @ts-ignore: decorator\n@lazy @inline const LOG2_DATA_TAB1 = memory.data([\n // invc , logc\n 0x3FF724286BB1ACF8, 0xBFE1095FEECDB000,\n 0x3FF6E1F766D2CCA1, 0xBFE08494BD76D000,\n 0x3FF6A13D0E30D48A, 0xBFE00143AEE8F800,\n 0x3FF661EC32D06C85, 0xBFDEFEC5360B4000,\n 0x3FF623FA951198F8, 0xBFDDFDD91AB7E000,\n 0x3FF5E75BA4CF026C, 0xBFDCFFAE0CC79000,\n 0x3FF5AC055A214FB8, 0xBFDC043811FDA000,\n 0x3FF571ED0F166E1E, 0xBFDB0B67323AE000,\n 0x3FF53909590BF835, 0xBFDA152F5A2DB000,\n 0x3FF5014FED61ADDD, 0xBFD9217F5AF86000,\n 0x3FF4CAB88E487BD0, 0xBFD8304DB0719000,\n 0x3FF49539B4334FEE, 0xBFD74189F9A9E000,\n 0x3FF460CBDFAFD569, 0xBFD6552BB5199000,\n 0x3FF42D664EE4B953, 0xBFD56B23A29B1000,\n 0x3FF3FB01111DD8A6, 0xBFD483650F5FA000,\n 0x3FF3C995B70C5836, 0xBFD39DE937F6A000,\n 0x3FF3991C4AB6FD4A, 0xBFD2BAA1538D6000,\n 0x3FF3698E0CE099B5, 0xBFD1D98340CA4000,\n 0x3FF33AE48213E7B2, 0xBFD0FA853A40E000,\n 0x3FF30D191985BDB1, 0xBFD01D9C32E73000,\n 0x3FF2E025CAB271D7, 0xBFCE857DA2FA6000,\n 0x3FF2B404CF13CD82, 0xBFCCD3C8633D8000,\n 0x3FF288B02C7CCB50, 0xBFCB26034C14A000,\n 0x3FF25E2263944DE5, 0xBFC97C1C2F4FE000,\n 0x3FF234563D8615B1, 0xBFC7D6023F800000,\n 0x3FF20B46E33EAF38, 0xBFC633A71A05E000,\n 0x3FF1E2EEFDCDA3DD, 0xBFC494F5E9570000,\n 0x3FF1BB4A580B3930, 0xBFC2F9E424E0A000,\n 0x3FF19453847F2200, 0xBFC162595AFDC000,\n 0x3FF16E06C0D5D73C, 0xBFBF9C9A75BD8000,\n 0x3FF1485F47B7E4C2, 0xBFBC7B575BF9C000,\n 0x3FF12358AD0085D1, 0xBFB960C60FF48000,\n 0x3FF0FEF00F532227, 0xBFB64CE247B60000,\n 0x3FF0DB2077D03A8F, 0xBFB33F78B2014000,\n 0x3FF0B7E6D65980D9, 0xBFB0387D1A42C000,\n 0x3FF0953EFE7B408D, 0xBFAA6F9208B50000,\n 0x3FF07325CAC53B83, 0xBFA47A954F770000,\n 0x3FF05197E40D1B5C, 0xBF9D23A8C50C0000,\n 0x3FF03091C1208EA2, 0xBF916A2629780000,\n 0x3FF0101025B37E21, 0xBF7720F8D8E80000,\n 0x3FEFC07EF9CAA76B, 0x3F86FE53B1500000,\n 0x3FEF4465D3F6F184, 0x3FA11CCCE10F8000,\n 0x3FEECC079F84107F, 0x3FAC4DFC8C8B8000,\n 0x3FEE573A99975AE8, 0x3FB3AA321E574000,\n 0x3FEDE5D6F0BD3DE6, 0x3FB918A0D08B8000,\n 0x3FED77B681FF38B3, 0x3FBE72E9DA044000,\n 0x3FED0CB5724DE943, 0x3FC1DCD2507F6000,\n 0x3FECA4B2DC0E7563, 0x3FC476AB03DEA000,\n 0x3FEC3F8EE8D6CB51, 0x3FC7074377E22000,\n 0x3FEBDD2B4F020C4C, 0x3FC98EDE8BA94000,\n 0x3FEB7D6C006015CA, 0x3FCC0DB86AD2E000,\n 0x3FEB20366E2E338F, 0x3FCE840AAFCEE000,\n 0x3FEAC57026295039, 0x3FD0790AB4678000,\n 0x3FEA6D01BC2731DD, 0x3FD1AC056801C000,\n 0x3FEA16D3BC3FF18B, 0x3FD2DB11D4FEE000,\n 0x3FE9C2D14967FEAD, 0x3FD406464EC58000,\n 0x3FE970E4F47C9902, 0x3FD52DBE093AF000,\n 0x3FE920FB3982BCF2, 0x3FD651902050D000,\n 0x3FE8D30187F759F1, 0x3FD771D2CDEAF000,\n 0x3FE886E5EBB9F66D, 0x3FD88E9C857D9000,\n 0x3FE83C97B658B994, 0x3FD9A80155E16000,\n 0x3FE7F405FFC61022, 0x3FDABE186ED3D000,\n 0x3FE7AD22181415CA, 0x3FDBD0F2AEA0E000,\n 0x3FE767DCF99EFF8C, 0x3FDCE0A43DBF4000\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const LOG2_DATA_TAB2 = memory.data([\n // chi , clo\n 0x3FE6200012B90A8E, 0x3C8904AB0644B605,\n 0x3FE66000045734A6, 0x3C61FF9BEA62F7A9,\n 0x3FE69FFFC325F2C5, 0x3C827ECFCB3C90BA,\n 0x3FE6E00038B95A04, 0x3C88FF8856739326,\n 0x3FE71FFFE09994E3, 0x3C8AFD40275F82B1,\n 0x3FE7600015590E10, 0xBC72FD75B4238341,\n 0x3FE7A00012655BD5, 0x3C7808E67C242B76,\n 0x3FE7E0003259E9A6, 0xBC6208E426F622B7,\n 0x3FE81FFFEDB4B2D2, 0xBC8402461EA5C92F,\n 0x3FE860002DFAFCC3, 0x3C6DF7F4A2F29A1F,\n 0x3FE89FFFF78C6B50, 0xBC8E0453094995FD,\n 0x3FE8E00039671566, 0xBC8A04F3BEC77B45,\n 0x3FE91FFFE2BF1745, 0xBC77FA34400E203C,\n 0x3FE95FFFCC5C9FD1, 0xBC76FF8005A0695D,\n 0x3FE9A0003BBA4767, 0x3C70F8C4C4EC7E03,\n 0x3FE9DFFFE7B92DA5, 0x3C8E7FD9478C4602,\n 0x3FEA1FFFD72EFDAF, 0xBC6A0C554DCDAE7E,\n 0x3FEA5FFFDE04FF95, 0x3C867DA98CE9B26B,\n 0x3FEA9FFFCA5E8D2B, 0xBC8284C9B54C13DE,\n 0x3FEADFFFDDAD03EA, 0x3C5812C8EA602E3C,\n 0x3FEB1FFFF10D3D4D, 0xBC8EFADDAD27789C,\n 0x3FEB5FFFCE21165A, 0x3C53CB1719C61237,\n 0x3FEB9FFFD950E674, 0x3C73F7D94194CE00,\n 0x3FEBE000139CA8AF, 0x3C750AC4215D9BC0,\n 0x3FEC20005B46DF99, 0x3C6BEEA653E9C1C9,\n 0x3FEC600040B9F7AE, 0xBC7C079F274A70D6,\n 0x3FECA0006255FD8A, 0xBC7A0B4076E84C1F,\n 0x3FECDFFFD94C095D, 0x3C88F933F99AB5D7,\n 0x3FED1FFFF975D6CF, 0xBC582C08665FE1BE,\n 0x3FED5FFFA2561C93, 0xBC7B04289BD295F3,\n 0x3FED9FFF9D228B0C, 0x3C870251340FA236,\n 0x3FEDE00065BC7E16, 0xBC75011E16A4D80C,\n 0x3FEE200002F64791, 0x3C89802F09EF62E0,\n 0x3FEE600057D7A6D8, 0xBC7E0B75580CF7FA,\n 0x3FEEA00027EDC00C, 0xBC8C848309459811,\n 0x3FEEE0006CF5CB7C, 0xBC8F8027951576F4,\n 0x3FEF2000782B7DCC, 0xBC8F81D97274538F,\n 0x3FEF6000260C450A, 0xBC4071002727FFDC,\n 0x3FEF9FFFE88CD533, 0xBC581BDCE1FDA8B0,\n 0x3FEFDFFFD50F8689, 0x3C87F91ACB918E6E,\n 0x3FF0200004292367, 0x3C9B7FF365324681,\n 0x3FF05FFFE3E3D668, 0x3C86FA08DDAE957B,\n 0x3FF0A0000A85A757, 0xBC57E2DE80D3FB91,\n 0x3FF0E0001A5F3FCC, 0xBC91823305C5F014,\n 0x3FF11FFFF8AFBAF5, 0xBC8BFABB6680BAC2,\n 0x3FF15FFFE54D91AD, 0xBC9D7F121737E7EF,\n 0x3FF1A00011AC36E1, 0x3C9C000A0516F5FF,\n 0x3FF1E00019C84248, 0xBC9082FBE4DA5DA0,\n 0x3FF220000FFE5E6E, 0xBC88FDD04C9CFB43,\n 0x3FF26000269FD891, 0x3C8CFE2A7994D182,\n 0x3FF2A00029A6E6DA, 0xBC700273715E8BC5,\n 0x3FF2DFFFE0293E39, 0x3C9B7C39DAB2A6F9,\n 0x3FF31FFFF7DCF082, 0x3C7DF1336EDC5254,\n 0x3FF35FFFF05A8B60, 0xBC9E03564CCD31EB,\n 0x3FF3A0002E0EAECC, 0x3C75F0E74BD3A477,\n 0x3FF3E000043BB236, 0x3C9C7DCB149D8833,\n 0x3FF4200002D187FF, 0x3C7E08AFCF2D3D28,\n 0x3FF460000D387CB1, 0x3C820837856599A6,\n 0x3FF4A00004569F89, 0xBC89FA5C904FBCD2,\n 0x3FF4E000043543F3, 0xBC781125ED175329,\n 0x3FF51FFFCC027F0F, 0x3C9883D8847754DC,\n 0x3FF55FFFFD87B36F, 0xBC8709E731D02807,\n 0x3FF59FFFF21DF7BA, 0x3C87F79F68727B02,\n 0x3FF5DFFFEBFC3481, 0xBC9180902E30E93E\n]);\n\n// @ts-ignore: decorator\n@inline\nexport function log2_lut(x: f64): f64 {\n const N_MASK = (1 << LOG2_TABLE_BITS) - 1;\n\n const\n LO: u64 = 0x3FEEA4AF00000000, // reinterpret(1.0 - 0x1.5b51p-5)\n HI: u64 = 0x3FF0B55900000000; // reinterpret(1.0 + 0x1.6ab2p-5)\n\n const\n InvLn2hi = reinterpret(0x3FF7154765200000), // 0x1.7154765200000p+0\n InvLn2lo = reinterpret(0x3DE705FC2EEFA200), // 0x1.705fc2eefa200p-33\n Ox1p52 = reinterpret(0x4330000000000000); // 0x1p52\n\n const\n B0 = reinterpret(0xBFE71547652B82FE), // -0x1.71547652b82fep-1\n B1 = reinterpret(0x3FDEC709DC3A03F7), // 0x1.ec709dc3a03f7p-2\n B2 = reinterpret(0xBFD71547652B7C3F), // -0x1.71547652b7c3fp-2\n B3 = reinterpret(0x3FD2776C50F05BE4), // 0x1.2776c50f05be4p-2\n B4 = reinterpret(0xBFCEC709DD768FE5), // -0x1.ec709dd768fe5p-3\n B5 = reinterpret(0x3FCA61761EC4E736), // 0x1.a61761ec4e736p-3\n B6 = reinterpret(0xBFC7153FBC64A79B), // -0x1.7153fbc64a79bp-3\n B7 = reinterpret(0x3FC484D154F01B4A), // 0x1.484d154f01b4ap-3\n B8 = reinterpret(0xBFC289E4A72C383C), // -0x1.289e4a72c383cp-3\n B9 = reinterpret(0x3FC0B32F285AEE66); // 0x1.0b32f285aee66p-3\n\n const\n A0 = reinterpret(0xBFE71547652B8339), // -0x1.71547652b8339p-1\n A1 = reinterpret(0x3FDEC709DC3A04BE), // 0x1.ec709dc3a04bep-2\n A2 = reinterpret(0xBFD7154764702FFB), // -0x1.7154764702ffbp-2\n A3 = reinterpret(0x3FD2776C50034C48), // 0x1.2776c50034c48p-2\n A4 = reinterpret(0xBFCEC7B328EA92BC), // -0x1.ec7b328ea92bcp-3\n A5 = reinterpret(0x3FCA6225E117F92E); // 0x1.a6225e117f92ep-3\n\n let ix = reinterpret(x);\n if (ix - LO < HI - LO) {\n let r = x - 1.0;\n // #if __FP_FAST_FMA\n // hi = r * InvLn2hi;\n // lo = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -hi);\n // #else\n let rhi = reinterpret(reinterpret(r) & 0xFFFFFFFF00000000);\n let rlo = r - rhi;\n let hi = rhi * InvLn2hi;\n let lo = rlo * InvLn2hi + r * InvLn2lo;\n // #endif\n let r2 = r * r; // rounding error: 0x1p-62\n let r4 = r2 * r2;\n // Worst-case error is less than 0.54 ULP (0.55 ULP without fma)\n let p = r2 * (B0 + r * B1);\n let y = hi + p;\n lo += hi - y + p;\n lo += r4 * (B2 + r * B3 + r2 * (B4 + r * B5) +\n r4 * (B6 + r * B7 + r2 * (B8 + r * B9)));\n return y + lo;\n }\n let top = u32(ix >> 48);\n if (top - 0x0010 >= 0x7ff0 - 0x0010) {\n // x < 0x1p-1022 or inf or nan.\n if ((ix << 1) == 0) return -1.0 / (x * x);\n if (ix == 0x7FF0000000000000) return x; // log(inf) == inf\n if ((top & 0x8000) || (top & 0x7FF0) == 0x7FF0) return (x - x) / (x - x);\n // x is subnormal, normalize it.\n ix = reinterpret(x * Ox1p52);\n ix -= u64(52) << 52;\n }\n\n // x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ix - 0x3FE6000000000000;\n let i = ((tmp >> (52 - LOG2_TABLE_BITS)) & N_MASK);\n let k = tmp >> 52;\n let iz = ix - (tmp & 0xFFF0000000000000);\n\n let invc = load(LOG2_DATA_TAB1 + (i << (1 + alignof())), 0 << alignof()); // T[i].invc;\n let logc = load(LOG2_DATA_TAB1 + (i << (1 + alignof())), 1 << alignof()); // T[i].logc;\n let z = reinterpret(iz);\n let kd = k;\n\n // log2(x) = log2(z/c) + log2(c) + k.\n // r ~= z/c - 1, |r| < 1/(2*N).\n // #if __FP_FAST_FMA\n // \t// rounding error: 0x1p-55/N.\n // \tr = __builtin_fma(z, invc, -1.0);\n // \tt1 = r * InvLn2hi;\n // \tt2 = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -t1);\n // #else\n // rounding error: 0x1p-55/N + 0x1p-65.\n let chi = load(LOG2_DATA_TAB2 + (i << (1 + alignof())), 0 << alignof()); // T[i].chi;\n let clo = load(LOG2_DATA_TAB2 + (i << (1 + alignof())), 1 << alignof()); // T[i].clo;\n\n let r = (z - chi - clo) * invc;\n let rhi = reinterpret(reinterpret(r) & 0xFFFFFFFF00000000);\n let rlo = r - rhi;\n let t1 = rhi * InvLn2hi;\n let t2 = rlo * InvLn2hi + r * InvLn2lo;\n // #endif\n\n // hi + lo = r/ln2 + log2(c) + k\n let t3 = kd + logc;\n let hi = t3 + t1;\n let lo = t3 - hi + t1 + t2;\n\n // log2(r+1) = r/ln2 + r^2*poly(r)\n // Evaluation is optimized assuming superscalar pipelined execution\n let r2 = r * r; // rounding error: 0x1p-54/N^2\n // Worst-case error if |y| > 0x1p-4: 0.547 ULP (0.550 ULP without fma).\n // ~ 0.5 + 2/N/ln2 + abs-poly-error*0x1p56 ULP (+ 0.003 ULP without fma).\n let p = A0 + r * A1 + r2 * (A2 + r * A3) + (r2 * r2) * (A4 + r * A5);\n return lo + r2 * p + hi;\n}\n\n//\n// Lookup data for log. See: https://git.musl-libc.org/cgit/musl/tree/src/math/log.c\n//\n\n// @ts-ignore: decorator\n@inline const LOG_TABLE_BITS = 7;\n\n/* Algorithm:\n\n x = 2^k z\n log(x) = k ln2 + log(c) + log(z/c)\n log(z/c) = poly(z/c - 1)\n\nwhere z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls\ninto the ith one, then table entries are computed as\n\n tab[i].invc = 1/c\n tab[i].logc = (double)log(c)\n tab2[i].chi = (double)c\n tab2[i].clo = (double)(c - (double)c)\n\nwhere c is near the center of the subinterval and is chosen by trying +-2^29\nfloating point invc candidates around 1/center and selecting one for which\n\n 1) the rounding error in 0x1.8p9 + logc is 0,\n 2) the rounding error in z - chi - clo is < 0x1p-66 and\n 3) the rounding error in (double)log(c) is minimized (< 0x1p-66).\n\nNote: 1) ensures that k*ln2hi + logc can be computed without rounding error,\n2) ensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to\na single rounding error when there is no fast fma for z*invc - 1, 3) ensures\nthat logc + poly(z/c - 1) has small error, however near x == 1 when\n|log(x)| < 0x1p-4, this is not enough so that is special cased.*/\n\n// @ts-ignore: decorator\n@lazy @inline const LOG_DATA_TAB1 = memory.data([\n // invc , logc\n 0x3FF734F0C3E0DE9F, 0xBFD7CC7F79E69000,\n 0x3FF713786A2CE91F, 0xBFD76FEEC20D0000,\n 0x3FF6F26008FAB5A0, 0xBFD713E31351E000,\n 0x3FF6D1A61F138C7D, 0xBFD6B85B38287800,\n 0x3FF6B1490BC5B4D1, 0xBFD65D5590807800,\n 0x3FF69147332F0CBA, 0xBFD602D076180000,\n 0x3FF6719F18224223, 0xBFD5A8CA86909000,\n 0x3FF6524F99A51ED9, 0xBFD54F4356035000,\n 0x3FF63356AA8F24C4, 0xBFD4F637C36B4000,\n 0x3FF614B36B9DDC14, 0xBFD49DA7FDA85000,\n 0x3FF5F66452C65C4C, 0xBFD445923989A800,\n 0x3FF5D867B5912C4F, 0xBFD3EDF439B0B800,\n 0x3FF5BABCCB5B90DE, 0xBFD396CE448F7000,\n 0x3FF59D61F2D91A78, 0xBFD3401E17BDA000,\n 0x3FF5805612465687, 0xBFD2E9E2EF468000,\n 0x3FF56397CEE76BD3, 0xBFD2941B3830E000,\n 0x3FF54725E2A77F93, 0xBFD23EC58CDA8800,\n 0x3FF52AFF42064583, 0xBFD1E9E129279000,\n 0x3FF50F22DBB2BDDF, 0xBFD1956D2B48F800,\n 0x3FF4F38F4734DED7, 0xBFD141679AB9F800,\n 0x3FF4D843CFDE2840, 0xBFD0EDD094EF9800,\n 0x3FF4BD3EC078A3C8, 0xBFD09AA518DB1000,\n 0x3FF4A27FC3E0258A, 0xBFD047E65263B800,\n 0x3FF4880524D48434, 0xBFCFEB224586F000,\n 0x3FF46DCE1B192D0B, 0xBFCF474A7517B000,\n 0x3FF453D9D3391854, 0xBFCEA4443D103000,\n 0x3FF43A2744B4845A, 0xBFCE020D44E9B000,\n 0x3FF420B54115F8FB, 0xBFCD60A22977F000,\n 0x3FF40782DA3EF4B1, 0xBFCCC00104959000,\n 0x3FF3EE8F5D57FE8F, 0xBFCC202956891000,\n 0x3FF3D5D9A00B4CE9, 0xBFCB81178D811000,\n 0x3FF3BD60C010C12B, 0xBFCAE2C9CCD3D000,\n 0x3FF3A5242B75DAB8, 0xBFCA45402E129000,\n 0x3FF38D22CD9FD002, 0xBFC9A877681DF000,\n 0x3FF3755BC5847A1C, 0xBFC90C6D69483000,\n 0x3FF35DCE49AD36E2, 0xBFC87120A645C000,\n 0x3FF34679984DD440, 0xBFC7D68FB4143000,\n 0x3FF32F5CCEFFCB24, 0xBFC73CB83C627000,\n 0x3FF3187775A10D49, 0xBFC6A39A9B376000,\n 0x3FF301C8373E3990, 0xBFC60B3154B7A000,\n 0x3FF2EB4EBB95F841, 0xBFC5737D76243000,\n 0x3FF2D50A0219A9D1, 0xBFC4DC7B8FC23000,\n 0x3FF2BEF9A8B7FD2A, 0xBFC4462C51D20000,\n 0x3FF2A91C7A0C1BAB, 0xBFC3B08ABC830000,\n 0x3FF293726014B530, 0xBFC31B996B490000,\n 0x3FF27DFA5757A1F5, 0xBFC2875490A44000,\n 0x3FF268B39B1D3BBF, 0xBFC1F3B9F879A000,\n 0x3FF2539D838FF5BD, 0xBFC160C8252CA000,\n 0x3FF23EB7AAC9083B, 0xBFC0CE7F57F72000,\n 0x3FF22A012BA940B6, 0xBFC03CDC49FEA000,\n 0x3FF2157996CC4132, 0xBFBF57BDBC4B8000,\n 0x3FF201201DD2FC9B, 0xBFBE370896404000,\n 0x3FF1ECF4494D480B, 0xBFBD17983EF94000,\n 0x3FF1D8F5528F6569, 0xBFBBF9674ED8A000,\n 0x3FF1C52311577E7C, 0xBFBADC79202F6000,\n 0x3FF1B17C74CB26E9, 0xBFB9C0C3E7288000,\n 0x3FF19E010C2C1AB6, 0xBFB8A646B372C000,\n 0x3FF18AB07BB670BD, 0xBFB78D01B3AC0000,\n 0x3FF1778A25EFBCB6, 0xBFB674F145380000,\n 0x3FF1648D354C31DA, 0xBFB55E0E6D878000,\n 0x3FF151B990275FDD, 0xBFB4485CDEA1E000,\n 0x3FF13F0EA432D24C, 0xBFB333D94D6AA000,\n 0x3FF12C8B7210F9DA, 0xBFB22079F8C56000,\n 0x3FF11A3028ECB531, 0xBFB10E4698622000,\n 0x3FF107FBDA8434AF, 0xBFAFFA6C6AD20000,\n 0x3FF0F5EE0F4E6BB3, 0xBFADDA8D4A774000,\n 0x3FF0E4065D2A9FCE, 0xBFABBCECE4850000,\n 0x3FF0D244632CA521, 0xBFA9A1894012C000,\n 0x3FF0C0A77CE2981A, 0xBFA788583302C000,\n 0x3FF0AF2F83C636D1, 0xBFA5715E67D68000,\n 0x3FF09DDB98A01339, 0xBFA35C8A49658000,\n 0x3FF08CABAF52E7DF, 0xBFA149E364154000,\n 0x3FF07B9F2F4E28FB, 0xBF9E72C082EB8000,\n 0x3FF06AB58C358F19, 0xBF9A55F152528000,\n 0x3FF059EEA5ECF92C, 0xBF963D62CF818000,\n 0x3FF04949CDD12C90, 0xBF9228FB8CAA0000,\n 0x3FF038C6C6F0ADA9, 0xBF8C317B20F90000,\n 0x3FF02865137932A9, 0xBF8419355DAA0000,\n 0x3FF0182427EA7348, 0xBF781203C2EC0000,\n 0x3FF008040614B195, 0xBF60040979240000,\n 0x3FEFE01FF726FA1A, 0x3F6FEFF384900000,\n 0x3FEFA11CC261EA74, 0x3F87DC41353D0000,\n 0x3FEF6310B081992E, 0x3F93CEA3C4C28000,\n 0x3FEF25F63CEEADCD, 0x3F9B9FC114890000,\n 0x3FEEE9C8039113E7, 0x3FA1B0D8CE110000,\n 0x3FEEAE8078CBB1AB, 0x3FA58A5BD001C000,\n 0x3FEE741AA29D0C9B, 0x3FA95C8340D88000,\n 0x3FEE3A91830A99B5, 0x3FAD276AEF578000,\n 0x3FEE01E009609A56, 0x3FB07598E598C000,\n 0x3FEDCA01E577BB98, 0x3FB253F5E30D2000,\n 0x3FED92F20B7C9103, 0x3FB42EDD8B380000,\n 0x3FED5CAC66FB5CCE, 0x3FB606598757C000,\n 0x3FED272CAA5EDE9D, 0x3FB7DA76356A0000,\n 0x3FECF26E3E6B2CCD, 0x3FB9AB434E1C6000,\n 0x3FECBE6DA2A77902, 0x3FBB78C7BB0D6000,\n 0x3FEC8B266D37086D, 0x3FBD431332E72000,\n 0x3FEC5894BD5D5804, 0x3FBF0A3171DE6000,\n 0x3FEC26B533BB9F8C, 0x3FC067152B914000,\n 0x3FEBF583EEECE73F, 0x3FC147858292B000,\n 0x3FEBC4FD75DB96C1, 0x3FC2266ECDCA3000,\n 0x3FEB951E0C864A28, 0x3FC303D7A6C55000,\n 0x3FEB65E2C5EF3E2C, 0x3FC3DFC33C331000,\n 0x3FEB374867C9888B, 0x3FC4BA366B7A8000,\n 0x3FEB094B211D304A, 0x3FC5933928D1F000,\n 0x3FEADBE885F2EF7E, 0x3FC66ACD2418F000,\n 0x3FEAAF1D31603DA2, 0x3FC740F8EC669000,\n 0x3FEA82E63FD358A7, 0x3FC815C0F51AF000,\n 0x3FEA5740EF09738B, 0x3FC8E92954F68000,\n 0x3FEA2C2A90AB4B27, 0x3FC9BB3602F84000,\n 0x3FEA01A01393F2D1, 0x3FCA8BED1C2C0000,\n 0x3FE9D79F24DB3C1B, 0x3FCB5B515C01D000,\n 0x3FE9AE2505C7B190, 0x3FCC2967CCBCC000,\n 0x3FE9852EF297CE2F, 0x3FCCF635D5486000,\n 0x3FE95CBAEEA44B75, 0x3FCDC1BD3446C000,\n 0x3FE934C69DE74838, 0x3FCE8C01B8CFE000,\n 0x3FE90D4F2F6752E6, 0x3FCF5509C0179000,\n 0x3FE8E6528EFFD79D, 0x3FD00E6C121FB800,\n 0x3FE8BFCE9FCC007C, 0x3FD071B80E93D000,\n 0x3FE899C0DABEC30E, 0x3FD0D46B9E867000,\n 0x3FE87427AA2317FB, 0x3FD13687334BD000,\n 0x3FE84F00ACB39A08, 0x3FD1980D67234800,\n 0x3FE82A49E8653E55, 0x3FD1F8FFE0CC8000,\n 0x3FE8060195F40260, 0x3FD2595FD7636800,\n 0x3FE7E22563E0A329, 0x3FD2B9300914A800,\n 0x3FE7BEB377DCB5AD, 0x3FD3187210436000,\n 0x3FE79BAA679725C2, 0x3FD377266DEC1800,\n 0x3FE77907F2170657, 0x3FD3D54FFBAF3000,\n 0x3FE756CADBD6130C, 0x3FD432EEE32FE000\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const LOG_DATA_TAB2 = memory.data([\n // chi , clo\n 0x3FE61000014FB66B, 0x3C7E026C91425B3C,\n 0x3FE63000034DB495, 0x3C8DBFEA48005D41,\n 0x3FE650000D94D478, 0x3C8E7FA786D6A5B7,\n 0x3FE67000074E6FAD, 0x3C61FCEA6B54254C,\n 0x3FE68FFFFEDF0FAE, 0xBC7C7E274C590EFD,\n 0x3FE6B0000763C5BC, 0xBC8AC16848DCDA01,\n 0x3FE6D0001E5CC1F6, 0x3C833F1C9D499311,\n 0x3FE6EFFFEB05F63E, 0xBC7E80041AE22D53,\n 0x3FE710000E869780, 0x3C7BFF6671097952,\n 0x3FE72FFFFC67E912, 0x3C8C00E226BD8724,\n 0x3FE74FFFDF81116A, 0xBC6E02916EF101D2,\n 0x3FE770000F679C90, 0xBC67FC71CD549C74,\n 0x3FE78FFFFA7EC835, 0x3C81BEC19EF50483,\n 0x3FE7AFFFFE20C2E6, 0xBC707E1729CC6465,\n 0x3FE7CFFFED3FC900, 0xBC808072087B8B1C,\n 0x3FE7EFFFE9261A76, 0x3C8DC0286D9DF9AE,\n 0x3FE81000049CA3E8, 0x3C897FD251E54C33,\n 0x3FE8300017932C8F, 0xBC8AFEE9B630F381,\n 0x3FE850000633739C, 0x3C89BFBF6B6535BC,\n 0x3FE87000204289C6, 0xBC8BBF65F3117B75,\n 0x3FE88FFFEBF57904, 0xBC89006EA23DCB57,\n 0x3FE8B00022BC04DF, 0xBC7D00DF38E04B0A,\n 0x3FE8CFFFE50C1B8A, 0xBC88007146FF9F05,\n 0x3FE8EFFFFC918E43, 0x3C83817BD07A7038,\n 0x3FE910001EFA5FC7, 0x3C893E9176DFB403,\n 0x3FE9300013467BB9, 0x3C7F804E4B980276,\n 0x3FE94FFFE6EE076F, 0xBC8F7EF0D9FF622E,\n 0x3FE96FFFDE3C12D1, 0xBC7082AA962638BA,\n 0x3FE98FFFF4458A0D, 0xBC87801B9164A8EF,\n 0x3FE9AFFFDD982E3E, 0xBC8740E08A5A9337,\n 0x3FE9CFFFED49FB66, 0x3C3FCE08C19BE000,\n 0x3FE9F00020F19C51, 0xBC8A3FAA27885B0A,\n 0x3FEA10001145B006, 0x3C74FF489958DA56,\n 0x3FEA300007BBF6FA, 0x3C8CBEAB8A2B6D18,\n 0x3FEA500010971D79, 0x3C88FECADD787930,\n 0x3FEA70001DF52E48, 0xBC8F41763DD8ABDB,\n 0x3FEA90001C593352, 0xBC8EBF0284C27612,\n 0x3FEAB0002A4F3E4B, 0xBC69FD043CFF3F5F,\n 0x3FEACFFFD7AE1ED1, 0xBC823EE7129070B4,\n 0x3FEAEFFFEE510478, 0x3C6A063EE00EDEA3,\n 0x3FEB0FFFDB650D5B, 0x3C5A06C8381F0AB9,\n 0x3FEB2FFFFEAACA57, 0xBC79011E74233C1D,\n 0x3FEB4FFFD995BADC, 0xBC79FF1068862A9F,\n 0x3FEB7000249E659C, 0x3C8AFF45D0864F3E,\n 0x3FEB8FFFF9871640, 0x3C7CFE7796C2C3F9,\n 0x3FEBAFFFD204CB4F, 0xBC63FF27EEF22BC4,\n 0x3FEBCFFFD2415C45, 0xBC6CFFB7EE3BEA21,\n 0x3FEBEFFFF86309DF, 0xBC814103972E0B5C,\n 0x3FEC0FFFE1B57653, 0x3C8BC16494B76A19,\n 0x3FEC2FFFF1FA57E3, 0xBC64FEEF8D30C6ED,\n 0x3FEC4FFFDCBFE424, 0xBC843F68BCEC4775,\n 0x3FEC6FFFED54B9F7, 0x3C847EA3F053E0EC,\n 0x3FEC8FFFEB998FD5, 0x3C7383068DF992F1,\n 0x3FECB0002125219A, 0xBC68FD8E64180E04,\n 0x3FECCFFFDD94469C, 0x3C8E7EBE1CC7EA72,\n 0x3FECEFFFEAFDC476, 0x3C8EBE39AD9F88FE,\n 0x3FED1000169AF82B, 0x3C757D91A8B95A71,\n 0x3FED30000D0FF71D, 0x3C89C1906970C7DA,\n 0x3FED4FFFEA790FC4, 0xBC580E37C558FE0C,\n 0x3FED70002EDC87E5, 0xBC7F80D64DC10F44,\n 0x3FED900021DC82AA, 0xBC747C8F94FD5C5C,\n 0x3FEDAFFFD86B0283, 0x3C8C7F1DC521617E,\n 0x3FEDD000296C4739, 0x3C88019EB2FFB153,\n 0x3FEDEFFFE54490F5, 0x3C6E00D2C652CC89,\n 0x3FEE0FFFCDABF694, 0xBC7F8340202D69D2,\n 0x3FEE2FFFDB52C8DD, 0x3C7B00C1CA1B0864,\n 0x3FEE4FFFF24216EF, 0x3C72FFA8B094AB51,\n 0x3FEE6FFFE88A5E11, 0xBC57F673B1EFBE59,\n 0x3FEE9000119EFF0D, 0xBC84808D5E0BC801,\n 0x3FEEAFFFDFA51744, 0x3C780006D54320B5,\n 0x3FEED0001A127FA1, 0xBC5002F860565C92,\n 0x3FEEF00007BABCC4, 0xBC8540445D35E611,\n 0x3FEF0FFFF57A8D02, 0xBC4FFB3139EF9105,\n 0x3FEF30001EE58AC7, 0x3C8A81ACF2731155,\n 0x3FEF4FFFF5823494, 0x3C8A3F41D4D7C743,\n 0x3FEF6FFFFCA94C6B, 0xBC6202F41C987875,\n 0x3FEF8FFFE1F9C441, 0x3C777DD1F477E74B,\n 0x3FEFAFFFD2E0E37E, 0xBC6F01199A7CA331,\n 0x3FEFD0001C77E49E, 0x3C7181EE4BCEACB1,\n 0x3FEFEFFFF7E0C331, 0xBC6E05370170875A,\n 0x3FF00FFFF465606E, 0xBC8A7EAD491C0ADA,\n 0x3FF02FFFF3867A58, 0xBC977F69C3FCB2E0,\n 0x3FF04FFFFDFC0D17, 0x3C97BFFE34CB945B,\n 0x3FF0700003CD4D82, 0x3C820083C0E456CB,\n 0x3FF08FFFF9F2CBE8, 0xBC6DFFDFBE37751A,\n 0x3FF0B000010CDA65, 0xBC913F7FAEE626EB,\n 0x3FF0D00001A4D338, 0x3C807DFA79489FF7,\n 0x3FF0EFFFFADAFDFD, 0xBC77040570D66BC0,\n 0x3FF110000BBAFD96, 0x3C8E80D4846D0B62,\n 0x3FF12FFFFAE5F45D, 0x3C9DBFFA64FD36EF,\n 0x3FF150000DD59AD9, 0x3C9A0077701250AE,\n 0x3FF170000F21559A, 0x3C8DFDF9E2E3DEEE,\n 0x3FF18FFFFC275426, 0x3C910030DC3B7273,\n 0x3FF1B000123D3C59, 0x3C997F7980030188,\n 0x3FF1CFFFF8299EB7, 0xBC65F932AB9F8C67,\n 0x3FF1EFFFF48AD400, 0x3C937FBF9DA75BEB,\n 0x3FF210000C8B86A4, 0x3C9F806B91FD5B22,\n 0x3FF2300003854303, 0x3C93FFC2EB9FBF33,\n 0x3FF24FFFFFBCF684, 0x3C7601E77E2E2E72,\n 0x3FF26FFFF52921D9, 0x3C7FFCBB767F0C61,\n 0x3FF2900014933A3C, 0xBC7202CA3C02412B,\n 0x3FF2B00014556313, 0xBC92808233F21F02,\n 0x3FF2CFFFEBFE523B, 0xBC88FF7E384FDCF2,\n 0x3FF2F0000BB8AD96, 0xBC85FF51503041C5,\n 0x3FF30FFFFB7AE2AF, 0xBC810071885E289D,\n 0x3FF32FFFFEAC5F7F, 0xBC91FF5D3FB7B715,\n 0x3FF350000CA66756, 0x3C957F82228B82BD,\n 0x3FF3700011FBF721, 0x3C8000BAC40DD5CC,\n 0x3FF38FFFF9592FB9, 0xBC943F9D2DB2A751,\n 0x3FF3B00004DDD242, 0x3C857F6B707638E1,\n 0x3FF3CFFFF5B2C957, 0x3C7A023A10BF1231,\n 0x3FF3EFFFEAB0B418, 0x3C987F6D66B152B0,\n 0x3FF410001532AFF4, 0x3C67F8375F198524,\n 0x3FF4300017478B29, 0x3C8301E672DC5143,\n 0x3FF44FFFE795B463, 0x3C89FF69B8B2895A,\n 0x3FF46FFFE80475E0, 0xBC95C0B19BC2F254,\n 0x3FF48FFFEF6FC1E7, 0x3C9B4009F23A2A72,\n 0x3FF4AFFFE5BEA704, 0xBC94FFB7BF0D7D45,\n 0x3FF4D000171027DE, 0xBC99C06471DC6A3D,\n 0x3FF4F0000FF03EE2, 0x3C977F890B85531C,\n 0x3FF5100012DC4BD1, 0x3C6004657166A436,\n 0x3FF530001605277A, 0xBC96BFCECE233209,\n 0x3FF54FFFECDB704C, 0xBC8902720505A1D7,\n 0x3FF56FFFEF5F54A9, 0x3C9BBFE60EC96412,\n 0x3FF5900017E61012, 0x3C887EC581AFEF90,\n 0x3FF5B00003C93E92, 0xBC9F41080ABF0CC0,\n 0x3FF5D0001D4919BC, 0xBC98812AFB254729,\n 0x3FF5EFFFE7B87A89, 0xBC947EB780ED6904\n]);\n\n// @ts-ignore: decorator\n@inline\nexport function log_lut(x: f64): f64 {\n const N_MASK = (1 << LOG_TABLE_BITS) - 1;\n\n const\n B0 = reinterpret(0xBFE0000000000000), // -0x1p-1\n B1 = reinterpret(0x3FD5555555555577), // 0x1.5555555555577p-2\n B2 = reinterpret(0xBFCFFFFFFFFFFDCB), // -0x1.ffffffffffdcbp-3\n B3 = reinterpret(0x3FC999999995DD0C), // 0x1.999999995dd0cp-3\n B4 = reinterpret(0xBFC55555556745A7), // -0x1.55555556745a7p-3\n B5 = reinterpret(0x3FC24924A344DE30), // 0x1.24924a344de3p-3\n B6 = reinterpret(0xBFBFFFFFA4423D65), // -0x1.fffffa4423d65p-4\n B7 = reinterpret(0x3FBC7184282AD6CA), // 0x1.c7184282ad6cap-4\n B8 = reinterpret(0xBFB999EB43B068FF), // -0x1.999eb43b068ffp-4\n B9 = reinterpret(0x3FB78182F7AFD085), // 0x1.78182f7afd085p-4\n B10 = reinterpret(0xBFB5521375D145CD); // -0x1.5521375d145cdp-4\n\n const\n A0 = reinterpret(0xBFE0000000000001), // -0x1.0000000000001p-1\n A1 = reinterpret(0x3FD555555551305B), // 0x1.555555551305bp-2\n A2 = reinterpret(0xBFCFFFFFFFEB4590), // -0x1.fffffffeb459p-3\n A3 = reinterpret(0x3FC999B324F10111), // 0x1.999b324f10111p-3\n A4 = reinterpret(0xBFC55575E506C89F); // -0x1.55575e506c89fp-3\n\n const\n LO: u64 = 0x3FEE000000000000,\n HI: u64 = 0x3FF1090000000000;\n\n const\n Ln2hi = reinterpret(0x3FE62E42FEFA3800), // 0x1.62e42fefa3800p-1\n Ln2lo = reinterpret(0x3D2EF35793C76730), // 0x1.ef35793c76730p-45\n Ox1p27 = reinterpret(0x41A0000000000000), // 0x1p27\n Ox1p52 = reinterpret(0x4330000000000000); // 0x1p52\n\n let ix = reinterpret(x);\n if (ix - LO < HI - LO) {\n let r = x - 1.0;\n let r2 = r * r;\n let r3 = r2 * r;\n let y =\n r3 * (B1 + r * B2 + r2 * B3 +\n r3 * (B4 + r * B5 + r2 * B6 +\n r3 * (B7 + r * B8 + r2 * B9 + r3 * B10)));\n // Worst-case error is around 0.507 ULP\n let w = r * Ox1p27;\n let rhi = r + w - w;\n let rlo = r - rhi;\n w = rhi * rhi * B0; // B[0] == -0.5\n let hi = r + w;\n let lo = r - hi + w;\n lo += B0 * rlo * (rhi + r);\n return y + lo + hi;\n }\n let top = u32(ix >> 48);\n if (top - 0x0010 >= 0x7FF0 - 0x0010) {\n // x < 0x1p-1022 or inf or nan\n if ((ix << 1) == 0) return -1.0 / (x * x);\n if (ix == reinterpret(Infinity)) return x; // log(inf) == inf\n if ((top & 0x8000) || (top & 0x7FF0) == 0x7FF0) return (x - x) / (x - x);\n // x is subnormal, normalize it\n ix = reinterpret(x * Ox1p52);\n ix -= u64(52) << 52;\n }\n\n // x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ix - 0x3FE6000000000000;\n let i = ((tmp >> (52 - LOG_TABLE_BITS)) & N_MASK);\n let k = tmp >> 52;\n let iz = ix - (tmp & (u64(0xFFF) << 52));\n\n let invc = load(LOG_DATA_TAB1 + (i << (1 + alignof())), 0 << alignof()); // T[i].invc;\n let logc = load(LOG_DATA_TAB1 + (i << (1 + alignof())), 1 << alignof()); // T[i].logc;\n let z = reinterpret(iz);\n\n // log(x) = log1p(z/c-1) + log(c) + k*Ln2.\n // r ~= z/c - 1, |r| < 1/(2*N)\n // #if __FP_FAST_FMA\n // \t// rounding error: 0x1p-55/N\n // \tr = __builtin_fma(z, invc, -1.0);\n // #else\n // rounding error: 0x1p-55/N + 0x1p-66\n const chi = load(LOG_DATA_TAB2 + (i << (1 + alignof())), 0 << alignof()); // T2[i].chi\n const clo = load(LOG_DATA_TAB2 + (i << (1 + alignof())), 1 << alignof()); // T2[i].clo\n let r = (z - chi - clo) * invc;\n // #endif\n let kd = k;\n\n // hi + lo = r + log(c) + k*Ln2\n let w = kd * Ln2hi + logc;\n let hi = w + r;\n let lo = w - hi + r + kd * Ln2lo;\n\n // log(x) = lo + (log1p(r) - r) + hi\n let r2 = r * r; // rounding error: 0x1p-54/N^2\n // Worst case error if |y| > 0x1p-5:\n // 0.5 + 4.13/N + abs-poly-error*2^57 ULP (+ 0.002 ULP without fma)\n // Worst case error if |y| > 0x1p-4:\n // 0.5 + 2.06/N + abs-poly-error*2^56 ULP (+ 0.001 ULP without fma).\n return lo + r2 * A0 + r * r2 * (A1 + r * A2 + r2 * (A3 + r * A4)) + hi;\n}\n\n//\n// Lookup data for pow. See: https://git.musl-libc.org/cgit/musl/tree/src/math/pow.c\n//\n\n// @ts-ignore: decorator\n@inline const POW_LOG_TABLE_BITS = 7;\n\n/* Algorithm:\n\n x = 2^k z\n log(x) = k ln2 + log(c) + log(z/c)\n log(z/c) = poly(z/c - 1)\n\nwhere z is in [0x1.69555p-1; 0x1.69555p0] which is split into N subintervals\nand z falls into the ith one, then table entries are computed as\n\n tab[i].invc = 1/c\n tab[i].logc = round(0x1p43*log(c))/0x1p43\n tab[i].logctail = (double)(log(c) - logc)\n\nwhere c is chosen near the center of the subinterval such that 1/c has only a\nfew precision bits so z/c - 1 is exactly representible as double:\n\n 1/c = center < 1 ? round(N/center)/N : round(2*N/center)/N/2\n\nNote: |z/c - 1| < 1/N for the chosen c, |log(c) - logc - logctail| < 0x1p-97,\nthe last few bits of logc are rounded away so k*ln2hi + logc has no rounding\nerror and the interval for z is selected such that near x == 1, where log(x)\nis tiny, large cancellation error is avoided in logc + poly(z/c - 1). */\n\n// @ts-ignore: decorator\n@lazy @inline const POW_LOG_DATA_TAB = memory.data([\n // invc ,pad, logc , logctail\n 0x3FF6A00000000000, 0, 0xBFD62C82F2B9C800, 0x3CFAB42428375680,\n 0x3FF6800000000000, 0, 0xBFD5D1BDBF580800, 0xBD1CA508D8E0F720,\n 0x3FF6600000000000, 0, 0xBFD5767717455800, 0xBD2362A4D5B6506D,\n 0x3FF6400000000000, 0, 0xBFD51AAD872DF800, 0xBCE684E49EB067D5,\n 0x3FF6200000000000, 0, 0xBFD4BE5F95777800, 0xBD041B6993293EE0,\n 0x3FF6000000000000, 0, 0xBFD4618BC21C6000, 0x3D13D82F484C84CC,\n 0x3FF5E00000000000, 0, 0xBFD404308686A800, 0x3CDC42F3ED820B3A,\n 0x3FF5C00000000000, 0, 0xBFD3A64C55694800, 0x3D20B1C686519460,\n 0x3FF5A00000000000, 0, 0xBFD347DD9A988000, 0x3D25594DD4C58092,\n 0x3FF5800000000000, 0, 0xBFD2E8E2BAE12000, 0x3D267B1E99B72BD8,\n 0x3FF5600000000000, 0, 0xBFD2895A13DE8800, 0x3D15CA14B6CFB03F,\n 0x3FF5600000000000, 0, 0xBFD2895A13DE8800, 0x3D15CA14B6CFB03F,\n 0x3FF5400000000000, 0, 0xBFD22941FBCF7800, 0xBD165A242853DA76,\n 0x3FF5200000000000, 0, 0xBFD1C898C1699800, 0xBD1FAFBC68E75404,\n 0x3FF5000000000000, 0, 0xBFD1675CABABA800, 0x3D1F1FC63382A8F0,\n 0x3FF4E00000000000, 0, 0xBFD1058BF9AE4800, 0xBD26A8C4FD055A66,\n 0x3FF4C00000000000, 0, 0xBFD0A324E2739000, 0xBD0C6BEE7EF4030E,\n 0x3FF4A00000000000, 0, 0xBFD0402594B4D000, 0xBCF036B89EF42D7F,\n 0x3FF4A00000000000, 0, 0xBFD0402594B4D000, 0xBCF036B89EF42D7F,\n 0x3FF4800000000000, 0, 0xBFCFB9186D5E4000, 0x3D0D572AAB993C87,\n 0x3FF4600000000000, 0, 0xBFCEF0ADCBDC6000, 0x3D2B26B79C86AF24,\n 0x3FF4400000000000, 0, 0xBFCE27076E2AF000, 0xBD172F4F543FFF10,\n 0x3FF4200000000000, 0, 0xBFCD5C216B4FC000, 0x3D21BA91BBCA681B,\n 0x3FF4000000000000, 0, 0xBFCC8FF7C79AA000, 0x3D27794F689F8434,\n 0x3FF4000000000000, 0, 0xBFCC8FF7C79AA000, 0x3D27794F689F8434,\n 0x3FF3E00000000000, 0, 0xBFCBC286742D9000, 0x3D194EB0318BB78F,\n 0x3FF3C00000000000, 0, 0xBFCAF3C94E80C000, 0x3CBA4E633FCD9066,\n 0x3FF3A00000000000, 0, 0xBFCA23BC1FE2B000, 0xBD258C64DC46C1EA,\n 0x3FF3A00000000000, 0, 0xBFCA23BC1FE2B000, 0xBD258C64DC46C1EA,\n 0x3FF3800000000000, 0, 0xBFC9525A9CF45000, 0xBD2AD1D904C1D4E3,\n 0x3FF3600000000000, 0, 0xBFC87FA06520D000, 0x3D2BBDBF7FDBFA09,\n 0x3FF3400000000000, 0, 0xBFC7AB890210E000, 0x3D2BDB9072534A58,\n 0x3FF3400000000000, 0, 0xBFC7AB890210E000, 0x3D2BDB9072534A58,\n 0x3FF3200000000000, 0, 0xBFC6D60FE719D000, 0xBD10E46AA3B2E266,\n 0x3FF3000000000000, 0, 0xBFC5FF3070A79000, 0xBD1E9E439F105039,\n 0x3FF3000000000000, 0, 0xBFC5FF3070A79000, 0xBD1E9E439F105039,\n 0x3FF2E00000000000, 0, 0xBFC526E5E3A1B000, 0xBD20DE8B90075B8F,\n 0x3FF2C00000000000, 0, 0xBFC44D2B6CCB8000, 0x3D170CC16135783C,\n 0x3FF2C00000000000, 0, 0xBFC44D2B6CCB8000, 0x3D170CC16135783C,\n 0x3FF2A00000000000, 0, 0xBFC371FC201E9000, 0x3CF178864D27543A,\n 0x3FF2800000000000, 0, 0xBFC29552F81FF000, 0xBD248D301771C408,\n 0x3FF2600000000000, 0, 0xBFC1B72AD52F6000, 0xBD2E80A41811A396,\n 0x3FF2600000000000, 0, 0xBFC1B72AD52F6000, 0xBD2E80A41811A396,\n 0x3FF2400000000000, 0, 0xBFC0D77E7CD09000, 0x3D0A699688E85BF4,\n 0x3FF2400000000000, 0, 0xBFC0D77E7CD09000, 0x3D0A699688E85BF4,\n 0x3FF2200000000000, 0, 0xBFBFEC9131DBE000, 0xBD2575545CA333F2,\n 0x3FF2000000000000, 0, 0xBFBE27076E2B0000, 0x3D2A342C2AF0003C,\n 0x3FF2000000000000, 0, 0xBFBE27076E2B0000, 0x3D2A342C2AF0003C,\n 0x3FF1E00000000000, 0, 0xBFBC5E548F5BC000, 0xBD1D0C57585FBE06,\n 0x3FF1C00000000000, 0, 0xBFBA926D3A4AE000, 0x3D253935E85BAAC8,\n 0x3FF1C00000000000, 0, 0xBFBA926D3A4AE000, 0x3D253935E85BAAC8,\n 0x3FF1A00000000000, 0, 0xBFB8C345D631A000, 0x3D137C294D2F5668,\n 0x3FF1A00000000000, 0, 0xBFB8C345D631A000, 0x3D137C294D2F5668,\n 0x3FF1800000000000, 0, 0xBFB6F0D28AE56000, 0xBD269737C93373DA,\n 0x3FF1600000000000, 0, 0xBFB51B073F062000, 0x3D1F025B61C65E57,\n 0x3FF1600000000000, 0, 0xBFB51B073F062000, 0x3D1F025B61C65E57,\n 0x3FF1400000000000, 0, 0xBFB341D7961BE000, 0x3D2C5EDACCF913DF,\n 0x3FF1400000000000, 0, 0xBFB341D7961BE000, 0x3D2C5EDACCF913DF,\n 0x3FF1200000000000, 0, 0xBFB16536EEA38000, 0x3D147C5E768FA309,\n 0x3FF1000000000000, 0, 0xBFAF0A30C0118000, 0x3D2D599E83368E91,\n 0x3FF1000000000000, 0, 0xBFAF0A30C0118000, 0x3D2D599E83368E91,\n 0x3FF0E00000000000, 0, 0xBFAB42DD71198000, 0x3D1C827AE5D6704C,\n 0x3FF0E00000000000, 0, 0xBFAB42DD71198000, 0x3D1C827AE5D6704C,\n 0x3FF0C00000000000, 0, 0xBFA77458F632C000, 0xBD2CFC4634F2A1EE,\n 0x3FF0C00000000000, 0, 0xBFA77458F632C000, 0xBD2CFC4634F2A1EE,\n 0x3FF0A00000000000, 0, 0xBFA39E87B9FEC000, 0x3CF502B7F526FEAA,\n 0x3FF0A00000000000, 0, 0xBFA39E87B9FEC000, 0x3CF502B7F526FEAA,\n 0x3FF0800000000000, 0, 0xBF9F829B0E780000, 0xBD2980267C7E09E4,\n 0x3FF0800000000000, 0, 0xBF9F829B0E780000, 0xBD2980267C7E09E4,\n 0x3FF0600000000000, 0, 0xBF97B91B07D58000, 0xBD288D5493FAA639,\n 0x3FF0400000000000, 0, 0xBF8FC0A8B0FC0000, 0xBCDF1E7CF6D3A69C,\n 0x3FF0400000000000, 0, 0xBF8FC0A8B0FC0000, 0xBCDF1E7CF6D3A69C,\n 0x3FF0200000000000, 0, 0xBF7FE02A6B100000, 0xBD19E23F0DDA40E4,\n 0x3FF0200000000000, 0, 0xBF7FE02A6B100000, 0xBD19E23F0DDA40E4,\n 0x3FF0000000000000, 0, 0, 0,\n 0x3FF0000000000000, 0, 0, 0,\n 0x3FEFC00000000000, 0, 0x3F80101575890000, 0xBD10C76B999D2BE8,\n 0x3FEF800000000000, 0, 0x3F90205658938000, 0xBD23DC5B06E2F7D2,\n 0x3FEF400000000000, 0, 0x3F98492528C90000, 0xBD2AA0BA325A0C34,\n 0x3FEF000000000000, 0, 0x3FA0415D89E74000, 0x3D0111C05CF1D753,\n 0x3FEEC00000000000, 0, 0x3FA466AED42E0000, 0xBD2C167375BDFD28,\n 0x3FEE800000000000, 0, 0x3FA894AA149FC000, 0xBD197995D05A267D,\n 0x3FEE400000000000, 0, 0x3FACCB73CDDDC000, 0xBD1A68F247D82807,\n 0x3FEE200000000000, 0, 0x3FAEEA31C006C000, 0xBD0E113E4FC93B7B,\n 0x3FEDE00000000000, 0, 0x3FB1973BD1466000, 0xBD25325D560D9E9B,\n 0x3FEDA00000000000, 0, 0x3FB3BDF5A7D1E000, 0x3D2CC85EA5DB4ED7,\n 0x3FED600000000000, 0, 0x3FB5E95A4D97A000, 0xBD2C69063C5D1D1E,\n 0x3FED400000000000, 0, 0x3FB700D30AEAC000, 0x3CEC1E8DA99DED32,\n 0x3FED000000000000, 0, 0x3FB9335E5D594000, 0x3D23115C3ABD47DA,\n 0x3FECC00000000000, 0, 0x3FBB6AC88DAD6000, 0xBD1390802BF768E5,\n 0x3FECA00000000000, 0, 0x3FBC885801BC4000, 0x3D2646D1C65AACD3,\n 0x3FEC600000000000, 0, 0x3FBEC739830A2000, 0xBD2DC068AFE645E0,\n 0x3FEC400000000000, 0, 0x3FBFE89139DBE000, 0xBD2534D64FA10AFD,\n 0x3FEC000000000000, 0, 0x3FC1178E8227E000, 0x3D21EF78CE2D07F2,\n 0x3FEBE00000000000, 0, 0x3FC1AA2B7E23F000, 0x3D2CA78E44389934,\n 0x3FEBA00000000000, 0, 0x3FC2D1610C868000, 0x3D039D6CCB81B4A1,\n 0x3FEB800000000000, 0, 0x3FC365FCB0159000, 0x3CC62FA8234B7289,\n 0x3FEB400000000000, 0, 0x3FC4913D8333B000, 0x3D25837954FDB678,\n 0x3FEB200000000000, 0, 0x3FC527E5E4A1B000, 0x3D2633E8E5697DC7,\n 0x3FEAE00000000000, 0, 0x3FC6574EBE8C1000, 0x3D19CF8B2C3C2E78,\n 0x3FEAC00000000000, 0, 0x3FC6F0128B757000, 0xBD25118DE59C21E1,\n 0x3FEAA00000000000, 0, 0x3FC7898D85445000, 0xBD1C661070914305,\n 0x3FEA600000000000, 0, 0x3FC8BEAFEB390000, 0xBD073D54AAE92CD1,\n 0x3FEA400000000000, 0, 0x3FC95A5ADCF70000, 0x3D07F22858A0FF6F,\n 0x3FEA000000000000, 0, 0x3FCA93ED3C8AE000, 0xBD28724350562169,\n 0x3FE9E00000000000, 0, 0x3FCB31D8575BD000, 0xBD0C358D4EACE1AA,\n 0x3FE9C00000000000, 0, 0x3FCBD087383BE000, 0xBD2D4BC4595412B6,\n 0x3FE9A00000000000, 0, 0x3FCC6FFBC6F01000, 0xBCF1EC72C5962BD2,\n 0x3FE9600000000000, 0, 0x3FCDB13DB0D49000, 0xBD2AFF2AF715B035,\n 0x3FE9400000000000, 0, 0x3FCE530EFFE71000, 0x3CC212276041F430,\n 0x3FE9200000000000, 0, 0x3FCEF5ADE4DD0000, 0xBCCA211565BB8E11,\n 0x3FE9000000000000, 0, 0x3FCF991C6CB3B000, 0x3D1BCBECCA0CDF30,\n 0x3FE8C00000000000, 0, 0x3FD07138604D5800, 0x3CF89CDB16ED4E91,\n 0x3FE8A00000000000, 0, 0x3FD0C42D67616000, 0x3D27188B163CEAE9,\n 0x3FE8800000000000, 0, 0x3FD1178E8227E800, 0xBD2C210E63A5F01C,\n 0x3FE8600000000000, 0, 0x3FD16B5CCBACF800, 0x3D2B9ACDF7A51681,\n 0x3FE8400000000000, 0, 0x3FD1BF99635A6800, 0x3D2CA6ED5147BDB7,\n 0x3FE8200000000000, 0, 0x3FD214456D0EB800, 0x3D0A87DEBA46BAEA,\n 0x3FE7E00000000000, 0, 0x3FD2BEF07CDC9000, 0x3D2A9CFA4A5004F4,\n 0x3FE7C00000000000, 0, 0x3FD314F1E1D36000, 0xBD28E27AD3213CB8,\n 0x3FE7A00000000000, 0, 0x3FD36B6776BE1000, 0x3D116ECDB0F177C8,\n 0x3FE7800000000000, 0, 0x3FD3C25277333000, 0x3D183B54B606BD5C,\n 0x3FE7600000000000, 0, 0x3FD419B423D5E800, 0x3D08E436EC90E09D,\n 0x3FE7400000000000, 0, 0x3FD4718DC271C800, 0xBD2F27CE0967D675,\n 0x3FE7200000000000, 0, 0x3FD4C9E09E173000, 0xBD2E20891B0AD8A4,\n 0x3FE7000000000000, 0, 0x3FD522AE0738A000, 0x3D2EBE708164C759,\n 0x3FE6E00000000000, 0, 0x3FD57BF753C8D000, 0x3D1FADEDEE5D40EF,\n 0x3FE6C00000000000, 0, 0x3FD5D5BDDF596000, 0xBD0A0B2A08A465DC\n]);\n\n// Returns 0 if not int, 1 if odd int, 2 if even int. The argument is\n// the bit representation of a non-zero finite floating-point value.\n// @ts-ignore: decorator\n@inline\nfunction checkint(iy: u64): i32 {\n let e = iy >> 52 & 0x7FF;\n if (e < 0x3FF ) return 0;\n if (e > 0x3FF + 52) return 2;\n e = u64(1) << (0x3FF + 52 - e);\n if (iy & (e - 1)) return 0;\n if (iy & e ) return 1;\n return 2;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction xflow(sign: u32, y: f64): f64 {\n return select(-y, y, sign) * y;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction uflow(sign: u32): f64 {\n return xflow(sign, reinterpret(0x1000000000000000)); // 0x1p-767\n}\n\n// @ts-ignore: decorator\n@inline\nfunction oflow(sign: u32): f64 {\n return xflow(sign, reinterpret(0x7000000000000000)); // 0x1p769\n}\n\n// Returns 1 if input is the bit representation of 0, infinity or nan.\n// @ts-ignore: decorator\n@inline\nfunction zeroinfnan(u: u64): bool {\n return (u << 1) - 1 >= 0xFFE0000000000000 - 1;\n}\n\n// @ts-ignore: decorator\n@lazy let log_tail: f64 = 0;\n\n// Compute y+TAIL = log(x) where the rounded result is y and TAIL has about\n// additional 15 bits precision. IX is the bit representation of x, but\n// normalized in the subnormal range using the sign bit for the exponent.\n// @ts-ignore: decorator\n@inline\nfunction log_inline(ix: u64): f64 {\n const N = 1 << POW_LOG_TABLE_BITS;\n const N_MASK = N - 1;\n\n const\n Ln2hi = reinterpret(0x3FE62E42FEFA3800),\n Ln2lo = reinterpret(0x3D2EF35793C76730);\n\n const\n A0 = reinterpret(0xBFE0000000000000),\n A1 = reinterpret(0xBFE5555555555560),\n A2 = reinterpret(0x3FE0000000000006),\n A3 = reinterpret(0x3FE999999959554E),\n A4 = reinterpret(0xBFE555555529A47A),\n A5 = reinterpret(0xBFF2495B9B4845E9),\n A6 = reinterpret(0x3FF0002B8B263FC3);\n\n // x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ix - 0x3fE6955500000000;\n let i = usize((tmp >> (52 - POW_LOG_TABLE_BITS)) & N_MASK);\n let k = tmp >> 52;\n let iz = ix - (tmp & u64(0xFFF) << 52);\n let z = reinterpret(iz);\n let kd = k;\n\n // log(x) = k*Ln2 + log(c) + log1p(z/c-1).\n let invc = load(POW_LOG_DATA_TAB + (i << (2 + alignof())), 0 << alignof()); // tab[i].invc\n let logc = load(POW_LOG_DATA_TAB + (i << (2 + alignof())), 2 << alignof()); // tab[i].logc\n let logctail = load(POW_LOG_DATA_TAB + (i << (2 + alignof())), 3 << alignof()); // tab[i].logctail\n\n // Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and\n // |z/c - 1| < 1/N, so r = z/c - 1 is exactly representible.\n // Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|.\n let zhi = reinterpret((iz + u64(0x80000000)) & 0xFFFFFFFF00000000);\n let zlo = z - zhi;\n let rhi = zhi * invc - 1.0;\n let rlo = zlo * invc;\n let r = rhi + rlo;\n\n // k * Ln2 + log(c) + r.\n let t1 = kd * Ln2hi + logc;\n let t2 = t1 + r;\n let lo1 = kd * Ln2lo + logctail;\n let lo2 = t1 - t2 + r;\n\n // Evaluation is optimized assuming superscalar pipelined execution.\n let ar = A0 * r; // A[0] = -0.5\n let ar2 = r * ar;\n let ar3 = r * ar2;\n // k * Ln2 + log(c) + r + A[0] * r * r.\n let arhi = A0 * rhi;\n let arhi2 = rhi * arhi;\n let hi = t2 + arhi2;\n let lo3 = rlo * (ar + arhi);\n let lo4 = t2 - hi + arhi2;\n\n // p = log1p(r) - r - A[0] * r * r.\n let p = ar3 * (A1 + r * A2 + ar2 * (A3 + r * A4 + ar2 * (A5 + r * A6)));\n let lo = lo1 + lo2 + lo3 + lo4 + p;\n let y = hi + lo;\n log_tail = hi - y + lo;\n\n return y;\n}\n\n// @ts-ignore: decorator\n@inline const SIGN_BIAS = 0x800 << EXP_TABLE_BITS;\n\n// Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|.\n// The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1.\n// @ts-ignore: decorator\n@inline\nfunction exp_inline(x: f64, xtail: f64, sign_bias: u32): f64 {\n const N = 1 << EXP_TABLE_BITS;\n const N_MASK = N - 1;\n\n const\n InvLn2N = reinterpret(0x3FF71547652B82FE) * N, // 0x1.71547652b82fep0\n NegLn2hiN = reinterpret(0xBF762E42FEFA0000), // -0x1.62e42fefa0000p-8\n NegLn2loN = reinterpret(0xBD0CF79ABC9E3B3A), // -0x1.cf79abc9e3b3ap-47\n shift = reinterpret(0x4338000000000000); // 0x1.8p52\n\n const\n C2 = reinterpret(0x3FDFFFFFFFFFFDBD), // __exp_data.poly[0] (0x1.ffffffffffdbdp-2)\n C3 = reinterpret(0x3FC555555555543C), // __exp_data.poly[1] (0x1.555555555543cp-3)\n C4 = reinterpret(0x3FA55555CF172B91), // __exp_data.poly[2] (0x1.55555cf172b91p-5)\n C5 = reinterpret(0x3F81111167A4D017); // __exp_data.poly[3] (0x1.1111167a4d017p-7)\n\n let abstop: u32;\n let ki: u64, top: u64, sbits: u64;\n let idx: usize;\n // double_t for better performance on targets with FLT_EVAL_METHOD==2.\n let kd: f64, z: f64, r: f64, r2: f64, scale: f64, tail: f64, tmp: f64;\n\n let ux = reinterpret(x);\n abstop = u32(ux >> 52) & 0x7FF;\n if (abstop - 0x3C9 >= 0x03F) {\n if (abstop - 0x3C9 >= 0x80000000) {\n // Avoid spurious underflow for tiny x.\n // Note: 0 is common input.\n return select(-1.0, 1.0, sign_bias);\n }\n if (abstop >= 0x409) { // top12(1024.0)\n // Note: inf and nan are already handled.\n return ux < 0\n ? uflow(sign_bias)\n : oflow(sign_bias);\n }\n // Large x is special cased below.\n abstop = 0;\n }\n\n // exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)].\n // x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N].\n z = InvLn2N * x;\n\n // #if TOINT_INTRINSICS\n // kd = roundtoint(z);\n // ki = converttoint(z);\n // #elif EXP_USE_TOINT_NARROW\n // // z - kd is in [-0.5-2^-16, 0.5] in all rounding modes.\n // kd = eval_as_double(z + shift);\n // ki = asuint64(kd) >> 16;\n // kd = (double_t)(int32_t)ki;\n // #else\n // z - kd is in [-1, 1] in non-nearest rounding modes\n kd = z + shift;\n ki = reinterpret(kd);\n kd -= shift;\n // #endif\n r = x + kd * NegLn2hiN + kd * NegLn2loN;\n // The code assumes 2^-200 < |xtail| < 2^-8/N\n r += xtail;\n // 2^(k/N) ~= scale * (1 + tail)\n idx = usize((ki & N_MASK) << 1);\n top = (ki + sign_bias) << (52 - EXP_TABLE_BITS);\n\n tail = reinterpret(load(EXP_DATA_TAB + (idx << alignof())));\n // This is only a valid scale when -1023*N < k < 1024*N\n sbits = load(EXP_DATA_TAB + (idx << alignof()), 1 << alignof()) + top;\n // exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1).\n // Evaluation is optimized assuming superscalar pipelined execution.\n r2 = r * r;\n // Without fma the worst case error is 0.25/N ulp larger.\n // Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp\n tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n if (abstop == 0) return specialcase(tmp, sbits, ki);\n scale = reinterpret(sbits);\n // Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there\n // is no spurious underflow here even without fma.\n return scale + scale * tmp;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function pow_lut(x: f64, y: f64): f64 {\n const Ox1p52 = reinterpret(0x4330000000000000); // 0x1p52\n\n let sign_bias: u32 = 0;\n let ix = reinterpret(x);\n let iy = reinterpret(y);\n let topx = ix >> 52;\n let topy = iy >> 52;\n\n if (topx - 0x001 >= 0x7FF - 0x001 || (topy & 0x7FF) - 0x3BE >= 0x43e - 0x3BE) {\n // Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0\n // and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1.\n // Special cases: (x < 0x1p-126 or inf or nan) or\n // (|y| < 0x1p-65 or |y| >= 0x1p63 or nan).\n if (zeroinfnan(iy)) {\n if ((iy << 1) == 0) return 1.0;\n if (ix == 0x3FF0000000000000) return NaN; // original: 1.0\n if ((ix << 1) > 0xFFE0000000000000 || (iy << 1) > 0xFFE0000000000000) return x + y;\n if ((ix << 1) == 0x7FE0000000000000) return NaN; // original: 1.0\n if (((ix << 1) < 0x7FE0000000000000) == !(iy >> 63)) return 0; // |x|<1 && y==inf or |x|>1 && y==-inf.\n return y * y;\n }\n if (zeroinfnan(ix)) {\n let x2 = x * x;\n if (i32(ix >> 63) && checkint(iy) == 1) x2 = -x2;\n return iy < 0 ? 1 / x2 : x2;\n }\n // Here x and y are non-zero finite\n if (ix < 0) {\n // Finite x < 0\n let yint = checkint(iy);\n if (yint == 0) return (x - x) / (x - x);\n if (yint == 1) sign_bias = SIGN_BIAS;\n ix &= 0x7FFFFFFFFFFFFFFF;\n topx &= 0x7FF;\n }\n if ((topy & 0x7FF) - 0x3BE >= 0x43E - 0x3BE) {\n // Note: sign_bias == 0 here because y is not odd.\n if (ix == 0x3FF0000000000000) return 1;\n if ((topy & 0x7FF) < 0x3BE) return 1; // |y| < 2^-65, x^y ~= 1 + y*log(x).\n return (ix > 0x3FF0000000000000) == (topy < 0x800) ? Infinity : 0;\n }\n if (topx == 0) {\n // Normalize subnormal x so exponent becomes negative.\n ix = reinterpret(x * Ox1p52);\n ix &= 0x7FFFFFFFFFFFFFFF;\n ix -= u64(52) << 52;\n }\n }\n\n let hi = log_inline(ix);\n let lo = log_tail;\n let ehi: f64, elo: f64;\n // #if __FP_FAST_FMA\n // ehi = y * hi;\n // elo = y * lo + __builtin_fma(y, hi, -ehi);\n // #else\n let yhi = reinterpret(iy & 0xFFFFFFFFF8000000);\n let ylo = y - yhi;\n let lhi = reinterpret(reinterpret(hi) & 0xFFFFFFFFF8000000);\n let llo = hi - lhi + lo;\n ehi = yhi * lhi;\n elo = ylo * lhi + y * llo; // |elo| < |ehi| * 2^-25.\n // #endif\n return exp_inline(ehi, elo, sign_bias);\n}\n","import {\n itoa32,\n utoa32,\n itoa64,\n utoa64,\n dtoa,\n itoa_buffered,\n dtoa_buffered,\n MAX_DOUBLE_LENGTH\n} from \"./number\";\n\nimport {\n ipow32\n} from \"../math\";\n\n// All tables are stored as two staged lookup tables (static tries)\n// because the full range of Unicode symbols can't be efficiently\n// represented as-is in memory (see Unicode spec ch 5, p.196):\n// https://www.unicode.org/versions/Unicode12.0.0/ch05.pdf\n// Tables have been generated using these forked musl tools:\n// https://github.com/MaxGraey/musl-chartable-tools/tree/case-ignorable\n\n// Lookup table to check if a character is alphanumeric or not\n// See: https://git.musl-libc.org/cgit/musl/tree/src/ctype/alpha.h\n// size: 3904 bytes\n// @ts-ignore\n@inline @lazy const ALPHA_TABLE = memory.data([\n 18,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40,\n 41,42,43,44,17,45,46,47,16,16,48,16,16,16,16,16,16,16,49,50,51,16,52,53,16,16,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,54,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,55,17,17,17,17,56,17,57,58,59,60,61,62,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,63,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,64,65,17,66,67,\n 68,69,70,71,72,73,74,17,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,\n 93,94,16,95,96,97,98,17,17,17,99,100,101,16,16,16,16,16,16,16,16,16,16,17,17,\n 17,17,102,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,103,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,17,17,104,105,16,16,106,107,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,108,17,17,17,17,109,110,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 17,111,112,16,16,16,16,16,16,16,16,16,113,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,114,115,116,117,16,16,16,16,16,16,16,16,118,\n 119,120,16,16,16,16,16,121,122,16,16,16,16,123,16,16,124,16,16,16,16,16,16,16,\n 16,16,125,16,16,16,\n 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,254,255,255,7,254,\n 255,255,7,0,0,0,0,0,4,32,4,255,255,127,255,255,255,127,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,195,255,3,0,31,80,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,223,188,64,215,255,255,\n 251,255,255,255,255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,3,252,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,127,2,255,255,255,\n 255,255,1,0,0,0,0,255,191,182,0,255,255,255,135,7,0,0,0,255,7,255,255,255,255,\n 255,255,255,254,255,195,255,255,255,255,255,255,255,255,255,255,255,255,239,\n 31,254,225,255,\n 159,0,0,255,255,255,255,255,255,0,224,255,255,255,255,255,255,255,255,255,255,\n 255,255,3,0,255,255,255,255,255,7,48,4,255,255,255,252,255,31,0,0,255,255,255,\n 1,255,7,0,0,0,0,0,0,255,255,223,255,255,0,240,255,248,3,255,255,255,255,255,\n 255,255,255,255,239,255,223,225,255,207,255,254,255,239,159,249,255,255,253,\n 197,227,159,89,128,176,207,255,3,16,238,135,249,255,255,253,109,195,135,25,2,\n 94,192,255,63,0,238,191,251,255,255,253,237,227,191,27,1,0,207,255,0,30,238,\n 159,249,255,255,253,237,227,159,25,192,176,207,255,2,0,236,199,61,214,24,199,\n 255,195,199,29,129,0,192,255,0,0,239,223,253,255,255,253,255,227,223,29,96,7,\n 207,255,0,0,239,223,253,255,255,253,239,227,223,29,96,64,207,255,6,0,255,223,\n 253,255,255,255,255,231,223,93,240,128,207,255,0,252,238,255,127,252,255,255,\n 251,47,127,128,95,255,192,255,12,0,254,255,255,255,255,127,255,7,63,32,255,3,\n 0,0,0,0,214,247,255,255,175,255,255,59,95,32,255,243,0,0,0,\n 0,1,0,0,0,255,3,0,0,255,254,255,255,255,31,254,255,3,255,255,254,255,255,255,\n 31,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,249,255,3,255,255,255,255,255,\n 255,255,255,255,63,255,255,255,255,191,32,255,255,255,255,255,247,255,255,255,\n 255,255,255,255,255,255,61,127,61,255,255,255,255,255,61,255,255,255,255,61,\n 127,61,255,127,255,255,255,255,255,255,255,61,255,255,255,255,255,255,255,255,\n 7,0,0,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,63,63,254,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,159,255,255,254,255,255,7,255,255,255,255,255,255,255,255,\n 255,199,255,1,255,223,15,0,255,255,15,0,255,255,15,0,255,223,13,0,255,255,255,\n 255,255,255,207,255,255,1,128,16,255,3,0,0,0,0,255,3,255,255,255,255,255,255,\n 255,255,255,255,255,1,255,255,255,255,255,7,255,255,255,255,255,255,255,255,\n 63,\n 0,255,255,255,127,255,15,255,1,192,255,255,255,255,63,31,0,255,255,255,255,\n 255,15,255,255,255,3,255,3,0,0,0,0,255,255,255,15,255,255,255,255,255,255,255,\n 127,254,255,31,0,255,3,255,3,128,0,0,128,1,0,0,0,0,0,0,0,255,255,255,255,255,\n 255,239,255,239,15,255,3,0,0,0,0,255,255,255,255,255,243,255,255,255,255,255,\n 255,191,255,3,0,255,255,255,255,255,255,127,0,255,227,255,255,255,255,255,63,\n 255,1,255,255,255,255,255,231,0,0,0,0,0,222,111,4,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,\n 128,255,31,0,255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,255,\n 255,255,255,255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,2,128,0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,132,252,47,62,80,189,255,243,\n 224,67,0,0,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,\n 0,255,255,255,255,255,127,255,255,255,255,255,127,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,31,120,12,0,255,255,255,255,191,32,255,\n 255,255,255,255,255,255,128,0,0,255,255,127,0,127,127,127,127,127,127,127,127,\n 255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,224,0,0,0,254,3,62,31,254,255,255,255,255,255,255,255,255,255,127,224,254,\n 255,255,255,255,255,255,255,255,255,255,247,224,255,255,255,255,255,254,255,\n 255,255,255,255,255,255,255,255,255,127,0,0,255,255,255,255,0,0,0,0,0,0,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,\n 31,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,\n 0,0,0,0,0,0,255,255,255,255,255,63,255,31,255,255,255,15,0,0,255,255,255,255,\n 255,127,240,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,\n 0,128,255,252,255,255,255,255,255,255,255,255,255,255,255,255,249,255,255,255,\n 255,255,255,252,7,0,0,0,0,224,255,191,255,255,255,255,0,0,0,255,255,255,255,\n 255,255,15,0,255,255,255,255,255,255,255,255,47,0,255,3,0,0,252,232,255,255,\n 255,255,255,7,255,255,255,255,7,0,255,255,255,31,255,255,255,255,255,255,247,\n 255,0,128,255,3,255,255,255,127,255,255,255,255,255,255,127,0,255,63,255,3,\n 255,255,127,252,255,255,255,255,255,255,255,127,5,0,0,56,255,255,60,0,126,126,\n 126,0,127,127,255,255,255,255,255,247,255,3,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,7,255,3,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,15,0,255,255,127,248,255,255,255,255,\n 255,\n 15,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,3,0,0,0,0,127,0,248,224,255,253,127,95,219,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,248,255,255,255,\n 255,255,255,255,255,255,255,255,255,63,0,0,255,255,255,255,255,255,255,255,\n 252,255,255,255,255,255,255,0,0,0,0,0,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,255,3,\n 254,255,255,7,254,255,255,7,192,255,255,255,255,255,255,255,255,255,255,127,\n 252,252,252,28,0,0,0,0,255,239,255,255,127,255,255,183,255,63,255,63,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,31,255,255,255,255,255,255,1,0,0,0,0,\n 0,255,255,255,255,0,224,255,255,255,7,255,255,255,255,255,7,255,255,255,63,\n 255,255,255,255,15,255,62,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,63,255,3,255,255,255,255,15,255,255,255,\n 255,15,255,255,255,255,255,0,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,255,255,63,0,255,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,63,253,255,255,255,255,191,145,255,255,63,0,255,255,\n 127,0,255,255,255,127,0,0,0,0,0,0,0,0,255,255,55,0,255,255,63,0,255,255,255,3,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192,0,0,0,0,0,0,0,0,111,240,239,\n 254,255,255,63,0,0,0,0,0,255,255,255,31,255,255,255,31,0,0,0,0,255,254,255,\n 255,31,0,0,0,255,255,255,255,255,255,63,0,255,255,63,0,255,255,7,0,255,255,3,\n 0,0,0,0,0,0,0,0,0,0,0,0,\n 0,255,255,255,255,255,255,255,255,255,1,0,0,0,0,0,0,255,255,255,255,255,255,7,\n 0,255,255,255,255,255,255,7,0,255,255,255,255,255,0,255,3,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,\n 255,27,3,0,0,0,0,0,0,0,0,0,255,255,255,31,128,0,255,255,63,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,255,255,31,0,0,0,255,255,127,0,255,255,255,255,255,255,255,255,63,0,0,\n 0,192,255,0,0,252,255,255,255,255,255,255,1,0,0,255,255,255,1,255,3,255,255,\n 255,255,255,255,199,255,240,0,255,255,255,255,71,0,255,255,255,255,255,255,\n 255,255,30,192,255,23,0,0,0,0,255,255,251,255,255,255,159,64,0,0,0,0,0,0,0,0,\n 127,189,255,191,255,1,255,255,255,255,255,255,255,1,255,3,239,159,249,255,255,\n 253,237,227,159,25,129,224,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,255,255,255,255,255,255,255,255,187,7,255,131,3,0,0,0,255,255,255,255,255,\n 255,255,255,179,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n 255,255,255,63,127,0,0,0,63,0,0,0,0,255,255,255,255,255,255,255,127,17,0,255,\n 3,0,0,0,0,255,255,255,255,255,255,63,1,255,3,0,0,0,0,0,0,255,255,255,231,255,\n 7,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,\n 255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,3,0,128,\n 127,242,111,255,255,255,191,153,7,0,255,3,0,0,0,0,0,0,0,0,255,252,255,255,255,\n 255,255,252,26,0,0,0,255,255,255,255,255,255,231,127,0,0,255,255,255,255,255,\n 255,255,255,255,32,0,0,0,0,255,255,255,255,255,255,255,1,255,253,255,255,255,\n 255,127,127,1,0,255,3,0,0,252,255,255,255,252,255,255,254,127,0,0,0,0,0,0,0,0,\n 0,127,251,255,255,255,255,127,180,203,0,255,3,191,253,255,255,255,127,123,1,\n 255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,\n 0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,3,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,127,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,255,255,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,\n 0,255,255,255,255,255,255,255,1,255,255,255,127,255,3,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,63,0,0,255,255,255,255,255,255,0,0,15,0,255,3,248,255,255,224,255,\n 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,\n 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,135,\n 255,255,255,255,255,255,255,128,255,255,0,0,0,0,0,0,0,0,11,0,3,0,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,\n 255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n 127,0,0,0,0,0,0,7,0,240,0,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,15,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,7,255,31,255,1,255,67,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,255,255,255,\n 223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,223,223,255,255,\n 255,123,95,252,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,63,255,255,255,253,255,255,247,255,255,255,\n 247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,255,255,255,253,\n 255,255,255,253,255,255,247,207,255,255,255,255,255,255,127,255,255,249,219,7,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,31,\n 128,63,255,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,15,255,\n 3,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,31,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,143,8,\n 255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,239,255,255,255,150,254,247,10,\n 132,234,150,170,150,247,247,94,255,251,255,15,238,251,255,15,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,255,255,255,3,255,255,255,3,255,255,255,3,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,3\n]);\n\n// size: 1568 bytes (compressed to ~1380 bytes after binaryen)\n// @ts-ignore: decorator\n@lazy @inline const CASED = memory.data([\n 18,19,20,21,22,23,16,16,16,16,16,16,16,16,16,16,\n 24,16,16,25,16,16,16,16,16,16,16,16,26,27,17,28,\n 29,30,16,16,31,16,16,16,16,16,16,16,32,33,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,34,35,16,16,16,36,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,37,16,16,16,38,\n 16,16,16,16,39,16,16,16,16,16,16,16,40,16,16,16,\n 16,16,16,16,16,16,16,16,41,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,42,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,43,44,45,46,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,47,16,16,16,16,16,16,\n 16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,0,0,0,0,254,255,255,7,254,255,255,7,0,0,0,0,0,4,32,4,\n 255,255,127,255,255,255,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,247,240,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,239,255,255,255,255,1,3,0,0,0,31,0,0,0,\n 0,0,0,0,0,0,0,0,32,0,0,0,0,0,207,188,64,215,255,255,251,255,255,255,\n 255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 3,252,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,255,\n 255,255,127,0,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,\n 191,32,255,255,255,255,255,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,255,255,255,255,255,255,255,255,255,255,63,63,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,1,255,255,255,255,255,231,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,0,0,0,0,255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,\n 255,255,255,255,255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,2,128,0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,\n 132,252,47,62,80,189,31,242,224,67,0,0,255,255,255,255,24,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,0,255,255,255,255,255,127,255,255,\n 255,255,255,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,120,12,0,\n 255,255,255,255,191,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,63,0,0,\n 255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,255,255,255,\n 255,255,255,255,255,255,255,255,255,120,255,255,255,255,255,255,252,7,0,0,0,0,96,7,\n 0,0,0,0,0,0,255,255,255,255,255,247,255,1,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,0,0,0,0,127,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,255,7,\n 254,255,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n 255,255,15,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,7,0,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,\n 255,255,255,223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,223,223,255,255,255,123,\n 95,252,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,\n 253,255,255,247,255,255,255,247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,255,255,\n 255,253,255,255,255,253,255,255,247,15,0,0,0,0,0,0,255,255,255,255,255,255,255,255,\n 15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,255,255,255,3,255,255,255,3,255,255,255,3,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0\n]);\n\n// size: 2976 bytes (compressed to ~2050 bytes after binaryen)\n// @ts-ignore: decorator\n@lazy @inline const CASE_IGNORABLES = memory.data([\n 18,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,\n 33,16,16,34,16,16,16,35,36,37,38,39,40,41,16,42,\n 43,16,16,16,16,16,16,16,16,16,16,16,44,45,46,16,\n 47,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 48,16,16,16,49,16,50,51,52,53,54,55,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,56,16,16,57,58,\n 16,59,60,61,16,16,16,16,16,16,62,16,16,63,64,65,\n 66,67,68,69,70,71,72,73,74,75,76,16,77,78,79,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,81,82,16,16,16,83,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,84,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,85,86,16,16,16,16,16,16,16,87,16,16,16,16,16,\n 88,89,90,16,16,16,16,16,91,92,16,16,16,16,16,16,\n 16,16,16,93,16,16,16,16,16,16,16,16,16,16,16,16,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,128,64,0,4,0,0,0,64,1,0,0,0,0,0,0,0,0,161,144,1,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,48,4,176,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,3,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,\n 0,0,254,255,255,255,255,191,182,0,0,0,0,0,16,0,63,0,255,23,0,0,0,0,\n 1,248,255,255,0,0,1,0,0,0,0,0,0,0,0,0,0,0,192,191,255,61,0,0,\n 0,128,2,0,0,0,255,255,255,7,0,0,0,0,0,0,0,0,0,0,192,255,1,0,\n 0,0,0,0,0,248,63,36,0,0,192,255,255,63,0,0,0,0,0,14,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,248,255,255,255,255,255,7,0,0,0,0,0,0,20,\n 254,33,254,0,12,0,2,0,2,0,0,0,0,0,0,16,30,32,0,0,12,0,0,64,\n 6,0,0,0,0,0,0,16,134,57,2,0,0,0,35,0,6,0,0,0,0,0,0,16,\n 190,33,0,0,12,0,0,252,2,0,0,0,0,0,0,144,30,32,96,0,12,0,0,0,\n 4,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,17,0,0,0,0,0,0,192,\n 193,61,96,0,12,0,0,0,2,0,0,0,0,0,0,144,64,48,0,0,12,0,0,0,\n 3,0,0,0,0,0,0,24,30,32,0,0,12,0,0,0,2,0,0,0,0,0,0,0,\n 0,4,92,0,0,0,0,0,0,0,0,0,0,0,242,7,192,127,0,0,0,0,0,0,\n 0,0,0,0,0,0,242,31,64,63,0,0,0,0,0,0,0,0,0,3,0,0,160,2,\n 0,0,0,0,0,0,254,127,223,224,255,254,255,255,255,31,64,0,0,0,0,0,0,0,\n 0,0,0,0,0,224,253,102,0,0,0,195,1,0,30,0,100,32,0,32,0,0,0,0,\n 0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,28,0,\n 0,0,12,0,0,0,12,0,0,0,0,0,0,0,176,63,64,254,143,32,0,0,0,0,\n 0,120,0,0,0,0,0,0,8,0,0,0,0,0,0,0,96,0,0,0,0,2,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,135,1,4,14,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,9,0,0,0,0,\n 0,0,64,127,229,31,248,159,0,0,0,0,128,0,255,255,1,0,0,0,0,0,0,0,\n 15,0,0,0,0,0,208,23,4,0,0,0,0,248,15,0,3,0,0,0,60,59,0,0,\n 0,0,0,0,64,163,3,0,0,0,0,0,0,240,207,0,0,0,0,0,0,0,0,63,\n 0,0,0,0,0,0,0,0,0,0,247,255,253,33,16,3,0,0,0,0,0,240,255,255,\n 255,255,255,255,255,7,0,1,0,0,0,248,255,255,255,255,255,255,255,255,255,255,255,251,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,\n 3,224,0,224,0,224,0,96,0,248,0,3,144,124,0,0,0,0,0,0,223,255,2,128,\n 0,0,255,31,0,0,0,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,128,0,0,0,0,0,0,0,0,\n 0,0,0,0,255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,60,62,8,\n 0,0,0,0,0,0,0,0,0,0,0,126,0,0,0,0,0,0,0,0,0,0,0,112,\n 0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,16,0,0,0,0,0,0,\n 0,0,0,0,0,128,247,191,0,0,0,240,0,0,0,0,0,0,0,0,0,0,3,0,\n 255,255,255,255,3,0,0,0,0,0,0,0,0,0,1,0,0,7,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,3,68,8,0,0,96,16,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,48,0,0,0,255,255,3,128,0,0,0,0,192,63,0,0,\n 128,255,3,0,0,0,0,0,7,0,0,0,0,0,200,51,0,128,0,0,96,0,0,0,\n 0,0,0,0,0,126,102,0,8,16,0,0,0,0,1,16,0,0,0,0,0,0,157,193,\n 2,0,0,32,0,48,88,0,0,0,0,0,0,0,0,0,0,0,0,248,0,14,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,32,33,0,0,0,0,0,64,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,255,3,0,0,0,0,0,0,0,\n 255,255,8,0,255,255,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,128,128,64,0,4,0,0,0,64,1,0,0,0,0,0,1,0,\n 0,0,0,192,0,0,0,0,0,0,0,0,8,0,0,14,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,7,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,240,0,0,0,0,0,135,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,\n 0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 192,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 2,0,0,0,0,0,0,255,127,0,0,0,0,0,0,128,3,0,0,0,0,0,120,38,\n 0,32,0,0,0,0,0,0,7,0,0,0,128,239,31,0,0,0,0,0,0,0,8,0,\n 3,0,0,0,0,0,192,127,0,158,0,0,0,0,0,0,0,0,0,0,0,128,211,64,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,248,7,0,0,\n 3,0,0,0,0,0,0,24,1,0,0,0,192,31,31,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,92,0,0,64,0,0,0,0,\n 0,0,0,0,0,0,248,133,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,176,1,0,0,48,0,0,0,0,\n 0,0,0,0,0,0,248,167,1,0,0,0,0,0,0,0,0,0,0,0,0,40,191,0,\n 0,0,0,0,0,0,0,0,0,0,0,224,188,15,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,255,6,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,88,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,240,12,1,0,0,0,254,7,0,0,0,0,248,121,128,0,126,14,0,0,0,0,\n 0,252,127,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,191,\n 0,0,0,0,0,0,0,0,0,0,252,255,255,252,109,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,126,180,191,0,0,0,0,0,0,0,0,0,163,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,255,1,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,31,0,0,0,0,0,0,0,127,0,15,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,128,0,0,0,0,0,0,0,128,255,255,0,0,0,0,0,0,0,0,27,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,15,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,248,255,\n 231,15,0,0,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,127,248,255,255,255,255,255,31,32,0,16,0,0,248,254,255,0,0,\n 0,0,0,0,0,0,0,0,127,255,255,249,219,7,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,63,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 240,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,248\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const LOWER127 = memory.data([\n 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,\n 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,\n 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,\n 64,\n 97,98,99,100,101,102,103,104,105,106,107,108,109,\n 110,111,112,113,114,115,116,117,118,119,120,121,122,\n 91,92,93,94,95,96,\n 97,98,99,100,101,102,103,104,105,106,107,108,109,\n 110,111,112,113,114,115,116,117,118,119,120,121,122,\n 123,124,125,126,127\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const UPPER127 = memory.data([\n 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,\n 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,\n 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,\n 64,\n 65,66,67,68,69,70,71,72,73,74,75,76,77,\n 78,79,80,81,82,83,84,85,86,87,88,89,90,\n 91,92,93,94,95,96,\n 65,66,67,68,69,70,71,72,73,74,75,76,77,\n 78,79,80,81,82,83,84,85,86,87,88,89,90,\n 123,124,125,126,127\n]);\n\n// 23 * 8 = 184 bytes\n// @ts-ignore: decorator\n@lazy @inline const POWERS10 = memory.data([\n 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,\n 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,\n 1e20, 1e21, 1e22\n]);\n\n// @ts-ignore: decorator\n@inline\nexport const enum CharCode {\n PERCENT = 0x25,\n PLUS = 0x2B,\n MINUS = 0x2D,\n DOT = 0x2E,\n _0 = 0x30,\n _1 = 0x31,\n _2 = 0x32,\n _3 = 0x33,\n _4 = 0x34,\n _5 = 0x35,\n _6 = 0x36,\n _7 = 0x37,\n _8 = 0x38,\n _9 = 0x39,\n A = 0x41,\n B = 0x42,\n E = 0x45,\n I = 0x49,\n N = 0x4E,\n O = 0x4F,\n X = 0x58,\n Z = 0x5A,\n a = 0x61,\n b = 0x62,\n e = 0x65,\n n = 0x6E,\n o = 0x6F,\n u = 0x75,\n x = 0x78,\n z = 0x7A\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isAscii(c: u32): bool {\n return !(c >> 7);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isLower8(c: u32): bool {\n return c - CharCode.a < 26;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isUpper8(c: u32): bool {\n return c - CharCode.A < 26;\n}\n\nexport function isSpace(c: u32): bool {\n if (c < 0x1680) { // < (1)\n // , , , , , and \n // (c == 0x20 || c == 0xA0) was optimized to (c | 0x80) == 0xA0\n return ((c | 0x80) == 0xA0) || (c - 0x09 <= 0x0D - 0x09);\n }\n if (c - 0x2000 <= 0x200A - 0x2000) return true;\n switch (c) {\n case 0x1680: // (1)\n case 0x2028: // (2)\n case 0x2029: // \n case 0x202F: // \n case 0x205F: // \n case 0x3000: // \n case 0xFEFF: return true; // \n }\n return false;\n}\n\nexport function isAlpha(c: u32): bool {\n if (isAscii(c)) return (c | 32) - CharCode.a < 26;\n if (c < 0x20000) {\n // @ts-ignore: cast\n return stagedBinaryLookup(ALPHA_TABLE, c);\n }\n return c < 0x2FFFE;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isCased(c: u32): bool {\n // @ts-ignore: cast\n return c < 0x1F18A && stagedBinaryLookup(CASED, c);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isCaseIgnorable(c: u32): bool {\n // @ts-ignore: cast\n return c < 0xE01F0 && stagedBinaryLookup(CASE_IGNORABLES, c);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isFinalSigma(buffer: usize, index: isize, len: isize): bool {\n const lookaheadLimit = 30; // max lookahead limit\n let found = false;\n let pos = index;\n let minPos = max(0, pos - lookaheadLimit);\n while (pos > minPos) {\n let c = codePointBefore(buffer, pos);\n if (!isCaseIgnorable(c)) {\n if (isCased(c)) {\n found = true;\n } else {\n return false;\n }\n }\n pos -= isize(c >= 0x10000) + 1;\n }\n if (!found) return false;\n pos = index + 1;\n let maxPos = min(pos + lookaheadLimit, len);\n while (pos < maxPos) {\n let c = load(buffer + (pos << 1));\n if (u32((c & 0xFC00) == 0xD800) & u32(pos + 1 != len)) {\n let c1 = load(buffer + (pos << 1), 2);\n if ((c1 & 0xFC00) == 0xDC00) {\n c = (c - 0xD800 << 10) + (c1 - 0xDC00) + 0x10000;\n }\n }\n if (!isCaseIgnorable(c)) {\n return !isCased(c);\n }\n pos += isize(c >= 0x10000) + 1;\n }\n return true;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction codePointBefore(buffer: usize, index: isize): i32 {\n if (index <= 0) return -1;\n let c = load(buffer + (index - 1 << 1));\n if (u32((c & 0xFC00) == 0xDC00) & u32(index - 2 >= 0)) {\n let c1 = load(buffer + (index - 2 << 1));\n if ((c1 & 0xFC00) == 0xD800) {\n return ((c1 & 0x3FF) << 10) + (c & 0x3FF) + 0x10000;\n }\n }\n return (c & 0xF800) == 0xD800 ? 0xFFFD : c;\n}\n\n// Search routine for two-staged lookup tables\nfunction stagedBinaryLookup(table: usize, c: u32): bool {\n return ((load(table + (load(table + (c >>> 8)) << 5) + ((c & 255) >> 3)) >>> (c & 7)) & 1);\n}\n\nexport function compareImpl(str1: string, index1: usize, str2: string, index2: usize, len: usize): i32 {\n let ptr1 = changetype(str1) + (index1 << 1);\n let ptr2 = changetype(str2) + (index2 << 1);\n if (ASC_SHRINK_LEVEL < 2) {\n if (len >= 4 && !((ptr1 & 7) | (ptr2 & 7))) {\n do {\n if (load(ptr1) != load(ptr2)) break;\n ptr1 += 8;\n ptr2 += 8;\n len -= 4;\n } while (len >= 4);\n }\n }\n while (len--) {\n let a = load(ptr1);\n let b = load(ptr2);\n if (a != b) return a - b;\n ptr1 += 2;\n ptr2 += 2;\n }\n return 0;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function toLower8(c: u32): u32 {\n if (ASC_SHRINK_LEVEL > 0) {\n return c | u32(isUpper8(c)) << 5;\n } else {\n return load(LOWER127 + c);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nexport function toUpper8(c: u32): u32 {\n if (ASC_SHRINK_LEVEL > 0) {\n return c & ~(u32(isLower8(c)) << 5);\n } else {\n return load(UPPER127 + c);\n }\n}\n\n/** Parses a string to an integer (usually), using the specified radix. */\nexport function strtol(str: string, radix: i32 = 0): T {\n let len = str.length;\n if (!len) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n\n let ptr = changetype(str) /* + HEAD -> offset */;\n let code = load(ptr);\n\n // trim white spaces\n while (isSpace(code)) {\n code = load(ptr += 2);\n --len;\n }\n // determine sign\n // @ts-ignore\n let sign: T = 1;\n if (code == CharCode.MINUS || code == CharCode.PLUS) {\n if (!--len) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n if (code == CharCode.MINUS) {\n // @ts-ignore: type\n sign = -1;\n }\n code = load(ptr += 2);\n }\n\n // See https://tc39.es/ecma262/#sec-parseint-string-radix\n if (radix) {\n if (radix < 2 || radix > 36) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n // handle case as parseInt(\"0xFF\", 16) by spec\n if (radix == 16) {\n if (\n len > 2 &&\n code == CharCode._0 &&\n (load(ptr, 2) | 32) == CharCode.x\n ) {\n ptr += 4; len -= 2;\n }\n }\n } else {\n // determine radix by literal prefix\n if (code == CharCode._0 && len > 2) {\n switch (load(ptr, 2) | 32) {\n case CharCode.b: {\n ptr += 4; len -= 2;\n radix = 2;\n break;\n }\n case CharCode.o: {\n ptr += 4; len -= 2;\n radix = 8;\n break;\n }\n case CharCode.x: {\n ptr += 4; len -= 2;\n radix = 16;\n break;\n }\n }\n }\n if (!radix) radix = 10;\n }\n\n // calculate value\n // @ts-ignore: type\n let num: T = 0;\n let initial = len - 1;\n while (len--) {\n code = load(ptr);\n if (code - CharCode._0 < 10) {\n code -= CharCode._0;\n } else if (code - CharCode.A <= (CharCode.Z - CharCode.A)) {\n code -= CharCode.A - 10;\n } else if (code - CharCode.a <= (CharCode.z - CharCode.a)) {\n code -= CharCode.a - 10;\n }\n if (code >= radix) {\n if (initial == len) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n break;\n }\n // @ts-ignore: type\n num = num * radix + code;\n ptr += 2;\n }\n // @ts-ignore: type\n return sign * num;\n}\n\nexport function strtod(str: string): f64 {\n let len = str.length;\n if (!len) return NaN;\n\n let ptr = changetype(str);\n let code = load(ptr);\n\n let sign = 1.0;\n // skip white spaces\n while (len && isSpace(code)) {\n code = load(ptr += 2);\n --len;\n }\n if (!len) return NaN;\n\n // try parse '-' or '+'\n if (code == CharCode.MINUS) {\n if (!--len) return NaN;\n code = load(ptr += 2);\n sign = -1;\n } else if (code == CharCode.PLUS) {\n if (!--len) return NaN;\n code = load(ptr += 2);\n }\n\n // try parse Infinity\n if (len >= 8 && code == CharCode.I) {\n if (\n load(ptr, 0) == 0x690066006E0049 && // ifnI\n load(ptr, 8) == 0x7900740069006E // ytin\n ) {\n return Infinity * sign;\n }\n return NaN;\n }\n // validate next symbol\n if (code != CharCode.DOT && (code - CharCode._0) >= 10) {\n return NaN;\n }\n let savedPtr = ptr;\n // skip zeros\n while (code == CharCode._0) {\n code = load(ptr += 2);\n --len;\n }\n if (len <= 0) return 0.0 * sign;\n const capacity = 19; // int(64 * 0.3010)\n let pointed = false;\n let consumed = 0;\n let position = 0;\n let x: u64 = 0;\n if (code == CharCode.DOT) {\n let noDigits = !(savedPtr - ptr);\n ptr += 2; --len;\n if (!len && noDigits) return NaN;\n for (pointed = true; (code = load(ptr)) == CharCode._0; --position, ptr += 2) --len;\n if (len <= 0) return 0.0 * sign;\n if (!position && noDigits && code - CharCode._0 >= 10) return NaN;\n }\n for (let digit = code - CharCode._0; digit < 10 || (code == CharCode.DOT && !pointed); digit = code - CharCode._0) {\n if (digit < 10) {\n x = consumed < capacity ? 10 * x + digit : x | u64(!!digit);\n ++consumed;\n } else {\n position = consumed;\n pointed = true;\n }\n if (!--len) break;\n code = load(ptr += 2);\n }\n\n if (!pointed) position = consumed;\n return copysign(scientific(x, position - min(capacity, consumed) + parseExp(ptr, len)), sign);\n}\n\nexport function strtob(str: string): bool {\n let size: usize = str.length << 1;\n let offset: usize = 0;\n if (size > 8) {\n // try trim end whitespaces first\n while (size && isSpace(load(changetype(str) + size - 2))) size -= 2;\n if (size > 8) {\n // trim start whitespaces\n while (offset < size && isSpace(load(changetype(str) + offset))) offset += 2;\n size -= offset;\n }\n }\n if (size != 8) return false;\n // \"true\" represents as \\00\\e\\00\\u\\00\\e\\00\\t (00 65 00 75 00 72 00 74)\n return load(changetype(str) + offset) == 0x0065_0075_0072_0074;\n}\n\nexport function joinBooleanArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) return select(\"true\", \"false\", load(dataStart));\n\n let sepLen = separator.length;\n let valueLen = 5; // max possible length of element len(\"false\")\n let estLen = (valueLen + sepLen) * lastIndex + valueLen;\n let result = changetype(__new(estLen << 1, idof()));\n let offset = 0;\n let value: bool;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + i);\n valueLen = 4 + i32(!value);\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(select(\"true\", \"false\", value)),\n valueLen << 1\n );\n offset += valueLen;\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + lastIndex);\n valueLen = 4 + i32(!value);\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(select(\"true\", \"false\", value)),\n valueLen << 1\n );\n offset += valueLen;\n\n if (estLen > offset) return result.substring(0, offset);\n return result;\n}\n\nexport function joinIntegerArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) {\n let value = load(dataStart);\n if (isSigned()) {\n if (sizeof() <= 4) {\n // @ts-ignore: type\n return changetype(itoa32(value, 10));\n } else {\n // @ts-ignore: type\n return changetype(itoa64(value, 10));\n }\n } else {\n if (sizeof() <= 4) {\n // @ts-ignore: type\n return changetype(utoa32(value, 10));\n } else {\n // @ts-ignore: type\n return changetype(utoa64(value, 10));\n }\n }\n }\n\n let sepLen = separator.length;\n const valueLen = (sizeof() <= 4 ? 10 : 20) + i32(isSigned());\n let estLen = (valueLen + sepLen) * lastIndex + valueLen;\n let result = changetype(__new(estLen << 1, idof()));\n let offset = 0;\n let value: T;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n // @ts-ignore: type\n offset += itoa_buffered(changetype(result) + (offset << 1), value);\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + (lastIndex << alignof()));\n // @ts-ignore: type\n offset += itoa_buffered(changetype(result) + (offset << 1), value);\n if (estLen > offset) return result.substring(0, offset);\n return result;\n}\n\nexport function joinFloatArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) {\n return changetype(dtoa(\n // @ts-ignore: type\n load(dataStart))\n );\n }\n\n const valueLen = MAX_DOUBLE_LENGTH;\n let sepLen = separator.length;\n let estLen = (valueLen + sepLen) * lastIndex + valueLen;\n let result = changetype(__new(estLen << 1, idof()));\n let offset = 0;\n let value: T;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n // @ts-ignore: type\n offset += dtoa_buffered(changetype(result) + (offset << 1), value);\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + (lastIndex << alignof()));\n // @ts-ignore: type\n offset += dtoa_buffered(changetype(result) + (offset << 1), value);\n if (estLen > offset) return result.substring(0, offset);\n return result;\n}\n\nexport function joinStringArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) {\n // @ts-ignore: type\n return load(dataStart) || \"\";\n }\n let estLen = 0;\n let value: string;\n for (let i = 0; i < length; ++i) {\n value = load(dataStart + (i << alignof()));\n if (changetype(value) != 0) estLen += value.length;\n }\n let offset = 0;\n let sepLen = separator.length;\n let result = changetype(__new((estLen + sepLen * lastIndex) << 1, idof()));\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n if (changetype(value) != 0) {\n let valueLen = value.length;\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(value),\n valueLen << 1\n );\n offset += valueLen;\n }\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + (lastIndex << alignof()));\n if (changetype(value) != 0) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(value),\n value.length << 1\n );\n }\n return result;\n}\n\nexport function joinReferenceArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n let value: T;\n if (!lastIndex) {\n value = load(dataStart);\n // @ts-ignore: type\n return value != null ? value.toString() : \"\";\n }\n let result = \"\";\n let sepLen = separator.length;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n // @ts-ignore: type\n if (value != null) result += value.toString();\n if (sepLen) result += separator;\n }\n value = load(dataStart + (lastIndex << alignof()));\n // @ts-ignore: type\n if (value != null) result += value.toString();\n return result;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction scientific(significand: u64, exp: i32): f64 {\n if (!significand || exp < -342) return 0;\n if (exp > 308) return Infinity;\n // Try use fast path\n // Use fast path for string-to-double conversion if possible\n // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion\n // Simple integer\n let significandf = significand;\n if (!exp) return significandf;\n if (exp > 22 && exp <= 22 + 15) {\n significandf *= pow10(exp - 22);\n exp = 22;\n }\n if (significand <= 9007199254740991 && abs(exp) <= 22) {\n if (exp > 0) return significandf * pow10(exp);\n return significandf / pow10(-exp);\n } else if (exp < 0) {\n return scaledown(significand, exp);\n } else {\n return scaleup(significand, exp);\n }\n}\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction scaledown(significand: u64, exp: i32): f64 {\n const denom: u64 = 6103515625; // 1e14 * 0x1p-14\n const scale = reinterpret(0x3F06849B86A12B9B); // 1e-14 * 0x1p32\n\n let shift = clz(significand);\n significand <<= shift;\n shift = exp - shift;\n\n for (; exp <= -14; exp += 14) {\n let q = significand / denom;\n let r = significand % denom;\n let s = clz(q);\n significand = (q << s) + nearest(scale * (r << (s - 18)));\n shift -= s;\n }\n let b = ipow32(5, -exp);\n let q = significand / b;\n let r = significand % b;\n let s = clz(q);\n significand = (q << s) + (reinterpret(reinterpret(r) + (s << 52)) / b);\n shift -= s;\n\n return NativeMath.scalbn(significand, shift);\n}\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction scaleup(significand: u64, exp: i32): f64 {\n const coeff: u32 = 1220703125; // 1e13 * 0x1p-13;\n let shift = ctz(significand);\n significand >>= shift;\n shift += exp;\n\n __fixmulShift = shift;\n for (; exp >= 13; exp -= 13) {\n significand = fixmul(significand, coeff);\n }\n significand = fixmul(significand, ipow32(5, exp));\n shift = __fixmulShift;\n return NativeMath.scalbn(significand, shift);\n}\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction parseExp(ptr: usize, len: i32): i32 {\n let sign = 1, magnitude = 0;\n let code = load(ptr);\n // check code is 'e' or 'E'\n if ((code | 32) != CharCode.e) return 0;\n\n if (!--len) return 0;\n code = load(ptr += 2);\n if (code == CharCode.MINUS) {\n if (!--len) return 0;\n code = load(ptr += 2);\n sign = -1;\n } else if (code == CharCode.PLUS) {\n if (!--len) return 0;\n code = load(ptr += 2);\n }\n // skip zeros\n while (code == CharCode._0) {\n if (!--len) return 0;\n code = load(ptr += 2);\n }\n for (let digit: u32 = code - CharCode._0; len && digit < 10; digit = code - CharCode._0) {\n if (magnitude >= 3200) return sign * 3200;\n magnitude = 10 * magnitude + digit;\n code = load(ptr += 2);\n --len;\n }\n return sign * magnitude;\n}\n\n// @ts-ignore: decorator\n@lazy let __fixmulShift: u64 = 0;\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction fixmul(a: u64, b: u32): u64 {\n let low = (a & 0xFFFFFFFF) * b;\n let high = (a >> 32) * b + (low >> 32);\n let overflow = (high >> 32);\n let space = clz(overflow);\n let revspace: u64 = 32 - space;\n __fixmulShift += revspace;\n return (high << space | (low & 0xFFFFFFFF) >> revspace) + (low << space >> 31 & 1);\n}\n\n// @ts-ignore: decorator\n@inline\nfunction pow10(n: i32): f64 {\n // argument `n` should bounds in [0, 22] range\n return load(POWERS10 + (n << alignof()));\n}\n","// This file is shared with the compiler and must remain portable\n\n/** Runtime types. */\nexport enum Runtime {\n /** Simple bump allocator without GC. */\n Stub = 0,\n /** Stop the world semi-automatic GC. */\n Minimal = 1,\n /** incremental GC. */\n Incremental = 2,\n}\n","import { compareImpl } from \"./string\";\n\ntype Comparator = (a: T, b: T) => i32;\n\n// @ts-ignore: decorator\n@lazy @inline const EMPTY = u32.MAX_VALUE;\n// @ts-ignore: decorator\n@inline const INSERTION_SORT_THRESHOLD = 48;\n// @ts-ignore: decorator\n@inline const MIN_RUN_LENGTH = 32;\n\n// @ts-ignore: decorator\n@inline\nfunction log2u(n: u32): u32 {\n return 31 - clz(n);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function COMPARATOR(): Comparator {\n if (isInteger()) {\n if (isSigned() && sizeof() <= 4) {\n return (a, b) => i32(a) - i32(b);\n } else {\n return (a, b) => i32(a > b) - i32(a < b);\n }\n } else if (isFloat()) {\n if (sizeof() == 4) {\n return (a, b) => {\n let ia = reinterpret(f32(a));\n let ib = reinterpret(f32(b));\n ia ^= ia >> 31 >>> 1;\n ib ^= ib >> 31 >>> 1;\n return i32(ia > ib) - i32(ia < ib);\n };\n } else {\n return (a, b) => {\n let ia = reinterpret(f64(a));\n let ib = reinterpret(f64(b));\n ia ^= ia >> 63 >>> 1;\n ib ^= ib >> 63 >>> 1;\n return i32(ia > ib) - i32(ia < ib);\n };\n }\n } else if (isString()) {\n return (a, b) => {\n if (\n changetype(a) == changetype(b) ||\n changetype(a) == 0 ||\n changetype(b) == 0\n ) return 0;\n let alen = changetype(a).length;\n let blen = changetype(b).length;\n if (!(alen | blen)) return 0;\n if (!alen) return -1;\n if (!blen) return 1;\n let res = compareImpl(\n changetype(a), 0,\n changetype(b), 0,\n min(alen, blen)\n );\n return res ? res : alen - blen;\n };\n } else {\n return (a, b) => i32(a > b) - i32(a < b);\n }\n}\n\n// Power Sort implementation (stable) from paper \"Nearly-Optimal Mergesorts\"\n// https://arxiv.org/pdf/1805.04154.pdf\n// This method usually outperform TimSort.\n// TODO: refactor c >>> 31 to c < 0 when binaryen will support this opt\nexport function SORT(\n ptr: usize,\n len: i32,\n comparator: Comparator\n): void {\n if (len <= INSERTION_SORT_THRESHOLD) {\n if (len <= 1) return;\n if (ASC_SHRINK_LEVEL < 1) {\n switch (len) {\n case 3: {\n let a = load(ptr, 0);\n let b = load(ptr, 1 << alignof());\n let c = comparator(a, b) > 0;\n store(ptr, select(b, a, c), 0);\n a = select(a, b, c);\n b = load(ptr, 2 << alignof());\n c = comparator(a, b) > 0;\n store(ptr, select(b, a, c), 1 << alignof());\n store(ptr, select(a, b, c), 2 << alignof());\n }\n case 2: {\n let a = load(ptr, 0);\n let b = load(ptr, 1 << alignof());\n let c = comparator(a, b) > 0;\n store(ptr, select(b, a, c), 0);\n store(ptr, select(a, b, c), 1 << alignof());\n return;\n }\n }\n }\n insertionSort(ptr, 0, len - 1, 0, comparator);\n return;\n }\n\n let lgPlus2 = log2u(len) + 2;\n let lgPlus2Size = lgPlus2 << alignof();\n let leftRunStartBuf = __alloc(lgPlus2Size << 1);\n let leftRunEndBuf = leftRunStartBuf + lgPlus2Size;\n\n for (let i: u32 = 0; i < lgPlus2; ++i) {\n store(leftRunStartBuf + (i << alignof()), EMPTY);\n }\n\n let buffer = __alloc(len << alignof());\n\n let hi = len - 1;\n let endA = extendRunRight(ptr, 0, hi, comparator);\n let lenA = endA + 1;\n\n if (lenA < MIN_RUN_LENGTH) {\n endA = min(hi, MIN_RUN_LENGTH - 1);\n insertionSort(ptr, 0, endA, lenA, comparator);\n }\n\n let top: u32 = 0, startA = 0;\n while (endA < hi) {\n let startB = endA + 1;\n let endB = extendRunRight(ptr, startB, hi, comparator);\n let lenB = endB - startB + 1;\n\n if (lenB < MIN_RUN_LENGTH) {\n endB = min(hi, startB + MIN_RUN_LENGTH - 1);\n insertionSort(ptr, startB, endB, lenB, comparator);\n }\n\n let k = nodePower(0, hi, startA, startB, endB);\n\n for (let i = top; i > k; --i) {\n let start = load(leftRunStartBuf + (i << alignof()));\n if (start != EMPTY) {\n mergeRuns(\n ptr,\n start,\n load(leftRunEndBuf + (i << alignof())) + 1,\n endA,\n buffer,\n comparator\n );\n startA = start;\n store(leftRunStartBuf + (i << alignof()), EMPTY);\n }\n }\n\n store(leftRunStartBuf + (k << alignof()), startA);\n store(leftRunEndBuf + (k << alignof()), endA);\n startA = startB;\n endA = endB;\n top = k;\n }\n\n for (let i = top; i != 0; --i) {\n let start = load(leftRunStartBuf + (i << alignof()));\n if (start != EMPTY) {\n mergeRuns(\n ptr,\n start,\n load(leftRunEndBuf + (i << alignof())) + 1,\n hi,\n buffer,\n comparator\n );\n }\n }\n // dealloc aux buffers\n __free(buffer);\n __free(leftRunStartBuf);\n}\n\nfunction insertionSort(\n ptr: usize,\n left: i32,\n right: i32,\n presorted: i32,\n comparator: Comparator\n): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n // slightly improved original insertion sort\n for (let i = left + presorted; i <= right; ++i) {\n let j = i - 1;\n let a = load(ptr + (i << alignof()));\n while (j >= left) {\n let b = load(ptr + (j << alignof()));\n if (comparator(a, b) < 0) {\n store(ptr + (j << alignof()), b, 1 << alignof()); --j;\n } else break;\n }\n store(ptr + (j << alignof()), a, 1 << alignof());\n }\n } else {\n // even-odd two-way insertion sort which allow increase minRunLen\n let range = right - left + 1;\n let i = left + select(range & 1, presorted - ((range - presorted) & 1), presorted == 0);\n for (; i <= right; i += 2) {\n let a = load(ptr + (i << alignof()), 0);\n let b = load(ptr + (i << alignof()), 1 << alignof());\n let min = b, max = a;\n if (comparator(a, b) <= 0) {\n min = a, max = b;\n }\n let j = i - 1;\n while (j >= left) {\n a = load(ptr + (j << alignof()));\n if (comparator(a, max) > 0) {\n store(ptr + (j << alignof()), a, 2 << alignof()); --j;\n } else break;\n }\n store(ptr + (j << alignof()), max, 2 << alignof());\n while (j >= left) {\n a = load(ptr + (j << alignof()));\n if (comparator(a, min) > 0) {\n store(ptr + (j << alignof()), a, 1 << alignof()); --j;\n } else break;\n }\n store(ptr + (j << alignof()), min, 1 << alignof());\n }\n }\n}\n\nfunction nodePower(left: u32, right: u32, startA: u32, startB: u32, endB: u32): u32 {\n let n: u64 = right - left + 1;\n let s = startB - (left << 1);\n let l = startA + s;\n let r = endB + s + 1;\n let a = (l << 30) / n;\n let b = (r << 30) / n;\n return clz((a ^ b));\n}\n\nfunction extendRunRight(\n ptr: usize,\n i: i32,\n right: i32,\n comparator: Comparator\n): i32 {\n if (i == right) return i;\n let j = i;\n if (comparator(\n load(ptr + ( j << alignof())),\n load(ptr + (++j << alignof()))\n ) > 0) {\n while (\n j < right &&\n (comparator(\n load(ptr + (j << alignof()), 1 << alignof()),\n load(ptr + (j << alignof()))\n ) >>> 31) // < 0\n ) ++j;\n // reverse\n let k = j;\n while (i < k) {\n let tmp = load(ptr + (i << alignof()));\n store(ptr + (i << alignof()), load(ptr + (k << alignof()))); ++i;\n store(ptr + (k << alignof()), tmp); --k;\n }\n } else {\n while (\n j < right &&\n comparator(\n load(ptr + (j << alignof()), 1 << alignof()),\n load(ptr + (j << alignof()))\n ) >= 0\n ) ++j;\n }\n return j;\n}\n\n// Merges arr[l..m - 1] and arr[m..r]\nfunction mergeRuns(\n ptr: usize,\n l: i32,\n m: i32,\n r: i32,\n buffer: usize,\n comparator: Comparator\n): void {\n --m;\n let i: i32, j: i32, t = r + m;\n for (i = m + 1; i > l; --i) {\n store(\n buffer + ((i - 1) << alignof()),\n load(ptr + ((i - 1) << alignof()))\n );\n }\n for (j = m; j < r; ++j) {\n store(\n buffer + ((t - j) << alignof()),\n load(ptr + (j << alignof()), 1 << alignof())\n );\n }\n for (let k = l; k <= r; ++k) {\n let a = load(buffer + (j << alignof()));\n let b = load(buffer + (i << alignof()));\n if (comparator(a, b) < 0) {\n store(ptr + (k << alignof()), a);\n --j;\n } else {\n store(ptr + (k << alignof()), b);\n ++i;\n }\n }\n}\n","/// \n\nimport { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from \"./rt/common\";\nimport { compareImpl, strtol, strtod, isSpace, isAscii, isFinalSigma, toLower8, toUpper8 } from \"./util/string\";\nimport { SPECIALS_UPPER, casemap, bsearch } from \"./util/casemap\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_UNPAIRED_SURROGATE } from \"./util/error\";\nimport { idof } from \"./builtins\";\nimport { Array } from \"./array\";\n\n@final export abstract class String {\n\n @lazy static readonly MAX_LENGTH: i32 = (BLOCK_MAXSIZE >>> alignof());\n\n static fromCharCode(unit: i32, surr: i32 = -1): String {\n let hasSur = surr > 0;\n let out = changetype(__new(2 << i32(hasSur), idof()));\n store(changetype(out), unit);\n if (hasSur) store(changetype(out), surr, 2);\n return out;\n }\n\n static fromCharCodes(units: Array): String {\n let length = units.length;\n let out = changetype(__new(length << 1, idof()));\n let ptr = units.dataStart;\n for (let i = 0; i < length; ++i) {\n store(changetype(out) + (i << 1), load(ptr + (i << 2)));\n }\n return out;\n }\n\n static fromCodePoint(code: i32): String {\n let hasSur = code > 0xFFFF;\n let out = changetype(__new(2 << i32(hasSur), idof()));\n if (!hasSur) {\n store(changetype(out), code);\n } else {\n // Checks valid code point range\n assert(code <= 0x10FFFF);\n code -= 0x10000;\n let hi = (code & 0x03FF) | 0xDC00;\n let lo = code >>> 10 | 0xD800;\n store(changetype(out), lo | hi << 16);\n }\n return out;\n }\n\n @builtin static raw(parts: TemplateStringsArray, ...args: unknown[]): string { return unreachable(); }\n\n get length(): i32 {\n return changetype(changetype(this) - TOTAL_OVERHEAD).rtSize >> 1;\n }\n\n at(pos: i32): String {\n let len = this.length;\n pos += select(0, len, pos >= 0);\n if (pos >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n let out = __new(2, idof());\n store(out, load(changetype(this) + (pos << 1)));\n return changetype(out); // retains\n }\n\n @operator(\"[]\") charAt(pos: i32): String {\n if (pos >= this.length) return changetype(\"\");\n let out = changetype(__new(2, idof()));\n store(changetype(out), load(changetype(this) + (pos << 1)));\n return out;\n }\n\n charCodeAt(pos: i32): i32 {\n if (pos >= this.length) return -1; // (NaN)\n return load(changetype(this) + (pos << 1));\n }\n\n codePointAt(pos: i32): i32 {\n let len = this.length;\n if (pos >= len) return -1; // (undefined)\n let first = load(changetype(this) + (pos << 1));\n if ((first & 0xFC00) != 0xD800 || pos + 1 == len) return first;\n let second = load(changetype(this) + (pos << 1), 2);\n if ((second & 0xFC00) != 0xDC00) return first;\n return (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;\n }\n\n @operator(\"+\") private static __concat(left: String, right: String): String {\n return left.concat(right);\n }\n\n concat(other: String): String {\n let thisSize: isize = this.length << 1;\n let otherSize: isize = other.length << 1;\n let outSize: usize = thisSize + otherSize;\n if (outSize == 0) return changetype(\"\");\n let out = changetype(__new(outSize, idof()));\n memory.copy(changetype(out), changetype(this), thisSize);\n memory.copy(changetype(out) + thisSize, changetype(other), otherSize);\n return out;\n }\n\n endsWith(search: String, end: i32 = String.MAX_LENGTH): bool {\n end = min(max(end, 0), this.length);\n let searchLength = search.length;\n let searchStart = end - searchLength;\n if (searchStart < 0) return false;\n // @ts-ignore: string <-> String\n return !compareImpl(this, searchStart, search, 0, searchLength);\n }\n\n @operator(\"==\") private static __eq(left: String | null, right: String | null): bool {\n if (changetype(left) == changetype(right)) return true;\n if (changetype(left) == 0 || changetype(right) == 0) return false;\n let leftLength = changetype(left).length;\n if (leftLength != changetype(right).length) return false;\n // @ts-ignore: string <-> String\n return !compareImpl(left, 0, right, 0, leftLength);\n }\n\n @operator.prefix(\"!\")\n private static __not(str: String | null): bool {\n return changetype(str) == 0 || !changetype(str).length;\n }\n\n @operator(\"!=\")\n private static __ne(left: String | null, right: String | null): bool {\n return !this.__eq(left, right);\n }\n\n @operator(\">\") private static __gt(left: String, right: String): bool {\n if (changetype(left) == changetype(right)) return false;\n let leftLength = left.length;\n if (!leftLength) return false;\n let rightLength = right.length;\n if (!rightLength) return true;\n // @ts-ignore: string <-> String\n let res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));\n return res ? res > 0 : leftLength > rightLength;\n }\n\n @operator(\">=\") private static __gte(left: String, right: String): bool {\n return !this.__lt(left, right);\n }\n\n @operator(\"<\") private static __lt(left: String, right: String): bool {\n if (changetype(left) == changetype(right)) return false;\n let rightLength = right.length;\n if (!rightLength) return false;\n let leftLength = left.length;\n if (!leftLength) return true;\n // @ts-ignore: string <-> String\n let res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));\n return res ? res < 0 : leftLength < rightLength;\n }\n\n @operator(\"<=\") private static __lte(left: String, right: String): bool {\n return !this.__gt(left, right);\n }\n\n includes(search: String, start: i32 = 0): bool {\n return this.indexOf(search, start) != -1;\n }\n\n indexOf(search: String, start: i32 = 0): i32 {\n let searchLen = search.length;\n if (!searchLen) return 0;\n let len = this.length;\n if (!len) return -1;\n let searchStart = min(max(start, 0), len);\n for (len -= searchLen; searchStart <= len; ++searchStart) {\n // @ts-ignore: string <-> String\n if (!compareImpl(this, searchStart, search, 0, searchLen)) return searchStart;\n }\n return -1;\n }\n\n lastIndexOf(search: String, start: i32 = i32.MAX_VALUE): i32 {\n let searchLen = search.length;\n if (!searchLen) return this.length;\n let len = this.length;\n if (!len) return -1;\n let searchStart = min(max(start, 0), len - searchLen);\n for (; searchStart >= 0; --searchStart) {\n // @ts-ignore: string <-> String\n if (!compareImpl(this, searchStart, search, 0, searchLen)) return searchStart;\n }\n return -1;\n }\n\n // TODO: implement full locale comparison with locales and Collator options\n localeCompare(other: String): i32 {\n if (changetype(other) == changetype(this)) return 0;\n let alen = this.length;\n let blen = other.length;\n // @ts-ignore: string <-> String\n let res = compareImpl(this, 0, other, 0, min(alen, blen));\n res = res ? res : alen - blen;\n // normalize to [-1, 1] range\n return i32(res > 0) - i32(res < 0);\n }\n\n startsWith(search: String, start: i32 = 0): bool {\n let len = this.length;\n let searchStart = min(max(start, 0), len);\n let searchLength = search.length;\n if (searchLength + searchStart > len) return false;\n // @ts-ignore: string <-> String\n return !compareImpl(this, searchStart, search, 0, searchLength);\n }\n\n substr(start: i32, length: i32 = i32.MAX_VALUE): String { // legacy\n let intStart: isize = start;\n let end: isize = length;\n let len: isize = this.length;\n if (intStart < 0) intStart = max(len + intStart, 0);\n let size = min(max(end, 0), len - intStart) << 1;\n if (size <= 0) return changetype(\"\");\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + (intStart << 1), size);\n return out;\n }\n\n substring(start: i32, end: i32 = i32.MAX_VALUE): String {\n let len: isize = this.length;\n let finalStart = min(max(start, 0), len);\n let finalEnd = min(max(end, 0), len);\n let fromPos = min(finalStart, finalEnd) << 1;\n let toPos = max(finalStart, finalEnd) << 1;\n let size = toPos - fromPos;\n if (!size) return changetype(\"\");\n if (!fromPos && toPos == len << 1) return this;\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + fromPos, size);\n return out;\n }\n\n trim(): String {\n let len = this.length;\n let size: usize = len << 1;\n while (size && isSpace(load(changetype(this) + size - 2))) {\n size -= 2;\n }\n let offset: usize = 0;\n while (offset < size && isSpace(load(changetype(this) + offset))) {\n offset += 2; size -= 2;\n }\n if (!size) return changetype(\"\");\n if (!offset && size == len << 1) return this;\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + offset, size);\n return out;\n }\n\n @inline\n trimLeft(): String {\n return this.trimStart();\n }\n\n @inline\n trimRight(): String {\n return this.trimEnd();\n }\n\n trimStart(): String {\n let size = this.length << 1;\n let offset: usize = 0;\n while (offset < size && isSpace(load(changetype(this) + offset))) {\n offset += 2;\n }\n if (!offset) return this;\n size -= offset;\n if (!size) return changetype(\"\");\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + offset, size);\n return out;\n }\n\n trimEnd(): String {\n let originalSize = this.length << 1;\n let size = originalSize;\n while (size && isSpace(load(changetype(this) + size - 2))) {\n size -= 2;\n }\n if (!size) return changetype(\"\");\n if (size == originalSize) return this;\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this), size);\n return out;\n }\n\n padStart(length: i32, pad: string = \" \"): String {\n let thisSize = this.length << 1;\n let targetSize = length << 1;\n let padSize = pad.length << 1;\n if (targetSize < thisSize || !padSize) return this;\n let prependSize = targetSize - thisSize;\n let out = changetype(__new(targetSize, idof()));\n if (prependSize > padSize) {\n let repeatCount = (prependSize - 2) / padSize;\n let restBase = repeatCount * padSize;\n let restSize = prependSize - restBase;\n memory.repeat(changetype(out), changetype(pad), padSize, repeatCount);\n memory.copy(changetype(out) + restBase, changetype(pad), restSize);\n } else {\n memory.copy(changetype(out), changetype(pad), prependSize);\n }\n memory.copy(changetype(out) + prependSize, changetype(this), thisSize);\n return out;\n }\n\n padEnd(length: i32, pad: string = \" \"): String {\n let thisSize = this.length << 1;\n let targetSize = length << 1;\n let padSize = pad.length << 1;\n if (targetSize < thisSize || !padSize) return this;\n let appendSize = targetSize - thisSize;\n let out = changetype(__new(targetSize, idof()));\n memory.copy(changetype(out), changetype(this), thisSize);\n if (appendSize > padSize) {\n let repeatCount = (appendSize - 2) / padSize;\n let restBase = repeatCount * padSize;\n let restSize = appendSize - restBase;\n memory.repeat(changetype(out) + thisSize, changetype(pad), padSize, repeatCount);\n memory.copy(changetype(out) + thisSize + restBase, changetype(pad), restSize);\n } else {\n memory.copy(changetype(out) + thisSize, changetype(pad), appendSize);\n }\n return out;\n }\n\n repeat(count: i32 = 0): String {\n let length = this.length;\n\n // Most browsers can't handle strings 1 << 28 chars or longer\n if (count < 0 || length * count > (1 << 28)) {\n throw new RangeError(E_INVALIDLENGTH);\n }\n\n if (count == 0 || !length) return changetype(\"\");\n if (count == 1) return this;\n let out = changetype(__new((length * count) << 1, idof()));\n memory.repeat(changetype(out), changetype(this), length << 1, count);\n return out;\n }\n\n replace(search: String, replacement: String): String {\n let len: usize = this.length;\n let slen: usize = search.length;\n if (len <= slen) {\n return len < slen ? this : select(replacement, this, search == this);\n }\n let index: isize = this.indexOf(search);\n if (~index) {\n let rlen: usize = replacement.length;\n len -= slen;\n let olen = len + rlen;\n if (olen) {\n let out = changetype(__new(olen << 1, idof()));\n memory.copy(changetype(out), changetype(this), index << 1);\n memory.copy(\n changetype(out) + (index << 1),\n changetype(replacement),\n rlen << 1\n );\n memory.copy(\n changetype(out) + ((index + rlen) << 1),\n changetype(this) + ((index + slen) << 1),\n (len - index) << 1\n );\n return out;\n }\n }\n return this;\n }\n\n replaceAll(search: String, replacement: String): String {\n let thisLen: usize = this.length;\n let searchLen: usize = search.length;\n if (thisLen <= searchLen) {\n return thisLen < searchLen\n ? this\n : select(replacement, this, search == this);\n }\n let replaceLen: usize = replacement.length;\n if (!searchLen) {\n if (!replaceLen) return this;\n // Special case: 'abc'.replaceAll('', '-') -> '-a-b-c-'\n let out = changetype(__new((thisLen + (thisLen + 1) * replaceLen) << 1, idof()));\n memory.copy(changetype(out), changetype(replacement), replaceLen << 1);\n let offset = replaceLen;\n for (let i: usize = 0; i < thisLen; ++i) {\n store(\n changetype(out) + (offset++ << 1),\n load(changetype(this) + (i << 1))\n );\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(replacement),\n replaceLen << 1\n );\n offset += replaceLen;\n }\n return out;\n }\n let prev: isize = 0, next: isize = 0;\n if (searchLen == replaceLen) {\n // Fast path when search and replacement have same length\n let outSize = thisLen << 1;\n let out = changetype(__new(outSize, idof()));\n memory.copy(changetype(out), changetype(this), outSize);\n while (~(next = this.indexOf(search, prev))) {\n memory.copy(changetype(out) + (next << 1), changetype(replacement), replaceLen << 1);\n prev = next + searchLen;\n }\n return out;\n }\n let out: String | null = null, offset: usize = 0, outSize = thisLen;\n while (~(next = this.indexOf(search, prev))) {\n if (!out) out = changetype(__new(thisLen << 1, idof()));\n let chunk = next - prev;\n if (offset + chunk + replaceLen > outSize) {\n outSize <<= 1;\n out = changetype(__renew(changetype(out), outSize << 1));\n }\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(this) + (prev << 1),\n chunk << 1\n );\n offset += chunk;\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(replacement),\n replaceLen << 1\n );\n offset += replaceLen;\n prev = next + searchLen;\n }\n if (out) {\n let rest = thisLen - prev;\n if (offset + rest > outSize) {\n outSize <<= 1;\n out = changetype(__renew(changetype(out), outSize << 1));\n }\n if (rest) {\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(this) + (prev << 1),\n rest << 1\n );\n }\n rest += offset;\n if (outSize > rest) {\n out = changetype(__renew(changetype(out), rest << 1));\n }\n return out;\n }\n return this;\n }\n\n slice(start: i32, end: i32 = i32.MAX_VALUE): String {\n let len = this.length;\n start = start < 0 ? max(start + len, 0) : min(start, len);\n end = end < 0 ? max(end + len, 0) : min(end, len);\n len = end - start;\n if (len <= 0) return changetype(\"\");\n let out = changetype(__new(len << 1, idof()));\n memory.copy(changetype(out), changetype(this) + (start << 1), len << 1);\n return out;\n }\n\n split(separator: String | null = null, limit: i32 = i32.MAX_VALUE): String[] {\n if (!limit) return changetype(__newArray(0, alignof(), idof>()));\n if (changetype(separator) == 0) return [ this ];\n let length: isize = this.length;\n let sepLen = changetype(separator).length;\n if (limit < 0) limit = i32.MAX_VALUE;\n if (!sepLen) {\n if (!length) return changetype(__newArray(0, alignof(), idof>()));\n // split by chars\n length = min(length, limit);\n let result = changetype(__newArray(length, alignof(), idof>()));\n // @ts-ignore: cast\n let resultStart = result.dataStart as usize;\n for (let i: isize = 0; i < length; ++i) {\n let charStr = changetype(__new(2, idof()));\n store(changetype(charStr), load(changetype(this) + (i << 1)));\n store(resultStart + (i << alignof()), changetype(charStr)); // result[i] = charStr\n __link(changetype(result), changetype(charStr), true);\n }\n return result;\n } else if (!length) {\n let result = changetype(__newArray(1, alignof(), idof>()));\n // @ts-ignore: cast\n store(result.dataStart as usize, changetype(\"\")); // static \"\"\n return result;\n }\n let result = changetype(__newArray(0, alignof(), idof>()));\n let end = 0, start = 0, i = 0;\n while (~(end = this.indexOf(changetype(separator), start))) {\n let len = end - start;\n if (len > 0) {\n let out = changetype(__new(len << 1, idof()));\n memory.copy(changetype(out), changetype(this) + (start << 1), len << 1);\n result.push(out);\n } else {\n result.push(changetype(\"\"));\n }\n if (++i == limit) return result;\n start = end + sepLen;\n }\n if (!start) { // also means: loop above didn't do anything\n result.push(this);\n return result;\n }\n let len = length - start;\n if (len > 0) {\n let out = changetype(__new(len << 1, idof()));\n memory.copy(changetype(out), changetype(this) + (start << 1), len << 1);\n result.push(out);\n } else {\n result.push(changetype(\"\")); // static \"\"\n }\n return result;\n }\n\n toLowerCase(): String {\n let len = this.length;\n if (!len) return this;\n let codes = changetype(__new(len * 2 * 2, idof()));\n let j: usize = 0;\n for (let i: usize = 0; i < len; ++i, ++j) {\n let c = load(changetype(this) + (i << 1));\n if (isAscii(c)) {\n store(changetype(codes) + (j << 1), toLower8(c));\n } else {\n // check and read surrogate pair\n if ((c - 0xD7FF < 0xDC00 - 0xD7FF) && i < len - 1) {\n let c1 = load(changetype(this) + (i << 1), 2);\n if (c1 - 0xDBFF < 0xE000 - 0xDBFF) {\n let c0 = c;\n c = (((c & 0x03FF) << 10) | (c1 & 0x03FF)) + 0x10000;\n ++i;\n if (c >= 0x20000) {\n store(changetype(codes) + (j << 1), c0 | (c1 << 16));\n ++j;\n continue;\n }\n }\n }\n // check special casing for lower table. It has one ently so instead lookup we just inline this.\n if (c == 0x0130) {\n // 0x0130 -> [0x0069, 0x0307]\n store(changetype(codes) + (j << 1), (0x0307 << 16) | 0x0069);\n ++j;\n } else if (c == 0x03A3) { // 'Σ'\n // Σ maps to σ but except at the end of a word where it maps to ς\n let sigma = 0x03C3; // σ\n if (len > 1 && isFinalSigma(changetype(this), i, len)) {\n sigma = 0x03C2; // ς\n }\n store(changetype(codes) + (j << 1), sigma);\n } else if (c - 0x24B6 <= 0x24CF - 0x24B6) {\n // Range 0x24B6 <= c <= 0x24CF not covered by casemap and require special early handling\n store(changetype(codes) + (j << 1), c + 26);\n } else {\n let code = casemap(c, 0) & 0x1FFFFF;\n if (code < 0x10000) {\n store(changetype(codes) + (j << 1), code);\n } else {\n // store as surrogare pair\n code -= 0x10000;\n let lo = (code >>> 10) | 0xD800;\n let hi = (code & 0x03FF) | 0xDC00;\n store(changetype(codes) + (j << 1), lo | (hi << 16));\n ++j;\n }\n }\n }\n }\n return changetype(__renew(changetype(codes), j << 1));\n }\n\n toUpperCase(): String {\n let len = this.length;\n if (!len) return this;\n let codes = changetype(__new(len * 3 * 2, idof()));\n let specialsPtr = changetype(SPECIALS_UPPER);\n let specialsLen = SPECIALS_UPPER.length;\n let j: usize = 0;\n for (let i: usize = 0; i < len; ++i, ++j) {\n let c = load(changetype(this) + (i << 1));\n if (isAscii(c)) {\n store(changetype(codes) + (j << 1), toUpper8(c));\n } else {\n // check and read surrogate pair\n if ((c - 0xD7FF < 0xDC00 - 0xD7FF) && i < len - 1) {\n let c1 = load(changetype(this) + (i << 1), 2);\n if (c1 - 0xDBFF < 0xE000 - 0xDBFF) {\n let c0 = c;\n c = (((c & 0x03FF) << 10) | (c1 & 0x03FF)) + 0x10000;\n ++i;\n if (c >= 0x20000) {\n store(changetype(codes) + (j << 1), c0 | (c1 << 16));\n ++j;\n continue;\n }\n }\n }\n // Range 0x24D0 <= c <= 0x24E9 not covered by casemap and require special early handling\n if (c - 0x24D0 <= 0x24E9 - 0x24D0) {\n // monkey patch\n store(changetype(codes) + (j << 1), c - 26);\n } else {\n let index: usize = -1;\n // Fast range check. See first and last rows in specialsUpper table\n if (c - 0x00DF <= 0xFB17 - 0x00DF) {\n index = bsearch(c, specialsPtr, specialsLen);\n }\n if (~index) {\n // load next 3 code points from row with `index` offset for specialsUpper table\n let ab = load(specialsPtr + (index << 1), 2);\n let cc = load(specialsPtr + (index << 1), 6);\n store(changetype(codes) + (j << 1), ab, 0);\n store(changetype(codes) + (j << 1), cc, 4);\n j += 1 + usize(cc != 0);\n } else {\n let code = casemap(c, 1) & 0x1FFFFF;\n if (code < 0x10000) {\n store(changetype(codes) + (j << 1), code);\n } else {\n // store as surrogare pair\n code -= 0x10000;\n let lo = (code >>> 10) | 0xD800;\n let hi = (code & 0x03FF) | 0xDC00;\n store(changetype(codes) + (j << 1), lo | (hi << 16));\n ++j;\n }\n }\n }\n }\n }\n return changetype(__renew(changetype(codes), j << 1));\n }\n\n toString(): String {\n return this;\n }\n}\n\n// @ts-ignore: nolib\nexport type string = String;\n\nexport function parseInt(str: string, radix: i32 = 0): f64 {\n return strtol(str, radix);\n}\n\nexport function parseFloat(str: string): f64 {\n return strtod(str);\n}\n\n// Encoding helpers\nexport namespace String {\n\n export namespace UTF8 {\n\n export const enum ErrorMode {\n WTF8,\n REPLACE,\n ERROR\n }\n\n export function byteLength(str: string, nullTerminated: bool = false): i32 {\n let strOff = changetype(str);\n let strEnd = strOff + changetype(changetype(str) - TOTAL_OVERHEAD).rtSize;\n let bufLen = i32(nullTerminated);\n while (strOff < strEnd) {\n let c1 = load(strOff);\n if (c1 < 128) {\n // @ts-ignore: cast\n if (nullTerminated & !c1) break;\n bufLen += 1;\n } else if (c1 < 2048) {\n bufLen += 2;\n } else {\n if ((c1 & 0xFC00) == 0xD800 && strOff + 2 < strEnd) {\n if ((load(strOff, 2) & 0xFC00) == 0xDC00) {\n bufLen += 4; strOff += 4;\n continue;\n }\n }\n bufLen += 3;\n }\n strOff += 2;\n }\n return bufLen;\n }\n\n export function encode(str: string, nullTerminated: bool = false, errorMode: ErrorMode = ErrorMode.WTF8): ArrayBuffer {\n let buf = changetype(__new(byteLength(str, nullTerminated), idof()));\n encodeUnsafe(changetype(str), str.length, changetype(buf), nullTerminated, errorMode);\n return buf;\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function encodeUnsafe(str: usize, len: i32, buf: usize, nullTerminated: bool = false, errorMode: ErrorMode = ErrorMode.WTF8): usize {\n let strEnd = str + (len << 1);\n let bufOff = buf;\n while (str < strEnd) {\n let c1 = load(str);\n if (c1 < 128) {\n store(bufOff, c1);\n bufOff++;\n // @ts-ignore: cast\n if (nullTerminated & !c1) return bufOff - buf;\n } else if (c1 < 2048) {\n let b0 = c1 >> 6 | 192;\n let b1 = c1 & 63 | 128;\n store(bufOff, b1 << 8 | b0);\n bufOff += 2;\n } else {\n // D800: 11011 0 0000000000 Lead\n // DBFF: 11011 0 1111111111\n // DC00: 11011 1 0000000000 Trail\n // DFFF: 11011 1 1111111111\n // F800: 11111 0 0000000000 Mask\n // FC00: 11111 1 0000000000\n if ((c1 & 0xF800) == 0xD800) {\n if (c1 < 0xDC00 && str + 2 < strEnd) {\n let c2 = load(str, 2);\n if ((c2 & 0xFC00) == 0xDC00) {\n c1 = 0x10000 + ((c1 & 0x03FF) << 10) | (c2 & 0x03FF);\n let b0 = c1 >> 18 | 240;\n let b1 = c1 >> 12 & 63 | 128;\n let b2 = c1 >> 6 & 63 | 128;\n let b3 = c1 & 63 | 128;\n store(bufOff, b3 << 24 | b2 << 16 | b1 << 8 | b0);\n bufOff += 4; str += 4;\n continue;\n }\n }\n if (errorMode != ErrorMode.WTF8) { // unlikely\n if (errorMode == ErrorMode.ERROR) throw new Error(E_UNPAIRED_SURROGATE);\n c1 = 0xFFFD;\n }\n }\n let b0 = c1 >> 12 | 224;\n let b1 = c1 >> 6 & 63 | 128;\n let b2 = c1 & 63 | 128;\n store(bufOff, b1 << 8 | b0);\n store(bufOff, b2, 2);\n bufOff += 3;\n }\n str += 2;\n }\n if (nullTerminated) {\n store(bufOff++, 0);\n }\n return bufOff - buf;\n }\n\n export function decode(buf: ArrayBuffer, nullTerminated: bool = false): String {\n return decodeUnsafe(changetype(buf), buf.byteLength, nullTerminated);\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function decodeUnsafe(buf: usize, len: usize, nullTerminated: bool = false): String {\n let bufOff = buf;\n let bufEnd = buf + len;\n assert(bufEnd >= bufOff); // guard wraparound\n let str = changetype(__new(len << 1, idof())); // max is one u16 char per u8 byte\n let strOff = changetype(str);\n while (bufOff < bufEnd) {\n let u0 = load(bufOff); ++bufOff;\n if (!(u0 & 128)) {\n // @ts-ignore: cast\n if (nullTerminated & !u0) break;\n store(strOff, u0);\n } else {\n if (bufEnd == bufOff) break;\n let u1 = load(bufOff) & 63; ++bufOff;\n if ((u0 & 224) == 192) {\n store(strOff, (u0 & 31) << 6 | u1);\n } else {\n if (bufEnd == bufOff) break;\n let u2 = load(bufOff) & 63; ++bufOff;\n if ((u0 & 240) == 224) {\n u0 = (u0 & 15) << 12 | u1 << 6 | u2;\n } else {\n if (bufEnd == bufOff) break;\n u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | load(bufOff) & 63;\n ++bufOff;\n }\n if (u0 < 0x10000) {\n store(strOff, u0);\n } else {\n u0 -= 0x10000;\n let lo = u0 >> 10 | 0xD800;\n let hi = (u0 & 0x03FF) | 0xDC00;\n store(strOff, lo | (hi << 16));\n strOff += 2;\n }\n }\n }\n strOff += 2;\n }\n return changetype(__renew(changetype(str), strOff - changetype(str)));\n }\n }\n\n export namespace UTF16 {\n\n export function byteLength(str: string): i32 {\n return changetype(changetype(str) - TOTAL_OVERHEAD).rtSize;\n }\n\n export function encode(str: string): ArrayBuffer {\n let buf = changetype(__new(byteLength(str), idof()));\n encodeUnsafe(changetype(str), str.length, changetype(buf));\n return buf;\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function encodeUnsafe(str: usize, len: i32, buf: usize): usize {\n let size = len << 1;\n memory.copy(buf, changetype(str), size);\n return size;\n }\n\n export function decode(buf: ArrayBuffer): String {\n return decodeUnsafe(changetype(buf), buf.byteLength);\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function decodeUnsafe(buf: usize, len: usize): String {\n let str = changetype(__new(len &= ~1, idof()));\n memory.copy(changetype(str), buf, len);\n return str;\n }\n }\n}\n\nexport class TemplateStringsArray extends Array {\n readonly raw: string[];\n}\n","// Common error messages for use across the standard library. Keeping error messages compact\n// and reusing them where possible ensures minimal static data in binaries.\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_INDEXOUTOFRANGE: string = \"Index out of range\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_VALUEOUTOFRANGE: string = \"Value out of range\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_INVALIDLENGTH: string = \"Invalid length\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_EMPTYARRAY: string = \"Array is empty\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_HOLEYARRAY: string = \"Element type must be nullable if array is holey\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_NOTIMPLEMENTED: string = \"Not implemented\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_KEYNOTFOUND: string = \"Key does not exist\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_ALLOCATION_TOO_LARGE: string = \"Allocation too large\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_ALREADY_PINNED: string = \"Object already pinned\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_NOT_PINNED: string = \"Object is not pinned\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_URI_MALFORMED: string = \"URI malformed\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_INVALIDDATE: string = \"Invalid Date\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_UNPAIRED_SURROGATE: string = \"Unpaired surrogate\";\n","import { Typeinfo, TypeinfoFlags } from \"./shared/typeinfo\";\nimport { E_INDEXOUTOFRANGE } from \"./util/error\";\nimport { ArrayBufferView } from \"./arraybuffer\";\n\n// @ts-ignore: decorator\n@builtin\nexport declare const __rtti_base: usize;\n\n// @ts-ignore: decorator\n@builtin @unsafe\nexport declare function __visit_globals(cookie: u32): void;\n\n// @ts-ignore: decorator\n@builtin @unsafe\nexport declare function __visit_members(ref: usize, cookie: u32): void;\n\n// @ts-ignore: decorator\n@unsafe\nexport function __typeinfo(id: u32): TypeinfoFlags {\n let ptr = __rtti_base;\n if (id > load(ptr)) throw new Error(E_INDEXOUTOFRANGE);\n return changetype(ptr + sizeof() + id * offsetof()).flags;\n}\n\n// @ts-ignore: decorator\n@unsafe\nexport function __newBuffer(size: usize, id: u32, data: usize = 0): usize {\n let buffer = __new(size, id);\n if (data) memory.copy(buffer, data, size);\n return buffer;\n}\n\n// @ts-ignore: decorator\n@unsafe\nexport function __newArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize {\n let bufferSize = length << alignLog2;\n // make sure `buffer` is tracked by the shadow stack\n let buffer = changetype(__newBuffer(bufferSize, idof(), data));\n // ...since allocating the array may trigger GC steps\n let array = __new(offsetof(), id);\n store(array, changetype(buffer), offsetof(\"buffer\"));\n __link(array, changetype(buffer), false);\n store(array, changetype(buffer), offsetof(\"dataStart\"));\n store(array, bufferSize, offsetof(\"byteLength\"));\n store(array, length, offsetof(\"length_\"));\n return array;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nfunction __tostack(ptr: usize): usize { // eslint-disable-line\n return ptr;\n}\n\n// These are provided by the respective implementation, included as another entry file by asc:\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __alloc(size: usize): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __realloc(ptr: usize, size: usize): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __free(ptr: usize): void;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __new(size: usize, id: u32): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __renew(ptr: usize, size: usize): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __collect(): void;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __visit(ptr: usize, cookie: u32): void;\n","// This file is shared with the compiler and must remain portable\n\n/** Indicates specific features to activate. */\nexport const enum Feature {\n /** No additional features. */\n None = 0,\n /** Sign extension operations. */\n SignExtension = 1 << 0, // see: https://github.com/WebAssembly/sign-extension-ops\n /** Mutable global imports and exports. */\n MutableGlobals = 1 << 1, // see: https://github.com/WebAssembly/mutable-global\n /** Non-trapping float to integer operations. */\n NontrappingF2I = 1 << 2, // see: https://github.com/WebAssembly/nontrapping-float-to-int-conversions\n /** Bulk memory operations. */\n BulkMemory = 1 << 3, // see: https://github.com/WebAssembly/bulk-memory-operations\n /** SIMD types and operations. */\n Simd = 1 << 4, // see: https://github.com/WebAssembly/simd\n /** Threading and atomic operations. */\n Threads = 1 << 5, // see: https://github.com/WebAssembly/threads\n /** Exception handling operations. */\n ExceptionHandling = 1 << 6, // see: https://github.com/WebAssembly/exception-handling\n /** Tail call operations. */\n TailCalls = 1 << 7, // see: https://github.com/WebAssembly/tail-call\n /** Reference types. */\n ReferenceTypes = 1 << 8, // see: https://github.com/WebAssembly/reference-types\n /** Multi value types. */\n MultiValue = 1 << 9, // see: https://github.com/WebAssembly/multi-value\n /** Garbage collection. */\n GC = 1 << 10, // see: https://github.com/WebAssembly/gc\n /** Memory64. */\n Memory64 = 1 << 11, // see: https://github.com/WebAssembly/memory64\n /** Relaxed SIMD. */\n RelaxedSimd = 1 << 12, // see: https://github.com/WebAssembly/relaxed-simd\n /** Extended const expressions. */\n ExtendedConst = 1 << 13, // see: https://github.com/WebAssembly/extended-const\n /** Reference typed strings. */\n Stringref = 1 << 14, // see: https://github.com/WebAssembly/stringref\n}\n\n/** Gets the name of the specified feature one would specify on the command line. */\nexport function featureToString(feature: Feature): string {\n switch (feature) {\n case Feature.SignExtension: return \"sign-extension\";\n case Feature.MutableGlobals: return \"mutable-globals\";\n case Feature.NontrappingF2I: return \"nontrapping-f2i\";\n case Feature.BulkMemory: return \"bulk-memory\";\n case Feature.Simd: return \"simd\";\n case Feature.Threads: return \"threads\";\n case Feature.ExceptionHandling: return \"exception-handling\";\n case Feature.TailCalls: return \"tail-calls\";\n case Feature.ReferenceTypes: return \"reference-types\";\n case Feature.MultiValue: return \"multi-value\";\n case Feature.GC: return \"gc\";\n case Feature.Memory64: return \"memory64\";\n case Feature.RelaxedSimd: return \"relaxed-simd\";\n case Feature.ExtendedConst: return \"extended-const\";\n case Feature.Stringref: return \"stringref\";\n }\n assert(false);\n return \"\";\n}\n","// This file is shared with the compiler and must remain portable\n\n/** Compilation target. */\nexport enum Target {\n /** Portable. */\n Js = 0,\n /** WebAssembly with 32-bit pointers. */\n Wasm32 = 1,\n /** WebAssembly with 64-bit pointers. Experimental and not supported by any runtime yet. */\n Wasm64 = 2,\n}\n","// This file is shared with the compiler and must remain portable\n\n/** Runtime types. */\nexport enum Runtime {\n /** Simple bump allocator without GC. */\n Stub = 0,\n /** Stop the world semi-automatic GC. */\n Minimal = 1,\n /** incremental GC. */\n Incremental = 2,\n}\n","// This file is shared with the compiler and must remain portable\n\n// ╒═══════════════════ Typeinfo interpretation ═══════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤ ◄─ __rtti_base\n// │ count │\n// ╞═══════════════════════════════════════════════════════════════╡ ┐\n// │ Typeinfo#flags [id=0] │ id < count\n// ├───────────────────────────────────────────────────────────────┤\n// │ ... │\n\n/** Runtime type information data structure. */\n@unmanaged\nexport class Typeinfo {\n /** Flags describing the shape of this class type. */\n flags: TypeinfoFlags = TypeinfoFlags.NONE;\n}\n\n/** Runtime type information flags. */\nexport const enum TypeinfoFlags {\n /** No specific flags. */\n NONE = 0,\n /** Type is an `ArrayBufferView`. */\n ARRAYBUFFERVIEW = 1 << 0,\n /** Type is an `Array`. */\n ARRAY = 1 << 1,\n /** Type is a `StaticArray`. */\n STATICARRAY = 1 << 2,\n /** Type is a `Set`. */\n SET = 1 << 3,\n /** Type is a `Map`. */\n MAP = 1 << 4,\n /** Type has no outgoing pointers. */\n POINTERFREE = 1 << 5,\n /** Value alignment of 1 byte. */\n VALUE_ALIGN_0 = 1 << 6,\n /** Value alignment of 2 bytes. */\n VALUE_ALIGN_1 = 1 << 7,\n /** Value alignment of 4 bytes. */\n VALUE_ALIGN_2 = 1 << 8,\n /** Value alignment of 8 bytes. */\n VALUE_ALIGN_3 = 1 << 9,\n /** Value alignment of 16 bytes. */\n VALUE_ALIGN_4 = 1 << 10,\n /** Value is a signed type. */\n VALUE_SIGNED = 1 << 11,\n /** Value is a float type. */\n VALUE_FLOAT = 1 << 12,\n /** Value type is nullable. */\n VALUE_NULLABLE = 1 << 13,\n /** Value type is managed. */\n VALUE_MANAGED = 1 << 14,\n /** Key alignment of 1 byte. */\n KEY_ALIGN_0 = 1 << 15,\n /** Key alignment of 2 bytes. */\n KEY_ALIGN_1 = 1 << 16,\n /** Key alignment of 4 bytes. */\n KEY_ALIGN_2 = 1 << 17,\n /** Key alignment of 8 bytes. */\n KEY_ALIGN_3 = 1 << 18,\n /** Key alignment of 16 bytes. */\n KEY_ALIGN_4 = 1 << 19,\n /** Key is a signed type. */\n KEY_SIGNED = 1 << 20,\n /** Key is a float type. */\n KEY_FLOAT = 1 << 21,\n /** Key type is nullable. */\n KEY_NULLABLE = 1 << 22,\n /** Key type is managed. */\n KEY_MANAGED = 1 << 23\n}\n","/**\n * @fileoverview The AssemblyScript compiler.\n * @license Apache-2.0\n */\n\n// helper globals used by mangleImportName\nlet mangleImportName_moduleName: string = \"\";\nlet mangleImportName_elementName: string = \"\";\n\nimport {\n BuiltinNames,\n BuiltinFunctionContext,\n BuiltinVariableContext,\n builtinFunctions,\n builtinVariables_onAccess,\n builtinVariables_onCompile,\n compileVisitGlobals,\n compileVisitMembers,\n compileRTTI\n} from \"./builtins\";\n\nimport {\n Range,\n DiagnosticCode,\n DiagnosticEmitter\n} from \"./diagnostics\";\n\nimport {\n Module,\n MemorySegment,\n ExpressionRef,\n UnaryOp,\n BinaryOp,\n TypeRef,\n FunctionRef,\n ExpressionId,\n GlobalRef,\n FeatureFlags,\n Index,\n getExpressionId,\n getExpressionType,\n getConstValueI32,\n getConstValueI64Low,\n getConstValueI64High,\n getConstValueF32,\n getConstValueF64,\n getConstValueV128,\n getBlockChildCount,\n getBlockChildAt,\n getBlockName,\n getLocalSetValue,\n getGlobalGetName,\n isGlobalMutable,\n getSideEffects,\n SideEffects,\n SwitchBuilder,\n ExpressionRunnerFlags,\n isConstZero,\n isConstNegZero,\n isConstExpressionNaN,\n ensureType,\n createType\n} from \"./module\";\n\nimport {\n CommonFlags,\n STATIC_DELIMITER,\n INDEX_SUFFIX,\n CommonNames,\n Feature,\n Target,\n Runtime\n} from \"./common\";\n\nimport {\n Program,\n ClassPrototype,\n Class,\n Element,\n ElementKind,\n DeclaredElement,\n Enum,\n FunctionPrototype,\n Function,\n Global,\n Local,\n EnumValue,\n Property,\n VariableLikeElement,\n ConstantValueKind,\n OperatorKind,\n DecoratorFlags,\n PropertyPrototype,\n IndexSignature,\n File,\n mangleInternalName\n} from \"./program\";\n\nimport {\n FlowFlags,\n Flow,\n LocalFlags,\n FieldFlags,\n ConditionKind\n} from \"./flow\";\n\nimport {\n Resolver,\n ReportMode\n} from \"./resolver\";\n\nimport {\n Token,\n operatorTokenToString\n} from \"./tokenizer\";\n\nimport {\n Node,\n NodeKind,\n DecoratorKind,\n AssertionKind,\n SourceKind,\n FunctionTypeNode,\n DecoratorNode,\n\n Statement,\n BlockStatement,\n BreakStatement,\n ClassDeclaration,\n ContinueStatement,\n DeclarationStatement,\n DoStatement,\n EmptyStatement,\n EnumDeclaration,\n ExportDefaultStatement,\n ExportStatement,\n ExpressionStatement,\n FieldDeclaration,\n ForStatement,\n ForOfStatement,\n FunctionDeclaration,\n IfStatement,\n ImportStatement,\n InstanceOfExpression,\n NamespaceDeclaration,\n ReturnStatement,\n SwitchStatement,\n ThrowStatement,\n TryStatement,\n VariableStatement,\n VoidStatement,\n WhileStatement,\n\n Expression,\n AssertionExpression,\n BinaryExpression,\n CallExpression,\n CommaExpression,\n ElementAccessExpression,\n FloatLiteralExpression,\n FunctionExpression,\n IdentifierExpression,\n IntegerLiteralExpression,\n LiteralExpression,\n LiteralKind,\n NewExpression,\n ObjectLiteralExpression,\n ParenthesizedExpression,\n PropertyAccessExpression,\n TernaryExpression,\n ArrayLiteralExpression,\n StringLiteralExpression,\n TemplateLiteralExpression,\n UnaryPostfixExpression,\n UnaryPrefixExpression,\n CompiledExpression,\n\n TypeNode,\n NamedTypeNode,\n\n findDecorator,\n isTypeOmitted,\n Source\n} from \"./ast\";\n\nimport {\n Type,\n TypeKind,\n TypeFlags,\n Signature,\n typesToRefs\n} from \"./types\";\n\nimport {\n writeI8,\n writeI16,\n writeI32,\n writeI64,\n writeF32,\n writeF64,\n writeV128,\n cloneMap,\n isPowerOf2,\n readI32,\n isIdentifier,\n accuratePow64,\n v128_zero,\n v128_ones,\n} from \"./util\";\n\nimport {\n RtraceMemory\n} from \"./passes/rtrace\";\n\nimport {\n ShadowStackPass\n} from \"./passes/shadowstack\";\n\nimport {\n liftRequiresExportRuntime,\n lowerRequiresExportRuntime\n} from \"./bindings/js\";\n\n/** Compiler options. */\nexport class Options {\n constructor() { /* as internref */ }\n\n /** WebAssembly target. Defaults to {@link Target.Wasm32}. */\n target: Target = Target.Wasm32;\n /** Runtime type. Defaults to Incremental GC. */\n runtime: Runtime = Runtime.Incremental;\n /** If true, indicates that debug information will be emitted by Binaryen. */\n debugInfo: bool = false;\n /** If true, replaces assertions with nops. */\n noAssert: bool = false;\n /** It true, exports the memory to the embedder. */\n exportMemory: bool = true;\n /** If true, imports the memory provided by the embedder. */\n importMemory: bool = false;\n /** Initial memory size, in pages. */\n initialMemory: u32 = 0;\n /** Maximum memory size, in pages. */\n maximumMemory: u32 = 0;\n /** If true, memory is declared as shared. */\n sharedMemory: bool = false;\n /** If true, imported memory is zero filled. */\n zeroFilledMemory: bool = false;\n /** If true, imports the function table provided by the embedder. */\n importTable: bool = false;\n /** If true, exports the function table. */\n exportTable: bool = false;\n /** If true, generates information necessary for source maps. */\n sourceMap: bool = false;\n /** Unchecked behavior. Defaults to only using unchecked operations inside unchecked(). */\n uncheckedBehavior: UncheckedBehavior = UncheckedBehavior.Default;\n /** If given, exports the start function instead of calling it implicitly. */\n exportStart: string | null = null;\n /** Static memory start offset. */\n memoryBase: u32 = 0;\n /** Static table start offset. */\n tableBase: u32 = 0;\n /** Global aliases, mapping alias names as the key to internal names to be aliased as the value. */\n globalAliases: Map | null = null;\n /** Features to activate by default. These are the finished proposals. */\n features: Feature = Feature.MutableGlobals\n | Feature.SignExtension\n | Feature.NontrappingF2I\n | Feature.BulkMemory;\n /** If true, disallows unsafe features in user code. */\n noUnsafe: bool = false;\n /** If true, enables pedantic diagnostics. */\n pedantic: bool = false;\n /** Indicates a very low (<64k) memory limit. */\n lowMemoryLimit: u32 = 0;\n /** If true, exports the runtime helpers. */\n exportRuntime: bool = false;\n /** Stack size in bytes, if using a stack. */\n stackSize: i32 = 0;\n /** Semantic major bundle version from root package.json */\n bundleMajorVersion: i32 = 0;\n /** Semantic minor bundle version from root package.json */\n bundleMinorVersion: i32 = 0;\n /** Semantic patch bundle version from root package.json */\n bundlePatchVersion: i32 = 0;\n\n /** Hinted optimize level. Not applied by the compiler itself. */\n optimizeLevelHint: i32 = 0;\n /** Hinted shrink level. Not applied by the compiler itself. */\n shrinkLevelHint: i32 = 0;\n /** Hinted basename. */\n basenameHint: string = \"output\";\n /** Hinted bindings generation. */\n bindingsHint: bool = false;\n\n /** Tests if the target is WASM64 or, otherwise, WASM32. */\n get isWasm64(): bool {\n return this.target == Target.Wasm64;\n }\n\n /** Gets the unsigned size type matching the target. */\n get usizeType(): Type {\n return this.target == Target.Wasm64 ? Type.usize64 : Type.usize32;\n }\n\n /** Gets the signed size type matching the target. */\n get isizeType(): Type {\n return this.target == Target.Wasm64 ? Type.isize64 : Type.isize32;\n }\n\n /** Gets the size type reference matching the target. */\n get sizeTypeRef(): TypeRef {\n return this.target == Target.Wasm64 ? TypeRef.I64 : TypeRef.I32;\n }\n\n /** Gets if any optimizations will be performed. */\n get willOptimize(): bool {\n return this.optimizeLevelHint > 0 || this.shrinkLevelHint > 0;\n }\n\n /** Tests if a specific feature is activated. */\n hasFeature(feature: Feature): bool {\n return (this.features & feature) != 0;\n }\n}\n\n/** Behaviors regarding unchecked operations. */\nexport const enum UncheckedBehavior {\n /** Only use unchecked operations inside unchecked(). */\n Default = 0,\n /** Never use unchecked operations. */\n Never = 1,\n /** Always use unchecked operations if possible. */\n Always = 2\n}\n\n/** Various constraints in expression compilation. */\nexport const enum Constraints {\n None = 0,\n\n /** Must implicitly convert to the target type. */\n ConvImplicit = 1 << 0,\n /** Must explicitly convert to the target type. */\n ConvExplicit = 1 << 1,\n /** Must wrap small integer values to match the target type. */\n MustWrap = 1 << 2,\n\n /** Indicates that the value will be dropped immediately. */\n WillDrop = 1 << 3,\n /** Indicates that static data is preferred. */\n PreferStatic = 1 << 4,\n /** Indicates that the value will become `this` of a property access or instance call. */\n IsThis = 1 << 5\n}\n\n/** Runtime features to be activated by the compiler. */\nexport const enum RuntimeFeatures {\n None = 0,\n /** Requires data setup. */\n Data = 1 << 0,\n /** Requires a stack. */\n Stack = 1 << 1,\n /** Requires heap setup. */\n Heap = 1 << 2,\n /** Requires runtime type information setup. */\n Rtti = 1 << 3,\n /** Requires the built-in globals visitor. */\n visitGlobals = 1 << 4,\n /** Requires the built-in members visitor. */\n visitMembers = 1 << 5,\n /** Requires the setArgumentsLength export. */\n setArgumentsLength = 1 << 6\n}\n\n/** Imported default names of compiler-generated elements. */\nexport namespace ImportNames {\n /** Name of the default namespace */\n export const DefaultNamespace = \"env\";\n /** Name of the memory instance, if imported. */\n export const Memory = \"memory\";\n /** Name of the table instance, if imported. */\n export const Table = \"table\";\n}\n\n/** Exported names of compiler-generated elements. */\nexport namespace ExportNames {\n /** Name of the memory instance, if exported. */\n export const Memory = \"memory\";\n /** Name of the table instance, if exported. */\n export const Table = \"table\";\n /** Name of the argumentsLength varargs helper global. */\n export const argumentsLength = \"__argumentsLength\";\n /** Name of the alternative argumentsLength setter function. */\n export const setArgumentsLength = \"__setArgumentsLength\";\n}\n\n/** Functions to export if `--exportRuntime` is set. */\nconst runtimeFunctions = [ \"__new\", \"__pin\", \"__unpin\", \"__collect\" ];\n/** Globals to export if `--exportRuntime` is set. */\nconst runtimeGlobals = [ \"__rtti_base\" ];\n\n/** Compiler interface. */\nexport class Compiler extends DiagnosticEmitter {\n\n /** Program reference. */\n program: Program;\n /** Module instance being compiled. */\n get module(): Module { return this.program.module; }\n /** Provided options. */\n get options(): Options { return this.program.options; }\n /** Resolver reference. */\n get resolver(): Resolver { return this.program.resolver; }\n\n /** Current control flow. */\n currentFlow: Flow;\n /** Current parent element if not a function, i.e. an enum or namespace. */\n currentParent: Element | null = null;\n /** Current type in compilation. */\n currentType: Type = Type.void;\n /** Start function statements. */\n currentBody: ExpressionRef[];\n /** Counting memory offset. */\n memoryOffset: i64;\n /** Memory segments being compiled. */\n memorySegments: MemorySegment[] = [];\n /** Map of already compiled static string segments. */\n stringSegments: Map = new Map();\n /** Function table being compiled. First elem is blank. */\n functionTable: Function[] = [];\n /** Arguments length helper global. */\n builtinArgumentsLength: GlobalRef = 0;\n /** Requires runtime features. */\n runtimeFeatures: RuntimeFeatures = RuntimeFeatures.None;\n /** Current inline functions stack. */\n inlineStack: Function[] = [];\n /** Lazily compiled functions. */\n lazyFunctions: Set = new Set();\n /** Pending instanceof helpers and their names. */\n pendingInstanceOf: Map = new Map();\n /** Stubs to defer calls to overridden methods. */\n overrideStubs: Set = new Set();\n /** Elements currently undergoing compilation. */\n pendingElements: Set = new Set();\n /** Elements, that are module exports, already processed */\n doneModuleExports: Set = new Set();\n /** Shadow stack reference. */\n shadowStack!: ShadowStackPass;\n /** Whether the module has custom function exports. */\n hasCustomFunctionExports: bool = false;\n /** Whether the module would use the exported runtime to lift/lower. */\n desiresExportRuntime: bool = false;\n\n /** Compiles a {@link Program} to a {@link Module} using the specified options. */\n static compile(program: Program): Module {\n return new Compiler(program).compile();\n }\n\n /** Constructs a new compiler for a {@link Program} using the specified options. */\n constructor(program: Program) {\n super(program.diagnostics);\n this.program = program;\n let module = program.module;\n let options = program.options;\n if (options.memoryBase) {\n this.memoryOffset = i64_new(options.memoryBase);\n module.setLowMemoryUnused(false);\n } else {\n if (!options.lowMemoryLimit && options.optimizeLevelHint >= 2) {\n this.memoryOffset = i64_new(1024);\n module.setLowMemoryUnused(true);\n } else {\n this.memoryOffset = i64_new(8);\n module.setLowMemoryUnused(false);\n }\n }\n let featureFlags: FeatureFlags = 0;\n if (options.hasFeature(Feature.SignExtension)) featureFlags |= FeatureFlags.SignExt;\n if (options.hasFeature(Feature.MutableGlobals)) featureFlags |= FeatureFlags.MutableGlobals;\n if (options.hasFeature(Feature.NontrappingF2I)) featureFlags |= FeatureFlags.TruncSat;\n if (options.hasFeature(Feature.BulkMemory)) featureFlags |= FeatureFlags.BulkMemory;\n if (options.hasFeature(Feature.Simd)) featureFlags |= FeatureFlags.SIMD;\n if (options.hasFeature(Feature.Threads)) featureFlags |= FeatureFlags.Atomics;\n if (options.hasFeature(Feature.ExceptionHandling)) featureFlags |= FeatureFlags.ExceptionHandling;\n if (options.hasFeature(Feature.TailCalls)) featureFlags |= FeatureFlags.TailCall;\n if (options.hasFeature(Feature.ReferenceTypes)) featureFlags |= FeatureFlags.ReferenceTypes;\n if (options.hasFeature(Feature.MultiValue)) featureFlags |= FeatureFlags.MultiValue;\n if (options.hasFeature(Feature.GC)) featureFlags |= FeatureFlags.GC;\n if (options.hasFeature(Feature.Memory64)) featureFlags |= FeatureFlags.Memory64;\n if (options.hasFeature(Feature.RelaxedSimd)) featureFlags |= FeatureFlags.RelaxedSIMD;\n if (options.hasFeature(Feature.ExtendedConst)) featureFlags |= FeatureFlags.ExtendedConst;\n if (options.hasFeature(Feature.Stringref)) featureFlags |= FeatureFlags.Stringref;\n module.setFeatures(featureFlags);\n\n // set up the main start function\n let startFunctionInstance = program.makeNativeFunction(BuiltinNames.start, Signature.create(program, [], Type.void));\n startFunctionInstance.internalName = BuiltinNames.start;\n this.currentFlow = startFunctionInstance.flow;\n this.currentBody = new Array();\n this.shadowStack = new ShadowStackPass(this);\n }\n\n /** Performs compilation of the underlying {@link Program} to a {@link Module}. */\n compile(): Module {\n let options = this.options;\n let module = this.module;\n let program = this.program;\n let resolver = this.resolver;\n let hasShadowStack = options.stackSize > 0; // implies runtime=incremental\n\n // initialize lookup maps, built-ins, imports, exports, etc.\n this.program.initialize();\n\n // obtain the main start function\n let startFunctionInstance = this.currentFlow.targetFunction;\n assert(startFunctionInstance.internalName == BuiltinNames.start);\n let startFunctionBody = this.currentBody;\n assert(startFunctionBody.length == 0);\n\n // compile entry file(s) while traversing reachable elements\n let files = program.filesByName;\n // TODO: for (let file of files.values()) {\n for (let _values = Map_values(files), i = 0, k = _values.length; i < k; ++i) {\n let file = unchecked(_values[i]);\n if (file.source.sourceKind == SourceKind.UserEntry) {\n this.compileFile(file);\n this.compileModuleExports(file);\n }\n }\n\n // compile and export runtime if requested or necessary\n if (this.options.exportRuntime || (this.options.bindingsHint && this.desiresExportRuntime)) {\n for (let i = 0, k = runtimeFunctions.length; i < k; ++i) {\n let name = runtimeFunctions[i];\n let instance = program.requireFunction(name);\n if (this.compileFunction(instance) && !module.hasExport(name)) {\n module.addFunctionExport(instance.internalName, name);\n }\n }\n for (let i = 0, k = runtimeGlobals.length; i < k; ++i) {\n let name = runtimeGlobals[i];\n let instance = program.requireGlobal(name);\n if (this.compileGlobal(instance) && !module.hasExport(name)) {\n module.addGlobalExport(instance.internalName, name);\n }\n }\n }\n\n // compile lazy functions\n let lazyFunctions = this.lazyFunctions;\n do {\n let functionsToCompile = new Array();\n // TODO: for (let instance of lazyLibraryFunctions) {\n for (let _values = Set_values(lazyFunctions), i = 0, k = _values.length; i < k; ++i) {\n let instance = unchecked(_values[i]);\n functionsToCompile.push(instance);\n }\n lazyFunctions.clear();\n for (let i = 0, k = functionsToCompile.length; i < k; ++i) {\n this.compileFunction(unchecked(functionsToCompile[i]), true);\n }\n } while (lazyFunctions.size);\n\n // compile pending instanceof helpers\n for (let _keys = Map_keys(this.pendingInstanceOf), i = 0, k = _keys.length; i < k; ++i) {\n let elem = _keys[i];\n let name = assert(this.pendingInstanceOf.get(elem));\n switch (elem.kind) {\n case ElementKind.Class:\n case ElementKind.Interface: {\n this.finalizeInstanceOf(elem, name);\n break;\n }\n case ElementKind.ClassPrototype:\n case ElementKind.InterfacePrototype: {\n this.finalizeAnyInstanceOf(elem, name);\n break;\n }\n default: assert(false);\n }\n }\n\n // set up override stubs\n let functionTable = this.functionTable;\n let overrideStubs = this.overrideStubs;\n for (let i = 0, k = functionTable.length; i < k; ++i) {\n let instance = functionTable[i];\n if (instance.is(CommonFlags.Overridden)) {\n assert(instance.is(CommonFlags.Instance));\n functionTable[i] = this.ensureOverrideStub(instance); // includes varargs stub\n } else if (instance.signature.requiredParameters < instance.signature.parameterTypes.length) {\n functionTable[i] = this.ensureVarargsStub(instance);\n }\n }\n let overrideStubsSeen = new Set();\n do {\n // override stubs and overrides have cross-dependencies on each other, in that compiling\n // either may discover the respective other. do this in a loop until no more are found.\n resolver.discoveredOverride = false;\n for (let _values = Set_values(overrideStubs), i = 0, k = _values.length; i < k; ++i) {\n let instance = unchecked(_values[i]);\n let overrideInstances = resolver.resolveOverrides(instance);\n if (overrideInstances) {\n for (let i = 0, k = overrideInstances.length; i < k; ++i) {\n this.compileFunction(overrideInstances[i]);\n }\n }\n overrideStubsSeen.add(instance);\n }\n } while (overrideStubs.size > overrideStubsSeen.size || resolver.discoveredOverride);\n overrideStubsSeen.clear();\n for (let _values = Set_values(overrideStubs), i = 0, k = _values.length; i < k; ++i) {\n this.finalizeOverrideStub(_values[i]);\n }\n\n // finalize runtime features\n module.removeGlobal(BuiltinNames.rtti_base);\n if (this.runtimeFeatures & RuntimeFeatures.Rtti) compileRTTI(this);\n if (this.runtimeFeatures & RuntimeFeatures.visitGlobals) compileVisitGlobals(this);\n if (this.runtimeFeatures & RuntimeFeatures.visitMembers) compileVisitMembers(this);\n\n let memoryOffset = i64_align(this.memoryOffset, options.usizeType.byteSize);\n\n // finalize data\n module.removeGlobal(BuiltinNames.data_end);\n if ((this.runtimeFeatures & RuntimeFeatures.Data) != 0 || hasShadowStack) {\n if (options.isWasm64) {\n module.addGlobal(BuiltinNames.data_end, TypeRef.I64, false,\n module.i64(i64_low(memoryOffset), i64_high(memoryOffset))\n );\n } else {\n module.addGlobal(BuiltinNames.data_end, TypeRef.I32, false,\n module.i32(i64_low(memoryOffset))\n );\n }\n }\n\n // finalize stack (grows down from __heap_base to __data_end)\n module.removeGlobal(BuiltinNames.stack_pointer);\n if ((this.runtimeFeatures & RuntimeFeatures.Stack) != 0 || hasShadowStack) {\n memoryOffset = i64_align(\n i64_add(memoryOffset, i64_new(options.stackSize)),\n options.usizeType.byteSize\n );\n if (options.isWasm64) {\n module.addGlobal(BuiltinNames.stack_pointer, TypeRef.I64, true,\n module.i64(i64_low(memoryOffset), i64_high(memoryOffset))\n );\n } else {\n module.addGlobal(BuiltinNames.stack_pointer, TypeRef.I32, true,\n module.i32(i64_low(memoryOffset))\n );\n }\n }\n\n // finalize heap\n module.removeGlobal(BuiltinNames.heap_base);\n if ((this.runtimeFeatures & RuntimeFeatures.Heap) != 0 || hasShadowStack) {\n if (options.isWasm64) {\n module.addGlobal(BuiltinNames.heap_base, TypeRef.I64, false,\n module.i64(i64_low(memoryOffset), i64_high(memoryOffset))\n );\n } else {\n module.addGlobal(BuiltinNames.heap_base, TypeRef.I32, false,\n module.i32(i64_low(memoryOffset))\n );\n }\n }\n\n // setup default memory & table\n this.initDefaultMemory(memoryOffset);\n this.initDefaultTable();\n\n // expose the arguments length helper if there are varargs exports\n if (this.runtimeFeatures & RuntimeFeatures.setArgumentsLength) {\n module.addFunction(BuiltinNames.setArgumentsLength, TypeRef.I32, TypeRef.None, null,\n module.global_set(this.ensureArgumentsLength(), module.local_get(0, TypeRef.I32))\n );\n module.addFunctionExport(BuiltinNames.setArgumentsLength, ExportNames.setArgumentsLength);\n }\n\n // NOTE: no more element compiles from here. may go to the start function!\n\n // compile the start function if not empty or if explicitly requested\n let startIsEmpty = !startFunctionBody.length;\n let exportStart = options.exportStart;\n if (!startIsEmpty || exportStart != null) {\n let signature = startFunctionInstance.signature;\n if (!startIsEmpty && exportStart != null) {\n module.addGlobal(BuiltinNames.started, TypeRef.I32, true, module.i32(0));\n startFunctionBody.unshift(\n module.global_set(BuiltinNames.started, module.i32(1))\n );\n startFunctionBody.unshift(\n module.if(\n module.global_get(BuiltinNames.started, TypeRef.I32),\n module.return()\n )\n );\n }\n let funcRef = module.addFunction(\n startFunctionInstance.internalName,\n signature.paramRefs,\n signature.resultRefs,\n typesToRefs(startFunctionInstance.getNonParameterLocalTypes()),\n module.flatten(startFunctionBody)\n );\n startFunctionInstance.finalize(module, funcRef);\n if (exportStart == null) module.setStart(funcRef);\n else {\n if (!isIdentifier(exportStart) || module.hasExport(exportStart)) {\n this.error(\n DiagnosticCode.Start_function_name_0_is_invalid_or_conflicts_with_another_export,\n Source.native.range, exportStart\n );\n } else {\n module.addFunctionExport(startFunctionInstance.internalName, exportStart);\n }\n }\n }\n\n // Run custom passes\n if (hasShadowStack) {\n this.shadowStack.walkModule();\n }\n if (program.lookup(\"ASC_RTRACE\") != null) {\n new RtraceMemory(this).walkModule();\n }\n\n return module;\n }\n\n private initDefaultMemory(memoryOffset: i64): void {\n this.memoryOffset = memoryOffset;\n\n let options = this.options;\n let module = this.module;\n let memorySegments = this.memorySegments;\n\n let initialPages: u32 = 0;\n let maximumPages = Module.UNLIMITED_MEMORY;\n let isSharedMemory = false;\n\n if (options.memoryBase /* is specified */ || memorySegments.length) {\n initialPages = u32(i64_low(i64_shr_u(i64_align(memoryOffset, 0x10000), i64_new(16))));\n }\n\n if (options.initialMemory) {\n if (options.initialMemory < initialPages) {\n this.error(\n DiagnosticCode.Module_requires_at_least_0_pages_of_initial_memory,\n null,\n initialPages.toString()\n );\n } else {\n initialPages = options.initialMemory;\n }\n }\n\n if (options.maximumMemory) {\n if (options.maximumMemory < initialPages) {\n this.error(\n DiagnosticCode.Module_requires_at_least_0_pages_of_maximum_memory,\n null,\n initialPages.toString()\n );\n } else {\n maximumPages = options.maximumMemory;\n }\n }\n\n if (options.sharedMemory) {\n isSharedMemory = true;\n if (!options.maximumMemory) {\n this.error(\n DiagnosticCode.Shared_memory_requires_maximum_memory_to_be_defined,\n null\n );\n isSharedMemory = false;\n }\n if (!options.hasFeature(Feature.Threads)) {\n this.error(\n DiagnosticCode.Shared_memory_requires_feature_threads_to_be_enabled,\n null\n );\n isSharedMemory = false;\n }\n }\n\n // check that we didn't exceed lowMemoryLimit already\n let lowMemoryLimit32 = options.lowMemoryLimit;\n if (lowMemoryLimit32) {\n let lowMemoryLimit = i64_new(lowMemoryLimit32 & ~15);\n if (i64_gt(memoryOffset, lowMemoryLimit)) {\n this.error(\n DiagnosticCode.Low_memory_limit_exceeded_by_static_data_0_1,\n null, i64_to_string(memoryOffset), i64_to_string(lowMemoryLimit)\n );\n }\n }\n\n // Setup internal memory with default name \"0\"\n module.setMemory(\n initialPages,\n maximumPages,\n memorySegments,\n options.target,\n options.exportMemory ? ExportNames.Memory : null,\n CommonNames.DefaultMemory,\n isSharedMemory\n );\n\n // import memory if requested (default memory is named '0' by Binaryen)\n if (options.importMemory) {\n module.addMemoryImport(\n CommonNames.DefaultMemory,\n ImportNames.DefaultNamespace,\n ImportNames.Memory,\n isSharedMemory\n );\n }\n }\n\n private initDefaultTable(): void {\n let options = this.options;\n let module = this.module;\n\n // import and/or export table if requested (default table is named '0' by Binaryen)\n if (options.importTable) {\n module.addTableImport(\n CommonNames.DefaultTable,\n ImportNames.DefaultNamespace,\n ImportNames.Table\n );\n if (options.pedantic && options.willOptimize) {\n this.pedantic(\n DiagnosticCode.Importing_the_table_disables_some_indirect_call_optimizations,\n null\n );\n }\n }\n if (options.exportTable) {\n module.addTableExport(CommonNames.DefaultTable, ExportNames.Table);\n if (options.pedantic && options.willOptimize) {\n this.pedantic(\n DiagnosticCode.Exporting_the_table_disables_some_indirect_call_optimizations,\n null\n );\n }\n }\n\n // set up function table (first elem is blank)\n let tableBase = options.tableBase;\n if (!tableBase) tableBase = 1; // leave first elem blank\n let functionTable = this.functionTable;\n let functionTableNames = new Array(functionTable.length);\n for (let i = 0, k = functionTable.length; i < k; ++i) {\n functionTableNames[i] = functionTable[i].internalName;\n }\n\n let initialTableSize = tableBase + functionTable.length;\n let maximumTableSize = Module.UNLIMITED_TABLE;\n\n if (!(options.importTable || options.exportTable)) {\n // use fixed size for non-imported and non-exported tables\n maximumTableSize = initialTableSize;\n if (options.willOptimize) {\n // Hint for directize pass which indicate table's content will not change\n // and can be better optimized\n module.setPassArgument(\"directize-initial-contents-immutable\", \"true\");\n }\n }\n module.addFunctionTable(\n CommonNames.DefaultTable,\n initialTableSize,\n maximumTableSize,\n functionTableNames,\n module.i32(tableBase)\n );\n }\n\n // === Exports ==================================================================================\n\n /** Compiles the respective module exports for the specified entry file. */\n private compileModuleExports(file: File): void {\n let exports = file.exports;\n if (exports) {\n // TODO: for (let [elementName, element] of exports) {\n for (let _keys = Map_keys(exports), i = 0, k = _keys.length; i < k; ++i) {\n let elementName = unchecked(_keys[i]);\n let element = assert(exports.get(elementName));\n this.compileModuleExport(elementName, element);\n }\n }\n let exportsStar = file.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n this.compileModuleExports(exportsStar[i]);\n }\n }\n }\n\n /** Compiles the respective module export(s) for the specified element. */\n private compileModuleExport(name: string, element: DeclaredElement, prefix: string = \"\"): void {\n let module = this.module;\n switch (element.kind) {\n case ElementKind.FunctionPrototype: {\n // obtain the default instance\n let functionPrototype = element;\n if (!functionPrototype.is(CommonFlags.Generic)) {\n let functionInstance = this.resolver.resolveFunction(functionPrototype, null);\n if (functionInstance) {\n this.compileModuleExport(name, functionInstance, prefix);\n }\n return;\n }\n break;\n }\n case ElementKind.Function: {\n let functionInstance = element;\n if (!functionInstance.hasDecorator(DecoratorFlags.Builtin)) {\n let signature = functionInstance.signature;\n if (signature.requiredParameters < signature.parameterTypes.length) {\n // utilize varargs stub to fill in omitted arguments\n functionInstance = this.ensureVarargsStub(functionInstance);\n this.runtimeFeatures |= RuntimeFeatures.setArgumentsLength;\n }\n this.compileFunction(functionInstance);\n if (functionInstance.is(CommonFlags.Compiled)) {\n let exportName = prefix + name;\n if (!module.hasExport(exportName)) {\n module.addFunctionExport(functionInstance.internalName, exportName);\n this.hasCustomFunctionExports = true;\n let hasManagedOperands = signature.hasManagedOperands;\n if (hasManagedOperands) {\n this.shadowStack.noteExport(exportName, signature.getManagedOperandIndices());\n }\n if (!this.desiresExportRuntime) {\n let thisType = signature.thisType;\n if (\n thisType && lowerRequiresExportRuntime(thisType) ||\n liftRequiresExportRuntime(signature.returnType)\n ) {\n this.desiresExportRuntime = true;\n } else {\n let parameterTypes = signature.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (lowerRequiresExportRuntime(parameterTypes[i])) {\n this.desiresExportRuntime = true;\n break;\n }\n }\n }\n }\n }\n return;\n }\n }\n break;\n }\n case ElementKind.Global: {\n let global = element;\n let isConst = global.is(CommonFlags.Const) || global.is(CommonFlags.Static | CommonFlags.Readonly);\n if (!isConst && !this.options.hasFeature(Feature.MutableGlobals)) {\n this.warning(\n DiagnosticCode.Feature_0_is_not_enabled,\n global.identifierNode.range, \"mutable-globals\"\n );\n return;\n }\n this.compileGlobal(global);\n if (global.is(CommonFlags.Compiled)) {\n let exportName = prefix + name;\n if (!module.hasExport(exportName)) {\n module.addGlobalExport(element.internalName, exportName);\n if (!this.desiresExportRuntime) {\n let type = global.type;\n if (\n liftRequiresExportRuntime(type) ||\n !global.is(CommonFlags.Const) && lowerRequiresExportRuntime(type)\n ) {\n this.desiresExportRuntime = true;\n }\n }\n }\n if (global.type == Type.v128) {\n this.warning(\n DiagnosticCode.Exchange_of_0_values_is_not_supported_by_all_embeddings,\n global.typeNode\n ? assert(global.typeNode).range\n : global.identifierNode.range,\n \"v128\"\n );\n }\n return;\n }\n break;\n }\n case ElementKind.Enum: {\n this.compileEnum(element);\n let members = element.members;\n if (members) {\n let subPrefix = prefix + name + STATIC_DELIMITER;\n for (let _keys = Map_keys(members), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let member = assert(members.get(memberName));\n if (!member.is(CommonFlags.Private)) {\n this.compileModuleExport(memberName, member, subPrefix);\n }\n }\n }\n return;\n }\n case ElementKind.EnumValue: {\n let enumValue = element;\n if (!enumValue.isImmutable && !this.options.hasFeature(Feature.MutableGlobals)) {\n this.error(\n DiagnosticCode.Feature_0_is_not_enabled,\n enumValue.identifierNode.range, \"mutable-globals\"\n );\n return;\n }\n if (enumValue.is(CommonFlags.Compiled)) {\n let exportName = prefix + name;\n if (!module.hasExport(exportName)) {\n module.addGlobalExport(element.internalName, exportName);\n }\n return;\n }\n break;\n }\n }\n this.warning(\n DiagnosticCode.Only_variables_functions_and_enums_become_WebAssembly_module_exports,\n element.identifierNode.range\n );\n }\n\n // files\n\n /** Compiles the file matching the specified path. */\n compileFileByPath(normalizedPathWithoutExtension: string, reportNode: Node): void {\n let file: File;\n let filesByName = this.program.filesByName;\n let pathWithIndex: string;\n if (filesByName.has(normalizedPathWithoutExtension)) {\n file = assert(filesByName.get(normalizedPathWithoutExtension));\n } else if (filesByName.has(pathWithIndex = normalizedPathWithoutExtension + INDEX_SUFFIX)) {\n file = assert(filesByName.get(pathWithIndex));\n } else {\n this.error(\n DiagnosticCode.File_0_not_found,\n reportNode.range, normalizedPathWithoutExtension\n );\n return;\n }\n this.compileFile(file);\n }\n\n /** Compiles the specified file. */\n compileFile(file: File): void {\n if (file.is(CommonFlags.Compiled)) return;\n file.set(CommonFlags.Compiled);\n\n // compile top-level statements within the file's start function\n let startFunction = file.startFunction;\n let startSignature = startFunction.signature;\n let previousBody = this.currentBody;\n let startFunctionBody = new Array();\n this.currentBody = startFunctionBody;\n\n // compile top-level statements\n let previousFlow = this.currentFlow;\n let flow = startFunction.flow;\n this.currentFlow = flow;\n for (let statements = file.source.statements, i = 0, k = statements.length; i < k; ++i) {\n this.compileTopLevelStatement(statements[i], startFunctionBody);\n }\n // no need to insert unreachable since last statement should have done that\n this.currentFlow = previousFlow;\n this.currentBody = previousBody;\n\n // if top-level statements are present, make the per-file start function and call it in start\n if (startFunctionBody.length) {\n let module = this.module;\n let locals = startFunction.localsByIndex;\n let numLocals = locals.length;\n let varTypes = new Array(numLocals);\n for (let i = 0; i < numLocals; ++i) varTypes[i] = locals[i].type.toRef();\n const funcRef = module.addFunction(\n startFunction.internalName,\n startSignature.paramRefs,\n startSignature.resultRefs,\n varTypes,\n module.flatten(startFunctionBody)\n );\n startFunction.finalize(module, funcRef);\n previousBody.push(\n module.call(startFunction.internalName, null, TypeRef.None)\n );\n }\n }\n\n // === Globals ==================================================================================\n\n /** Tries to compile a global variable lazily. */\n compileGlobalLazy(global: Global, reportNode: Node): bool {\n if (global.is(CommonFlags.Compiled)) return !global.is(CommonFlags.Errored);\n if (global.hasAnyDecorator(DecoratorFlags.Lazy | DecoratorFlags.Builtin) || global.is(CommonFlags.Ambient)) {\n return this.compileGlobal(global); // compile now\n }\n // Otherwise the global is used before its initializer executes\n this.errorRelated(\n DiagnosticCode.Variable_0_used_before_its_declaration,\n reportNode.range, global.identifierNode.range, global.internalName\n );\n return false;\n }\n\n /** Compiles a global variable. */\n compileGlobal(global: Global): bool {\n if (global.is(CommonFlags.Compiled)) return !global.is(CommonFlags.Errored);\n global.set(CommonFlags.Compiled);\n\n let pendingElements = this.pendingElements;\n pendingElements.add(global);\n\n let module = this.module;\n let initExpr: ExpressionRef = 0;\n let typeNode = global.typeNode;\n let initializerNode = global.initializerNode;\n\n if (!global.is(CommonFlags.Resolved)) {\n\n // Resolve type if annotated\n if (typeNode) {\n let resolvedType = this.resolver.resolveType(typeNode, global.parent); // reports\n if (!resolvedType) {\n global.set(CommonFlags.Errored);\n pendingElements.delete(global);\n return false;\n }\n if (resolvedType == Type.void) {\n this.error(\n DiagnosticCode.Type_expected,\n typeNode.range\n );\n global.set(CommonFlags.Errored);\n pendingElements.delete(global);\n return false;\n }\n global.setType(resolvedType);\n this.program.checkTypeSupported(resolvedType, typeNode);\n\n // Otherwise infer type from initializer\n } else if (initializerNode) {\n let previousFlow = this.currentFlow;\n if (global.hasDecorator(DecoratorFlags.Lazy)) {\n this.currentFlow = global.file.startFunction.flow;\n }\n initExpr = this.compileExpression(initializerNode, Type.auto, // reports\n Constraints.MustWrap | Constraints.PreferStatic\n );\n this.currentFlow = previousFlow;\n if (this.currentType == Type.void) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n initializerNode.range, this.currentType.toString(), \"\"\n );\n global.set(CommonFlags.Errored);\n pendingElements.delete(global);\n return false;\n }\n global.setType(this.currentType);\n\n // Error if there's neither a type nor an initializer\n } else {\n this.error(\n DiagnosticCode.Type_expected,\n global.identifierNode.range.atEnd\n );\n global.set(CommonFlags.Errored);\n pendingElements.delete(global);\n return false;\n }\n }\n\n // Handle builtins like '__heap_base' that need to be resolved but are added explicitly\n if (global.hasDecorator(DecoratorFlags.Builtin)) {\n let internalName = global.internalName;\n if (builtinVariables_onCompile.has(internalName)) { // optional\n let fn = assert(builtinVariables_onCompile.get(internalName));\n fn(new BuiltinVariableContext(this, global));\n }\n pendingElements.delete(global);\n return true;\n }\n\n let type = global.type;\n\n // Enforce either an initializer, a definitive assignment or a nullable type\n // to guarantee soundness when globals are accessed. In the absence of an\n // initializer, a definitive assignment guarantees a runtime check, whereas\n // a nullable type guarantees that obtaining default `null` is OK. Avoids:\n //\n // let foo: string;\n // function bar() {\n // foo.length; // no error in TS even though undefined\n // }\n // bar();\n if (\n !initializerNode && !global.is(CommonFlags.DefinitelyAssigned) &&\n type.isReference && !type.isNullableReference\n ) {\n this.error(\n DiagnosticCode.Initializer_definitive_assignment_or_nullable_type_expected,\n global.identifierNode.range\n );\n }\n\n let typeRef = type.toRef();\n let isDeclaredConstant = global.is(CommonFlags.Const) || global.is(CommonFlags.Static | CommonFlags.Readonly);\n let isDeclaredInline = global.hasDecorator(DecoratorFlags.Inline);\n\n // Handle imports\n if (global.is(CommonFlags.Ambient)) {\n\n // Constant global or mutable globals enabled\n if (isDeclaredConstant || this.options.hasFeature(Feature.MutableGlobals)) {\n mangleImportName(global, global.declaration);\n this.program.markModuleImport(mangleImportName_moduleName, mangleImportName_elementName, global);\n module.addGlobalImport(\n global.internalName,\n mangleImportName_moduleName,\n mangleImportName_elementName,\n typeRef,\n !isDeclaredConstant\n );\n pendingElements.delete(global);\n if (!this.desiresExportRuntime && lowerRequiresExportRuntime(type)) {\n this.desiresExportRuntime = true;\n }\n return true;\n }\n\n // Importing mutable globals is not supported in the MVP\n this.error(\n DiagnosticCode.Feature_0_is_not_enabled,\n global.declaration.range, \"mutable-globals\"\n );\n global.set(CommonFlags.Errored);\n pendingElements.delete(global);\n return false;\n }\n\n // The MVP does not yet support initializer expressions other than constants and gets of\n // imported immutable globals, hence such initializations must be performed in the start.\n let initializeInStart = false;\n\n // Evaluate initializer if present\n if (initializerNode) {\n if (!initExpr) {\n let previousFlow = this.currentFlow;\n if (global.hasDecorator(DecoratorFlags.Lazy)) {\n this.currentFlow = global.file.startFunction.flow;\n }\n initExpr = this.compileExpression(initializerNode, type,\n Constraints.ConvImplicit | Constraints.MustWrap | Constraints.PreferStatic\n );\n this.currentFlow = previousFlow;\n }\n\n // If not a constant expression, attempt to precompute\n if (!module.isConstExpression(initExpr)) {\n if (isDeclaredConstant) {\n let precomp = module.runExpression(initExpr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n initExpr = precomp;\n } else {\n initializeInStart = true;\n }\n } else {\n initializeInStart = true;\n }\n }\n\n // Handle special case of initializing from imported immutable global\n if (initializeInStart && getExpressionId(initExpr) == ExpressionId.GlobalGet) {\n let fromName = assert(getGlobalGetName(initExpr));\n if (!isGlobalMutable(module.getGlobal(fromName))) {\n let elementsByName = this.program.elementsByName;\n if (elementsByName.has(fromName)) {\n let global = assert(elementsByName.get(fromName));\n if (global.is(CommonFlags.Ambient)) initializeInStart = false;\n }\n }\n }\n\n // Explicitly inline if annotated\n if (isDeclaredInline) {\n if (initializeInStart) {\n this.warning(\n DiagnosticCode.Mutable_value_cannot_be_inlined,\n initializerNode.range\n );\n } else {\n assert(getExpressionId(initExpr) == ExpressionId.Const);\n let exprType = getExpressionType(initExpr);\n switch (exprType) {\n case TypeRef.I32: {\n global.constantValueKind = ConstantValueKind.Integer;\n global.constantIntegerValue = i64_new(getConstValueI32(initExpr), 0);\n break;\n }\n case TypeRef.I64: {\n global.constantValueKind = ConstantValueKind.Integer;\n global.constantIntegerValue = i64_new(\n getConstValueI64Low(initExpr),\n getConstValueI64High(initExpr)\n );\n break;\n }\n case TypeRef.F32: {\n global.constantValueKind = ConstantValueKind.Float;\n global.constantFloatValue = getConstValueF32(initExpr);\n break;\n }\n case TypeRef.F64: {\n global.constantValueKind = ConstantValueKind.Float;\n global.constantFloatValue = getConstValueF64(initExpr);\n break;\n }\n default: {\n assert(false);\n global.set(CommonFlags.Errored);\n pendingElements.delete(global);\n return false;\n }\n }\n global.set(CommonFlags.Inlined); // inline the value from now on\n }\n }\n\n // Initialize to zero if there's no initializer\n } else {\n if (global.is(CommonFlags.Inlined)) {\n initExpr = this.compileInlineConstant(global, global.type, Constraints.PreferStatic);\n } else {\n initExpr = this.makeZero(type);\n }\n }\n\n let internalName = global.internalName;\n\n if (initializeInStart) { // initialize to mutable zero and set the actual value in start\n if (isDeclaredInline) {\n this.error(\n DiagnosticCode.Decorator_0_is_not_valid_here,\n findDecorator(DecoratorKind.Inline, global.decoratorNodes)!.range, \"inline\"\n );\n }\n module.addGlobal(internalName, typeRef, true, this.makeZero(type));\n this.currentBody.push(\n module.global_set(internalName, initExpr)\n );\n } else if (!isDeclaredInline) { // compile normally\n module.addGlobal(internalName, typeRef, !isDeclaredConstant, initExpr);\n }\n pendingElements.delete(global);\n return true;\n }\n\n // === Enums ====================================================================================\n\n /** Compiles an enum. */\n compileEnum(element: Enum): bool {\n if (element.is(CommonFlags.Compiled)) return !element.is(CommonFlags.Errored);\n element.set(CommonFlags.Compiled);\n\n let pendingElements = this.pendingElements;\n pendingElements.add(element);\n\n let module = this.module;\n let previousParent = this.currentParent;\n this.currentParent = element;\n let previousValue: EnumValue | null = null;\n let previousValueIsMut = false;\n let isInline = element.is(CommonFlags.Const) || element.hasDecorator(DecoratorFlags.Inline);\n\n let members = element.members;\n if (members) {\n // TODO: for (let member of element.members.values()) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n if (member.kind != ElementKind.EnumValue) continue; // happens if an enum is also a namespace\n let initInStart = false;\n let enumValue = member;\n let valueNode = enumValue.valueNode;\n enumValue.set(CommonFlags.Compiled);\n let previousFlow = this.currentFlow;\n if (element.hasDecorator(DecoratorFlags.Lazy)) {\n this.currentFlow = element.file.startFunction.flow;\n }\n let initExpr: ExpressionRef;\n if (valueNode) {\n initExpr = this.compileExpression(valueNode, Type.i32,\n Constraints.ConvImplicit\n );\n if (getExpressionId(initExpr) != ExpressionId.Const) {\n let precomp = module.runExpression(initExpr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n initExpr = precomp;\n } else {\n if (element.is(CommonFlags.Const)) {\n this.error(\n DiagnosticCode.In_const_enum_declarations_member_initializer_must_be_constant_expression,\n valueNode.range\n );\n }\n initInStart = true;\n }\n }\n } else if (previousValue == null) {\n initExpr = module.i32(0);\n } else {\n if (previousValueIsMut) {\n this.error(\n DiagnosticCode.Enum_member_must_have_initializer,\n enumValue.identifierNode.range.atEnd\n );\n }\n if (isInline) {\n let value = i64_add(previousValue.constantIntegerValue, i64_new(1));\n assert(!i64_high(value));\n initExpr = module.i32(i64_low(value));\n } else {\n initExpr = module.binary(BinaryOp.AddI32,\n module.global_get(previousValue.internalName, TypeRef.I32),\n module.i32(1)\n );\n let precomp = module.runExpression(initExpr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n initExpr = precomp;\n } else {\n if (element.is(CommonFlags.Const)) {\n this.error(\n DiagnosticCode.In_const_enum_declarations_member_initializer_must_be_constant_expression,\n member.declaration.range\n );\n }\n initInStart = true;\n }\n }\n }\n this.currentFlow = previousFlow;\n if (initInStart) {\n module.addGlobal(enumValue.internalName, TypeRef.I32, true, module.i32(0));\n this.currentBody.push(\n this.makeGlobalAssignment(enumValue, initExpr, Type.i32, false)\n );\n previousValueIsMut = true;\n } else {\n if (isInline) {\n enumValue.setConstantIntegerValue(i64_new(getConstValueI32(initExpr)), Type.i32);\n if (enumValue.is(CommonFlags.ModuleExport)) {\n module.addGlobal(enumValue.internalName, TypeRef.I32, false, initExpr);\n }\n } else {\n module.addGlobal(enumValue.internalName, TypeRef.I32, false, initExpr);\n }\n enumValue.isImmutable = true;\n previousValueIsMut = false;\n }\n previousValue = enumValue;\n }\n }\n this.currentParent = previousParent;\n pendingElements.delete(element);\n return true;\n }\n\n // === Functions ================================================================================\n\n /** Compiles a priorly resolved function. */\n compileFunction(\n /** Function to compile. */\n instance: Function,\n /** Force compilation of stdlib alternative if a builtin. */\n forceStdAlternative: bool = false\n ): bool {\n if (instance.is(CommonFlags.Compiled)) return !instance.is(CommonFlags.Errored);\n\n if (!forceStdAlternative) {\n if (instance.hasDecorator(DecoratorFlags.Builtin)) return true;\n if (instance.hasDecorator(DecoratorFlags.Lazy)) {\n this.lazyFunctions.add(instance);\n return true;\n }\n }\n\n // ensure the function has no duplicate parameters\n let parameters = instance.prototype.functionTypeNode.parameters;\n let numParameters = parameters.length;\n if (numParameters >= 2) {\n let visited = new Set();\n visited.add(parameters[0].name.text);\n for (let i = 1; i < numParameters; i++) {\n let paramIdentifier = parameters[i].name;\n let paramName = paramIdentifier.text;\n if (!visited.has(paramName)) {\n visited.add(paramName);\n } else {\n this.error(\n DiagnosticCode.Duplicate_identifier_0,\n paramIdentifier.range, paramName\n );\n }\n }\n }\n\n instance.set(CommonFlags.Compiled);\n let pendingElements = this.pendingElements;\n pendingElements.add(instance);\n\n let previousType = this.currentType;\n let module = this.module;\n let signature = instance.signature;\n let bodyNode = instance.prototype.bodyNode;\n let declarationNode = instance.declaration;\n assert(declarationNode.kind == NodeKind.FunctionDeclaration || declarationNode.kind == NodeKind.MethodDeclaration);\n this.checkSignatureSupported(instance.signature, (declarationNode).signature);\n\n let funcRef: FunctionRef = 0;\n\n // concrete function\n if (bodyNode) {\n\n // must not be ambient\n if (instance.is(CommonFlags.Ambient)) {\n this.error(\n DiagnosticCode.An_implementation_cannot_be_declared_in_ambient_contexts,\n instance.identifierNode.range\n );\n }\n\n // cannot have an annotated external name or code\n if (instance.hasAnyDecorator(DecoratorFlags.External | DecoratorFlags.ExternalJs)) {\n let decoratorNodes = instance.decoratorNodes;\n let decorator: DecoratorNode | null;\n if (decorator = findDecorator(DecoratorKind.External, decoratorNodes)) {\n this.error(\n DiagnosticCode.Decorator_0_is_not_valid_here,\n decorator.range, \"external\"\n );\n }\n if (decorator = findDecorator(DecoratorKind.ExternalJs, decoratorNodes)) {\n this.error(\n DiagnosticCode.Decorator_0_is_not_valid_here,\n decorator.range, \"external.js\"\n );\n }\n }\n\n // compile body in this function's context\n let previousFlow = this.currentFlow;\n let flow = instance.flow;\n this.currentFlow = flow;\n let stmts = new Array();\n\n if (!this.compileFunctionBody(instance, stmts)) {\n stmts.push(module.unreachable());\n }\n\n this.currentFlow = previousFlow;\n\n // create the function\n funcRef = module.addFunction(\n instance.internalName,\n signature.paramRefs,\n signature.resultRefs,\n typesToRefs(instance.getNonParameterLocalTypes()),\n module.flatten(stmts, instance.signature.returnType.toRef())\n );\n\n // imported function\n } else if (instance.is(CommonFlags.Ambient)) {\n mangleImportName(instance, declarationNode); // TODO: check for duplicates\n this.program.markModuleImport(mangleImportName_moduleName, mangleImportName_elementName, instance);\n module.addFunctionImport(\n instance.internalName,\n mangleImportName_moduleName,\n mangleImportName_elementName,\n signature.paramRefs,\n signature.resultRefs\n );\n funcRef = module.getFunction(instance.internalName);\n if (!this.desiresExportRuntime) {\n let thisType = signature.thisType;\n if (\n thisType && liftRequiresExportRuntime(thisType) ||\n lowerRequiresExportRuntime(signature.returnType)\n ) {\n this.desiresExportRuntime = true;\n } else {\n let parameterTypes = signature.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (liftRequiresExportRuntime(parameterTypes[i])) {\n this.desiresExportRuntime = true;\n break;\n }\n }\n }\n }\n\n // abstract or interface function\n } else if (instance.is(CommonFlags.Abstract) || instance.parent.kind == ElementKind.Interface) {\n funcRef = module.addFunction(\n instance.internalName,\n signature.paramRefs,\n signature.resultRefs,\n null,\n module.unreachable()\n );\n\n } else {\n // built-in field accessor?\n if (instance.isAny(CommonFlags.Get | CommonFlags.Set)) {\n let propertyName = instance.declaration.name.text;\n let propertyParent = assert(instance.parent.getMember(propertyName));\n assert(propertyParent.kind == ElementKind.PropertyPrototype);\n let propertyInstance = (propertyParent).instance;\n if (propertyInstance && propertyInstance.isField) {\n funcRef = instance.is(CommonFlags.Get)\n ? this.makeBuiltinFieldGetter(propertyInstance)\n : this.makeBuiltinFieldSetter(propertyInstance);\n assert(instance.is(CommonFlags.Compiled));\n }\n }\n if (!funcRef) {\n this.error(\n DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration,\n instance.identifierNode.range\n );\n instance.set(CommonFlags.Errored);\n }\n }\n\n if (instance.is(CommonFlags.Ambient) || instance.is(CommonFlags.Export)) {\n // Verify and print warn if signature has v128 type for imported or exported functions\n let hasVectorValueOperands = signature.hasVectorValueOperands;\n if (hasVectorValueOperands) {\n let range: Range;\n let fnTypeNode = instance.prototype.functionTypeNode;\n if (signature.returnType == Type.v128) {\n range = fnTypeNode.returnType.range;\n } else {\n let firstIndex = signature.getVectorValueOperandIndices()[0];\n range = fnTypeNode.parameters[firstIndex].range;\n }\n this.warning(\n DiagnosticCode.Exchange_of_0_values_is_not_supported_by_all_embeddings,\n range, \"v128\"\n );\n }\n }\n\n instance.finalize(module, funcRef);\n this.currentType = previousType;\n pendingElements.delete(instance);\n return true;\n }\n\n /** Compiles the body of a function within the specified flow. */\n private compileFunctionBody(\n /** Function to compile. */\n instance: Function,\n /** Target array of statements also being returned. Creates a new array if omitted. */\n stmts: ExpressionRef[]\n ): bool {\n let module = this.module;\n let bodyNode = assert(instance.prototype.bodyNode);\n let returnType = instance.signature.returnType;\n let flow = this.currentFlow;\n let thisLocal = instance.signature.thisType\n ? assert(flow.lookupLocal(CommonNames.this_))\n : null;\n let bodyStartIndex = stmts.length;\n\n // compile statements\n if (bodyNode.kind == NodeKind.Block) {\n stmts = this.compileStatements((bodyNode).statements, stmts);\n } else {\n // must be an expression statement if not a block\n assert(bodyNode.kind == NodeKind.Expression);\n\n // must be an arrow function\n assert(instance.prototype.arrowKind);\n\n // none of the following can be an arrow function\n assert(!instance.isAny(CommonFlags.Constructor | CommonFlags.Get | CommonFlags.Set));\n\n let expr = this.compileExpression((bodyNode).expression, returnType, Constraints.ConvImplicit);\n if (!flow.canOverflow(expr, returnType)) flow.set(FlowFlags.ReturnsWrapped);\n if (flow.isNonnull(expr, returnType)) flow.set(FlowFlags.ReturnsNonNull);\n\n if (!stmts) stmts = [ expr ];\n else stmts.push(expr);\n\n if (!flow.is(FlowFlags.Terminates)) {\n if (!flow.canOverflow(expr, returnType)) flow.set(FlowFlags.ReturnsWrapped);\n if (flow.isNonnull(expr, returnType)) flow.set(FlowFlags.ReturnsNonNull);\n flow.set(FlowFlags.Returns | FlowFlags.Terminates);\n }\n }\n\n // Make constructors return their instance pointer, and prepend a conditional\n // allocation if any code path accesses `this`.\n if (instance.is(CommonFlags.Constructor)) {\n assert(instance.is(CommonFlags.Instance));\n thisLocal = assert(thisLocal);\n let parent = assert(instance.parent);\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n\n if (flow.isAny(FlowFlags.AccessesThis | FlowFlags.ConditionallyAccessesThis) || !flow.is(FlowFlags.Terminates)) {\n\n // Allocate `this` if not a super call, and initialize fields\n let allocStmts = new Array();\n allocStmts.push(\n this.makeConditionalAllocation(classInstance, thisLocal.index)\n );\n this.makeFieldInitializationInConstructor(classInstance, allocStmts);\n\n // Insert right before the body\n for (let i = stmts.length - 1; i >= bodyStartIndex; --i) {\n stmts[i + 1] = stmts[i];\n }\n stmts[bodyStartIndex] = module.flatten(allocStmts, TypeRef.None);\n\n // Just prepended allocation is dropped when returning non-'this'\n if (flow.is(FlowFlags.MayReturnNonThis)) {\n if (this.options.pedantic) {\n this.pedantic(\n DiagnosticCode.Explicitly_returning_constructor_drops_this_allocation,\n instance.identifierNode.range\n );\n }\n }\n }\n\n // Returning something else than 'this' would break 'super()' calls\n if (flow.is(FlowFlags.MayReturnNonThis) && !classInstance.hasDecorator(DecoratorFlags.Final)) {\n this.error(\n DiagnosticCode.A_class_with_a_constructor_explicitly_returning_something_else_than_this_must_be_final,\n classInstance.identifierNode.range\n );\n }\n\n // Implicitly return `this` if the flow falls through\n if (!flow.is(FlowFlags.Terminates)) {\n stmts.push(\n module.local_get(thisLocal.index, this.options.sizeTypeRef)\n );\n flow.set(FlowFlags.Returns | FlowFlags.ReturnsNonNull | FlowFlags.Terminates);\n }\n\n // check that super has been called if this is a derived class\n if (classInstance.base && !classInstance.prototype.implicitlyExtendsObject && !flow.is(FlowFlags.CallsSuper)) {\n this.error(\n DiagnosticCode.Constructors_for_derived_classes_must_contain_a_super_call,\n instance.prototype.declaration.range\n );\n }\n\n // if this is a normal function, make sure that all branches terminate\n } else if (returnType != Type.void && !flow.is(FlowFlags.Terminates)) {\n this.error(\n DiagnosticCode.A_function_whose_declared_type_is_not_void_must_return_a_value,\n instance.prototype.functionTypeNode.returnType.range\n );\n return false; // not recoverable\n }\n\n return true;\n }\n\n /** Makes a built-in getter of a property that is a field. */\n private makeBuiltinFieldGetter(property: Property): FunctionRef {\n let getterInstance = assert(property.getterInstance);\n let module = this.module;\n let valueType = property.type;\n let valueTypeRef = valueType.toRef();\n let thisTypeRef = this.options.sizeTypeRef;\n getterInstance.set(CommonFlags.Compiled);\n let body = module.load(valueType.byteSize, valueType.isSignedIntegerValue,\n module.local_get(0, thisTypeRef),\n valueTypeRef, property.memoryOffset\n );\n let flowBefore = this.currentFlow;\n let flow = getterInstance.flow;\n this.currentFlow = flow;\n if (property.is(CommonFlags.DefinitelyAssigned) && valueType.isReference && !valueType.isNullableReference) {\n body = this.makeRuntimeNonNullCheck(body, valueType, getterInstance.identifierNode);\n }\n this.currentFlow = flowBefore;\n return module.addFunction(\n getterInstance.internalName,\n thisTypeRef,\n valueTypeRef,\n typesToRefs(getterInstance.getNonParameterLocalTypes()),\n body\n );\n }\n\n /** Makes a built-in setter of a property that is a field. */\n private makeBuiltinFieldSetter(property: Property): FunctionRef {\n let setterInstance = assert(property.setterInstance);\n let module = this.module;\n let valueType = property.type;\n let thisTypeRef = this.options.sizeTypeRef;\n let valueTypeRef = valueType.toRef();\n // void(this.field = value)\n let bodyExpr = module.store(valueType.byteSize,\n module.local_get(0, thisTypeRef),\n module.local_get(1, valueTypeRef),\n valueTypeRef, property.memoryOffset\n );\n if (valueType.isManaged) {\n let parent = setterInstance.parent;\n assert(parent.kind == ElementKind.Class);\n if ((parent).type.isManaged) {\n let linkInstance = this.program.linkInstance;\n this.compileFunction(linkInstance);\n bodyExpr = module.block(null, [\n bodyExpr,\n module.call(linkInstance.internalName, [\n module.local_get(0, thisTypeRef),\n module.local_get(1, valueTypeRef),\n module.i32(0)\n ], TypeRef.None)\n ], TypeRef.None);\n }\n }\n setterInstance.set(CommonFlags.Compiled);\n return module.addFunction(\n setterInstance.internalName,\n createType([ thisTypeRef, valueTypeRef ]),\n TypeRef.None,\n null,\n bodyExpr\n );\n }\n\n // === Memory ===================================================================================\n\n /** Adds a static memory segment with the specified data. */\n addAlignedMemorySegment(buffer: Uint8Array, alignment: i32 = 16): MemorySegment {\n assert(isPowerOf2(alignment));\n let memoryOffset = i64_align(this.memoryOffset, alignment);\n let segment = new MemorySegment(buffer, memoryOffset);\n this.memorySegments.push(segment);\n this.memoryOffset = i64_add(memoryOffset, i64_new(buffer.length));\n return segment;\n }\n\n /** Adds a static memory segment representing a runtime object. */\n addRuntimeMemorySegment(buffer: Uint8Array): MemorySegment {\n let memoryOffset = this.program.computeBlockStart64(this.memoryOffset);\n let segment = new MemorySegment(buffer, memoryOffset);\n this.memorySegments.push(segment);\n this.memoryOffset = i64_add(memoryOffset, i64_new(buffer.length));\n return segment;\n }\n\n /** Ensures that a string exists in static memory and returns a pointer expression. Deduplicates. */\n ensureStaticString(stringValue: string): ExpressionRef {\n let ptr = this.ensureStaticStringPtr(stringValue);\n this.currentType = this.program.stringInstance.type;\n return this.module.usize(ptr);\n }\n\n /** Ensures that a string exists in static memory and returns a pointer to it. Deduplicates. */\n ensureStaticStringPtr(stringValue: string): i64 {\n let program = this.program;\n let totalOverhead = program.totalOverhead;\n let stringInstance = assert(program.stringInstance);\n let stringSegment: MemorySegment;\n let segments = this.stringSegments;\n if (segments.has(stringValue)) {\n stringSegment = assert(segments.get(stringValue)); // reuse\n } else {\n let len = stringValue.length;\n let buf = stringInstance.createBuffer(len << 1);\n for (let i = 0; i < len; ++i) {\n writeI16(stringValue.charCodeAt(i), buf, totalOverhead + (i << 1));\n }\n stringSegment = this.addRuntimeMemorySegment(buf);\n segments.set(stringValue, stringSegment);\n }\n return i64_add(stringSegment.offset, i64_new(totalOverhead));\n }\n\n /** Writes a series of static values of the specified type to a buffer. */\n writeStaticBuffer(buf: Uint8Array, pos: i32, elementType: Type, values: ExpressionRef[]): i32 {\n let length = values.length;\n let byteSize = elementType.byteSize;\n let elementTypeRef = elementType.toRef();\n switch (elementTypeRef) {\n case TypeRef.I32: {\n switch (byteSize) {\n case 1: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeI8(getConstValueI32(value), buf, pos);\n pos += 1;\n }\n break;\n }\n case 2: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeI16(getConstValueI32(value), buf, pos);\n pos += 2;\n }\n break;\n }\n case 4: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeI32(getConstValueI32(value), buf, pos);\n pos += 4;\n }\n break;\n }\n default: assert(false);\n }\n break;\n }\n case TypeRef.I64: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeI64(i64_new(getConstValueI64Low(value), getConstValueI64High(value)), buf, pos);\n pos += 8;\n }\n break;\n }\n case TypeRef.F32: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeF32(getConstValueF32(value), buf, pos);\n pos += 4;\n }\n break;\n }\n case TypeRef.F64: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeF64(getConstValueF64(value), buf, pos);\n pos += 8;\n }\n break;\n }\n case TypeRef.V128: {\n for (let i = 0; i < length; ++i) {\n let value = values[i];\n assert(getExpressionType(value) == elementTypeRef);\n assert(getExpressionId(value) == ExpressionId.Const);\n writeV128(getConstValueV128(value), buf, pos);\n pos += 16;\n }\n break;\n }\n case TypeRef.None: {\n // nothing to write\n break;\n }\n default: assert(false);\n }\n return pos;\n }\n\n /** Adds a buffer to static memory and returns the created segment. */\n addStaticBuffer(elementType: Type, values: ExpressionRef[], id: u32 = this.program.arrayBufferInstance.id): MemorySegment {\n let program = this.program;\n let arrayBufferInstance = program.arrayBufferInstance;\n let buf = arrayBufferInstance.createBuffer(values.length * elementType.byteSize);\n this.program.OBJECTInstance.writeField(\"rtId\", id, buf, 0); // use specified rtId\n this.writeStaticBuffer(buf, program.totalOverhead, elementType, values);\n return this.addRuntimeMemorySegment(buf);\n }\n\n /** Adds an array header to static memory and returns the created segment. */\n private addStaticArrayHeader(\n elementType: Type,\n bufferSegment: MemorySegment,\n /** Optional array instance override. */\n arrayInstance: Class | null = null\n ): MemorySegment {\n let program = this.program;\n if (!arrayInstance) {\n arrayInstance = assert(this.resolver.resolveClass(this.program.arrayPrototype, [ elementType ]));\n }\n let bufferLength = readI32(bufferSegment.buffer, program.OBJECTInstance.offsetof(\"rtSize\"));\n let arrayLength = i32(bufferLength / elementType.byteSize);\n let bufferAddress = i64_add(bufferSegment.offset, i64_new(program.totalOverhead));\n let buf = arrayInstance.createBuffer();\n assert(arrayInstance.writeField(\"buffer\", bufferAddress, buf));\n assert(arrayInstance.writeField(\"dataStart\", bufferAddress, buf));\n assert(arrayInstance.writeField(\"byteLength\", bufferLength, buf));\n assert(arrayInstance.writeField(\"length_\", arrayLength, buf));\n return this.addRuntimeMemorySegment(buf);\n }\n\n // === Table ====================================================================================\n\n /** Ensures that a runtime counterpart of the specified function exists and returns its address. */\n ensureRuntimeFunction(instance: Function): i64 {\n assert(instance.is(CommonFlags.Compiled) && !instance.is(CommonFlags.Stub));\n let program = this.program;\n let memorySegment = instance.memorySegment;\n if (!memorySegment) {\n\n // Add to the function table\n let functionTable = this.functionTable;\n let tableBase = this.options.tableBase;\n if (!tableBase) tableBase = 1; // leave first elem blank\n let index = tableBase + functionTable.length;\n functionTable.push(instance);\n\n // Create runtime function\n let rtInstance = assert(this.resolver.resolveClass(program.functionPrototype, [ instance.type ]));\n let buf = rtInstance.createBuffer();\n assert(rtInstance.writeField(\"_index\", index, buf));\n assert(rtInstance.writeField(\"_env\", 0, buf));\n instance.memorySegment = memorySegment = this.addRuntimeMemorySegment(buf);\n }\n return i64_add(memorySegment.offset, i64_new(program.totalOverhead));\n }\n\n // === Statements ===============================================================================\n\n /** Compiles a top level statement (incl. function declarations etc.) to the specified body. */\n compileTopLevelStatement(statement: Statement, body: ExpressionRef[]): void {\n switch (statement.kind) {\n case NodeKind.ClassDeclaration: {\n let memberStatements = (statement).members;\n for (let i = 0, k = memberStatements.length; i < k; ++i) {\n this.compileTopLevelStatement(memberStatements[i], body);\n }\n break;\n }\n case NodeKind.EnumDeclaration: {\n let element = this.program.getElementByDeclaration(statement);\n if (element) {\n assert(element.kind == ElementKind.Enum);\n if (!element.hasDecorator(DecoratorFlags.Lazy)) this.compileEnum(element);\n }\n break;\n }\n case NodeKind.NamespaceDeclaration: {\n let declaration = statement;\n let element = this.program.getElementByDeclaration(declaration);\n if (element) {\n // any potential merged element\n let previousParent = this.currentParent;\n this.currentParent = element;\n let memberStatements = declaration.members;\n for (let i = 0, k = memberStatements.length; i < k; ++i) {\n this.compileTopLevelStatement(memberStatements[i], body);\n }\n this.currentParent = previousParent;\n }\n break;\n }\n case NodeKind.Variable: {\n let declarations = (statement).declarations;\n for (let i = 0, k = declarations.length; i < k; ++i) {\n let element = this.program.getElementByDeclaration(declarations[i]);\n if (element) {\n assert(element.kind == ElementKind.Global);\n if (\n !element.is(CommonFlags.Ambient) && // delay imports\n !element.hasDecorator(DecoratorFlags.Lazy)\n ) this.compileGlobal(element);\n }\n }\n break;\n }\n case NodeKind.FieldDeclaration: {\n let element = this.program.getElementByDeclaration(statement);\n if (element && element.kind == ElementKind.Global) { // static\n if (!element.hasDecorator(DecoratorFlags.Lazy)) this.compileGlobal(element);\n }\n break;\n }\n case NodeKind.Export: {\n let exportStatement = statement;\n let internalPath = exportStatement.internalPath;\n if (internalPath != null) {\n this.compileFileByPath(internalPath, assert(exportStatement.path));\n }\n break;\n }\n case NodeKind.ExportDefault: {\n this.compileTopLevelStatement((statement).declaration, body);\n break;\n }\n case NodeKind.Import: {\n let importStatement = statement;\n this.compileFileByPath(importStatement.internalPath, importStatement.path);\n break;\n }\n case NodeKind.FunctionDeclaration:\n case NodeKind.MethodDeclaration:\n case NodeKind.InterfaceDeclaration:\n case NodeKind.IndexSignature:\n case NodeKind.TypeDeclaration: break;\n default: { // otherwise a top-level statement that is part of the start function's body\n let stmt = this.compileStatement(statement);\n if (getExpressionId(stmt) != ExpressionId.Nop) body.push(stmt);\n break;\n }\n }\n }\n\n /** Compiles a statement. */\n compileStatement(\n /** Statement to compile. */\n statement: Statement\n ): ExpressionRef {\n let module = this.module;\n let stmt: ExpressionRef;\n switch (statement.kind) {\n case NodeKind.Block: {\n stmt = this.compileBlockStatement(statement);\n break;\n }\n case NodeKind.Break: {\n stmt = this.compileBreakStatement(statement);\n break;\n }\n case NodeKind.Continue: {\n stmt = this.compileContinueStatement(statement);\n break;\n }\n case NodeKind.Do: {\n stmt = this.compileDoStatement(statement);\n break;\n }\n case NodeKind.Empty: {\n stmt = this.compileEmptyStatement(statement);\n break;\n }\n case NodeKind.Expression: {\n stmt = this.compileExpressionStatement(statement);\n break;\n }\n case NodeKind.For: {\n stmt = this.compileForStatement(statement);\n break;\n }\n case NodeKind.ForOf: {\n stmt = this.compileForOfStatement(statement);\n break;\n }\n case NodeKind.If: {\n stmt = this.compileIfStatement(statement);\n break;\n }\n case NodeKind.Return: {\n stmt = this.compileReturnStatement(statement);\n break;\n }\n case NodeKind.Switch: {\n stmt = this.compileSwitchStatement(statement);\n break;\n }\n case NodeKind.Throw: {\n stmt = this.compileThrowStatement(statement);\n break;\n }\n case NodeKind.Try: {\n stmt = this.compileTryStatement(statement);\n break;\n }\n case NodeKind.Variable: {\n stmt = this.compileVariableStatement(statement);\n if (!stmt) stmt = module.nop();\n break;\n }\n case NodeKind.Void: {\n stmt = this.compileVoidStatement(statement);\n break;\n }\n case NodeKind.While: {\n stmt = this.compileWhileStatement(statement);\n break;\n }\n case NodeKind.TypeDeclaration: {\n // TODO: integrate inner type declaration into flow\n this.error(\n DiagnosticCode.Not_implemented_0,\n statement.range,\n \"Inner type alias\"\n );\n stmt = module.unreachable();\n break;\n }\n case NodeKind.Module: {\n stmt = module.nop();\n break;\n }\n default: {\n assert(false);\n stmt = module.unreachable();\n }\n }\n if (this.options.sourceMap) this.addDebugLocation(stmt, statement.range);\n return stmt;\n }\n\n /** Compiles a series of statements. */\n compileStatements(\n /** Statements to compile. */\n statements: Statement[],\n /** Statements to append to. Also returned, created if omitted. */\n stmts: ExpressionRef[] | null = null\n ): ExpressionRef[] {\n let numStatements = statements.length;\n if (!stmts) {\n stmts = new Array(numStatements);\n stmts.length = 0;\n }\n let flow = this.currentFlow;\n for (let i = 0; i < numStatements; ++i) {\n let stmt = this.compileStatement(statements[i]);\n switch (getExpressionId(stmt)) {\n case ExpressionId.Block: {\n if (!getBlockName(stmt)) {\n for (let j: Index = 0, k = getBlockChildCount(stmt); j < k; ++j) stmts.push(getBlockChildAt(stmt, j));\n break;\n }\n // fall-through\n }\n default: stmts.push(stmt);\n case ExpressionId.Nop:\n }\n if (flow.isAny(FlowFlags.Terminates | FlowFlags.Breaks)) break;\n }\n return stmts;\n }\n\n private compileBlockStatement(\n statement: BlockStatement\n ): ExpressionRef {\n let statements = statement.statements;\n let outerFlow = this.currentFlow;\n let innerFlow = outerFlow.fork();\n this.currentFlow = innerFlow;\n\n let stmts = this.compileStatements(statements);\n outerFlow.inherit(innerFlow);\n this.currentFlow = outerFlow;\n return this.module.flatten(stmts);\n }\n\n private compileBreakStatement(\n statement: BreakStatement\n ): ExpressionRef {\n let module = this.module;\n let labelNode = statement.label;\n if (labelNode) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n labelNode.range,\n \"Break label\"\n );\n return module.unreachable();\n }\n let flow = this.currentFlow;\n let breakLabel = flow.breakLabel;\n if (breakLabel == null) {\n this.error(\n DiagnosticCode.A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement,\n statement.range\n );\n return module.unreachable();\n }\n flow.set(FlowFlags.Breaks);\n return module.br(breakLabel);\n }\n\n private compileContinueStatement(\n statement: ContinueStatement\n ): ExpressionRef {\n let module = this.module;\n let label = statement.label;\n if (label) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n label.range,\n \"Continue label\"\n );\n return module.unreachable();\n }\n // Check if 'continue' is allowed here\n let flow = this.currentFlow;\n let continueLabel = flow.continueLabel;\n if (continueLabel == null) {\n this.error(\n DiagnosticCode.A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement,\n statement.range\n );\n return module.unreachable();\n }\n flow.set(FlowFlags.Continues | FlowFlags.Terminates);\n return module.br(continueLabel);\n }\n\n private compileDoStatement(\n /** Statement to compile. */\n statement: DoStatement\n ): ExpressionRef {\n return this.doCompileDoStatement(statement);\n }\n\n private doCompileDoStatement(\n /** Statement to compile. */\n statement: DoStatement\n ): ExpressionRef {\n let module = this.module;\n let outerFlow = this.currentFlow;\n let numLocalsBefore = outerFlow.targetFunction.localsByIndex.length;\n\n // (block $break\n // (loop $loop\n // (?block $continue\n // (body)\n // )\n // (br_if $loop (condition))\n // )\n // )\n\n // Cases of interest:\n // * If the body never falls through or continues, the condition never executes\n // * If the condition is always true and body never breaks, overall flow terminates\n // * If the body terminates with a continue, condition is still reached\n\n // Compile the body (always executes)\n let flow = outerFlow.fork(/* resetBreakContext */ true);\n let label = flow.pushControlFlowLabel();\n let breakLabel = `do-break|${label}`;\n flow.breakLabel = breakLabel;\n let continueLabel = `do-continue|${label}`;\n flow.continueLabel = continueLabel;\n let loopLabel = `do-loop|${label}`;\n this.currentFlow = flow;\n let bodyStmts = new Array();\n let body = statement.body;\n if (body.kind == NodeKind.Block) {\n this.compileStatements((body).statements, bodyStmts);\n } else {\n bodyStmts.push(this.compileStatement(body));\n }\n flow.popControlFlowLabel(label);\n\n let possiblyContinues = flow.isAny(FlowFlags.Continues | FlowFlags.ConditionallyContinues);\n let possiblyBreaks = flow.isAny(FlowFlags.Breaks | FlowFlags.ConditionallyBreaks);\n let possiblyFallsThrough = !flow.isAny(FlowFlags.Terminates | FlowFlags.Breaks);\n\n // Shortcut if the condition is never reached\n if (!possiblyFallsThrough && !possiblyContinues) {\n bodyStmts.push(\n module.unreachable()\n );\n outerFlow.inherit(flow);\n\n // If the body also never breaks, the overall flow terminates\n if (!possiblyBreaks) {\n outerFlow.set(FlowFlags.Terminates);\n }\n\n // Otherwise compile and evaluate the condition (from here on always executes)\n } else {\n let condExpr = this.compileExpression(statement.condition, Type.bool);\n let condExprTrueish = this.makeIsTrueish(condExpr, this.currentType, statement.condition);\n let condKind = this.evaluateCondition(condExprTrueish);\n\n // Detect if local flags are incompatible before and after looping, and\n // if so recompile by unifying local flags between iterations. Note that\n // this may be necessary multiple times where locals depend on each other.\n let possiblyLoops = condKind != ConditionKind.False && (possiblyContinues || possiblyFallsThrough);\n if (possiblyLoops && outerFlow.resetIfNeedsRecompile(flow.forkThen(condExpr), numLocalsBefore)) {\n this.currentFlow = outerFlow;\n return this.doCompileDoStatement(statement);\n }\n\n if (possiblyContinues) {\n bodyStmts[0] = module.block(continueLabel, bodyStmts);\n bodyStmts.length = 1;\n flow.unset(FlowFlags.Terminates); // Continue breaks to condition\n }\n bodyStmts.push(\n module.br(loopLabel,\n condExprTrueish\n )\n );\n outerFlow.inherit(flow);\n\n // Terminate if the condition is always true and body never breaks\n if (condKind == ConditionKind.True && !possiblyBreaks) {\n outerFlow.set(FlowFlags.Terminates);\n }\n }\n\n // Finalize and leave everything else to the optimizer\n this.currentFlow = outerFlow;\n let expr = module.loop(loopLabel,\n module.flatten(bodyStmts)\n );\n if (possiblyBreaks) {\n expr = module.block(breakLabel, [\n expr\n ]);\n }\n if (outerFlow.is(FlowFlags.Terminates)) {\n expr = module.block(null, [ expr, module.unreachable() ]);\n }\n return expr;\n }\n\n private compileEmptyStatement(\n statement: EmptyStatement\n ): ExpressionRef {\n return this.module.nop();\n }\n\n private compileExpressionStatement(\n statement: ExpressionStatement\n ): ExpressionRef {\n return this.compileExpression(statement.expression, Type.void, Constraints.ConvImplicit);\n }\n\n private compileForStatement(\n /** Statement to compile. */\n statement: ForStatement\n ): ExpressionRef {\n return this.doCompileForStatement(statement);\n }\n\n private doCompileForStatement(\n /** Statement to compile. */\n statement: ForStatement\n ): ExpressionRef {\n let module = this.module;\n let outerFlow = this.currentFlow;\n let numLocalsBefore = outerFlow.targetFunction.localsByIndex.length;\n\n // (initializer) └►┐ flow\n // (?block $break │ (initializer)\n // (?loop $loop ┌◄┤ (condition) shortcut if false ◄┐\n // (if (condition) ├►┐ bodyFlow │\n // (then │ │ (body) │\n // (?block $continue │ │ if loops: (incrementor) ─────┘\n // (body) │ │ recompile body?\n // ) ├◄┘ \n // (incrementor) ┌◄┘\n // (br $loop)\n // )\n // )\n // )\n // )\n\n // Compile initializer if present. The initializer might introduce scoped\n // locals bound to the for statement, so create a new flow early.\n let flow = outerFlow.fork();\n this.currentFlow = flow;\n let stmts = new Array();\n let initializer = statement.initializer;\n if (initializer) {\n assert(\n initializer.kind == NodeKind.Expression ||\n initializer.kind == NodeKind.Variable\n );\n stmts.push(this.compileStatement(initializer));\n }\n\n // Precompute the condition if present, or default to `true`\n let condExpr: ExpressionRef;\n let condExprTrueish: ExpressionRef;\n let condKind: ConditionKind;\n let condition = statement.condition;\n if (condition) {\n condExpr = this.compileExpression(condition, Type.bool);\n condExprTrueish = this.makeIsTrueish(condExpr, this.currentType, condition);\n condKind = this.evaluateCondition(condExprTrueish);\n\n // Shortcut if condition is always false (body never executes)\n if (condKind == ConditionKind.False) {\n stmts.push(\n module.drop(condExprTrueish)\n );\n outerFlow.inherit(flow);\n this.currentFlow = outerFlow;\n return module.flatten(stmts);\n }\n } else {\n condExpr = module.i32(1);\n condExprTrueish = condExpr;\n condKind = ConditionKind.True;\n }\n // From here on condition is either true or unknown\n\n // Compile the body assuming the condition turned out true\n let bodyFlow = flow.forkThen(condExpr, /* newBreakContext */ true);\n let label = bodyFlow.pushControlFlowLabel();\n let breakLabel = `for-break${label}`;\n bodyFlow.breakLabel = breakLabel;\n let continueLabel = `for-continue|${label}`;\n bodyFlow.continueLabel = continueLabel;\n let loopLabel = `for-loop|${label}`;\n this.currentFlow = bodyFlow;\n let bodyStmts = new Array();\n let body = statement.body;\n if (body.kind == NodeKind.Block) {\n this.compileStatements((body).statements, bodyStmts);\n } else {\n bodyStmts.push(this.compileStatement(body));\n }\n bodyFlow.popControlFlowLabel(label);\n bodyFlow.breakLabel = null;\n bodyFlow.continueLabel = null;\n\n let possiblyFallsThrough = !bodyFlow.isAny(FlowFlags.Terminates | FlowFlags.Breaks);\n let possiblyContinues = bodyFlow.isAny(FlowFlags.Continues | FlowFlags.ConditionallyContinues);\n let possiblyBreaks = bodyFlow.isAny(FlowFlags.Breaks | FlowFlags.ConditionallyBreaks);\n\n if (possiblyContinues) {\n bodyStmts[0] = module.block(continueLabel, bodyStmts);\n bodyStmts.length = 1;\n }\n\n // Compile the incrementor if it possibly executes\n let possiblyLoops = possiblyContinues || possiblyFallsThrough;\n if (possiblyLoops) {\n let incrementor = statement.incrementor;\n if (incrementor) {\n bodyStmts.push(\n this.compileExpression(incrementor, Type.void, Constraints.ConvImplicit | Constraints.WillDrop)\n );\n }\n bodyStmts.push(\n module.br(loopLabel)\n );\n\n // Detect if local flags are incompatible before and after looping, and if\n // so recompile by unifying local flags between iterations. Note that this\n // may be necessary multiple times where locals depend on each other.\n if (outerFlow.resetIfNeedsRecompile(bodyFlow.forkThen(condExpr), numLocalsBefore)) {\n this.currentFlow = outerFlow;\n return this.doCompileForStatement(statement);\n }\n }\n\n // Body executes at least once\n if (condKind == ConditionKind.True) {\n flow.inherit(bodyFlow);\n\n // Otherwise executes conditionally\n } else {\n flow.mergeBranch(bodyFlow);\n }\n\n // Finalize\n outerFlow.inherit(flow);\n this.currentFlow = outerFlow;\n let expr = module.if(condExprTrueish,\n module.flatten(bodyStmts)\n );\n if (possiblyLoops) {\n expr = module.loop(loopLabel, expr);\n }\n if (possiblyBreaks) {\n expr = module.block(breakLabel, [ expr ]);\n }\n stmts.push(expr);\n if (outerFlow.is(FlowFlags.Terminates)) {\n stmts.push(module.unreachable());\n }\n return module.flatten(stmts);\n }\n\n private compileForOfStatement(\n statement: ForOfStatement\n ): ExpressionRef {\n this.error(\n DiagnosticCode.Not_implemented_0,\n statement.range,\n \"Iterators\"\n );\n return this.module.unreachable();\n }\n\n private compileIfStatement(\n statement: IfStatement\n ): ExpressionRef {\n let module = this.module;\n let ifTrue = statement.ifTrue;\n let ifFalse = statement.ifFalse;\n\n // (if (condition)\n // (then (ifTrue))\n // (?else (ifFalse))\n // )\n\n // Cases of interest:\n // * If the condition is always true or false, the other branch is eliminated\n // * If both then and else terminate, the overall flow does as well\n // * Without an else, when then terminates, follow-up flow acts like an else\n\n // Precompute the condition (always executes)\n let condExpr = this.compileExpression(statement.condition, Type.bool);\n let condExprTrueish = this.makeIsTrueish(\n condExpr,\n this.currentType,\n statement.condition\n );\n let condKind = this.evaluateCondition(condExprTrueish);\n\n // Shortcut if the condition is constant\n switch (condKind) {\n case ConditionKind.True: {\n return module.block(null, [\n module.drop(condExprTrueish),\n this.compileStatement(ifTrue)\n ]);\n }\n case ConditionKind.False: {\n return ifFalse\n ? module.block(null, [\n module.drop(condExprTrueish),\n this.compileStatement(ifFalse)\n ])\n : module.drop(condExprTrueish);\n }\n }\n\n // From here on condition is always unknown\n\n let flow = this.currentFlow;\n\n // Compile ifTrue assuming the condition turned out true\n let thenStmts = new Array();\n let thenFlow = flow.forkThen(condExpr);\n this.currentFlow = thenFlow;\n if (ifTrue.kind == NodeKind.Block) {\n this.compileStatements((ifTrue).statements, thenStmts);\n } else {\n thenStmts.push(this.compileStatement(ifTrue));\n }\n this.currentFlow = flow;\n\n // Compile ifFalse assuming the condition turned out false, if present\n let elseFlow = flow.forkElse(condExpr);\n if (ifFalse) {\n this.currentFlow = elseFlow;\n let elseStmts = new Array();\n if (ifFalse.kind == NodeKind.Block) {\n this.compileStatements((ifFalse).statements, elseStmts);\n } else {\n elseStmts.push(this.compileStatement(ifFalse));\n }\n flow.inheritAlternatives(thenFlow, elseFlow); // terminates if both do\n this.currentFlow = flow;\n return module.if(condExprTrueish,\n module.flatten(thenStmts),\n module.flatten(elseStmts)\n );\n } else {\n if (thenFlow.isAny(FlowFlags.Terminates | FlowFlags.Breaks)) {\n // Only getting past if condition was false (acts like else)\n flow.inherit(elseFlow);\n flow.mergeSideEffects(thenFlow);\n } else {\n // Otherwise getting past conditionally\n flow.inheritAlternatives(thenFlow, elseFlow);\n }\n this.currentFlow = flow;\n return module.if(condExprTrueish,\n module.flatten(thenStmts)\n );\n }\n }\n\n private compileReturnStatement(\n statement: ReturnStatement\n ): ExpressionRef {\n let module = this.module;\n let expr: ExpressionRef = 0;\n let flow = this.currentFlow;\n let returnType = flow.returnType;\n\n let valueExpression = statement.value;\n if (valueExpression) {\n let constraints = Constraints.ConvImplicit;\n if (flow.sourceFunction.is(CommonFlags.ModuleExport)) constraints |= Constraints.MustWrap;\n\n expr = this.compileExpression(valueExpression, returnType, constraints);\n if (!flow.canOverflow(expr, returnType)) flow.set(FlowFlags.ReturnsWrapped);\n if (flow.isNonnull(expr, returnType)) flow.set(FlowFlags.ReturnsNonNull);\n if (flow.sourceFunction.is(CommonFlags.Constructor) && valueExpression.kind != NodeKind.This) {\n flow.set(FlowFlags.MayReturnNonThis);\n }\n } else if (returnType != Type.void) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n statement.range, \"void\", returnType.toString()\n );\n this.currentType = returnType;\n return module.unreachable();\n }\n\n // Remember that this flow returns\n flow.set(FlowFlags.Returns | FlowFlags.Terminates);\n\n // Handle inline return\n if (flow.isInline) {\n let inlineReturnLabel = assert(flow.inlineReturnLabel);\n return expr\n ? this.currentType == Type.void\n ? module.block(null, [ expr, module.br(inlineReturnLabel) ])\n : module.br(inlineReturnLabel, 0, expr)\n : module.br(inlineReturnLabel);\n }\n\n // Otherwise emit a normal return\n return expr\n ? this.currentType == Type.void\n ? module.block(null, [ expr, module.return() ])\n : module.return(expr)\n : module.return();\n }\n\n private compileSwitchStatement(\n statement: SwitchStatement\n ): ExpressionRef {\n let module = this.module;\n let cases = statement.cases;\n let numCases = cases.length;\n\n // Compile the condition (always executes)\n let condExpr = this.compileExpression(statement.condition, Type.u32,\n Constraints.ConvImplicit\n );\n\n // Shortcut if there are no cases\n if (!numCases) return module.drop(condExpr);\n \n // Assign the condition to a temporary local as we compare it multiple times\n let outerFlow = this.currentFlow;\n let tempLocal = outerFlow.getTempLocal(Type.u32);\n let tempLocalIndex = tempLocal.index;\n let breaks = new Array(1 + numCases);\n breaks[0] = module.local_set(tempLocalIndex, condExpr, false); // u32\n \n // Make one br_if per labeled case and leave it to Binaryen to optimize the\n // sequence of br_ifs to a br_table according to optimization levels\n let breakIndex = 1;\n let defaultIndex = -1;\n let label = outerFlow.pushControlFlowLabel();\n for (let i = 0; i < numCases; ++i) {\n let case_ = cases[i];\n if (case_.isDefault) {\n defaultIndex = i;\n continue;\n }\n breaks[breakIndex++] = module.br(`case${i}|${label}`,\n module.binary(BinaryOp.EqI32,\n module.local_get(tempLocalIndex, TypeRef.I32),\n this.compileExpression(assert(case_.label), Type.u32,\n Constraints.ConvImplicit\n )\n )\n );\n }\n\n // If there is a default case, break to it, otherwise break out of the switch\n breaks[breakIndex] = module.br(defaultIndex >= 0\n ? `case${defaultIndex}|${label}`\n : `break|${label}`\n );\n\n // Nest the case blocks in order, to be targeted by the br_if sequence\n let currentBlock = module.block(`case0|${label}`, breaks, TypeRef.None);\n let fallThroughFlow: Flow | null = null;\n let breakingFlowAlternatives: Flow | null = null;\n for (let i = 0; i < numCases; ++i) {\n let case_ = cases[i];\n let statements = case_.statements;\n let numStatements = statements.length;\n\n // Can get here by matching the case or possibly by fall-through\n let innerFlow = outerFlow.fork(/* newBreakContext */ true, /* newContinueContext */ false);\n if (fallThroughFlow) innerFlow.mergeBranch(fallThroughFlow);\n this.currentFlow = innerFlow;\n let breakLabel = `break|${label}`;\n innerFlow.breakLabel = breakLabel;\n\n let isLast = i == numCases - 1;\n let nextLabel = isLast ? breakLabel : `case${i + 1}|${label}`;\n let stmts = new Array(1 + numStatements);\n stmts[0] = currentBlock;\n let count = 1;\n let possiblyFallsThrough = true;\n for (let j = 0; j < numStatements; ++j) {\n let stmt = this.compileStatement(statements[j]);\n if (getExpressionId(stmt) != ExpressionId.Nop) {\n stmts[count++] = stmt;\n }\n if (innerFlow.isAny(FlowFlags.Terminates | FlowFlags.Breaks)) {\n possiblyFallsThrough = false;\n break;\n }\n }\n stmts.length = count;\n fallThroughFlow = possiblyFallsThrough ? innerFlow : null;\n let possiblyBreaks = innerFlow.isAny(FlowFlags.Breaks | FlowFlags.ConditionallyBreaks);\n innerFlow.unset(FlowFlags.Breaks | FlowFlags.ConditionallyBreaks); // clear\n\n // Combine all alternatives that merge again with outer flow\n if (possiblyBreaks || (isLast && possiblyFallsThrough)) {\n if (breakingFlowAlternatives) breakingFlowAlternatives.inheritAlternatives(breakingFlowAlternatives, innerFlow);\n else breakingFlowAlternatives = innerFlow;\n\n // Otherwise just merge the effects of a non-merging branch\n } else if (!possiblyFallsThrough) {\n outerFlow.mergeSideEffects(innerFlow);\n }\n\n this.currentFlow = outerFlow;\n currentBlock = module.block(nextLabel, stmts, TypeRef.None); // must be a labeled block\n }\n outerFlow.popControlFlowLabel(label);\n\n // If the switch has a default, we only get past through any breaking flow\n if (defaultIndex >= 0) {\n if (breakingFlowAlternatives) outerFlow.inherit(breakingFlowAlternatives);\n else outerFlow.set(FlowFlags.Terminates);\n\n // Otherwise either none or any breaking flow can get past conditionally\n } else if (breakingFlowAlternatives) {\n outerFlow.mergeBranch(breakingFlowAlternatives);\n }\n\n this.currentFlow = outerFlow;\n return currentBlock;\n }\n\n private compileThrowStatement(\n statement: ThrowStatement\n ): ExpressionRef {\n // TODO: requires exception-handling spec.\n let flow = this.currentFlow;\n\n // Remember that this branch throws\n flow.set(FlowFlags.Throws | FlowFlags.Terminates);\n\n let stmts = new Array();\n let value = statement.value;\n let message: Expression | null = null;\n if (value.kind == NodeKind.New) {\n let newArgs = (value).args;\n if (newArgs.length) message = newArgs[0]; // FIXME: naively assumes type string\n }\n stmts.push(\n this.makeAbort(message, statement)\n );\n return this.module.flatten(stmts);\n }\n\n private compileTryStatement(\n statement: TryStatement\n ): ExpressionRef {\n // TODO: can't yet support something like: try { return ... } finally { ... }\n // worthwhile to investigate lowering returns to block results (here)?\n this.error(\n DiagnosticCode.Not_implemented_0,\n statement.range,\n \"Exceptions\"\n );\n return this.module.unreachable();\n }\n\n /** Compiles a variable statement. Returns `0` if an initializer is not necessary. */\n private compileVariableStatement(\n statement: VariableStatement\n ): ExpressionRef {\n let module = this.module;\n let declarations = statement.declarations;\n let numDeclarations = declarations.length;\n let flow = this.currentFlow;\n let initializers = new Array();\n let resolver = this.resolver;\n\n for (let i = 0; i < numDeclarations; ++i) {\n let declaration = declarations[i];\n let name = declaration.name.text;\n let type: Type | null = null;\n let initExpr: ExpressionRef = 0;\n let initType: Type | null = null;\n\n if (declaration.is(CommonFlags.DefinitelyAssigned)) {\n this.warning(\n DiagnosticCode.Definitive_assignment_has_no_effect_on_local_variables,\n declaration.name.range\n );\n }\n\n // Resolve type if annotated\n let typeNode = declaration.type;\n let initializerNode = declaration.initializer;\n if (typeNode) {\n type = resolver.resolveType( // reports\n typeNode,\n flow.sourceFunction,\n cloneMap(flow.contextualTypeArguments)\n );\n if (!type) continue;\n this.program.checkTypeSupported(type, typeNode);\n\n if (initializerNode) {\n let pendingElements = this.pendingElements;\n let dummy = flow.addScopedDummyLocal(name, type, statement); // pending dummy\n pendingElements.add(dummy);\n initExpr = this.compileExpression(initializerNode, type, // reports\n Constraints.ConvImplicit\n );\n initType = this.currentType;\n pendingElements.delete(dummy);\n flow.freeScopedDummyLocal(name);\n }\n\n // Otherwise infer type from initializer\n } else if (initializerNode) {\n let pendingElements = this.pendingElements;\n let temp = flow.addScopedDummyLocal(name, Type.auto, statement); // pending dummy\n pendingElements.add(temp);\n initExpr = this.compileExpression(initializerNode, Type.auto); // reports\n initType = this.currentType;\n pendingElements.delete(temp);\n flow.freeScopedDummyLocal(name);\n\n if (this.currentType == Type.void) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n declaration.range, this.currentType.toString(), \"\"\n );\n continue;\n }\n type = initType;\n\n // Error if there's neither a type nor an initializer\n } else {\n this.error(\n DiagnosticCode.Type_expected,\n declaration.name.range.atEnd\n );\n continue;\n }\n\n // Handle constants, and try to inline if value is static\n let isConst = declaration.is(CommonFlags.Const);\n let isStatic = false;\n if (isConst) {\n if (initExpr) {\n let precomp = module.runExpression(initExpr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n initExpr = precomp; // always use precomputed initExpr\n let local: Local | null = null;\n switch (getExpressionType(initExpr)) {\n case TypeRef.I32: {\n local = new Local(name, -1, type, flow.targetFunction);\n local.setConstantIntegerValue(\n i64_new(\n getConstValueI32(initExpr),\n 0\n ),\n type\n );\n break;\n }\n case TypeRef.I64: {\n local = new Local(name, -1, type, flow.targetFunction);\n local.setConstantIntegerValue(\n i64_new(\n getConstValueI64Low(initExpr),\n getConstValueI64High(initExpr)\n ),\n type\n );\n break;\n }\n case TypeRef.F32: {\n local = new Local(name, -1, type, flow.targetFunction);\n local.setConstantFloatValue(getConstValueF32(initExpr), type);\n break;\n }\n case TypeRef.F64: {\n local = new Local(name, -1, type, flow.targetFunction);\n local.setConstantFloatValue(getConstValueF64(initExpr), type);\n break;\n }\n }\n if (local) {\n // Add as a dummy local that doesn't actually exist in WebAssembly\n let scopedLocals = flow.scopedLocals;\n if (!scopedLocals) flow.scopedLocals = scopedLocals = new Map();\n else if (scopedLocals.has(name)) {\n let existing = assert(scopedLocals.get(name));\n this.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range,\n existing.declaration.name.range,\n name\n );\n return this.module.unreachable();\n }\n scopedLocals.set(name, local);\n isStatic = true;\n }\n }\n } else {\n this.error(\n DiagnosticCode._const_declarations_must_be_initialized,\n declaration.range\n );\n }\n }\n\n // Otherwise compile as mutable\n if (!isStatic) {\n let local: Local;\n if (\n declaration.isAny(CommonFlags.Let | CommonFlags.Const) ||\n flow.isInline\n ) { // here: not top-level\n let existingLocal = flow.getScopedLocal(name);\n if (existingLocal) {\n if (!existingLocal.declaration.range.source.isNative) {\n this.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range,\n existingLocal.declaration.name.range,\n name\n );\n } else { // scoped locals are shared temps that don't track declarations\n this.error(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range, name\n );\n }\n local = existingLocal;\n } else {\n local = flow.addScopedLocal(name, type);\n }\n if (isConst) flow.setLocalFlag(local.index, LocalFlags.Constant);\n } else {\n let existing = flow.lookupLocal(name);\n if (existing) {\n this.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range,\n existing.declaration.name.range,\n name\n );\n continue;\n }\n local = flow.targetFunction.addLocal(type, name, declaration);\n flow.unsetLocalFlag(local.index, ~0);\n if (isConst) flow.setLocalFlag(local.index, LocalFlags.Constant);\n }\n if (initExpr) {\n initializers.push(\n this.makeLocalAssignment(local, initExpr, initType ? initType : type, false)\n );\n } else {\n // no need to assign zero\n if (local.type.isShortIntegerValue) {\n flow.setLocalFlag(local.index, LocalFlags.Wrapped);\n }\n }\n }\n }\n this.currentType = Type.void;\n return initializers.length == 0\n ? 0\n : module.flatten(initializers);\n }\n\n private compileVoidStatement(\n statement: VoidStatement\n ): ExpressionRef {\n return this.compileExpression(statement.expression, Type.void,\n Constraints.ConvExplicit | Constraints.WillDrop\n );\n }\n\n private compileWhileStatement(\n /** Statement to compile. */\n statement: WhileStatement\n ): ExpressionRef {\n return this.doCompileWhileStatement(statement);\n }\n\n private doCompileWhileStatement(\n /** Statement to compile. */\n statement: WhileStatement\n ): ExpressionRef {\n let module = this.module;\n let outerFlow = this.currentFlow;\n let numLocalsBefore = outerFlow.targetFunction.localsByIndex.length;\n\n // (block $break\n // (loop $continue\n // (if (condition)\n // (then\n // (body)\n // (br $continue)\n // )\n // )\n // )\n\n // Cases of interest:\n // * If the condition is always false, eliminate the body as it never runs\n // * If the condition is always true and the body never breaks, terminate\n // * If the body runs but always terminates, continue as if condition was false\n\n // Compile and evaluate the condition (always executes)\n let condExpr = this.compileExpression(statement.condition, Type.bool);\n let condExprTrueish = this.makeIsTrueish(condExpr, this.currentType, statement.condition);\n let condKind = this.evaluateCondition(condExprTrueish);\n\n // Shortcut if condition is always false (body never runs)\n if (condKind == ConditionKind.False) {\n return module.drop(condExprTrueish);\n }\n\n // Compile the body assuming the condition turned out true\n let thenFlow = outerFlow.forkThen(condExpr, /* newBreakContext */ true);\n let label = thenFlow.pushControlFlowLabel();\n let breakLabel = `while-break|${label}`;\n thenFlow.breakLabel = breakLabel;\n let continueLabel = `while-continue|${label}`;\n thenFlow.continueLabel = continueLabel;\n this.currentFlow = thenFlow;\n let bodyStmts = new Array();\n let body = statement.body;\n if (body.kind == NodeKind.Block) {\n this.compileStatements((body).statements, bodyStmts);\n } else {\n bodyStmts.push(this.compileStatement(body));\n }\n bodyStmts.push(\n module.br(continueLabel)\n );\n thenFlow.popControlFlowLabel(label);\n\n let possiblyContinues = thenFlow.isAny(FlowFlags.Continues | FlowFlags.ConditionallyContinues);\n let possiblyBreaks = thenFlow.isAny(FlowFlags.Breaks | FlowFlags.ConditionallyBreaks);\n let possiblyFallsThrough = !thenFlow.isAny(FlowFlags.Terminates | FlowFlags.Breaks);\n\n // Detect if local flags are incompatible before and after looping, and\n // if so recompile by unifying local flags between iterations. Note that\n // this may be necessary multiple times where locals depend on each other.\n let possiblyLoops = possiblyContinues || possiblyFallsThrough;\n if (possiblyLoops && outerFlow.resetIfNeedsRecompile(thenFlow, numLocalsBefore)) {\n this.currentFlow = outerFlow;\n return this.doCompileWhileStatement(statement);\n }\n\n // If the condition is always true, the body's effects always happen\n let alwaysTerminates = false;\n if (condKind == ConditionKind.True) {\n outerFlow.inherit(thenFlow);\n\n // If the body also never breaks, the overall flow terminates\n if (!possiblyBreaks) {\n alwaysTerminates = true;\n outerFlow.set(FlowFlags.Terminates);\n }\n\n // Otherwise loop conditionally\n } else {\n let elseFlow = outerFlow.forkElse(condExpr);\n if (!possiblyFallsThrough && !possiblyBreaks) {\n // Only getting past if condition was false\n outerFlow.inherit(elseFlow);\n outerFlow.mergeSideEffects(thenFlow);\n } else {\n // Otherwise getting past conditionally\n outerFlow.inheritAlternatives(thenFlow, elseFlow);\n }\n }\n\n // Finalize and leave everything else to the optimizer\n this.currentFlow = outerFlow;\n let stmts: ExpressionRef[] = [\n module.loop(continueLabel,\n module.if(condExprTrueish,\n module.flatten(bodyStmts)\n )\n )\n ];\n if (alwaysTerminates) stmts.push(module.unreachable());\n return module.block(breakLabel, stmts);\n }\n\n // === Expressions ==============================================================================\n\n /** Compiles the value of an inlined constant element. */\n compileInlineConstant(\n element: VariableLikeElement,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n assert(element.is(CommonFlags.Inlined | CommonFlags.Resolved));\n let type = element.type;\n this.currentType = type;\n switch (type.kind) {\n case TypeKind.Bool: {\n return this.module.i32(\n element.constantValueKind == ConstantValueKind.Integer\n // @ts-ignore\n ? i64_ne(element.constantIntegerValue, i64_zero)\n : 0\n );\n }\n case TypeKind.I8:\n case TypeKind.I16: {\n let shift = type.computeSmallIntegerShift(Type.i32);\n return this.module.i32(\n element.constantValueKind == ConstantValueKind.Integer\n ? i64_low(element.constantIntegerValue) << shift >> shift\n : 0\n ); // recognized by canOverflow\n }\n case TypeKind.U8:\n case TypeKind.U16: {\n let mask = element.type.computeSmallIntegerMask(Type.i32);\n return this.module.i32(\n element.constantValueKind == ConstantValueKind.Integer\n ? i64_low(element.constantIntegerValue) & mask\n : 0\n ); // recognized by canOverflow\n }\n case TypeKind.I32:\n case TypeKind.U32: {\n return this.module.i32(\n element.constantValueKind == ConstantValueKind.Integer\n ? i64_low(element.constantIntegerValue)\n : 0\n );\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n if (!element.program.options.isWasm64) {\n return this.module.i32(\n element.constantValueKind == ConstantValueKind.Integer\n ? i64_low(element.constantIntegerValue)\n : 0\n );\n }\n // fall-through\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n return element.constantValueKind == ConstantValueKind.Integer\n ? this.module.i64(\n i64_low(element.constantIntegerValue),\n i64_high(element.constantIntegerValue)\n )\n : this.module.i64(0);\n }\n case TypeKind.F64: {\n // monkey-patch for converting built-in floats to f32 implicitly\n if (!(element.hasDecorator(DecoratorFlags.Builtin) && contextualType == Type.f32)) {\n return this.module.f64(element.constantFloatValue);\n }\n // otherwise fall-through: basically precomputes f32.demote/f64 of NaN / Infinity\n this.currentType = Type.f32;\n }\n case TypeKind.F32: {\n return this.module.f32(element.constantFloatValue);\n }\n default: {\n assert(false);\n return this.module.unreachable();\n }\n }\n }\n\n compileExpression(\n expression: Expression,\n contextualType: Type,\n constraints: Constraints = Constraints.None\n ): ExpressionRef {\n while (expression.kind == NodeKind.Parenthesized) { // skip\n expression = (expression).expression;\n }\n this.currentType = contextualType;\n if (contextualType == Type.void) constraints |= Constraints.WillDrop;\n let expr: ExpressionRef;\n switch (expression.kind) {\n case NodeKind.Assertion: {\n expr = this.compileAssertionExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Binary: {\n expr = this.compileBinaryExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Call: {\n expr = this.compileCallExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Comma: {\n expr = this.compileCommaExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.ElementAccess: {\n expr = this.compileElementAccessExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Function: {\n expr = this.compileFunctionExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Identifier:\n case NodeKind.False:\n case NodeKind.Null:\n case NodeKind.This:\n case NodeKind.Super:\n case NodeKind.True: {\n expr = this.compileIdentifierExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.InstanceOf: {\n expr = this.compileInstanceOfExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Literal: {\n expr = this.compileLiteralExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.New: {\n expr = this.compileNewExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.PropertyAccess: {\n expr = this.compilePropertyAccessExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Ternary: {\n expr = this.compileTernaryExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.UnaryPostfix: {\n expr = this.compileUnaryPostfixExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.UnaryPrefix: {\n expr = this.compileUnaryPrefixExpression(expression, contextualType, constraints);\n break;\n }\n case NodeKind.Compiled: {\n let compiled = expression;\n expr = compiled.expr;\n this.currentType = compiled.type;\n break;\n }\n case NodeKind.Class: {\n // TODO: compile as class expression\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range,\n \"Block-scoped class declarations or expressions\"\n );\n expr = this.module.unreachable();\n break;\n }\n default: {\n assert(false);\n expr = this.module.unreachable();\n }\n }\n // ensure conversion and wrapping in case the respective function doesn't on its own\n let currentType = this.currentType;\n let wrap = (constraints & Constraints.MustWrap) != 0;\n if (currentType != contextualType.nonNullableType) { // allow assigning non-nullable to nullable\n if (constraints & Constraints.ConvExplicit) {\n expr = this.convertExpression(expr, currentType, contextualType, true, expression);\n this.currentType = currentType = contextualType;\n } else if (constraints & Constraints.ConvImplicit) {\n expr = this.convertExpression(expr, currentType, contextualType, false, expression);\n this.currentType = currentType = contextualType;\n }\n }\n if (wrap) expr = this.ensureSmallIntegerWrap(expr, currentType);\n // debug location is added here so the caller doesn't have to. means: compilation of an expression\n // must go through this function, with the respective per-kind functions not being used directly.\n if (this.options.sourceMap) this.addDebugLocation(expr, expression.range);\n return expr;\n }\n\n /** Converts an expression's result from one type to another. */\n convertExpression(\n expr: ExpressionRef,\n /** Original type. */\n fromType: Type,\n /** New type. */\n toType: Type,\n /** Whether the conversion is explicit. */\n explicit: bool,\n /** Report node. */\n reportNode: Node\n ): ExpressionRef {\n let module = this.module;\n\n if (fromType.kind == TypeKind.Void) {\n if (toType.kind == TypeKind.Void) {\n // void to void: Can happen as a result of a foregoing error. Since we\n // have an `expr` here that is already supposed to be void, return it.\n return expr;\n }\n // void to any\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n reportNode.range, fromType.toString(), toType.toString()\n );\n return module.unreachable();\n }\n\n // any to void\n if (toType.kind == TypeKind.Void) return module.drop(expr);\n\n // reference involved\n if (fromType.isReference || toType.isReference) {\n if (this.currentFlow.isNonnull(expr, fromType)) {\n fromType = fromType.nonNullableType;\n } else if (explicit && fromType.isNullableReference && !toType.isNullableReference) {\n // explicit conversion from nullable to non-nullable requires a runtime\n // check here because nonnull state above already didn't know better\n if (!this.options.noAssert) {\n expr = this.makeRuntimeNonNullCheck(expr, fromType, reportNode);\n }\n fromType = fromType.nonNullableType;\n }\n if (fromType.isAssignableTo(toType)) { // upcast or same\n assert(toType.isExternalReference || fromType.kind == toType.kind);\n this.currentType = toType;\n return expr;\n }\n if (explicit && toType.nonNullableType.isAssignableTo(fromType)) { // downcast\n // (maybeCat)\n if (toType.isExternalReference) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n reportNode.range,\n \"ref.cast\"\n );\n this.currentType = toType;\n return module.unreachable();\n }\n assert(fromType.kind == toType.kind);\n if (!this.options.noAssert) {\n expr = this.makeRuntimeDowncastCheck(expr, fromType, toType, reportNode);\n }\n this.currentType = toType;\n return expr;\n }\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n reportNode.range, fromType.toString(), toType.toString()\n );\n this.currentType = toType;\n return module.unreachable();\n }\n\n // not dealing with references from here on\n assert(!fromType.isReference && !toType.isReference);\n\n // Early return if we have same types\n if (toType.kind == fromType.kind) {\n this.currentType = toType;\n return expr;\n }\n\n // v128 to any / any to v128\n // except v128 to bool\n //\n // NOTE:In case we would have more conversions to and from v128 type it's better\n // to make these checks more individual and integrate in below flow.\n if (\n !toType.isBooleanValue &&\n (toType.isVectorValue || fromType.isVectorValue)\n ) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n reportNode.range, fromType.toString(), toType.toString()\n );\n return module.unreachable();\n }\n\n if (!fromType.isAssignableTo(toType)) {\n if (!explicit) {\n this.error(\n DiagnosticCode.Conversion_from_type_0_to_1_requires_an_explicit_cast,\n reportNode.range, fromType.toString(), toType.toString()\n ); // recoverable\n }\n }\n\n if (fromType.isFloatValue) {\n\n // float to float\n if (toType.isFloatValue) {\n if (fromType.kind == TypeKind.F32) {\n\n // f32 to f64\n if (toType.kind == TypeKind.F64) {\n expr = module.unary(UnaryOp.PromoteF32ToF64, expr);\n }\n\n // otherwise f32 to f32\n\n // f64 to f32\n } else if (toType.kind == TypeKind.F32) {\n expr = module.unary(UnaryOp.DemoteF64ToF32, expr);\n }\n\n // otherwise f64 to f64\n\n // float to int\n } else if (toType.isIntegerValue) {\n\n // f32 to int\n if (fromType.kind == TypeKind.F32) {\n if (toType.isBooleanValue) {\n expr = this.makeIsTrueish(expr, Type.f32, reportNode);\n } else if (toType.isSignedIntegerValue) {\n let saturating = this.options.hasFeature(Feature.NontrappingF2I);\n if (toType.isLongIntegerValue) {\n expr = module.unary(saturating ? UnaryOp.TruncSatF32ToI64 : UnaryOp.TruncF32ToI64, expr);\n } else {\n expr = module.unary(saturating ? UnaryOp.TruncSatF32ToI32 : UnaryOp.TruncF32ToI32, expr);\n }\n } else {\n let saturating = this.options.hasFeature(Feature.NontrappingF2I);\n if (toType.isLongIntegerValue) {\n expr = module.unary(saturating ? UnaryOp.TruncSatF32ToU64 : UnaryOp.TruncF32ToU64, expr);\n } else {\n expr = module.unary(saturating ? UnaryOp.TruncSatF32ToU32 : UnaryOp.TruncF32ToU32, expr);\n }\n }\n\n // f64 to int\n } else {\n if (toType.isBooleanValue) {\n expr = this.makeIsTrueish(expr, Type.f64, reportNode);\n } else if (toType.isSignedIntegerValue) {\n let saturating = this.options.hasFeature(Feature.NontrappingF2I);\n if (toType.isLongIntegerValue) {\n expr = module.unary(saturating ? UnaryOp.TruncSatF64ToI64 : UnaryOp.TruncF64ToI64, expr);\n } else {\n expr = module.unary(saturating ? UnaryOp.TruncSatF64ToI32 : UnaryOp.TruncF64ToI32, expr);\n }\n } else {\n let saturating = this.options.hasFeature(Feature.NontrappingF2I);\n if (toType.isLongIntegerValue) {\n expr = module.unary(saturating ? UnaryOp.TruncSatF64ToU64 : UnaryOp.TruncF64ToU64, expr);\n } else {\n expr = module.unary(saturating ? UnaryOp.TruncSatF64ToU32 : UnaryOp.TruncF64ToU32, expr);\n }\n }\n }\n\n // float to void\n } else {\n assert(toType.flags == TypeFlags.None, \"void type expected\");\n expr = module.drop(expr);\n }\n\n // int to float\n } else if (fromType.isIntegerValue && toType.isFloatValue) {\n\n // int to f32\n if (toType.kind == TypeKind.F32) {\n if (fromType.isLongIntegerValue) {\n expr = module.unary(\n fromType.isSignedIntegerValue\n ? UnaryOp.ConvertI64ToF32\n : UnaryOp.ConvertU64ToF32,\n expr\n );\n } else {\n expr = module.unary(\n fromType.isSignedIntegerValue\n ? UnaryOp.ConvertI32ToF32\n : UnaryOp.ConvertU32ToF32,\n expr\n );\n }\n\n // int to f64\n } else {\n if (fromType.isLongIntegerValue) {\n expr = module.unary(\n fromType.isSignedIntegerValue\n ? UnaryOp.ConvertI64ToF64\n : UnaryOp.ConvertU64ToF64,\n expr\n );\n } else {\n expr = module.unary(\n fromType.isSignedIntegerValue\n ? UnaryOp.ConvertI32ToF64\n : UnaryOp.ConvertU32ToF64,\n expr\n );\n }\n }\n\n // v128 to bool\n } else if (fromType == Type.v128 && toType.isBooleanValue) {\n expr = this.makeIsTrueish(expr, Type.v128, reportNode);\n\n // int to int\n } else {\n // i64 to ...\n if (fromType.isLongIntegerValue) {\n\n // i64 to i32 or smaller\n if (toType.isBooleanValue) {\n expr = module.binary(BinaryOp.NeI64, expr, module.i64(0));\n } else if (!toType.isLongIntegerValue) {\n expr = module.unary(UnaryOp.WrapI64ToI32, expr); // discards upper bits\n }\n\n // i32 or smaller to i64\n } else if (toType.isLongIntegerValue) {\n expr = module.unary(\n fromType.isSignedIntegerValue ? UnaryOp.ExtendI32ToI64 : UnaryOp.ExtendU32ToU64,\n this.ensureSmallIntegerWrap(expr, fromType) // must clear garbage bits\n );\n\n // i32 to i32\n } else {\n // small i32 to ...\n if (fromType.isShortIntegerValue) {\n // small i32 to larger i32\n if (fromType.size < toType.size) {\n expr = this.ensureSmallIntegerWrap(expr, fromType); // must clear garbage bits\n }\n // same size\n } else {\n if (!explicit && !this.options.isWasm64 && fromType.isVaryingIntegerValue && !toType.isVaryingIntegerValue) {\n this.warning(\n DiagnosticCode.Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit,\n reportNode.range, fromType.toString(), toType.toString()\n );\n }\n }\n }\n }\n\n this.currentType = toType;\n return expr;\n }\n\n private compileAssertionExpression(\n expression: AssertionExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let inheritedConstraints = constraints & ~(Constraints.ConvImplicit | Constraints.ConvExplicit);\n switch (expression.assertionKind) {\n case AssertionKind.Prefix:\n case AssertionKind.As: {\n let flow = this.currentFlow;\n let toType = this.resolver.resolveType( // reports\n assert(expression.toType),\n flow.sourceFunction,\n cloneMap(flow.contextualTypeArguments)\n );\n if (!toType) return this.module.unreachable();\n return this.compileExpression(expression.expression, toType, inheritedConstraints | Constraints.ConvExplicit);\n }\n case AssertionKind.NonNull: {\n assert(!expression.toType);\n let expr = this.compileExpression(expression.expression, contextualType.exceptVoid, inheritedConstraints);\n let type = this.currentType;\n if (this.currentFlow.isNonnull(expr, type)) {\n this.info(\n DiagnosticCode.Expression_is_never_null,\n expression.expression.range\n );\n } else if (!this.options.noAssert) {\n expr = this.makeRuntimeNonNullCheck(expr, type, expression);\n }\n this.currentType = type.nonNullableType;\n return expr;\n }\n case AssertionKind.Const: {\n // TODO: decide on the layout of ReadonlyArray first\n // let operand = expression.expression;\n // if (operand.kind == NodeKind.Literal && (operand).literalKind == LiteralKind.Array) {\n // let element = this.resolver.lookupExpression(expression /* ! */, this.currentFlow, contextualType);\n // if (!element) return this.module.unreachable();\n // if (element.kind == ElementKind.Class) {\n // let arrayInstance = element;\n // if (arrayInstance.extends(this.program.readonlyArrayPrototype)) {\n // return this.compileStaticArrayLiteral(operand, arrayInstance.type, constraints);\n // }\n // }\n // }\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range,\n \"Const assertion\"\n );\n return this.module.unreachable();\n }\n default: assert(false);\n }\n return this.module.unreachable();\n }\n\n private f32ModInstance: Function | null = null;\n private f64ModInstance: Function | null = null;\n private f32PowInstance: Function | null = null;\n private f64PowInstance: Function | null = null;\n private i32PowInstance: Function | null = null;\n private i64PowInstance: Function | null = null;\n\n private compileBinaryExpression(\n expression: BinaryExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let left = expression.left;\n let right = expression.right;\n\n let leftExpr: ExpressionRef;\n let leftType: Type;\n let rightExpr: ExpressionRef;\n let rightType: Type;\n let commonType: Type | null;\n\n let expr: ExpressionRef;\n let compound = false;\n\n let operator = expression.operator;\n switch (operator) {\n case Token.LessThan: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Lt);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType, true);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"<\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n expr = this.makeLt(leftExpr, rightExpr, commonType);\n this.currentType = Type.bool;\n break;\n }\n case Token.GreaterThan: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Gt);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType, true);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \">\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n expr = this.makeGt(leftExpr, rightExpr, commonType);\n this.currentType = Type.bool;\n break;\n }\n case Token.LessThan_Equals: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Le);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType, true);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"<=\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n expr = this.makeLe(leftExpr, rightExpr, commonType);\n this.currentType = Type.bool;\n break;\n }\n case Token.GreaterThan_Equals: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Ge);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType, true);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \">=\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n expr = this.makeGe(leftExpr, rightExpr, commonType);\n this.currentType = Type.bool;\n break;\n }\n\n case Token.Equals_Equals_Equals:\n case Token.Equals_Equals: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Eq);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, operatorTokenToString(expression.operator), leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n if (commonType.isFloatValue) {\n if (\n isConstExpressionNaN(module, rightExpr) ||\n isConstExpressionNaN(module, leftExpr)\n ) {\n this.warning(\n DiagnosticCode._NaN_does_not_compare_equal_to_any_other_value_including_itself_Use_isNaN_x_instead,\n expression.range\n );\n }\n if (isConstNegZero(rightExpr) || isConstNegZero(leftExpr)) {\n this.warning(\n DiagnosticCode.Comparison_with_0_0_is_sign_insensitive_Use_Object_is_x_0_0_if_the_sign_matters,\n expression.range\n );\n }\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n expr = this.makeEq(leftExpr, rightExpr, commonType, expression);\n this.currentType = Type.bool;\n break;\n }\n case Token.Exclamation_Equals_Equals:\n case Token.Exclamation_Equals: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClass();\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Ne);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, operatorTokenToString(expression.operator), leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n if (commonType.isFloatValue) {\n if (\n isConstExpressionNaN(module, rightExpr) ||\n isConstExpressionNaN(module, leftExpr)\n ) {\n this.warning(\n DiagnosticCode._NaN_does_not_compare_equal_to_any_other_value_including_itself_Use_isNaN_x_instead,\n expression.range\n );\n }\n if (isConstNegZero(rightExpr) || isConstNegZero(leftExpr)) {\n this.warning(\n DiagnosticCode.Comparison_with_0_0_is_sign_insensitive_Use_Object_is_x_0_0_if_the_sign_matters,\n expression.range\n );\n }\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n expr = this.makeNe(leftExpr, rightExpr, commonType, expression);\n this.currentType = Type.bool;\n break;\n }\n case Token.Equals: {\n return this.compileAssignment(left, right, contextualType);\n }\n case Token.Plus_Equals: compound = true;\n case Token.Plus: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Add);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n if (compound) {\n if (!leftType.isNumericValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"+\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"+\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeAdd(leftExpr, rightExpr, commonType);\n break;\n }\n case Token.Minus_Equals: compound = true;\n case Token.Minus: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Sub);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isNumericValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"-\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !leftType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"-\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeSub(leftExpr, rightExpr, commonType);\n break;\n }\n case Token.Asterisk_Equals: compound = true;\n case Token.Asterisk: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Mul);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isNumericValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"*\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"*\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeMul(leftExpr, rightExpr, commonType);\n break;\n }\n case Token.Asterisk_Asterisk_Equals: compound = true;\n case Token.Asterisk_Asterisk: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Pow);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isNumericValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"**\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"**\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makePow(leftExpr, rightExpr, commonType, expression);\n break;\n }\n case Token.Slash_Equals: compound = true;\n case Token.Slash: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Div);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isNumericValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"/\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"/\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeDiv(leftExpr, rightExpr, commonType);\n break;\n }\n case Token.Percent_Equals: compound = true;\n case Token.Percent: {\n leftExpr = this.compileExpression(left, contextualType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Rem);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isNumericValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"%\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isNumericValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"%\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeRem(leftExpr, rightExpr, commonType, expression);\n break;\n }\n case Token.LessThan_LessThan_Equals: compound = true;\n case Token.LessThan_LessThan: {\n leftExpr = this.compileExpression(left, contextualType.intType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseShl);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n if (!leftType.isIntegerValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"<<\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = this.currentType;\n\n expr = this.makeShl(leftExpr, rightExpr, rightType);\n break;\n }\n case Token.GreaterThan_GreaterThan_Equals: compound = true;\n case Token.GreaterThan_GreaterThan: {\n leftExpr = this.compileExpression(left, contextualType.intType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseShr);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n if (!leftType.isIntegerValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \">>\", leftType.toString()\n );\n return this.module.unreachable();\n }\n\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = this.currentType;\n\n expr = this.makeShr(leftExpr, rightExpr, rightType);\n break;\n }\n case Token.GreaterThan_GreaterThan_GreaterThan_Equals: compound = true;\n case Token.GreaterThan_GreaterThan_GreaterThan: {\n leftExpr = this.compileExpression(left, contextualType.intType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseShrU);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n if (!leftType.isIntegerValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \">>>\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = this.currentType;\n\n expr = this.makeShru(leftExpr, rightExpr, rightType);\n break;\n }\n case Token.Ampersand_Equals: compound = true;\n case Token.Ampersand: {\n leftExpr = this.compileExpression(left, contextualType.intType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseAnd);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isIntegerValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"&\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isIntegerValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"&\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeAnd(leftExpr, rightExpr, commonType);\n break;\n }\n case Token.Bar_Equals: compound = true;\n case Token.Bar: {\n leftExpr = this.compileExpression(left, contextualType.intType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseOr);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isIntegerValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"|\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isIntegerValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"|\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeOr(leftExpr, rightExpr, commonType);\n break;\n }\n case Token.Caret_Equals: compound = true;\n case Token.Caret: {\n leftExpr = this.compileExpression(left, contextualType.intType);\n leftType = this.currentType;\n\n // check operator overload\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseXor);\n if (overload) {\n expr = this.compileBinaryOverload(overload, left, leftExpr, leftType, right, expression);\n break;\n }\n }\n\n if (compound) {\n if (!leftType.isIntegerValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"^\", leftType.toString()\n );\n return module.unreachable();\n }\n rightExpr = this.compileExpression(right, leftType, Constraints.ConvImplicit);\n rightType = commonType = this.currentType;\n } else {\n rightExpr = this.compileExpression(right, leftType);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType || !commonType.isIntegerValue) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"^\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n }\n expr = this.makeXor(leftExpr, rightExpr, commonType);\n break;\n }\n\n // logical (no overloading)\n\n case Token.Ampersand_Ampersand: { // left && right -> (t = left) ? right : t\n let flow = this.currentFlow;\n let inheritedConstraints = constraints & Constraints.MustWrap;\n leftExpr = this.compileExpression(left, contextualType.exceptVoid, inheritedConstraints);\n leftType = this.currentType;\n\n let rightFlow = flow.forkThen(leftExpr);\n this.currentFlow = rightFlow;\n\n // simplify if only interested in true or false\n if (contextualType == Type.bool || contextualType == Type.void) {\n leftExpr = this.makeIsTrueish(leftExpr, leftType, left);\n\n // shortcut if lhs is always false\n let condKind = this.evaluateCondition(leftExpr);\n if (condKind == ConditionKind.False) {\n expr = leftExpr;\n // RHS is not compiled\n } else {\n rightExpr = this.compileExpression(right, leftType, inheritedConstraints);\n rightType = this.currentType;\n rightExpr = this.makeIsTrueish(rightExpr, rightType, right);\n\n // simplify if lhs is always true\n if (condKind == ConditionKind.True) {\n expr = rightExpr;\n flow.inherit(rightFlow); // true && RHS -> RHS always executes\n } else {\n expr = module.if(leftExpr, rightExpr, module.i32(0));\n flow.mergeBranch(rightFlow); // LHS && RHS -> RHS conditionally executes\n flow.noteThen(expr, rightFlow); // LHS && RHS == true -> RHS always executes\n }\n }\n this.currentFlow = flow;\n this.currentType = Type.bool;\n\n } else {\n rightExpr = this.compileExpression(right, leftType, inheritedConstraints);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"&&\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n // simplify if copying left is trivial\n if (expr = module.tryCopyTrivialExpression(leftExpr)) {\n expr = module.if(\n this.makeIsTrueish(leftExpr, this.currentType, left),\n rightExpr,\n expr\n );\n\n // if not possible, tee left to a temp\n } else {\n let tempLocal = flow.getTempLocal(leftType);\n if (!flow.canOverflow(leftExpr, leftType)) flow.setLocalFlag(tempLocal.index, LocalFlags.Wrapped);\n if (flow.isNonnull(leftExpr, leftType)) flow.setLocalFlag(tempLocal.index, LocalFlags.NonNull);\n expr = module.if(\n this.makeIsTrueish(module.local_tee(tempLocal.index, leftExpr, leftType.isManaged), leftType, left),\n rightExpr,\n module.local_get(tempLocal.index, leftType.toRef())\n );\n }\n flow.mergeBranch(rightFlow); // LHS && RHS -> RHS conditionally executes\n flow.noteThen(expr, rightFlow); // LHS && RHS == true -> RHS always executes\n this.currentFlow = flow;\n this.currentType = commonType;\n }\n break;\n }\n case Token.Bar_Bar: { // left || right -> ((t = left) ? t : right)\n let flow = this.currentFlow;\n let inheritedConstraints = constraints & Constraints.MustWrap;\n leftExpr = this.compileExpression(left, contextualType.exceptVoid, inheritedConstraints);\n leftType = this.currentType;\n\n let rightFlow = flow.forkElse(leftExpr);\n this.currentFlow = rightFlow;\n\n // simplify if only interested in true or false\n if (contextualType == Type.bool || contextualType == Type.void) {\n leftExpr = this.makeIsTrueish(leftExpr, leftType, left);\n\n // shortcut if lhs is always true\n let condKind = this.evaluateCondition(leftExpr);\n if (condKind == ConditionKind.True) {\n expr = leftExpr;\n // RHS is not compiled\n } else {\n rightExpr = this.compileExpression(right, leftType, inheritedConstraints);\n rightType = this.currentType;\n rightExpr = this.makeIsTrueish(rightExpr, rightType, right);\n\n // simplify if lhs is always false\n if (condKind == ConditionKind.False) {\n expr = rightExpr;\n flow.inherit(rightFlow); // false || RHS -> RHS always executes\n } else {\n expr = module.if(leftExpr, module.i32(1), rightExpr);\n flow.mergeBranch(rightFlow); // LHS || RHS -> RHS conditionally executes\n flow.noteElse(expr, rightFlow); // LHS || RHS == false -> RHS always executes\n }\n }\n this.currentFlow = flow;\n this.currentType = Type.bool;\n\n } else {\n rightExpr = this.compileExpression(right, leftType, inheritedConstraints);\n rightType = this.currentType;\n commonType = Type.commonType(leftType, rightType, contextualType);\n if (!commonType) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"||\", leftType.toString(), rightType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n let possiblyNull = leftType.is(TypeFlags.Nullable) && rightType.is(TypeFlags.Nullable);\n leftExpr = this.convertExpression(leftExpr, leftType, commonType, false, left);\n leftType = commonType;\n rightExpr = this.convertExpression(rightExpr, rightType, commonType, false, right);\n rightType = commonType;\n\n // simplify if copying left is trivial\n if (expr = module.tryCopyTrivialExpression(leftExpr)) {\n expr = module.if(\n this.makeIsTrueish(leftExpr, leftType, left),\n expr,\n rightExpr\n );\n\n // if not possible, tee left to a temp. local\n } else {\n let temp = flow.getTempLocal(leftType);\n let tempIndex = temp.index;\n if (!flow.canOverflow(leftExpr, leftType)) flow.setLocalFlag(tempIndex, LocalFlags.Wrapped);\n if (flow.isNonnull(leftExpr, leftType)) flow.setLocalFlag(tempIndex, LocalFlags.NonNull);\n expr = module.if(\n this.makeIsTrueish(module.local_tee(tempIndex, leftExpr, leftType.isManaged), leftType, left),\n module.local_get(tempIndex, leftType.toRef()),\n rightExpr\n );\n }\n flow.mergeBranch(rightFlow); // LHS || RHS -> RHS conditionally executes\n flow.noteElse(expr, rightFlow); // LHS || RHS == false -> RHS always executes\n this.currentFlow = flow;\n this.currentType = possiblyNull\n ? commonType\n : commonType.nonNullableType;\n }\n break;\n }\n case Token.In: {\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range, \"'in' operator\"\n );\n this.currentType = Type.bool;\n return module.unreachable();\n }\n default: {\n assert(false);\n expr = this.module.unreachable();\n }\n }\n if (!compound) return expr;\n let resolver = this.resolver;\n let target = resolver.lookupExpression(left, this.currentFlow);\n if (!target) return module.unreachable();\n let targetType = resolver.getTypeOfElement(target);\n if (!targetType) targetType = Type.void;\n if (!this.currentType.isStrictlyAssignableTo(targetType)) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n expression.range, this.currentType.toString(), targetType.toString()\n );\n return module.unreachable();\n }\n return this.makeAssignment(\n target,\n expr,\n this.currentType,\n right,\n resolver.currentThisExpression,\n resolver.currentElementExpression,\n contextualType != Type.void\n );\n }\n\n makeLt(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32: return module.binary(BinaryOp.LtI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.LtI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.LtISize, leftExpr, rightExpr);\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.U32: return module.binary(BinaryOp.LtU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.LtU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.LtUSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.LtF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.LtF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeGt(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32: return module.binary(BinaryOp.GtI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.GtI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.GtISize, leftExpr, rightExpr);\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.U32: return module.binary(BinaryOp.GtU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.GtU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.GtUSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.GtF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.GtF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeLe(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32: return module.binary(BinaryOp.LeI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.LeI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.LeISize, leftExpr, rightExpr);\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.U32: return module.binary(BinaryOp.LeU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.LeU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.LeUSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.LeF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.LeF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeGe(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32: return module.binary(BinaryOp.GeI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.GeI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.GeISize, leftExpr, rightExpr);\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.U32: return module.binary(BinaryOp.GeU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.GeU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.GeUSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.GeF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.GeF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeEq(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {\n // Cares about garbage bits\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.EqI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.EqI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.EqSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.EqF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.EqF64, leftExpr, rightExpr);\n case TypeKind.V128: {\n return module.unary(UnaryOp.AllTrueI8x16,\n module.binary(BinaryOp.EqI8x16, leftExpr, rightExpr)\n );\n }\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.I31ref: return module.ref_eq(leftExpr, rightExpr);\n case TypeKind.Stringref: return module.string_eq(leftExpr, rightExpr);\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter:\n case TypeKind.Funcref:\n case TypeKind.Externref:\n case TypeKind.Anyref: {\n this.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n reportNode.range,\n \"ref.eq\",\n type.toString()\n );\n return module.unreachable();\n }\n }\n assert(false);\n return module.unreachable();\n }\n\n makeNe(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {\n // Cares about garbage bits\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.NeI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.NeI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.NeSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.NeF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.NeF64, leftExpr, rightExpr);\n case TypeKind.V128: {\n return module.unary(UnaryOp.AnyTrueV128,\n module.binary(BinaryOp.NeI8x16, leftExpr, rightExpr)\n );\n }\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.I31ref: {\n return module.unary(UnaryOp.EqzI32,\n module.ref_eq(leftExpr, rightExpr)\n );\n }\n case TypeKind.Stringref: {\n return module.unary(UnaryOp.EqzI32,\n module.string_eq(leftExpr, rightExpr)\n );\n }\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter:\n case TypeKind.Funcref:\n case TypeKind.Externref:\n case TypeKind.Anyref: {\n this.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n reportNode.range,\n \"ref.eq\",\n type.toString()\n );\n return module.unreachable();\n }\n }\n assert(false);\n return module.unreachable();\n }\n\n makeAdd(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Does not care about garbage bits or signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.AddI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.AddI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.AddSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.AddF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.AddF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeSub(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Does not care about garbage bits or signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.SubI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.SubI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.SubSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.SubF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.SubF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeMul(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Does not care about garbage bits or signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.MulI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.MulI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.MulSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.MulF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.MulF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makePow(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {\n // Cares about garbage bits\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool: {\n return module.select(\n module.i32(1),\n module.binary(BinaryOp.EqI32, rightExpr, module.i32(0)),\n leftExpr,\n TypeRef.I32\n );\n }\n case TypeKind.I8:\n case TypeKind.U8:\n case TypeKind.I16:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32:\n case TypeKind.U32: {\n if (this.options.willOptimize) {\n // Precompute power if LHS and RHS constants\n // TODO: move this optimization to AIR\n if (\n getExpressionId(leftExpr) == ExpressionId.Const &&\n getExpressionId(rightExpr) == ExpressionId.Const\n ) {\n let leftValue = getConstValueI32(leftExpr);\n let rightValue = getConstValueI32(rightExpr);\n this.currentType = type;\n return module.i32(i64_low(i64_pow(\n i64_new(leftValue),\n i64_new(rightValue)\n )));\n }\n }\n let instance = this.i32PowInstance;\n if (!instance) {\n let prototype = this.program.lookup(CommonNames.ipow32);\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"ipow32\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n this.i32PowInstance = instance = this.resolver.resolveFunction(prototype, null);\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n let expr = this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n if (type.size < 32) {\n // TODO: this is necessary because i32PowInstance is generic, and deals with 32-bit integers,\n // so its flow does not indicate whether returned SMIs are wrapped. worth to avoid?\n expr = this.ensureSmallIntegerWrap(expr, type);\n }\n return expr;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n if (this.options.willOptimize) {\n // Precompute power if LHS and RHS constants\n // TODO: move this optimization to AIR\n if (\n getExpressionId(leftExpr) == ExpressionId.Const &&\n getExpressionId(rightExpr) == ExpressionId.Const\n ) {\n let leftValue = i64_new(getConstValueI64Low(leftExpr), getConstValueI64High(leftExpr));\n let rightValue = i64_new(getConstValueI64Low(rightExpr), getConstValueI64High(rightExpr));\n let result = i64_pow(leftValue, rightValue);\n this.currentType = type;\n return module.i64(i64_low(result), i64_high(result));\n }\n }\n let instance = this.i64PowInstance;\n if (!instance) {\n let prototype = this.program.lookup(CommonNames.ipow64);\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"ipow64\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n this.i64PowInstance = instance = this.resolver.resolveFunction(prototype, null);\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n let isWasm64 = this.options.isWasm64;\n if (this.options.willOptimize) {\n // Precompute power if LHS and RHS constants\n // TODO: move this optimization to AIR\n if (\n getExpressionId(leftExpr) == ExpressionId.Const &&\n getExpressionId(rightExpr) == ExpressionId.Const\n ) {\n if (isWasm64) {\n let leftValue = i64_new(getConstValueI64Low(leftExpr), getConstValueI64High(leftExpr));\n let rightValue = i64_new(getConstValueI64Low(rightExpr), getConstValueI64High(rightExpr));\n let result = i64_pow(leftValue, rightValue);\n this.currentType = type;\n return module.i64(i64_low(result), i64_high(result));\n } else {\n let leftValue = getConstValueI32(leftExpr);\n let rightValue = getConstValueI32(rightExpr);\n this.currentType = type;\n return module.i32(i64_low(i64_pow(\n i64_new(leftValue),\n i64_new(rightValue)\n )));\n }\n }\n }\n let instance = isWasm64\n ? this.i64PowInstance\n : this.i32PowInstance;\n if (!instance) {\n let prototype = this.program.lookup(isWasm64\n ? CommonNames.ipow64\n : CommonNames.ipow32\n );\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, isWasm64 ? \"ipow64\" : \"ipow32\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n instance = this.resolver.resolveFunction(prototype, null);\n if (isWasm64) {\n this.i64PowInstance = instance;\n } else {\n this.i32PowInstance = instance;\n }\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n }\n case TypeKind.F32: {\n if (this.options.willOptimize) {\n // Precompute power if LHS and RHS constants\n // TODO: move this optimization to AIR\n if (\n getExpressionId(leftExpr) == ExpressionId.Const &&\n getExpressionId(rightExpr) == ExpressionId.Const\n ) {\n let leftValue = getConstValueF32(leftExpr);\n let rightValue = getConstValueF32(rightExpr);\n this.currentType = type;\n return module.f32(f32(accuratePow64(leftValue, rightValue)));\n }\n }\n let instance = this.f32PowInstance;\n if (!instance) {\n let namespace = this.program.lookup(CommonNames.Mathf);\n if (!namespace) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Mathf\"\n );\n return module.unreachable();\n }\n let prototype = namespace.getMember(CommonNames.pow);\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Mathf.pow\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n this.f32PowInstance = instance = this.resolver.resolveFunction(prototype, null);\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n }\n // Math.pow otherwise (result is f64)\n case TypeKind.F64: {\n if (this.options.willOptimize) {\n // Precompute power if LHS and RHS constants\n // TODO: move this optimization to AIR\n if (\n getExpressionId(leftExpr) == ExpressionId.Const &&\n getExpressionId(rightExpr) == ExpressionId.Const\n ) {\n let leftValue = getConstValueF64(leftExpr);\n let rightValue = getConstValueF64(rightExpr);\n this.currentType = type;\n return module.f64(accuratePow64(leftValue, rightValue));\n }\n }\n let instance = this.f64PowInstance;\n if (!instance) {\n let namespace = this.program.lookup(CommonNames.Math);\n if (!namespace) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Math\"\n );\n return module.unreachable();\n }\n let prototype = namespace.getMember(CommonNames.pow);\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Math.pow\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n this.f64PowInstance = instance = this.resolver.resolveFunction(prototype, null);\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n }\n }\n assert(false);\n return module.unreachable();\n }\n\n makeDiv(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32: return module.binary(BinaryOp.DivI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.DivI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.DivISize, leftExpr, rightExpr);\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.U32: return module.binary(BinaryOp.DivU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.DivU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.DivUSize, leftExpr, rightExpr);\n case TypeKind.F32: return module.binary(BinaryOp.DivF32, leftExpr, rightExpr);\n case TypeKind.F64: return module.binary(BinaryOp.DivF64, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeRem(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {\n // Cares about garbage bits and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.I32: return module.binary(BinaryOp.RemI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.RemI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.RemISize, leftExpr, rightExpr);\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16: {\n leftExpr = this.ensureSmallIntegerWrap(leftExpr, type);\n rightExpr = this.ensureSmallIntegerWrap(rightExpr, type);\n // falls through\n }\n case TypeKind.U32: return module.binary(BinaryOp.RemU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.RemU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.RemUSize, leftExpr, rightExpr);\n case TypeKind.F32: {\n let instance = this.f32ModInstance;\n if (!instance) {\n let namespace = this.program.lookup(CommonNames.Mathf);\n if (!namespace) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Mathf\"\n );\n return module.unreachable();\n }\n let prototype = namespace.getMember(CommonNames.mod);\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Mathf.mod\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n this.f32ModInstance = instance = this.resolver.resolveFunction(prototype, null);\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n }\n case TypeKind.F64: {\n let instance = this.f64ModInstance;\n if (!instance) {\n let namespace = this.program.lookup(CommonNames.Math);\n if (!namespace) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Math\"\n );\n return module.unreachable();\n }\n let prototype = namespace.getMember(CommonNames.mod);\n if (!prototype) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n reportNode.range, \"Math.mod\"\n );\n return module.unreachable();\n }\n assert(prototype.kind == ElementKind.FunctionPrototype);\n this.f64ModInstance = instance = this.resolver.resolveFunction(prototype, null);\n }\n if (!instance || !this.compileFunction(instance)) {\n return module.unreachable();\n }\n return this.makeCallDirect(instance, [ leftExpr, rightExpr ], reportNode);\n }\n }\n assert(false);\n return module.unreachable();\n }\n\n makeShl(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits on the RHS, but only for types smaller than 5 bits\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool: return leftExpr;\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n // leftExpr << (rightExpr & (7|15))\n return module.binary(\n BinaryOp.ShlI32,\n leftExpr,\n module.binary(\n BinaryOp.AndI32,\n rightExpr,\n module.i32(type.size - 1)\n )\n );\n }\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.ShlI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.ShlI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.ShlSize, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeShr(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits on the LHS, but on the RHS only for types smaller than 5 bits,\n // and signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool: return leftExpr;\n case TypeKind.I8:\n case TypeKind.I16: {\n // leftExpr >> (rightExpr & (7|15))\n return module.binary(\n BinaryOp.ShrI32,\n this.ensureSmallIntegerWrap(leftExpr, type),\n module.binary(\n BinaryOp.AndI32,\n rightExpr,\n module.i32(type.size - 1)\n )\n );\n }\n case TypeKind.U8:\n case TypeKind.U16: {\n // leftExpr >>> (rightExpr & (7|15))\n return module.binary(\n BinaryOp.ShrU32,\n this.ensureSmallIntegerWrap(leftExpr, type),\n module.binary(\n BinaryOp.AndI32,\n rightExpr,\n module.i32(type.size - 1)\n )\n );\n }\n case TypeKind.I32: return module.binary(BinaryOp.ShrI32, leftExpr, rightExpr);\n case TypeKind.I64: return module.binary(BinaryOp.ShrI64, leftExpr, rightExpr);\n case TypeKind.Isize: return module.binary(BinaryOp.ShrISize, leftExpr, rightExpr);\n case TypeKind.U32: return module.binary(BinaryOp.ShrU32, leftExpr, rightExpr);\n case TypeKind.U64: return module.binary(BinaryOp.ShrU64, leftExpr, rightExpr);\n case TypeKind.Usize: return module.binary(BinaryOp.ShrUSize, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeShru(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Cares about garbage bits on the LHS, but on the RHS only for types smaller than 5 bits\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool: return leftExpr;\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n // leftExpr >>> (rightExpr & (7|15))\n return module.binary(\n BinaryOp.ShrU32,\n this.ensureSmallIntegerWrap(leftExpr, type),\n module.binary(\n BinaryOp.AndI32,\n rightExpr,\n module.i32(type.size - 1)\n )\n );\n }\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.ShrU32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.ShrU64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.ShrUSize, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeAnd(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Does not care about garbage bits or signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: return module.binary(BinaryOp.AndI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.AndI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.AndSize, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeOr(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Does not care about garbage bits or signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: return module.binary(BinaryOp.OrI32, leftExpr, rightExpr);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.OrI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.OrI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.OrSize, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n makeXor(leftExpr: ExpressionRef, rightExpr: ExpressionRef, type: Type): ExpressionRef {\n // Does not care about garbage bits or signedness\n let module = this.module;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: return module.binary(BinaryOp.XorI32, leftExpr, rightExpr);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.XorI32, leftExpr, rightExpr);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.XorI64, leftExpr, rightExpr);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.XorSize, leftExpr, rightExpr);\n }\n assert(false);\n return module.unreachable();\n }\n\n private compileUnaryOverload(\n operatorInstance: Function,\n value: Expression,\n valueExpr: ExpressionRef,\n reportNode: Node\n ): ExpressionRef {\n // FIXME: see comment in compileBinaryOverload below why recompiling on type mismatch\n // is a bad idea currently. so this assumes that the type matches.\n return this.makeCallDirect(operatorInstance, [ valueExpr ], reportNode, false);\n }\n\n private compileBinaryOverload(\n operatorInstance: Function,\n left: Expression,\n leftExpr: ExpressionRef,\n leftType: Type,\n right: Expression,\n reportNode: Node\n ): ExpressionRef {\n let rightType: Type;\n let signature = operatorInstance.signature;\n let parameterTypes = signature.parameterTypes;\n if (operatorInstance.is(CommonFlags.Instance)) {\n leftExpr = this.convertExpression(leftExpr, leftType, assert(signature.thisType), false, left);\n rightType = parameterTypes[0];\n } else {\n leftExpr = this.convertExpression(leftExpr, leftType, parameterTypes[0], false, left);\n rightType = parameterTypes[1];\n }\n let rightExpr = this.compileExpression(right, rightType, Constraints.ConvImplicit);\n return this.makeCallDirect(operatorInstance, [ leftExpr, rightExpr ], reportNode);\n }\n\n private compileAssignment(\n expression: Expression,\n valueExpression: Expression,\n contextualType: Type\n ): ExpressionRef {\n let program = this.program;\n let resolver = program.resolver;\n let flow = this.currentFlow;\n let target = resolver.lookupExpression(expression, flow); // reports\n if (!target) return this.module.unreachable();\n let thisExpression = resolver.currentThisExpression;\n let elementExpression = resolver.currentElementExpression;\n\n // to compile just the value, we need to know the target's type\n let targetType: Type;\n switch (target.kind) {\n case ElementKind.Global: {\n if (!this.compileGlobalLazy(target, expression)) {\n return this.module.unreachable();\n }\n // fall-through\n }\n case ElementKind.Local: {\n if (this.pendingElements.has(target)) {\n this.error(\n DiagnosticCode.Variable_0_used_before_its_declaration,\n expression.range,\n target.internalName\n );\n return this.module.unreachable();\n }\n targetType = (target).type;\n if (target.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);\n break;\n }\n case ElementKind.PropertyPrototype: {\n let propertyPrototype = target;\n let propertyInstance = resolver.resolveProperty(propertyPrototype);\n if (!propertyInstance) return this.module.unreachable();\n target = propertyInstance;\n // fall-through\n }\n case ElementKind.Property: {\n let propertyInstance = target;\n if (propertyInstance.isField) {\n if (this.pendingElements.has(target)) {\n this.error(\n DiagnosticCode.Variable_0_used_before_its_declaration,\n expression.range,\n target.internalName\n );\n return this.module.unreachable();\n }\n }\n let setterInstance = propertyInstance.setterInstance;\n if (!setterInstance) {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n expression.range, propertyInstance.internalName\n );\n return this.module.unreachable();\n }\n assert(setterInstance.signature.parameterTypes.length == 1); // parser must guarantee this\n targetType = setterInstance.signature.parameterTypes[0];\n if (setterInstance.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);\n break;\n }\n case ElementKind.IndexSignature: {\n let parent = (target).parent;\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n let isUnchecked = flow.is(FlowFlags.UncheckedContext);\n let indexedSet = classInstance.lookupOverload(OperatorKind.IndexedSet, isUnchecked);\n if (!indexedSet) {\n let indexedGet = classInstance.lookupOverload(OperatorKind.IndexedGet, isUnchecked);\n if (!indexedGet) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n expression.range, classInstance.internalName\n );\n } else {\n this.error(\n DiagnosticCode.Index_signature_in_type_0_only_permits_reading,\n expression.range, classInstance.internalName\n );\n }\n return this.module.unreachable();\n }\n let parameterTypes = indexedSet.signature.parameterTypes;\n\n assert(parameterTypes.length == 2); // parser must guarantee this\n targetType = parameterTypes[1]; // 2nd parameter is the element\n\n if (indexedSet.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);\n if (!isUnchecked && this.options.pedantic) {\n this.pedantic(\n DiagnosticCode.Indexed_access_may_involve_bounds_checking,\n expression.range\n );\n }\n break;\n }\n default: {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n expression.range, target.internalName\n );\n return this.module.unreachable();\n }\n }\n\n // compile the value and do the assignment\n assert(targetType != Type.void);\n let valueExpr = this.compileExpression(valueExpression, targetType);\n let valueType = this.currentType;\n return this.makeAssignment(\n target,\n this.convertExpression(valueExpr, valueType, targetType, false, valueExpression),\n valueType,\n valueExpression,\n thisExpression,\n elementExpression,\n contextualType != Type.void\n );\n }\n\n /** Makes an assignment expression or block, assigning a value to a target. */\n makeAssignment(\n /** Target element, e.g. a Local. */\n target: Element,\n /** Value expression that has been compiled in a previous step already. */\n valueExpr: ExpressionRef,\n /** Value expression type. */\n valueType: Type,\n /** Expression reference. Has already been compiled to `valueExpr`. */\n valueExpression: Expression,\n /** `this` expression reference if a field or property set. */\n thisExpression: Expression | null,\n /** Index expression reference if an indexed set. */\n indexExpression: Expression | null,\n /** Whether to tee the value. */\n tee: bool\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n\n switch (target.kind) {\n case ElementKind.Local: {\n let local = target;\n if (flow.isLocalFlag(local.index, LocalFlags.Constant, true)) {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n valueExpression.range, target.internalName\n );\n this.currentType = tee ? local.type : Type.void;\n return module.unreachable();\n }\n return this.makeLocalAssignment(local, valueExpr, valueType, tee);\n }\n case ElementKind.Global: {\n let global = target;\n if (!this.compileGlobalLazy(global, valueExpression)) {\n return module.unreachable();\n }\n if (target.isAny(CommonFlags.Const | CommonFlags.Readonly)) {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n valueExpression.range,\n target.internalName\n );\n this.currentType = tee ? global.type : Type.void;\n return module.unreachable();\n }\n return this.makeGlobalAssignment(global, valueExpr, valueType, tee);\n }\n case ElementKind.PropertyPrototype: {\n let propertyInstance = this.resolver.resolveProperty(target);\n if (!propertyInstance) return module.unreachable();\n target = propertyInstance;\n // fall-through\n }\n case ElementKind.Property: {\n let propertyInstance = target;\n if (propertyInstance.isField) {\n // Cannot assign to readonly fields except in constructors if there's no initializer\n let isConstructor = flow.sourceFunction.is(CommonFlags.Constructor);\n if (propertyInstance.is(CommonFlags.Readonly)) {\n let initializerNode = propertyInstance.initializerNode;\n if (!isConstructor || initializerNode) {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n valueExpression.range, propertyInstance.internalName\n );\n return module.unreachable();\n }\n }\n // Mark initialized fields in constructors\n thisExpression = assert(thisExpression);\n if (isConstructor && thisExpression.kind == NodeKind.This) {\n flow.setThisFieldFlag(propertyInstance, FieldFlags.Initialized);\n }\n }\n let setterInstance = propertyInstance.setterInstance;\n if (!setterInstance) {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n valueExpression.range, target.internalName\n );\n return module.unreachable();\n }\n assert(setterInstance.signature.parameterTypes.length == 1);\n if (propertyInstance.is(CommonFlags.Instance)) {\n let thisType = assert(setterInstance.signature.thisType);\n let thisExpr = this.compileExpression(\n assert(thisExpression),\n thisType,\n Constraints.ConvImplicit | Constraints.IsThis\n );\n if (!tee) return this.makeCallDirect(setterInstance, [ thisExpr, valueExpr ], valueExpression);\n let getterInstance = assert((target).getterInstance);\n assert(getterInstance.signature.thisType == thisType);\n let returnType = getterInstance.signature.returnType;\n let returnTypeRef = returnType.toRef();\n let tempThis = flow.getTempLocal(returnType);\n let ret = module.block(null, [\n this.makeCallDirect(setterInstance, [\n module.local_tee(tempThis.index, thisExpr, returnType.isManaged),\n valueExpr\n ], valueExpression),\n this.makeCallDirect(getterInstance, [\n module.local_get(tempThis.index, returnTypeRef)\n ], valueExpression)\n ], returnTypeRef);\n return ret;\n } else {\n if (!tee) return this.makeCallDirect(setterInstance, [ valueExpr ], valueExpression);\n let getterInstance = assert((target).getterInstance);\n return module.block(null, [\n this.makeCallDirect(setterInstance, [ valueExpr ], valueExpression),\n this.makeCallDirect(getterInstance, null, valueExpression)\n ], getterInstance.signature.returnType.toRef());\n }\n }\n case ElementKind.IndexSignature: {\n let indexSignature = target;\n let parent = indexSignature.parent;\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n assert(classInstance.kind == ElementKind.Class);\n let isUnchecked = flow.is(FlowFlags.UncheckedContext);\n let getterInstance = classInstance.lookupOverload(OperatorKind.IndexedGet, isUnchecked);\n if (!getterInstance) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n valueExpression.range, classInstance.internalName\n );\n return module.unreachable();\n }\n let setterInstance = classInstance.lookupOverload(OperatorKind.IndexedSet, isUnchecked);\n if (!setterInstance) {\n this.error(\n DiagnosticCode.Index_signature_in_type_0_only_permits_reading,\n valueExpression.range, classInstance.internalName\n );\n this.currentType = tee ? getterInstance.signature.returnType : Type.void;\n return module.unreachable();\n }\n assert(setterInstance.signature.parameterTypes.length == 2);\n let thisType = classInstance.type;\n let thisExpr = this.compileExpression(\n assert(thisExpression),\n thisType,\n Constraints.ConvImplicit | Constraints.IsThis\n );\n let setterIndexType = setterInstance.signature.parameterTypes[0];\n let getterIndexType = getterInstance.signature.parameterTypes[0];\n if (!setterIndexType.equals(getterIndexType)) {\n this.errorRelated(\n DiagnosticCode.Index_signature_accessors_in_type_0_differ_in_types,\n getterInstance.identifierAndSignatureRange,\n setterInstance.identifierAndSignatureRange,\n classInstance.internalName,\n );\n this.currentType = tee ? getterInstance.signature.returnType : Type.void;\n return module.unreachable();\n }\n let elementExpr = this.compileExpression(assert(indexExpression), setterIndexType, Constraints.ConvImplicit);\n let elementType = this.currentType;\n if (tee) {\n let tempTarget = flow.getTempLocal(thisType);\n let tempElement = flow.getTempLocal(elementType);\n let returnType = getterInstance.signature.returnType;\n let ret = module.block(null, [\n this.makeCallDirect(setterInstance, [\n module.local_tee(tempTarget.index, thisExpr, thisType.isManaged),\n module.local_tee(tempElement.index, elementExpr, elementType.isManaged),\n valueExpr\n ], valueExpression),\n this.makeCallDirect(getterInstance, [\n module.local_get(tempTarget.index, tempTarget.type.toRef()),\n module.local_get(tempElement.index, tempElement.type.toRef())\n ], valueExpression)\n ], returnType.toRef());\n return ret;\n } else {\n return this.makeCallDirect(setterInstance, [\n thisExpr,\n elementExpr,\n valueExpr\n ], valueExpression);\n }\n }\n default: {\n this.error(\n DiagnosticCode.The_target_of_an_assignment_must_be_a_variable_or_a_property_access,\n valueExpression.range\n );\n }\n }\n return module.unreachable();\n }\n\n /** Makes an assignment to a local, keeping track of wrap and null states. */\n private makeLocalAssignment(\n /** Local to assign to. */\n local: Local,\n /** Value to assign. */\n valueExpr: ExpressionRef,\n /** Value type. */\n valueType: Type,\n /** Whether to tee the value. */\n tee: bool\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n let type = local.type;\n assert(type != Type.void);\n let localIndex = local.index;\n\n if (type.isNullableReference) {\n if (!valueType.isNullableReference || flow.isNonnull(valueExpr, type)) flow.setLocalFlag(localIndex, LocalFlags.NonNull);\n else flow.unsetLocalFlag(localIndex, LocalFlags.NonNull);\n }\n flow.setLocalFlag(localIndex, LocalFlags.Initialized);\n if (type.isShortIntegerValue) {\n if (!flow.canOverflow(valueExpr, type)) flow.setLocalFlag(localIndex, LocalFlags.Wrapped);\n else flow.unsetLocalFlag(localIndex, LocalFlags.Wrapped);\n }\n if (tee) { // local = value\n this.currentType = type;\n return module.local_tee(localIndex, valueExpr, type.isManaged);\n } else { // void(local = value)\n this.currentType = Type.void;\n return module.local_set(localIndex, valueExpr, type.isManaged);\n }\n }\n\n /** Makes an assignment to a global. */\n private makeGlobalAssignment(\n /** The global variable to assign to. */\n global: VariableLikeElement,\n /** The value to assign. */\n valueExpr: ExpressionRef,\n /** The type of the value to assign. */\n valueType: Type,\n /** Whether to tee the value. */\n tee: bool\n ): ExpressionRef {\n let module = this.module;\n let type = global.type;\n assert(type != Type.void);\n let typeRef = type.toRef();\n\n valueExpr = this.ensureSmallIntegerWrap(valueExpr, type); // globals must be wrapped\n if (tee) { // (global = value), global\n this.currentType = type;\n return module.block(null, [\n module.global_set(global.internalName, valueExpr),\n module.global_get(global.internalName, typeRef) // known to be assigned now\n ], typeRef);\n } else { // global = value\n this.currentType = Type.void;\n return module.global_set(global.internalName,\n valueExpr\n );\n }\n }\n\n /** Compiles a call expression according to the specified context. */\n private compileCallExpression(\n /** Call expression to compile. */\n expression: CallExpression,\n /** Contextual type indicating the return type the caller expects, if any. */\n contextualType: Type,\n /** Constraints indicating contextual conditions. */\n constraints: Constraints\n ): ExpressionRef {\n\n let module = this.module;\n let flow = this.currentFlow;\n\n // handle call to super\n if (expression.expression.kind == NodeKind.Super) {\n let flow = this.currentFlow;\n let sourceFunction = flow.sourceFunction;\n if (!sourceFunction.is(CommonFlags.Constructor)) {\n this.error(\n DiagnosticCode.Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors,\n expression.range\n );\n return module.unreachable();\n }\n\n let parent = assert(sourceFunction.parent);\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n let baseClassInstance = classInstance.base;\n if (!baseClassInstance || classInstance.prototype.implicitlyExtendsObject) {\n this.error(\n DiagnosticCode._super_can_only_be_referenced_in_a_derived_class,\n expression.expression.range\n );\n return module.unreachable();\n }\n let thisLocal = assert(flow.lookupLocal(CommonNames.this_));\n let sizeTypeRef = this.options.sizeTypeRef;\n\n let baseCtorInstance = this.ensureConstructor(baseClassInstance, expression);\n this.checkFieldInitialization(baseClassInstance, expression);\n let superCall = this.compileCallDirect(\n baseCtorInstance,\n expression.args,\n expression,\n module.local_get(thisLocal.index, sizeTypeRef)\n );\n\n // check that super had been called before accessing `this`\n if (flow.isAny(\n FlowFlags.AccessesThis |\n FlowFlags.ConditionallyAccessesThis\n )) {\n this.error(\n DiagnosticCode._super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class,\n expression.range\n );\n return module.unreachable();\n }\n flow.set(FlowFlags.AccessesThis | FlowFlags.CallsSuper);\n this.currentType = Type.void;\n return module.local_set(thisLocal.index, superCall, classInstance.type.isManaged);\n }\n\n // otherwise resolve normally\n let target = this.resolver.lookupExpression(expression.expression, flow); // reports\n if (!target) return module.unreachable();\n let thisExpression = this.resolver.currentThisExpression;\n\n // handle direct call\n switch (target.kind) {\n case ElementKind.FunctionPrototype: {\n let functionPrototype = target;\n if (functionPrototype.hasDecorator(DecoratorFlags.Builtin)) {\n // builtins handle present respectively omitted type arguments on their own\n return this.compileCallExpressionBuiltin(functionPrototype, expression, contextualType);\n }\n let functionInstance = this.resolver.maybeInferCall(expression, functionPrototype, flow);\n if (!functionInstance) return this.module.unreachable();\n target = functionInstance;\n // fall-through\n }\n case ElementKind.Function: {\n let functionInstance = target;\n let thisArg: ExpressionRef = 0;\n if (functionInstance.is(CommonFlags.Instance)) {\n thisArg = this.compileExpression(\n assert(thisExpression),\n assert(functionInstance.signature.thisType),\n Constraints.ConvImplicit | Constraints.IsThis\n );\n }\n return this.compileCallDirect(\n functionInstance,\n expression.args,\n expression,\n thisArg,\n constraints\n );\n }\n }\n\n // handle indirect call\n let functionArg = this.compileExpression(expression.expression, Type.auto);\n let signature = this.currentType.getSignature();\n if (signature) {\n return this.compileCallIndirect(\n signature,\n functionArg,\n expression.args,\n expression,\n 0,\n contextualType == Type.void\n );\n }\n this.error(\n DiagnosticCode.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures,\n expression.range, this.currentType.toString()\n );\n if (target.kind == ElementKind.PropertyPrototype) {\n let getterPrototype = (target).getterPrototype;\n if (getterPrototype) {\n this.infoRelated(\n DiagnosticCode.This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without,\n expression.range, getterPrototype.identifierNode.range\n );\n }\n }\n return module.unreachable();\n }\n\n /** Compiles the given arguments like a call expression according to the specified context. */\n private compileCallExpressionLike(\n /** Called expression. */\n expression: Expression,\n /** Call type arguments. */\n typeArguments: TypeNode[] | null,\n /** Call arguments. */\n args: Expression[],\n /** Diagnostic range. */\n range: Range,\n /** Contextual type indicating the return type the caller expects, if any. */\n contextualType: Type,\n /** Constraints indicating contextual conditions. */\n constraints: Constraints = Constraints.None\n ): ExpressionRef {\n // Desugaring like this can happen many times. Let's cache the intermediate allocation.\n let call = this._reusableCallExpression;\n if (call) {\n call.expression = expression;\n call.typeArguments = typeArguments;\n call.args = args;\n call.range = range;\n } else {\n this._reusableCallExpression = call = Node.createCallExpression(expression, typeArguments, args, range);\n }\n return this.compileCallExpression(call, contextualType, constraints);\n }\n private _reusableCallExpression: CallExpression | null = null;\n\n private compileCallExpressionBuiltin(\n prototype: FunctionPrototype,\n expression: CallExpression,\n contextualType: Type\n ): ExpressionRef {\n if (prototype.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);\n\n let typeArguments: Type[] | null = null;\n\n // builtins handle omitted type arguments on their own. if present, however, resolve them here\n // and pass them to the builtin, even if it's still up to the builtin how to handle them.\n let typeParameterNodes = prototype.typeParameterNodes;\n let typeArgumentNodes = expression.typeArguments;\n if (expression.typeArguments) {\n if (!prototype.is(CommonFlags.Generic)) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n expression.range, prototype.internalName\n );\n }\n typeArguments = this.resolver.resolveTypeArguments(\n assert(typeParameterNodes),\n typeArgumentNodes,\n this.currentFlow.sourceFunction.parent,\n cloneMap(this.currentFlow.contextualTypeArguments), // don't update\n expression\n );\n }\n let callee = expression.expression;\n let ctx = new BuiltinFunctionContext(\n this,\n prototype,\n typeArguments,\n expression.args,\n callee.kind == NodeKind.PropertyAccess\n ? (callee).expression\n : null,\n contextualType,\n expression,\n false\n );\n let internalName: string;\n if (prototype.is(CommonFlags.Instance)) {\n // omit generic name components, e.g. in `Function<...>#call`\n let parent = assert(prototype.getBoundClassOrInterface());\n internalName = `${parent.prototype.internalName}#${prototype.name}`;\n } else {\n internalName = prototype.internalName;\n }\n assert(builtinFunctions.has(internalName)); // checked earlier\n let fn = assert(builtinFunctions.get(internalName));\n return fn(ctx);\n }\n\n /**\n * Checks that a call with the given number as arguments can be performed according to the\n * specified signature.\n */\n checkCallSignature(\n signature: Signature,\n numArguments: i32,\n hasThis: bool,\n reportNode: Node\n ): bool {\n\n // cannot call an instance method without a `this` argument (TODO: `.call`?)\n let thisType = signature.thisType;\n if (hasThis != (thisType != null)) {\n this.error(\n DiagnosticCode.The_this_types_of_each_signature_are_incompatible,\n reportNode.range\n );\n return false;\n }\n\n // not yet implemented (TODO: maybe some sort of an unmanaged/lightweight array?)\n let hasRest = signature.hasRest;\n if (hasRest) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n reportNode.range, \"Rest parameters\"\n );\n return false;\n }\n\n let minimum = signature.requiredParameters;\n let maximum = signature.parameterTypes.length;\n\n // must at least be called with required arguments\n if (numArguments < minimum) {\n this.error(\n minimum < maximum\n ? DiagnosticCode.Expected_at_least_0_arguments_but_got_1\n : DiagnosticCode.Expected_0_arguments_but_got_1,\n reportNode.range, minimum.toString(), numArguments.toString()\n );\n return false;\n }\n\n // must not be called with more than the maximum arguments\n if (numArguments > maximum && !hasRest) {\n this.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n reportNode.range, maximum.toString(), numArguments.toString()\n );\n return false;\n }\n\n return true;\n }\n\n /** Checks that an unsafe expression is allowed. */\n private checkUnsafe(reportNode: Node, relatedReportNode: Node | null = null): void {\n // Library files may always use unsafe features\n if (this.options.noUnsafe && !reportNode.range.source.isLibrary) {\n if (relatedReportNode) {\n this.errorRelated(\n DiagnosticCode.Operation_is_unsafe,\n reportNode.range, relatedReportNode.range\n );\n } else {\n this.error(\n DiagnosticCode.Operation_is_unsafe,\n reportNode.range\n );\n }\n }\n }\n\n /** Compiles a direct call to a concrete function. */\n compileCallDirect(\n instance: Function,\n argumentExpressions: Expression[],\n reportNode: Node,\n thisArg: ExpressionRef = 0,\n constraints: Constraints = Constraints.None\n ): ExpressionRef {\n let numArguments = argumentExpressions.length;\n let signature = instance.signature;\n if (!this.checkCallSignature( // reports\n signature,\n numArguments,\n thisArg != 0,\n reportNode\n )) {\n this.currentType = signature.returnType;\n return this.module.unreachable();\n }\n if (instance.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(reportNode);\n\n // handle call on `this` in constructors\n let sourceFunction = this.currentFlow.sourceFunction;\n if (sourceFunction.is(CommonFlags.Constructor) && reportNode.isAccessOnThis) {\n let parent = sourceFunction.parent;\n assert(parent.kind == ElementKind.Class);\n this.checkFieldInitialization(parent, reportNode);\n }\n\n // Inline if explicitly requested\n if (instance.hasDecorator(DecoratorFlags.Inline) && (!instance.is(CommonFlags.Overridden) || reportNode.isAccessOnSuper)) {\n assert(!instance.is(CommonFlags.Stub)); // doesn't make sense\n let inlineStack = this.inlineStack;\n if (inlineStack.includes(instance)) {\n this.warning(\n DiagnosticCode.Function_0_cannot_be_inlined_into_itself,\n reportNode.range, instance.internalName\n );\n } else {\n let parameterTypes = signature.parameterTypes;\n assert(numArguments <= parameterTypes.length);\n // compile argument expressions *before* pushing to the inline stack\n // otherwise, the arguments may not be inlined, e.g. `abc(abc(123))`\n let args = new Array(numArguments);\n for (let i = 0; i < numArguments; ++i) {\n args[i] = this.compileExpression(argumentExpressions[i], parameterTypes[i], Constraints.ConvImplicit);\n }\n // make the inlined call\n inlineStack.push(instance);\n let expr = this.makeCallInline(instance, args, thisArg, (constraints & Constraints.WillDrop) != 0);\n inlineStack.pop();\n return expr;\n }\n }\n\n // Otherwise compile to just a call\n let numArgumentsInclThis = thisArg ? numArguments + 1 : numArguments;\n let operands = new Array(numArgumentsInclThis);\n let index = 0;\n if (thisArg) {\n operands[0] = thisArg;\n index = 1;\n }\n let parameterTypes = signature.parameterTypes;\n for (let i = 0; i < numArguments; ++i, ++index) {\n let paramType = parameterTypes[i];\n let paramExpr = this.compileExpression(argumentExpressions[i], paramType, Constraints.ConvImplicit);\n operands[index] = paramExpr;\n }\n assert(index == numArgumentsInclThis);\n return this.makeCallDirect(instance, operands, reportNode, (constraints & Constraints.WillDrop) != 0);\n }\n\n makeCallInline(\n instance: Function,\n operands: ExpressionRef[] | null,\n thisArg: ExpressionRef = 0,\n immediatelyDropped: bool = false\n ): ExpressionRef {\n let module = this.module;\n let numArguments = operands ? operands.length : 0;\n let signature = instance.signature;\n let parameterTypes = signature.parameterTypes;\n let numParameters = parameterTypes.length;\n\n // Create a new inline flow and use it to compile the function as a block\n let previousFlow = this.currentFlow;\n let flow = Flow.createInline(previousFlow.targetFunction, instance);\n let body = [];\n\n if (thisArg) {\n let parent = assert(instance.parent);\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n let thisType = assert(instance.signature.thisType);\n let thisLocal = flow.addScopedLocal(CommonNames.this_, thisType);\n body.push(\n module.local_set(thisLocal.index, thisArg, thisType.isManaged)\n );\n flow.setLocalFlag(thisLocal.index, LocalFlags.Initialized);\n let base = classInstance.base;\n if (base) flow.addScopedAlias(CommonNames.super_, base.type, thisLocal.index);\n } else {\n assert(!instance.signature.thisType);\n }\n for (let i = 0; i < numArguments; ++i) {\n let paramExpr = operands![i];\n let paramType = parameterTypes[i];\n let argumentLocal = flow.addScopedLocal(instance.getParameterName(i), paramType);\n // inlining is aware of wrap/nonnull states:\n if (!previousFlow.canOverflow(paramExpr, paramType)) flow.setLocalFlag(argumentLocal.index, LocalFlags.Wrapped);\n if (flow.isNonnull(paramExpr, paramType)) flow.setLocalFlag(argumentLocal.index, LocalFlags.NonNull);\n body.push(\n module.local_set(argumentLocal.index, paramExpr, paramType.isManaged)\n );\n flow.setLocalFlag(argumentLocal.index, LocalFlags.Initialized);\n }\n\n // Compile omitted arguments with final argument locals blocked. Doesn't need to take care of\n // side-effects within earlier expressions because these already happened on set.\n this.currentFlow = flow;\n let isConstructor = instance.is(CommonFlags.Constructor);\n if (isConstructor) flow.set(FlowFlags.CtorParamContext);\n for (let i = numArguments; i < numParameters; ++i) {\n let initType = parameterTypes[i];\n let initExpr = this.compileExpression(\n assert(instance.prototype.functionTypeNode.parameters[i].initializer),\n initType,\n Constraints.ConvImplicit\n );\n let argumentLocal = flow.addScopedLocal(instance.getParameterName(i), initType);\n body.push(\n this.makeLocalAssignment(argumentLocal, initExpr, initType, false)\n );\n }\n flow.unset(FlowFlags.CtorParamContext);\n\n // Compile the called function's body in the scope of the inlined flow\n this.compileFunctionBody(instance, body);\n\n // If a constructor, perform field init checks on its flow directly\n if (isConstructor) {\n let parent = instance.parent;\n assert(parent.kind == ElementKind.Class);\n this.checkFieldInitializationInFlow(parent, flow);\n }\n\n // Free any new scoped locals and reset to the original flow\n let returnType = flow.returnType;\n this.currentFlow = previousFlow;\n\n // Create an outer block that we can break to when returning a value out of order\n this.currentType = returnType;\n return module.block(flow.inlineReturnLabel, body, returnType.toRef());\n }\n\n /** Makes sure that the arguments length helper global is present. */\n ensureArgumentsLength(): string {\n let name = BuiltinNames.argumentsLength;\n if (!this.builtinArgumentsLength) {\n let module = this.module;\n this.builtinArgumentsLength = module.addGlobal(name, TypeRef.I32, true, module.i32(0));\n }\n return name;\n }\n\n /** Ensures compilation of the varargs stub for the specified function. */\n ensureVarargsStub(original: Function): Function {\n // A varargs stub is a function called with omitted arguments being zeroed,\n // reading the `argumentsLength` helper global to decide which initializers\n // to inject before calling the original function. It is typically attempted\n // to circumvent the varargs stub where possible, for example where omitted\n // arguments are constants and can be inlined into the original call.\n let stub = original.varargsStub;\n if (stub) return stub;\n\n let originalSignature = original.signature;\n let originalParameterTypes = originalSignature.parameterTypes;\n let originalParameterDeclarations = original.prototype.functionTypeNode.parameters;\n let returnType = originalSignature.returnType;\n let isInstance = original.is(CommonFlags.Instance);\n\n // arguments excl. `this`, operands incl. `this`\n let minArguments = originalSignature.requiredParameters;\n let minOperands = minArguments;\n let maxArguments = originalParameterTypes.length;\n let maxOperands = maxArguments;\n if (isInstance) {\n ++minOperands;\n ++maxOperands;\n }\n let numOptional = assert(maxOperands - minOperands);\n\n let forwardedOperands = new Array(minOperands);\n let operandIndex = 0;\n let stmts = new Array();\n\n // forward `this` if applicable\n let module = this.module;\n let thisType = originalSignature.thisType;\n if (thisType) {\n forwardedOperands[0] = module.local_get(0, thisType.toRef());\n operandIndex = 1;\n }\n\n // forward required arguments\n for (let i = 0; i < minArguments; ++i, ++operandIndex) {\n let paramType = originalParameterTypes[i];\n forwardedOperands[operandIndex] = module.local_get(operandIndex, paramType.toRef());\n }\n assert(operandIndex == minOperands);\n\n // create the varargs stub\n stub = original.newStub(\"varargs\", maxArguments);\n\n original.varargsStub = stub;\n\n // compile initializers of omitted arguments in the scope of the stub,\n // accounting for additional locals and a proper `this` context.\n let previousFlow = this.currentFlow;\n let flow = stub.flow;\n if (original.is(CommonFlags.Constructor)) flow.set(FlowFlags.CtorParamContext);\n this.currentFlow = flow;\n\n // create a br_table switching over the number of optional parameters provided\n let numNames = numOptional + 1; // incl. outer block\n let names = new Array(numNames);\n let ofN = `of${numOptional}`;\n for (let i = 0; i < numNames; ++i) {\n names[i] = `${i}${ofN}`;\n }\n let argumentsLength = this.ensureArgumentsLength();\n let table = module.block(names[0], [\n module.block(\"outOfRange\", [\n module.switch(names, \"outOfRange\",\n // condition is number of provided optional arguments, so subtract required arguments\n minArguments\n ? module.binary(\n BinaryOp.SubI32,\n module.global_get(argumentsLength, TypeRef.I32),\n module.i32(minArguments)\n )\n : module.global_get(argumentsLength, TypeRef.I32)\n )\n ]),\n module.unreachable()\n ]);\n for (let i = 0; i < numOptional; ++i, ++operandIndex) {\n let type = originalParameterTypes[minArguments + i];\n let declaration = originalParameterDeclarations[minArguments + i];\n let initializer = declaration.initializer;\n let initExpr: ExpressionRef;\n if (initializer) {\n initExpr = this.compileExpression(\n initializer,\n type,\n Constraints.ConvImplicit\n );\n initExpr = module.local_set(operandIndex, initExpr, type.isManaged);\n } else {\n this.error(\n DiagnosticCode.Optional_parameter_must_have_an_initializer,\n declaration.range\n );\n initExpr = module.unreachable();\n }\n table = module.block(names[i + 1], [\n table,\n initExpr,\n ]);\n forwardedOperands[operandIndex] = module.local_get(operandIndex, type.toRef());\n }\n assert(operandIndex == maxOperands);\n\n stmts.push(\n table\n );\n stmts.push(\n // assume this will always succeed (can just use name as the reportNode)\n this.makeCallDirect(original, forwardedOperands, original.declaration.name)\n );\n this.currentFlow = previousFlow;\n\n let funcRef = module.addFunction(\n stub.internalName,\n stub.signature.paramRefs,\n stub.signature.resultRefs,\n typesToRefs(stub.getNonParameterLocalTypes()),\n module.flatten(stmts, returnType.toRef())\n );\n stub.set(CommonFlags.Compiled);\n stub.finalize(module, funcRef);\n return stub;\n }\n\n /** Ensures compilation of the override stub for the specified function. */\n ensureOverrideStub(original: Function): Function {\n // An override stub is a function redirecting virtual calls to the actual\n // override targeted by the call. It utilizes varargs stubs where necessary\n // and as such has the same semantics as one. Here, we only make sure that\n // a placeholder exist, with actual code being generated as a finalization\n // step once module compilation is otherwise complete.\n let stub = original.overrideStub;\n if (stub) return stub;\n stub = original.newStub(\"override\");\n original.overrideStub = stub;\n let module = this.module;\n stub.ref = module.addFunction(\n stub.internalName,\n stub.signature.paramRefs,\n stub.signature.resultRefs,\n null,\n module.unreachable()\n );\n this.overrideStubs.add(original);\n return stub;\n }\n\n /** Finalizes the override stub of the specified function. */\n private finalizeOverrideStub(instance: Function): void {\n let stub = this.ensureOverrideStub(instance);\n if (stub.is(CommonFlags.Compiled)) return;\n\n assert(instance.parent.kind == ElementKind.Class || instance.parent.kind == ElementKind.Interface);\n let module = this.module;\n let usizeType = this.options.usizeType;\n let sizeTypeRef = usizeType.toRef();\n let parameterTypes = instance.signature.parameterTypes;\n let returnType = instance.signature.returnType;\n let numParameters = parameterTypes.length;\n let tempIndex = 1 + parameterTypes.length; // incl. `this`\n\n // Switch over this's rtId and map it to the respective overload\n let builder = new SwitchBuilder(this.module,\n module.load(4, false,\n module.binary(\n sizeTypeRef == TypeRef.I64\n ? BinaryOp.SubI64\n : BinaryOp.SubI32,\n module.local_get(0, sizeTypeRef),\n sizeTypeRef == TypeRef.I64\n ? module.i64(8) // rtId offset = -8\n : module.i32(8)\n ),\n TypeRef.I32\n )\n );\n let overrideInstances = this.resolver.resolveOverrides(instance);\n if (overrideInstances) {\n for (let i = 0, k = overrideInstances.length; i < k; ++i) {\n let overrideInstance = overrideInstances[i];\n if (!overrideInstance.is(CommonFlags.Compiled)) continue; // errored\n let overrideType = overrideInstance.type;\n let originalType = instance.type;\n if (!overrideType.isAssignableTo(originalType)) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n overrideInstance.identifierNode.range, overrideType.toString(), originalType.toString()\n );\n continue;\n }\n // TODO: additional optional parameters are not permitted by `isAssignableTo` yet\n let overrideSignature = overrideInstance.signature;\n let overrideParameterTypes = overrideSignature.parameterTypes;\n let overrideNumParameters = overrideParameterTypes.length;\n let paramExprs = new Array(1 + overrideNumParameters);\n paramExprs[0] = module.local_get(0, sizeTypeRef); // this\n for (let n = 1; n <= numParameters; ++n) {\n paramExprs[n] = module.local_get(n, parameterTypes[n - 1].toRef());\n }\n let needsVarargsStub = false;\n for (let n = numParameters; n < overrideNumParameters; ++n) {\n // TODO: inline constant initializers and skip varargs stub\n paramExprs[1 + n] = this.makeZero(overrideParameterTypes[n]);\n needsVarargsStub = true;\n }\n let calledName = needsVarargsStub\n ? this.ensureVarargsStub(overrideInstance).internalName\n : overrideInstance.internalName;\n let returnTypeRef = overrideSignature.returnType.toRef();\n let stmts = new Array();\n if (needsVarargsStub) {\n // Safe to prepend since paramExprs are local.get's\n stmts.push(module.global_set(this.ensureArgumentsLength(), module.i32(numParameters)));\n }\n if (returnType == Type.void) {\n stmts.push(\n module.call(calledName, paramExprs, returnTypeRef)\n );\n stmts.push(\n module.return()\n );\n } else {\n stmts.push(\n module.return(\n module.call(calledName, paramExprs, returnTypeRef)\n )\n );\n }\n let classInstance = assert(overrideInstance.getBoundClassOrInterface());\n builder.addCase(classInstance.id, stmts);\n // Also alias each extender inheriting this exact overload\n let extenders = classInstance.extenders;\n if (extenders) {\n for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) {\n let extender = _values[i];\n let instanceMembers = extender.prototype.instanceMembers;\n if (instanceMembers && instanceMembers.has(instance.declaration.name.text)) {\n continue; // skip those not inheriting\n }\n builder.addCase(extender.id, stmts);\n }\n }\n }\n }\n\n // Call the original function if no other id matches and the method is not\n // abstract or part of an interface. Note that doing so will not catch an\n // invalid id, but can reduce code size significantly since we also don't\n // have to add branches for extenders inheriting the original function.\n let body: ExpressionRef;\n let instanceClass = instance.getBoundClassOrInterface();\n if (!instance.is(CommonFlags.Abstract) && !(instanceClass && instanceClass.kind == ElementKind.Interface)) {\n let paramExprs = new Array(numParameters);\n paramExprs[0] = module.local_get(0, sizeTypeRef); // this\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n paramExprs[1 + i] = module.local_get(1 + i, parameterTypes[i].toRef());\n }\n body = module.call(instance.internalName, paramExprs, returnType.toRef());\n\n // Otherwise trap\n } else {\n body = module.unreachable();\n }\n\n // Create the stub function\n let ref = stub.ref;\n if (ref) module.removeFunction(stub.internalName);\n stub.ref = module.addFunction(\n stub.internalName,\n stub.signature.paramRefs,\n stub.signature.resultRefs,\n [ TypeRef.I32 ],\n module.block(null, [\n builder.render(tempIndex),\n body\n ], returnType.toRef())\n );\n stub.set(CommonFlags.Compiled);\n }\n\n /** Marks managed call operands for the shadow stack. */\n private operandsTostack(signature: Signature, operands: ExpressionRef[]): void {\n if (!this.options.stackSize) return;\n let module = this.module;\n let operandIndex = 0;\n let thisType = signature.thisType;\n if (thisType) {\n if (thisType.isManaged) {\n let operand = operands[0];\n let precomp = module.runExpression(operand, ExpressionRunnerFlags.Default);\n if (!isConstZero(precomp)) { // otherwise unnecessary\n operands[operandIndex] = module.tostack(operand);\n }\n }\n ++operandIndex;\n }\n let parameterIndex = 0;\n let parameterTypes = signature.parameterTypes;\n assert(parameterTypes.length >= operands.length - operandIndex);\n while (operandIndex < operands.length) {\n let paramType = parameterTypes[parameterIndex];\n if (paramType.isManaged) {\n let operand = operands[operandIndex];\n let precomp = module.runExpression(operand, ExpressionRunnerFlags.Default);\n if (!isConstZero(precomp)) { // otherwise unnecessary\n operands[operandIndex] = module.tostack(operand);\n }\n }\n ++operandIndex;\n ++parameterIndex;\n }\n }\n\n /** Creates a direct call to the specified function. */\n makeCallDirect(\n instance: Function,\n operands: ExpressionRef[] | null,\n reportNode: Node,\n immediatelyDropped: bool = false\n ): ExpressionRef {\n if (instance.hasDecorator(DecoratorFlags.Inline)) {\n if (!instance.is(CommonFlags.Overridden)) {\n assert(!instance.is(CommonFlags.Stub)); // doesn't make sense\n let inlineStack = this.inlineStack;\n if (inlineStack.includes(instance)) {\n this.warning(\n DiagnosticCode.Function_0_cannot_be_inlined_into_itself,\n reportNode.range, instance.internalName\n );\n } else {\n inlineStack.push(instance);\n let expr: ExpressionRef;\n if (instance.is(CommonFlags.Instance)) {\n let theOperands = assert(operands);\n assert(theOperands.length);\n expr = this.makeCallInline(instance, theOperands.slice(1), theOperands[0], immediatelyDropped);\n } else {\n expr = this.makeCallInline(instance, operands, 0, immediatelyDropped);\n }\n inlineStack.pop();\n return expr;\n }\n } else {\n this.warning(\n DiagnosticCode.Function_0_is_virtual_and_will_not_be_inlined,\n reportNode.range, instance.internalName\n );\n }\n }\n let module = this.module;\n let numOperands = operands ? operands.length : 0;\n let numArguments = numOperands;\n let minArguments = instance.signature.requiredParameters;\n let minOperands = minArguments;\n let parameterTypes = instance.signature.parameterTypes;\n let maxArguments = parameterTypes.length;\n let maxOperands = maxArguments;\n if (instance.is(CommonFlags.Instance)) {\n ++minOperands;\n ++maxOperands;\n --numArguments;\n }\n assert(numOperands >= minOperands);\n\n if (!this.compileFunction(instance)) return module.unreachable();\n let returnType = instance.signature.returnType;\n\n // fill up omitted arguments with their initializers, if constant, otherwise with zeroes.\n if (numOperands < maxOperands) {\n if (!operands) {\n operands = new Array(maxOperands);\n operands.length = 0;\n }\n let parameterNodes = instance.prototype.functionTypeNode.parameters;\n assert(parameterNodes.length == parameterTypes.length);\n let allOptionalsAreConstant = true;\n for (let i = numArguments; i < maxArguments; ++i) {\n let initializer = parameterNodes[i].initializer;\n if (initializer) {\n if (initializer.compilesToConst) {\n operands.push(this.compileExpression(\n initializer,\n parameterTypes[i],\n Constraints.ConvImplicit\n ));\n continue;\n }\n let resolved = this.resolver.lookupExpression(initializer, instance.flow, parameterTypes[i], ReportMode.Swallow);\n if (resolved && resolved.kind == ElementKind.Global) {\n let global = resolved;\n if (this.compileGlobalLazy(global, initializer) && global.is(CommonFlags.Inlined)) {\n operands.push(\n this.compileInlineConstant(global, parameterTypes[i], Constraints.ConvImplicit)\n );\n continue;\n }\n }\n }\n operands.push(this.makeZero(parameterTypes[i]));\n allOptionalsAreConstant = false;\n }\n if (!allOptionalsAreConstant && !instance.is(CommonFlags.ModuleImport)) {\n let original = instance;\n instance = this.ensureVarargsStub(instance);\n if (!this.compileFunction(instance)) return module.unreachable();\n instance.flow.flags = original.flow.flags;\n let returnTypeRef = returnType.toRef();\n // We know the last operand is optional and omitted, so inject setting\n // ~argumentsLength into that operand, which is always safe.\n let lastOperand = operands[maxOperands - 1];\n assert(!(getSideEffects(lastOperand, module.ref) & SideEffects.WritesGlobal));\n let lastOperandType = parameterTypes[maxArguments - 1];\n operands[maxOperands - 1] = module.block(null, [\n module.global_set(this.ensureArgumentsLength(), module.i32(numArguments)),\n lastOperand\n ], lastOperandType.toRef());\n this.operandsTostack(instance.signature, operands);\n let expr = module.call(instance.internalName, operands, returnTypeRef);\n if (returnType != Type.void && immediatelyDropped) {\n expr = module.drop(expr);\n this.currentType = Type.void;\n } else {\n this.currentType = returnType;\n }\n return expr;\n }\n }\n\n // Call the override stub if the function has overloads\n if (instance.is(CommonFlags.Overridden) && !reportNode.isAccessOnSuper) {\n instance = this.ensureOverrideStub(instance);\n }\n\n if (operands) this.operandsTostack(instance.signature, operands);\n let expr = module.call(instance.internalName, operands, returnType.toRef());\n this.currentType = returnType;\n return expr;\n }\n\n /** Compiles an indirect call to a first-class function. */\n compileCallIndirect(\n signature: Signature,\n functionArg: ExpressionRef,\n argumentExpressions: Expression[],\n reportNode: Node,\n thisArg: ExpressionRef = 0,\n immediatelyDropped: bool = false\n ): ExpressionRef {\n let numArguments = argumentExpressions.length;\n\n if (!this.checkCallSignature( // reports\n signature,\n numArguments,\n thisArg != 0,\n reportNode\n )) {\n return this.module.unreachable();\n }\n\n let numArgumentsInclThis = thisArg ? numArguments + 1 : numArguments;\n let operands = new Array(numArgumentsInclThis);\n let index = 0;\n if (thisArg) {\n operands[0] = thisArg;\n index = 1;\n }\n let parameterTypes = signature.parameterTypes;\n for (let i = 0; i < numArguments; ++i, ++index) {\n operands[index] = this.compileExpression(argumentExpressions[i], parameterTypes[i],\n Constraints.ConvImplicit\n );\n }\n assert(index == numArgumentsInclThis);\n return this.makeCallIndirect(signature, functionArg, reportNode, operands, immediatelyDropped);\n }\n\n /** Creates an indirect call to a first-class function. */\n makeCallIndirect(\n signature: Signature,\n functionArg: ExpressionRef,\n reportNode: Node,\n operands: ExpressionRef[] | null = null,\n immediatelyDropped: bool = false,\n ): ExpressionRef {\n let module = this.module;\n let numOperands = operands ? operands.length : 0;\n let numArguments = numOperands;\n let minArguments = signature.requiredParameters;\n let minOperands = minArguments;\n let parameterTypes = signature.parameterTypes;\n let returnType = signature.returnType;\n let maxArguments = parameterTypes.length;\n let maxOperands = maxArguments;\n if (signature.thisType) {\n ++minOperands;\n ++maxOperands;\n --numArguments;\n }\n assert(numOperands >= minOperands);\n\n // fill up omitted arguments with zeroes\n if (numOperands < maxOperands) {\n if (!operands) {\n operands = new Array(maxOperands);\n operands.length = 0;\n }\n let parameterTypes = signature.parameterTypes;\n for (let i = numArguments; i < maxArguments; ++i) {\n operands.push(this.makeZero(parameterTypes[i]));\n }\n }\n\n // We might be calling a varargs stub here, even if all operands have been\n // provided, so we must set `argumentsLength` in any case. Inject setting it\n // into the index argument, which becomes executed last after any operands.\n let argumentsLength = this.ensureArgumentsLength();\n let sizeTypeRef = this.options.sizeTypeRef;\n if (getSideEffects(functionArg, module.ref) & SideEffects.WritesGlobal) {\n let flow = this.currentFlow;\n let temp = flow.getTempLocal(this.options.usizeType);\n let tempIndex = temp.index;\n functionArg = module.block(null, [\n module.local_set(tempIndex, functionArg, true), // Function\n module.global_set(argumentsLength, module.i32(numArguments)),\n module.local_get(tempIndex, sizeTypeRef)\n ], sizeTypeRef);\n } else { // simplify\n functionArg = module.block(null, [\n module.global_set(argumentsLength, module.i32(numArguments)),\n functionArg\n ], sizeTypeRef);\n }\n if (operands) this.operandsTostack(signature, operands);\n let expr = module.call_indirect(\n null, // TODO: handle multiple tables\n module.load(4, false, functionArg, TypeRef.I32), // ._index\n operands,\n signature.paramRefs,\n signature.resultRefs\n );\n this.currentType = returnType;\n return expr;\n }\n\n private compileCommaExpression(\n expression: CommaExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let expressions = expression.expressions;\n let numExpressions = expressions.length;\n let exprs = new Array(numExpressions--);\n for (let i = 0; i < numExpressions; ++i) {\n exprs[i] = this.compileExpression(expressions[i], Type.void, // drop all except last\n Constraints.ConvImplicit | Constraints.WillDrop\n );\n }\n exprs[numExpressions] = this.compileExpression(expressions[numExpressions], contextualType, constraints);\n return this.module.flatten(exprs, this.currentType.toRef());\n }\n\n private compileElementAccessExpression(\n expression: ElementAccessExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let targetExpression = expression.expression;\n let targetType = this.resolver.resolveExpression(targetExpression, this.currentFlow); // reports\n if (targetType) {\n let classReference = targetType.getClassOrWrapper(this.program);\n if (classReference) {\n let isUnchecked = this.currentFlow.is(FlowFlags.UncheckedContext);\n let indexedGet = classReference.lookupOverload(OperatorKind.IndexedGet, isUnchecked);\n if (indexedGet) {\n let thisType = assert(indexedGet.signature.thisType);\n let thisArg = this.compileExpression(targetExpression, thisType,\n Constraints.ConvImplicit\n );\n if (!isUnchecked && this.options.pedantic) {\n this.pedantic(\n DiagnosticCode.Indexed_access_may_involve_bounds_checking,\n expression.range\n );\n }\n return this.compileCallDirect(indexedGet, [\n expression.elementExpression\n ], expression, thisArg, constraints);\n }\n }\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n expression.expression.range, targetType.toString()\n );\n }\n return module.unreachable();\n }\n\n private compileFunctionExpression(\n expression: FunctionExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let declaration = expression.declaration.clone(); // generic contexts can have multiple\n assert(!declaration.typeParameters); // function expression cannot be generic\n let flow = this.currentFlow;\n let sourceFunction = flow.sourceFunction;\n let isNamed = declaration.name.text.length > 0;\n let isSemanticallyAnonymous = !isNamed || contextualType != Type.void;\n let prototype = new FunctionPrototype(\n isSemanticallyAnonymous\n ? `${isNamed ? declaration.name.text : \"anonymous\"}|${sourceFunction.nextAnonymousId++}`\n : declaration.name.text,\n sourceFunction,\n declaration,\n DecoratorFlags.None\n );\n let instance: Function | null;\n let contextualTypeArguments = cloneMap(flow.contextualTypeArguments);\n let module = this.module;\n\n // compile according to context. this differs from a normal function in that omitted parameter\n // and return types can be inferred and omitted arguments can be replaced with dummies.\n let contextualSignature = contextualType.signatureReference;\n if (contextualSignature) {\n let signatureNode = prototype.functionTypeNode;\n let parameterNodes = signatureNode.parameters;\n let numPresentParameters = parameterNodes.length;\n\n // must not require more than the maximum number of parameters\n let parameterTypes = contextualSignature.parameterTypes;\n let numParameters = parameterTypes.length;\n if (numPresentParameters > numParameters) {\n this.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n expression.range, numParameters.toString(), numPresentParameters.toString()\n );\n return module.unreachable();\n }\n\n // check non-omitted parameter types\n for (let i = 0; i < numPresentParameters; ++i) {\n let parameterNode = parameterNodes[i];\n if (!isTypeOmitted(parameterNode.type)) {\n let resolvedType = this.resolver.resolveType(\n parameterNode.type,\n sourceFunction.parent,\n contextualTypeArguments\n );\n if (!resolvedType) return module.unreachable();\n if (!parameterTypes[i].isStrictlyAssignableTo(resolvedType)) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n parameterNode.range, parameterTypes[i].toString(), resolvedType.toString()\n );\n return module.unreachable();\n }\n }\n // any unused parameters are inherited but ignored\n }\n\n // check non-omitted return type\n let returnType = contextualSignature.returnType;\n if (!isTypeOmitted(signatureNode.returnType)) {\n let resolvedType = this.resolver.resolveType(\n signatureNode.returnType,\n sourceFunction.parent,\n contextualTypeArguments\n );\n if (!resolvedType) return module.unreachable();\n if (\n returnType == Type.void\n ? resolvedType != Type.void\n : !resolvedType.isStrictlyAssignableTo(returnType)\n ) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n signatureNode.returnType.range, resolvedType.toString(), returnType.toString()\n );\n return module.unreachable();\n }\n }\n\n // check explicit this type\n let thisType = contextualSignature.thisType;\n let thisTypeNode = signatureNode.explicitThisType;\n if (thisTypeNode) {\n if (!thisType) {\n this.error(\n DiagnosticCode._this_cannot_be_referenced_in_current_location,\n thisTypeNode.range\n );\n return module.unreachable();\n }\n let resolvedType = this.resolver.resolveType(\n thisTypeNode,\n sourceFunction.parent,\n contextualTypeArguments\n );\n if (!resolvedType) return module.unreachable();\n if (!thisType.isStrictlyAssignableTo(resolvedType)) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n thisTypeNode.range, thisType.toString(), resolvedType.toString()\n );\n return module.unreachable();\n }\n }\n\n let signature = Signature.create(this.program, parameterTypes, returnType, thisType, numParameters);\n instance = new Function(\n prototype.name,\n prototype,\n null,\n signature,\n contextualTypeArguments\n );\n instance.flow.outer = flow;\n let worked = this.compileFunction(instance);\n this.currentType = contextualSignature.type;\n if (!worked) return module.unreachable();\n\n // otherwise compile like a normal function\n } else {\n instance = this.resolver.resolveFunction(prototype, null, contextualTypeArguments);\n if (!instance) return this.module.unreachable();\n instance.flow.outer = flow;\n let worked = this.compileFunction(instance);\n this.currentType = instance.signature.type;\n if (!worked) return module.unreachable();\n }\n\n let offset = this.ensureRuntimeFunction(instance); // reports\n let expr = this.options.isWasm64\n ? module.i64(i64_low(offset), i64_high(offset))\n : module.i32(i64_low(offset));\n\n // add a constant local referring to the function if applicable\n if (!isSemanticallyAnonymous) {\n let fname = instance.name;\n let existingLocal = flow.getScopedLocal(fname);\n if (existingLocal) {\n if (!existingLocal.declaration.range.source.isNative) {\n this.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range,\n existingLocal.declaration.name.range,\n fname\n );\n } else { // scoped locals are shared temps that don't track declarations\n this.error(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range, fname\n );\n }\n } else {\n let ftype = instance.type;\n let local = flow.addScopedLocal(instance.name, ftype);\n flow.setLocalFlag(local.index, LocalFlags.Constant | LocalFlags.Initialized);\n expr = module.local_tee(local.index, expr, ftype.isManaged);\n }\n }\n\n return expr;\n }\n\n /** Makes sure the enclosing source file of the specified expression has been compiled. */\n private maybeCompileEnclosingSource(expression: Expression): void {\n let internalPath = expression.range.source.internalPath;\n let filesByName = this.program.filesByName;\n assert(filesByName.has(internalPath));\n let enclosingFile = assert(filesByName.get(internalPath));\n if (!enclosingFile.is(CommonFlags.Compiled)) {\n this.compileFileByPath(internalPath, expression);\n }\n }\n\n private compileIdentifierExpression(\n expression: IdentifierExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n let sourceFunction = flow.sourceFunction;\n\n // check special keywords first\n switch (expression.kind) {\n case NodeKind.Null: {\n let options = this.options;\n if (contextualType.isReference) {\n let classReference = contextualType.getClass();\n if (classReference) {\n this.currentType = classReference.type.asNullable();\n return options.isWasm64 ? module.i64(0) : module.i32(0);\n }\n let signatureReference = contextualType.getSignature();\n if (signatureReference) {\n this.currentType = signatureReference.type.asNullable();\n return options.isWasm64 ? module.i64(0) : module.i32(0);\n }\n return this.makeZero(contextualType);\n }\n this.currentType = options.usizeType;\n this.warning(\n DiagnosticCode.Expression_resolves_to_unusual_type_0,\n expression.range, this.currentType.toString()\n );\n return options.isWasm64\n ? module.i64(0)\n : module.i32(0);\n }\n case NodeKind.True: {\n this.currentType = Type.bool;\n return module.i32(1);\n }\n case NodeKind.False: {\n this.currentType = Type.bool;\n return module.i32(0);\n }\n case NodeKind.This: {\n let thisType = sourceFunction.signature.thisType;\n if (!thisType) {\n this.error(\n DiagnosticCode._this_cannot_be_referenced_in_current_location,\n expression.range\n );\n this.currentType = this.options.usizeType;\n return module.unreachable();\n }\n if (sourceFunction.is(CommonFlags.Constructor)) {\n if (flow.is(FlowFlags.CtorParamContext)) {\n this.error(\n DiagnosticCode._this_cannot_be_referenced_in_constructor_arguments,\n expression.range\n );\n }\n if (!(constraints & Constraints.IsThis)) {\n let parent = sourceFunction.parent;\n assert(parent.kind == ElementKind.Class);\n this.checkFieldInitialization(parent, expression);\n }\n }\n let thisLocal = assert(flow.lookupLocal(CommonNames.this_));\n flow.set(FlowFlags.AccessesThis);\n this.currentType = thisType;\n return module.local_get(thisLocal.index, thisType.toRef());\n }\n case NodeKind.Super: {\n if (sourceFunction.is(CommonFlags.Constructor)) {\n if (flow.is(FlowFlags.CtorParamContext)) {\n this.error(\n DiagnosticCode._super_cannot_be_referenced_in_constructor_arguments,\n expression.range\n );\n } else if (!flow.is(FlowFlags.CallsSuper)) {\n // TS1034 in the parser effectively limits this to property accesses\n this.error(\n DiagnosticCode._super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class,\n expression.range\n );\n }\n }\n if (flow.isInline) {\n let scopedThis = flow.lookupLocal(CommonNames.this_);\n if (scopedThis) {\n let scopedThisClass = assert(scopedThis.type.getClass());\n let base = scopedThisClass.base;\n if (base) {\n this.currentType = base.type;\n return module.local_get(scopedThis.index, base.type.toRef());\n }\n }\n }\n if (sourceFunction.is(CommonFlags.Instance)) {\n let parent = assert(sourceFunction.parent);\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n let baseClassInstance = classInstance.base;\n if (baseClassInstance) {\n let superType = baseClassInstance.type;\n this.currentType = superType;\n return module.local_get(0, superType.toRef());\n }\n }\n this.error(\n DiagnosticCode._super_can_only_be_referenced_in_a_derived_class,\n expression.range\n );\n this.currentType = this.options.usizeType;\n return module.unreachable();\n }\n }\n\n this.maybeCompileEnclosingSource(expression);\n\n // otherwise resolve\n let currentParent = this.currentParent;\n if (!currentParent) currentParent = sourceFunction;\n let target = this.resolver.lookupIdentifierExpression( // reports\n expression,\n flow,\n currentParent\n );\n if (!target) {\n // make a guess to avoid assertions in calling code\n if (this.currentType == Type.void) this.currentType = Type.i32;\n return module.unreachable();\n }\n\n switch (target.kind) {\n case ElementKind.Local: {\n let local = target;\n let localType = local.type;\n assert(localType != Type.void);\n if (this.pendingElements.has(local)) {\n this.error(\n DiagnosticCode.Variable_0_used_before_its_declaration,\n expression.range,\n local.internalName\n );\n this.currentType = localType;\n return module.unreachable();\n }\n if (local.is(CommonFlags.Inlined)) {\n return this.compileInlineConstant(local, contextualType, constraints);\n }\n let localIndex = local.index;\n if (!flow.isLocalFlag(localIndex, LocalFlags.Initialized)) {\n this.error(\n DiagnosticCode.Variable_0_is_used_before_being_assigned,\n expression.range, local.name\n );\n }\n assert(localIndex >= 0);\n if (localType.isNullableReference && flow.isLocalFlag(localIndex, LocalFlags.NonNull, false)) {\n localType = localType.nonNullableType;\n }\n this.currentType = localType;\n\n if (target.parent != flow.targetFunction) {\n // TODO: closures\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range,\n \"Closures\"\n );\n return module.unreachable();\n }\n return module.local_get(localIndex, localType.toRef());\n }\n case ElementKind.Global: {\n let global = target;\n if (!this.compileGlobalLazy(global, expression)) {\n return module.unreachable();\n }\n let globalType = global.type;\n if (this.pendingElements.has(global)) {\n this.error(\n DiagnosticCode.Variable_0_used_before_its_declaration,\n expression.range,\n global.internalName\n );\n this.currentType = globalType;\n return module.unreachable();\n }\n assert(globalType != Type.void);\n if (global.hasDecorator(DecoratorFlags.Builtin)) {\n return this.compileIdentifierExpressionBuiltin(global, expression, contextualType);\n }\n if (global.is(CommonFlags.Inlined)) {\n return this.compileInlineConstant(global, contextualType, constraints);\n }\n let expr = module.global_get(global.internalName, globalType.toRef());\n if (global.is(CommonFlags.DefinitelyAssigned) && globalType.isReference && !globalType.isNullableReference) {\n expr = this.makeRuntimeNonNullCheck(expr, globalType, expression);\n }\n this.currentType = globalType;\n return expr;\n }\n case ElementKind.EnumValue: { // here: if referenced from within the same enum\n let enumValue = target;\n if (!target.is(CommonFlags.Compiled)) {\n this.error(\n DiagnosticCode.A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums,\n expression.range\n );\n this.currentType = Type.i32;\n return module.unreachable();\n }\n this.currentType = Type.i32;\n if (enumValue.is(CommonFlags.Inlined)) {\n assert(enumValue.constantValueKind == ConstantValueKind.Integer);\n return module.i32(i64_low(enumValue.constantIntegerValue));\n }\n return module.global_get(enumValue.internalName, TypeRef.I32);\n }\n case ElementKind.FunctionPrototype: {\n let functionPrototype = target;\n let typeParameterNodes = functionPrototype.typeParameterNodes;\n\n if (typeParameterNodes && typeParameterNodes.length != 0) {\n this.error(\n DiagnosticCode.Type_argument_expected,\n expression.range\n );\n break; // also diagnose 'not a value at runtime'\n }\n\n let functionInstance = this.resolver.resolveFunction(\n functionPrototype,\n null,\n cloneMap(flow.contextualTypeArguments)\n );\n if (!functionInstance || !this.compileFunction(functionInstance)) return module.unreachable();\n if (functionInstance.hasDecorator(DecoratorFlags.Builtin)) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range, \"First-class built-ins\"\n );\n this.currentType = functionInstance.type;\n return module.unreachable();\n }\n if (contextualType.isExternalReference) {\n // TODO: Concrete function types currently map to first class functions implemented in\n // linear memory (on top of `usize`), leaving only generic `funcref` for use here. In the\n // future, once functions become Wasm GC objects, the actual signature type can be used.\n this.currentType = Type.funcref;\n return module.ref_func(functionInstance.internalName, ensureType(functionInstance.type));\n }\n let offset = this.ensureRuntimeFunction(functionInstance);\n this.currentType = functionInstance.signature.type;\n return this.options.isWasm64\n ? module.i64(i64_low(offset), i64_high(offset))\n : module.i32(i64_low(offset));\n }\n }\n this.error(\n DiagnosticCode.Expression_does_not_compile_to_a_value_at_runtime,\n expression.range\n );\n return module.unreachable();\n }\n\n private compileIdentifierExpressionBuiltin(\n element: VariableLikeElement,\n expression: IdentifierExpression,\n contextualType: Type\n ): ExpressionRef {\n if (element.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression, element.identifierNode);\n let internalName = element.internalName;\n assert(builtinVariables_onAccess.has(internalName)); // checked earlier\n let fn = assert(builtinVariables_onAccess.get(internalName));\n return fn(new BuiltinVariableContext(\n this,\n element,\n contextualType,\n expression\n ));\n }\n\n private compileInstanceOfExpression(\n expression: InstanceOfExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let flow = this.currentFlow;\n let isType = expression.isType;\n\n // Mimic `instanceof CLASS`\n if (isType.kind == NodeKind.NamedType) {\n let namedType = isType;\n if (!(namedType.isNullable || namedType.hasTypeArguments)) {\n let element = this.resolver.resolveTypeName(namedType.name, flow.sourceFunction, ReportMode.Swallow);\n if (element && element.kind == ElementKind.ClassPrototype) {\n let prototype = element;\n if (prototype.is(CommonFlags.Generic)) {\n return this.makeInstanceofClass(expression, prototype);\n }\n }\n }\n }\n\n // Fall back to `instanceof TYPE`\n let expectedType = this.resolver.resolveType(\n expression.isType,\n flow.sourceFunction,\n cloneMap(flow.contextualTypeArguments)\n );\n if (!expectedType) {\n this.currentType = Type.bool;\n return this.module.unreachable();\n }\n return this.makeInstanceofType(expression, expectedType);\n }\n\n private makeInstanceofType(expression: InstanceOfExpression, expectedType: Type): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n let expr = this.compileExpression(expression.expression, expectedType);\n let actualType = this.currentType;\n this.currentType = Type.bool;\n\n // instanceof - must be exact\n if (expectedType.isValue) {\n return module.maybeDropCondition(expr, module.i32(actualType == expectedType ? 1 : 0));\n }\n\n // instanceof - always false\n if (actualType.isValue) {\n return module.maybeDropCondition(expr, module.i32(0));\n }\n\n // both LHS and RHS are references now\n let sizeTypeRef = actualType.toRef();\n\n // instanceof - LHS must be != 0\n if (actualType.isNullableReference && !expectedType.isNullableReference) {\n\n // same or upcast - check statically\n if (actualType.nonNullableType.isAssignableTo(expectedType)) {\n return module.binary(\n sizeTypeRef == TypeRef.I64\n ? BinaryOp.NeI64\n : BinaryOp.NeI32,\n expr,\n this.makeZero(actualType)\n );\n }\n\n // potential downcast - check dynamically\n if (actualType.nonNullableType.hasSubtypeAssignableTo(expectedType)) {\n if (!(actualType.isUnmanaged || expectedType.isUnmanaged)) {\n if (this.options.pedantic) {\n this.pedantic(\n DiagnosticCode.Expression_compiles_to_a_dynamic_check_at_runtime,\n expression.range\n );\n }\n let temp = flow.getTempLocal(actualType);\n let tempIndex = temp.index;\n return module.if(\n module.unary(\n sizeTypeRef == TypeRef.I64\n ? UnaryOp.EqzI64\n : UnaryOp.EqzI32,\n module.local_tee(tempIndex, expr, actualType.isManaged),\n ),\n module.i32(0),\n module.call(this.prepareInstanceOf(expectedType.classReference!), [\n module.local_get(tempIndex, sizeTypeRef)\n ], TypeRef.I32)\n );\n } else {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"instanceof\", actualType.toString(), expectedType.toString()\n );\n }\n }\n\n // either none or both nullable\n } else {\n\n // same or upcast - check statically\n if (actualType.isAssignableTo(expectedType)) {\n return module.maybeDropCondition(expr, module.i32(1));\n }\n\n // potential downcast - check dynamically\n if (actualType.hasSubtypeAssignableTo(expectedType)) {\n if (!(actualType.isUnmanaged || expectedType.isUnmanaged)) {\n let temp = flow.getTempLocal(actualType);\n let tempIndex = temp.index;\n return module.if(\n module.unary(\n sizeTypeRef == TypeRef.I64\n ? UnaryOp.EqzI64\n : UnaryOp.EqzI32,\n module.local_tee(tempIndex, expr, actualType.isManaged),\n ),\n module.i32(0),\n module.call(this.prepareInstanceOf(expectedType.classReference!), [\n module.local_get(tempIndex, sizeTypeRef)\n ], TypeRef.I32)\n );\n } else {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n expression.range, \"instanceof\", actualType.toString(), expectedType.toString()\n );\n }\n }\n }\n\n // false\n return module.maybeDropCondition(expr, module.i32(0));\n }\n\n /** Prepares the instanceof helper for the given class or interface instance. */\n private prepareInstanceOf(instance: Class): string {\n let name = `~instanceof|${instance.internalName}`;\n let pending = this.pendingInstanceOf;\n if (pending.has(instance)) return assert(pending.get(instance));\n pending.set(instance, name);\n let module = this.module;\n module.addFunction(name, this.options.sizeTypeRef, TypeRef.I32, null,\n module.unreachable()\n );\n return name;\n }\n\n /** Finalizes the instanceof helper of the given class or interface instance. */\n private finalizeInstanceOf(\n /** Class to finalize the helper for. */\n instance: Class,\n /** Name of the helper function. */\n name: string\n ): void {\n let program = this.program;\n let module = this.module;\n let sizeType = this.options.sizeTypeRef;\n let stmts = new Array();\n // (block $is_instance\n // (local.set $1 (i32.load (...))) ;; class id\n // (br_if $is_instance (i32.eq (local.get $1) (ID)))\n // ...\n // (return (i32.const 0))\n // )\n // (i32.const 1)\n stmts.push(\n module.local_set(1,\n module.load(4, false,\n module.binary(\n sizeType == TypeRef.I64\n ? BinaryOp.SubI64\n : BinaryOp.SubI32,\n module.local_get(0, sizeType),\n module.i32(\n program.totalOverhead - program.OBJECTInstance.offsetof(\"rtId\")\n )\n ),\n TypeRef.I32\n ), false // managedness is irrelevant here, isn't interrupted\n )\n );\n let allInstances: Set | null;\n if (instance.isInterface) {\n allInstances = instance.implementers;\n } else {\n allInstances = new Set();\n allInstances.add(instance);\n let extenders = instance.extenders;\n if (extenders) {\n for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) {\n let extender = _values[i];\n allInstances.add(extender);\n }\n }\n }\n if (allInstances) {\n for (let _values = Set_values(allInstances), i = 0, k = _values.length; i < k; ++i) {\n let instance = _values[i];\n stmts.push(\n module.br(\"is_instance\",\n module.binary(BinaryOp.EqI32,\n module.local_get(1, TypeRef.I32),\n module.i32(instance.id)\n )\n )\n );\n }\n }\n stmts.push(\n module.return(\n module.i32(0)\n )\n );\n stmts[0] = module.block(\"is_instance\", stmts, TypeRef.None);\n stmts.length = 1;\n stmts.push(\n module.i32(1)\n ); \n module.removeFunction(name);\n module.addFunction(name, sizeType, TypeRef.I32, [ TypeRef.I32 ], module.block(null, stmts, TypeRef.I32));\n }\n\n private makeInstanceofClass(expression: InstanceOfExpression, prototype: ClassPrototype): ExpressionRef {\n let module = this.module;\n let expr = this.compileExpression(expression.expression, Type.auto);\n let actualType = this.currentType;\n let sizeTypeRef = actualType.toRef();\n\n this.currentType = Type.bool;\n\n // exclusively interested in class references here\n let classReference = actualType.getClass();\n if (classReference) {\n\n // static check\n if (classReference.extendsPrototype(prototype)) {\n\n // instanceof - LHS must be != 0\n if (actualType.isNullableReference) {\n return module.binary(\n sizeTypeRef == TypeRef.I64\n ? BinaryOp.NeI64\n : BinaryOp.NeI32,\n expr,\n this.makeZero(actualType)\n );\n\n // is just `true`\n } else {\n return module.maybeDropCondition(expr, module.i32(1));\n }\n\n // dynamic check against all possible concrete ids\n } else if (prototype.extends(classReference.prototype)) {\n let flow = this.currentFlow;\n let temp = flow.getTempLocal(actualType);\n let tempIndex = temp.index;\n // !(t = expr) ? 0 : anyinstanceof(t)\n return module.if(\n module.unary(\n sizeTypeRef == TypeRef.I64\n ? UnaryOp.EqzI64\n : UnaryOp.EqzI32,\n module.local_tee(tempIndex, expr, actualType.isManaged),\n ),\n module.i32(0),\n module.call(this.prepareAnyInstanceOf(prototype), [\n module.local_get(tempIndex, sizeTypeRef)\n ], TypeRef.I32)\n );\n }\n }\n\n // false\n return module.maybeDropCondition(expr, module.i32(0));\n }\n\n /** Prepares the instanceof helper for the given class or interface prototype. */\n private prepareAnyInstanceOf(prototype: ClassPrototype): string {\n let name = `~anyinstanceof|${prototype.internalName}`;\n let pending = this.pendingInstanceOf;\n if (pending.has(prototype)) return assert(pending.get(prototype));\n pending.set(prototype, name);\n let module = this.module;\n module.addFunction(name, this.options.sizeTypeRef, TypeRef.I32, null,\n module.unreachable()\n );\n return name;\n }\n\n /** Finalizes the instanceof helper of the given class prototype. */\n private finalizeAnyInstanceOf(prototype: ClassPrototype, name: string): void {\n let module = this.module;\n let sizeType = this.options.sizeTypeRef;\n let stmts = new Array();\n let instances = prototype.instances;\n // (block $is_instance\n // (local.set $1 (i32.load(...)))\n // (br_if $is_instance (i32.eq (local.get $1) (ID))\n // ...\n // (return (i32.const 0))\n // )\n // (i32.const 1)\n if (instances) {\n let program = this.program;\n stmts.push(\n module.local_set(1,\n module.load(4, false,\n module.binary(\n sizeType == TypeRef.I64\n ? BinaryOp.SubI64\n : BinaryOp.SubI32,\n module.local_get(0, sizeType),\n module.i32(\n program.totalOverhead - program.OBJECTInstance.offsetof(\"rtId\")\n )\n ),\n TypeRef.I32\n ), false // managedness is irrelevant here, isn't interrupted\n )\n );\n let allInstances = new Set();\n for (let _values = Map_values(instances), i = 0, k = _values.length; i < k; ++i) {\n let instance = _values[i];\n if (instance.isInterface) {\n let implementers = instance.implementers;\n if (implementers) {\n for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) {\n let implementer = _values[i];\n allInstances.add(implementer);\n }\n }\n } else {\n allInstances.add(instance);\n let extenders = instance.extenders;\n if (extenders) {\n for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) {\n let extender = _values[i];\n allInstances.add(extender);\n }\n }\n }\n }\n for (let _values = Set_values(allInstances), i = 0, k = _values.length; i < k; ++i) {\n let instance = _values[i];\n stmts.push(\n module.br(\"is_instance\",\n module.binary(BinaryOp.EqI32,\n module.local_get(1, TypeRef.I32),\n module.i32(instance.id)\n )\n )\n );\n }\n }\n stmts.push(\n module.return(\n module.i32(0)\n )\n );\n stmts[0] = module.block(\"is_instance\", stmts, TypeRef.None);\n stmts.length = 1;\n stmts.push(\n module.i32(1)\n );\n module.removeFunction(name);\n module.addFunction(name, sizeType, TypeRef.I32, [ TypeRef.I32 ], module.block(null, stmts, TypeRef.I32));\n }\n\n private compileLiteralExpression(\n expression: LiteralExpression,\n contextualType: Type,\n constraints: Constraints,\n implicitlyNegate: bool = false\n ): ExpressionRef {\n let module = this.module;\n switch (expression.literalKind) {\n case LiteralKind.Array: {\n assert(!implicitlyNegate);\n return this.compileArrayLiteral(\n expression,\n contextualType,\n constraints\n );\n }\n case LiteralKind.Float: {\n let floatValue = (expression).value;\n if (implicitlyNegate) {\n floatValue = -floatValue;\n }\n if (contextualType == Type.f32) {\n return module.f32(floatValue);\n }\n this.currentType = Type.f64;\n return module.f64(floatValue);\n }\n case LiteralKind.Integer: {\n let expr = expression;\n let type = this.resolver.determineIntegerLiteralType(expr, implicitlyNegate, contextualType);\n this.currentType = type;\n let intValue = expr.value;\n let sign = 1.0; // should multiply for float literals\n if (implicitlyNegate) {\n if (type.isFloatValue) {\n sign = -1.0;\n } else {\n intValue = i64_neg(intValue);\n }\n }\n switch (type.kind) {\n case TypeKind.Isize: if (!this.options.isWasm64) return module.i32(i64_low(intValue));\n case TypeKind.I64: return module.i64(i64_low(intValue), i64_high(intValue));\n case TypeKind.Usize: if (!this.options.isWasm64) return module.i32(i64_low(intValue));\n case TypeKind.U64: return module.i64(i64_low(intValue), i64_high(intValue));\n case TypeKind.F32: return module.f32(sign * i64_to_f32(intValue));\n case TypeKind.F64: return module.f64(sign * i64_to_f64(intValue));\n default: return module.i32(i64_low(intValue));\n }\n }\n case LiteralKind.String: {\n assert(!implicitlyNegate);\n return this.compileStringLiteral(expression, constraints);\n }\n case LiteralKind.Template: {\n assert(!implicitlyNegate);\n return this.compileTemplateLiteral(expression, constraints);\n }\n case LiteralKind.Object: {\n assert(!implicitlyNegate);\n return this.compileObjectLiteral(expression, contextualType);\n }\n case LiteralKind.RegExp: {\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range,\n \"Regular expressions\"\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n }\n assert(false);\n return module.unreachable();\n }\n\n private compileStringLiteral(\n expression: StringLiteralExpression,\n constraints: Constraints\n ): ExpressionRef {\n return this.ensureStaticString(expression.value);\n }\n\n private compileTemplateLiteral(\n expression: TemplateLiteralExpression,\n constraints: Constraints\n ): ExpressionRef {\n let tag = expression.tag;\n let parts = expression.parts;\n let numParts = parts.length;\n let expressions = expression.expressions;\n let numExpressions = expressions.length;\n assert(numExpressions == numParts - 1);\n\n let module = this.module;\n let stringInstance = this.program.stringInstance;\n let stringType = stringInstance.type;\n\n if (!tag) {\n // Shortcut if just a (multi-line) string\n if (numParts == 1) {\n return this.ensureStaticString(parts[0]);\n }\n\n // Shortcut for `${expr}`, `${expr}`, `${expr}`\n if (numParts == 2) {\n let expression = expressions[0];\n let lhsLen = parts[0].length;\n let rhsLen = parts[1].length;\n // Shortcut for `${expr}` -> expr.toString()\n if (!lhsLen && !rhsLen) {\n return this.makeToString(\n this.compileExpression(expression, stringType),\n this.currentType, expression\n );\n }\n // Shortcuts for\n // `${expr}` -> \"\" + expr.toString()\n // `${expr}` -> expr.toString() + \"\"\n let hasPrefix = lhsLen != 0;\n // @ts-ignore: cast\n if (hasPrefix ^ (rhsLen != 0)) {\n let lhs: ExpressionRef;\n let rhs: ExpressionRef;\n let expr = this.makeToString(\n this.compileExpression(expression, stringType),\n this.currentType, expression\n );\n if (hasPrefix) {\n lhs = this.ensureStaticString(parts[0]);\n rhs = expr;\n } else {\n // suffix\n lhs = expr;\n rhs = this.ensureStaticString(parts[1]);\n }\n let concatMethod = assert(stringInstance.getMethod(\"concat\"));\n return this.makeCallDirect(concatMethod, [ lhs, rhs ], expression);\n }\n }\n\n // Shortcut for `${exprA}${exprB}` -> exprA.toString() + exprB.toString()\n if (numParts == 3 && !parts[0].length && !parts[1].length && !parts[2].length) {\n let exprA = expressions[0];\n let exprB = expressions[1];\n\n let lhs = this.makeToString(\n this.compileExpression(exprA, stringType),\n this.currentType, exprA\n );\n let rhs = this.makeToString(\n this.compileExpression(exprB, stringType),\n this.currentType, exprB\n );\n let concatMethod = assert(stringInstance.getMethod(\"concat\"));\n return this.makeCallDirect(concatMethod, [ lhs, rhs ], expression);\n }\n\n // Compile to a `StaticArray#join(\"\") in the general case\n let expressionPositions = new Array(numExpressions);\n let values = new Array();\n if (parts[0].length > 0) values.push(this.ensureStaticString(parts[0]));\n for (let i = 1; i < numParts; ++i) {\n expressionPositions[i - 1] = values.length;\n values.push(module.usize(0));\n if (parts[i].length > 0) values.push(this.ensureStaticString(parts[i]));\n }\n let arrayInstance = assert(this.resolver.resolveClass(this.program.staticArrayPrototype, [ stringType ]));\n let segment = this.addStaticBuffer(stringType, values, arrayInstance.id);\n this.program.OBJECTInstance.writeField(\"gcInfo\", 3, segment.buffer, 0); // use transparent gcinfo\n let offset = i64_add(segment.offset, i64_new(this.program.totalOverhead));\n let joinInstance = assert(arrayInstance.getMethod(\"join\"));\n let indexedSetInstance = assert(arrayInstance.lookupOverload(OperatorKind.IndexedSet, true));\n let stmts = new Array(2 * numExpressions + 1);\n // Use one local per toString'ed subexpression, since otherwise recursion on the same\n // static array would overwrite already prepared parts. Avoids a temporary array.\n let temps = new Array(numExpressions);\n let flow = this.currentFlow;\n for (let i = 0; i < numExpressions; ++i) {\n let expression = expressions[i];\n let temp = flow.getTempLocal(stringType);\n temps[i] = temp;\n stmts[i] = module.local_set(temp.index,\n this.makeToString(\n this.compileExpression(expression, stringType),\n this.currentType, expression\n ),\n true\n );\n }\n // Populate the static array with the toString'ed subexpressions and call .join(\"\")\n for (let i = 0; i < numExpressions; ++i) {\n stmts[numExpressions + i] = this.makeCallDirect(indexedSetInstance, [\n module.usize(offset),\n module.i32(expressionPositions[i]),\n module.local_get(temps[i].index, stringType.toRef())\n ], expression);\n }\n stmts[2 * numExpressions] = this.makeCallDirect(joinInstance, [\n module.usize(offset),\n this.ensureStaticString(\"\")\n ], expression);\n return module.flatten(stmts, stringType.toRef());\n }\n\n // Try to find out whether the template function takes a full-blown TemplateStringsArray or if\n // it is sufficient to compile to a normal array. While technically incorrect, this allows us\n // to avoid generating unnecessary static data that is not explicitly signaled to be used.\n let tsaArrayInstance = this.program.templateStringsArrayInstance;\n let arrayInstance = tsaArrayInstance;\n let target = this.resolver.lookupExpression(tag, this.currentFlow, Type.auto, ReportMode.Swallow);\n if (target) {\n switch (target.kind) {\n case ElementKind.FunctionPrototype: {\n let instance = this.resolver.resolveFunction(\n target,\n null,\n new Map(),\n ReportMode.Swallow\n );\n if (!instance) break;\n target = instance;\n // fall-through\n }\n case ElementKind.Function: {\n let instance = target;\n let parameterTypes = instance.signature.parameterTypes;\n if (parameterTypes.length) {\n let first = parameterTypes[0].getClass();\n if (first && !first.extendsPrototype(tsaArrayInstance.prototype)) {\n arrayInstance = assert(this.resolver.resolveClass(this.program.arrayPrototype, [ stringType ]));\n }\n }\n break;\n }\n }\n }\n\n // Compile to a call to the tag function\n let rawParts = expression.rawParts;\n assert(rawParts.length == numParts);\n let partExprs = new Array(numParts);\n for (let i = 0; i < numParts; ++i) {\n partExprs[i] = this.ensureStaticString(parts[i]);\n }\n let arraySegment: MemorySegment;\n if (arrayInstance == tsaArrayInstance) {\n let rawExprs = new Array(numParts);\n for (let i = 0; i < numParts; ++i) {\n rawExprs[i] = this.ensureStaticString(rawParts[i]);\n }\n arraySegment = this.addStaticArrayHeader(stringType,\n this.addStaticBuffer(this.options.usizeType, partExprs),\n arrayInstance\n );\n let rawHeaderSegment = this.addStaticArrayHeader(stringType,\n this.addStaticBuffer(this.options.usizeType, rawExprs)\n );\n arrayInstance.writeField(\"raw\",\n i64_add(rawHeaderSegment.offset, i64_new(this.program.totalOverhead)),\n arraySegment.buffer\n );\n } else {\n arraySegment = this.addStaticArrayHeader(stringType,\n this.addStaticBuffer(this.options.usizeType, partExprs),\n arrayInstance\n );\n }\n\n // Desugar to compileCallExpression\n let args = expressions.slice();\n args.unshift(\n Node.createCompiledExpression(\n module.usize(i64_add(arraySegment.offset, i64_new(this.program.totalOverhead))),\n arrayInstance.type,\n Source.native.range\n )\n );\n // TODO: Requires ReadonlyArray to be safe\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range, \"Tagged template literals\"\n );\n return this.compileCallExpressionLike(tag, null, args, expression.range, stringType);\n }\n\n private compileArrayLiteral(\n expression: ArrayLiteralExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n let program = this.program;\n\n // handle static arrays\n let contextualClass = contextualType.getClass();\n if (contextualClass && contextualClass.extendsPrototype(program.staticArrayPrototype)) {\n return this.compileStaticArrayLiteral(expression, contextualType, constraints);\n }\n\n // handle normal arrays\n let element = this.resolver.lookupExpression(expression, flow, this.currentType);\n if (!element) return module.unreachable();\n assert(element.kind == ElementKind.Class);\n let arrayInstance = element;\n let arrayType = arrayInstance.type;\n let elementType = arrayInstance.getTypeArgumentsTo(program.arrayPrototype)![0];\n let arrayBufferInstance = assert(program.arrayBufferInstance);\n\n // block those here so compiling expressions doesn't conflict\n let tempThis = flow.getTempLocal(this.options.usizeType);\n let tempDataStart = flow.getTempLocal(arrayBufferInstance.type);\n\n // compile value expressions and find out whether all are constant\n let expressions = expression.elementExpressions;\n let length = expressions.length;\n let values = new Array(length);\n let isStatic = !elementType.isExternalReference;\n for (let i = 0; i < length; ++i) {\n let elementExpression = expressions[i];\n if (elementExpression.kind != NodeKind.Omitted) {\n let expr = this.compileExpression(elementExpression, elementType, Constraints.ConvImplicit);\n if (getExpressionType(expr) != elementType.toRef()) {\n isStatic = false;\n } else {\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n expr = precomp;\n } else {\n isStatic = false;\n }\n }\n values[i] = expr;\n } else {\n values[i] = this.makeZero(elementType);\n }\n }\n\n // if the array is static, make a static arraybuffer segment\n if (isStatic) {\n let totalOverhead = program.totalOverhead;\n let bufferSegment = this.addStaticBuffer(elementType, values);\n let bufferAddress = i64_add(bufferSegment.offset, i64_new(totalOverhead));\n\n // make both the buffer and array header static if assigned to a global. this can't be done\n // if inside of a function because each invocation must create a new array reference then.\n if (constraints & Constraints.PreferStatic) {\n let arraySegment = this.addStaticArrayHeader(elementType, bufferSegment);\n let arrayAddress = i64_add(arraySegment.offset, i64_new(totalOverhead));\n this.currentType = arrayType;\n return program.options.isWasm64\n ? this.module.i64(i64_low(arrayAddress), i64_high(arrayAddress))\n : this.module.i32(i64_low(arrayAddress));\n\n // otherwise allocate a new array header and make it wrap a copy of the static buffer\n } else {\n return this.makeNewArray(arrayInstance, length, bufferAddress, expression);\n }\n }\n\n // otherwise compile an explicit instantiation with indexed sets\n let indexedSet = arrayInstance.lookupOverload(OperatorKind.IndexedSet, true);\n if (!indexedSet) {\n this.error(\n DiagnosticCode.Index_signature_in_type_0_only_permits_reading,\n expression.range, arrayInstance.internalName\n );\n this.currentType = arrayType;\n return module.unreachable();\n }\n let arrayTypeRef = arrayType.toRef();\n\n let stmts = new Array();\n // tempThis = __newArray(length, alignLog2, classId, source = 0)\n stmts.push(\n module.local_set(tempThis.index,\n this.makeNewArray(arrayInstance, length, i64_new(0), expression),\n arrayType.isManaged\n )\n );\n // tempData = tempThis.dataStart\n let dataStartMember = assert(arrayInstance.getMember(\"dataStart\"));\n assert(dataStartMember.kind == ElementKind.PropertyPrototype);\n // is a field, so should have been resolved during class finalization\n let dataStartProperty = (dataStartMember).instance;\n if (!dataStartProperty) return module.unreachable();\n assert(dataStartProperty.isField && dataStartProperty.memoryOffset >= 0);\n stmts.push(\n module.local_set(tempDataStart.index,\n module.load(arrayType.byteSize, false,\n module.local_get(tempThis.index, arrayTypeRef),\n arrayTypeRef,\n dataStartProperty.memoryOffset\n ),\n true // ArrayBuffer\n )\n );\n for (let i = 0; i < length; ++i) {\n // this[i] = value\n stmts.push(\n module.call(indexedSet.internalName, [\n module.local_get(tempThis.index, arrayTypeRef),\n module.i32(i),\n values[i]\n ], TypeRef.None)\n );\n }\n // -> tempThis\n stmts.push(\n module.local_get(tempThis.index, arrayTypeRef)\n );\n if (length) this.compileFunction(indexedSet);\n this.currentType = arrayType;\n return module.flatten(stmts, arrayTypeRef);\n }\n\n /** Makes a new array instance from a static buffer segment. */\n private makeNewArray(\n /** Concrete array class. */\n arrayInstance: Class,\n /** Length of the array. */\n length: i32,\n /** Source address to copy from. Array is zeroed if `0`. */\n source: i64,\n /** Report node. */\n reportNode: Node\n ): ExpressionRef {\n let program = this.program;\n let module = this.module;\n assert(!arrayInstance.extendsPrototype(program.staticArrayPrototype));\n let elementType = arrayInstance.getArrayValueType(); // asserts\n\n // __newArray(length, alignLog2, classId, staticBuffer)\n let expr = this.makeCallDirect(program.newArrayInstance, [\n module.i32(length),\n program.options.isWasm64\n ? module.i64(elementType.alignLog2)\n : module.i32(elementType.alignLog2),\n module.i32(arrayInstance.id),\n program.options.isWasm64\n ? module.i64(i64_low(source), i64_high(source))\n : module.i32(i64_low(source))\n ], reportNode);\n this.currentType = arrayInstance.type;\n return expr;\n }\n\n /** Compiles a special `fixed` array literal. */\n private compileStaticArrayLiteral(\n expression: ArrayLiteralExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n let program = this.program;\n\n // make sure this method is only called with a valid contextualType\n let arrayInstance = assert(contextualType.getClass());\n let arrayType = arrayInstance.type;\n let typeArguments = assert(arrayInstance.getTypeArgumentsTo(program.staticArrayPrototype));\n let elementType = typeArguments[0];\n\n // block those here so compiling expressions doesn't conflict\n let tempThis = flow.getTempLocal(this.options.usizeType);\n\n // compile value expressions and check if all are compile-time constants\n let expressions = expression.elementExpressions;\n let length = expressions.length;\n let values = new Array(length);\n let isStatic = !elementType.isExternalReference;\n for (let i = 0; i < length; ++i) {\n let elementExpression = expressions[i];\n if (elementExpression.kind != NodeKind.Omitted) {\n let expr = this.compileExpression(elementExpression, elementType, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n expr = precomp;\n } else {\n isStatic = false;\n }\n values[i] = expr;\n } else {\n values[i] = this.makeZero(elementType);\n }\n }\n\n let isWasm64 = this.options.isWasm64;\n let bufferSize = values.length << elementType.alignLog2;\n\n // if the array is static, make a static arraybuffer segment\n if (isStatic) {\n let bufferSegment = this.addStaticBuffer(elementType, values, arrayInstance.id);\n let bufferAddress = i64_add(bufferSegment.offset, i64_new(program.totalOverhead));\n\n // return the static buffer directly if assigned to a global\n if (constraints & Constraints.PreferStatic) {\n let expr = this.options.isWasm64\n ? module.i64(i64_low(bufferAddress), i64_high(bufferAddress))\n : module.i32(i64_low(bufferAddress));\n this.currentType = arrayType;\n return expr;\n\n // otherwise allocate a new chunk of memory and return a copy of the buffer\n } else {\n // __newBuffer(bufferSize, id, buffer)\n let expr = this.makeCallDirect(program.newBufferInstance, [\n isWasm64\n ? module.i64(bufferSize)\n : module.i32(bufferSize),\n module.i32(arrayInstance.id),\n isWasm64\n ? module.i64(i64_low(bufferAddress), i64_high(bufferAddress))\n : module.i32(i64_low(bufferAddress))\n ], expression);\n this.currentType = arrayType;\n return expr;\n }\n }\n\n // otherwise compile an explicit instantiation with indexed sets\n let indexedSet = arrayInstance.lookupOverload(OperatorKind.IndexedSet, true);\n if (!indexedSet) {\n this.error(\n DiagnosticCode.Index_signature_in_type_0_only_permits_reading,\n expression.range, arrayInstance.internalName\n );\n this.currentType = arrayType;\n return module.unreachable();\n }\n let arrayTypeRef = arrayType.toRef();\n\n let stmts = new Array();\n // tempThis = __newBuffer(bufferSize, classId)\n stmts.push(\n module.local_set(tempThis.index,\n this.makeCallDirect(program.newBufferInstance, [\n isWasm64\n ? module.i64(bufferSize)\n : module.i32(bufferSize),\n module.i32(arrayInstance.id)\n ], expression),\n arrayType.isManaged\n )\n );\n for (let i = 0; i < length; ++i) {\n // array[i] = value\n stmts.push(\n module.call(indexedSet.internalName, [\n module.local_get(tempThis.index, arrayTypeRef),\n module.i32(i),\n values[i]\n ], TypeRef.None)\n );\n }\n // -> tempThis\n stmts.push(\n module.local_get(tempThis.index, arrayTypeRef)\n );\n if (length) this.compileFunction(indexedSet);\n this.currentType = arrayType;\n return module.flatten(stmts, arrayTypeRef);\n }\n\n private compileObjectLiteral(expression: ObjectLiteralExpression, contextualType: Type): ExpressionRef {\n let module = this.module;\n\n // Check that contextual type is a class (TODO: hidden class for interfaces?)\n let classReference = contextualType.getClass();\n if (!classReference) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n expression.range, \"\", contextualType.toString()\n );\n return module.unreachable();\n }\n let classType = classReference.type;\n this.currentType = classType.nonNullableType;\n if (classReference.kind == ElementKind.Interface) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range, \"Interface hidden classes\"\n );\n return module.unreachable();\n }\n if (classReference.is(CommonFlags.Abstract)) {\n this.error(\n DiagnosticCode.Cannot_create_an_instance_of_an_abstract_class,\n expression.range\n );\n return module.unreachable();\n }\n\n // Check that the class is compatible with object literals\n let ctorPrototype = classReference.prototype.constructorPrototype;\n if (ctorPrototype) {\n this.errorRelated(\n DiagnosticCode.Class_0_cannot_declare_a_constructor_when_instantiated_from_an_object_literal,\n expression.range, ctorPrototype.identifierNode.range, classType.toString()\n );\n return module.unreachable();\n }\n\n let isManaged = classType.isManaged;\n if (!isManaged) {\n this.checkUnsafe(expression, findDecorator(DecoratorKind.Unmanaged, classReference.decoratorNodes));\n }\n\n // check and compile field values\n let names = expression.names;\n let numNames = names.length;\n let values = expression.values;\n let members = classReference.members;\n let hasErrors = false;\n let exprs = new Array();\n let flow = this.currentFlow;\n let tempLocal = flow.getTempLocal(classType);\n let classTypeRef = classType.toRef();\n assert(numNames == values.length);\n\n // Assume all class fields will be omitted, and add them to our omitted list\n let omittedFields = new Set();\n if (members) {\n for (let _keys = Map_keys(members), i = 0, k = _keys.length; i < k; ++i) {\n let memberKey = _keys[i];\n let member = assert(members.get(memberKey));\n if (member && member.kind == ElementKind.PropertyPrototype) {\n // only interested in fields (resolved during class finalization)\n let property = (member).instance;\n if (property && property.isField) {\n omittedFields.add(property); // incl. private/protected\n }\n }\n }\n }\n\n // Iterate through the members defined in our expression\n let deferredProperties = new Array();\n for (let i = 0; i < numNames; ++i) {\n let memberName = names[i].text;\n let member = classReference.getMember(memberName);\n if (!member || member.kind != ElementKind.PropertyPrototype) {\n this.error(\n DiagnosticCode.Property_0_does_not_exist_on_type_1,\n names[i].range, memberName, classType.toString()\n );\n hasErrors = true;\n continue;\n }\n if (member.is(CommonFlags.Private)) {\n this.error(\n DiagnosticCode.Property_0_is_private_and_only_accessible_within_class_1,\n names[i].range, memberName, classType.toString()\n );\n hasErrors = true;\n continue;\n }\n if (member.is(CommonFlags.Protected)) {\n this.error(\n DiagnosticCode.Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses,\n names[i].range, memberName, classType.toString()\n );\n hasErrors = true;\n continue;\n }\n let propertyInstance = this.resolver.resolveProperty(member);\n if (!propertyInstance) continue;\n let setterInstance = propertyInstance.setterInstance;\n if (!setterInstance) {\n this.error(\n DiagnosticCode.Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property,\n names[i].range, memberName, classType.toString()\n );\n hasErrors = true;\n continue;\n }\n\n // This member is no longer omitted, so delete from our omitted fields\n omittedFields.delete(propertyInstance);\n\n // Defer real properties to be set after fields are initialized\n if (!propertyInstance.isField) {\n deferredProperties.push(propertyInstance);\n continue;\n }\n\n let propertyType = propertyInstance.type;\n let expr = this.makeCallDirect(setterInstance, [\n module.local_get(tempLocal.index, classTypeRef),\n this.compileExpression(values[i], propertyType, Constraints.ConvImplicit),\n ], setterInstance.identifierNode, true);\n if (this.currentType != Type.void) { // in case\n expr = module.drop(expr);\n }\n exprs.push(expr);\n }\n\n // Call deferred real property setters after\n for (let i = 0, k = deferredProperties.length; i < k; ++i) {\n let propertyInstance = deferredProperties[i];\n let setterInstance = assert(propertyInstance.setterInstance);\n exprs.push(\n this.makeCallDirect(setterInstance, [\n module.local_get(tempLocal.index, classTypeRef),\n this.compileExpression(values[i], propertyInstance.type, Constraints.ConvImplicit)\n ], setterInstance.identifierNode)\n );\n }\n\n this.currentType = classType.nonNullableType;\n if (hasErrors) return module.unreachable();\n\n // Check remaining omitted fields\n for (let _values = Set_values(omittedFields), j = 0, l = _values.length; j < l; ++j) {\n let propertyInstance = _values[j];\n assert(propertyInstance.isField);\n let propertyType = propertyInstance.type;\n\n if (propertyInstance.initializerNode) {\n continue; // set by generated ctor\n }\n\n if (propertyType.isReference) {\n if (!propertyType.isNullableReference) {\n this.error(\n DiagnosticCode.Property_0_is_missing_in_type_1_but_required_in_type_2,\n expression.range, propertyInstance.name, \"\", classType.toString()\n );\n hasErrors = true;\n continue;\n }\n }\n\n switch (propertyType.kind) {\n // Number Types (and Number alias types)\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize:\n case TypeKind.F32:\n case TypeKind.F64: {\n // Can store zeroes directly (no need to __link)\n exprs.push(\n module.store(\n propertyType.byteSize,\n module.local_get(tempLocal.index, classTypeRef),\n this.makeZero(propertyType),\n propertyType.toRef(),\n propertyInstance.memoryOffset\n )\n );\n continue;\n }\n }\n\n // Otherwise error\n this.error(\n DiagnosticCode.Property_0_is_missing_in_type_1_but_required_in_type_2,\n expression.range, propertyInstance.name, \"\", classType.toString()\n );\n hasErrors = true;\n }\n if (hasErrors) return module.unreachable();\n\n // generate the default constructor\n let ctor = this.ensureConstructor(classReference, expression);\n // note that this is not checking field initialization within the ctor, but\n // instead checks conditions above with provided fields taken into account.\n\n // allocate a new instance first and assign 'this' to the temp. local\n exprs.unshift(\n module.local_set(tempLocal.index,\n this.compileInstantiate(ctor, [], Constraints.None, expression),\n classType.isManaged\n )\n );\n\n // once all field values have been set, return 'this'\n exprs.push(\n module.local_get(tempLocal.index, classTypeRef)\n );\n\n this.currentType = classType.nonNullableType;\n return module.flatten(exprs, classTypeRef);\n }\n\n private compileNewExpression(\n expression: NewExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n\n // obtain the class being instantiated\n let target = this.resolver.resolveTypeName(expression.typeName, flow.sourceFunction);\n if (!target) return module.unreachable();\n if (target.kind != ElementKind.ClassPrototype) {\n this.error(\n DiagnosticCode.This_expression_is_not_constructable,\n expression.typeName.range\n );\n return this.module.unreachable();\n }\n if (target.is(CommonFlags.Abstract)) {\n this.error(\n DiagnosticCode.Cannot_create_an_instance_of_an_abstract_class,\n expression.typeName.range\n );\n return this.module.unreachable();\n }\n let classPrototype = target;\n let classInstance: Class | null = null;\n let typeArguments = expression.typeArguments;\n let classReference: Class | null;\n if (\n !typeArguments &&\n (classReference = contextualType.classReference) &&\n classReference.prototype == classPrototype &&\n classReference.is(CommonFlags.Generic)\n ) {\n // e.g. `arr: Array = new Array()`\n classInstance = this.resolver.resolveClass(\n classPrototype,\n classReference.typeArguments,\n cloneMap(flow.contextualTypeArguments)\n );\n } else {\n classInstance = this.resolver.resolveClassInclTypeArguments(\n classPrototype,\n typeArguments,\n flow.sourceFunction.parent, // relative to caller\n cloneMap(flow.contextualTypeArguments),\n expression\n );\n }\n if (!classInstance) return module.unreachable();\n if (contextualType == Type.void) constraints |= Constraints.WillDrop;\n let ctor = this.ensureConstructor(classInstance, expression);\n if (!ctor.hasDecorator(DecoratorFlags.Inline)) {\n // Inlined ctors haven't been compiled yet and are checked upon inline\n // compilation of their body instead.\n this.checkFieldInitialization(classInstance, expression);\n }\n return this.compileInstantiate(ctor, expression.args, constraints, expression);\n }\n\n /** Gets the compiled constructor of the specified class or generates one if none is present. */\n ensureConstructor(\n /** Class wanting a constructor. */\n classInstance: Class,\n /** Report node. */\n reportNode: Node\n ): Function {\n let instance = classInstance.constructorInstance;\n if (instance) {\n // shortcut if already compiled\n if (instance.is(CommonFlags.Compiled)) return instance;\n // do not attempt to compile if inlined anyway\n if (!instance.hasDecorator(DecoratorFlags.Inline)) this.compileFunction(instance);\n } else {\n // clone base constructor if a derived class. note that we cannot just\n // call the base ctor since the derived class may have additional fields.\n let baseClass = classInstance.base;\n let contextualTypeArguments = cloneMap(classInstance.contextualTypeArguments);\n if (baseClass) {\n let baseCtor = this.ensureConstructor(baseClass, reportNode);\n this.checkFieldInitialization(baseClass, reportNode);\n instance = new Function(\n CommonNames.constructor,\n new FunctionPrototype(\n CommonNames.constructor,\n classInstance,\n // declaration is important, i.e. to access optional parameter initializers\n (baseCtor.declaration).clone()\n ),\n null,\n Signature.create(\n this.program,\n baseCtor.signature.parameterTypes,\n classInstance.type,\n classInstance.type,\n baseCtor.signature.requiredParameters,\n baseCtor.signature.hasRest\n ),\n contextualTypeArguments\n );\n\n // otherwise make a default constructor\n } else {\n instance = new Function(\n CommonNames.constructor,\n new FunctionPrototype(\n CommonNames.constructor,\n classInstance, // bound\n this.program.makeNativeFunctionDeclaration(CommonNames.constructor,\n CommonFlags.Instance | CommonFlags.Constructor\n )\n ),\n null,\n Signature.create(this.program, [], classInstance.type, classInstance.type),\n contextualTypeArguments\n );\n }\n\n instance.set(CommonFlags.Compiled);\n instance.prototype.setResolvedInstance(\"\", instance);\n if (classInstance.is(CommonFlags.ModuleExport)) {\n instance.set(CommonFlags.ModuleExport);\n }\n classInstance.constructorInstance = instance;\n let members = classInstance.members;\n if (!members) classInstance.members = members = new Map();\n members.set(\"constructor\", instance.prototype);\n\n let previousFlow = this.currentFlow;\n let flow = instance.flow;\n this.currentFlow = flow;\n\n // generate body\n let signature = instance.signature;\n let module = this.module;\n let sizeTypeRef = this.options.sizeTypeRef;\n let stmts = new Array();\n\n // {\n // this = \n // IF_DERIVED: this = super(this, ...args)\n // this.a = X\n // this.b = Y\n // return this\n // }\n stmts.push(\n this.makeConditionalAllocation(classInstance, 0)\n );\n if (baseClass) {\n let parameterTypes = signature.parameterTypes;\n let numParameters = parameterTypes.length;\n let operands = new Array(1 + numParameters);\n operands[0] = module.local_get(0, sizeTypeRef);\n for (let i = 1; i <= numParameters; ++i) {\n operands[i] = module.local_get(i, parameterTypes[i - 1].toRef());\n }\n stmts.push(\n module.local_set(0,\n this.makeCallDirect(assert(baseClass.constructorInstance), operands, reportNode, false),\n baseClass.type.isManaged\n )\n );\n }\n this.makeFieldInitializationInConstructor(classInstance, stmts);\n stmts.push(\n module.local_get(0, sizeTypeRef)\n );\n this.currentFlow = previousFlow;\n\n // make the function\n let locals = instance.localsByIndex;\n let varTypes = new Array(); // of temp. vars added while compiling initializers\n let numOperands = 1 + signature.parameterTypes.length;\n let numLocals = locals.length;\n if (numLocals > numOperands) {\n for (let i = numOperands; i < numLocals; ++i) varTypes.push(locals[i].type.toRef());\n }\n let funcRef = module.addFunction(\n instance.internalName,\n signature.paramRefs,\n signature.resultRefs,\n varTypes,\n module.flatten(stmts, sizeTypeRef)\n );\n instance.finalize(module, funcRef);\n }\n\n return instance;\n }\n\n /** Checks that all class fields have been initialized. */\n checkFieldInitialization(classInstance: Class, relatedNode: Node | null = null): void {\n if (classInstance.didCheckFieldInitialization) return;\n classInstance.didCheckFieldInitialization = true;\n let ctor = assert(classInstance.constructorInstance);\n this.checkFieldInitializationInFlow(classInstance, ctor.flow, relatedNode);\n }\n\n /** Checks that all class fields have been initialized in the specified flow. */\n checkFieldInitializationInFlow(classInstance: Class, flow: Flow, relatedNode: Node | null = null): void {\n let members = classInstance.members;\n if (members) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let element = _values[i];\n if (element.kind != ElementKind.PropertyPrototype || element.parent != classInstance) continue;\n // only interested in fields (resolved during class finalization)\n let property = (element).instance;\n if (!property || !property.isField) continue;\n if (!property.initializerNode && !flow.isThisFieldFlag(property, FieldFlags.Initialized)) {\n if (!property.is(CommonFlags.DefinitelyAssigned)) {\n if (relatedNode) {\n this.errorRelated(\n DiagnosticCode.Property_0_has_no_initializer_and_is_not_assigned_in_the_constructor_before_this_is_used_or_returned,\n property.declaration.name.range,\n relatedNode.range,\n property.internalName\n );\n } else {\n this.error(\n DiagnosticCode.Property_0_has_no_initializer_and_is_not_assigned_in_the_constructor_before_this_is_used_or_returned,\n property.declaration.name.range,\n property.internalName\n );\n }\n }\n } else if (property.is(CommonFlags.DefinitelyAssigned)) {\n if (property.type.isReference) {\n this.warning( // involves a runtime check\n DiagnosticCode.Property_0_is_always_assigned_before_being_used,\n property.identifierNode.range,\n property.internalName\n );\n } else {\n this.pedantic( // is a nop anyway\n DiagnosticCode.Unnecessary_definite_assignment,\n property.identifierNode.range\n );\n }\n }\n }\n }\n }\n\n compileInstantiate(\n /** Constructor to call. */\n ctorInstance: Function,\n /** Constructor arguments. */\n argumentExpressions: Expression[],\n /** Contextual flags. */\n constraints: Constraints,\n /** Node to report on. */\n reportNode: Node\n ): ExpressionRef {\n assert(ctorInstance.is(CommonFlags.Constructor));\n let parent = ctorInstance.parent;\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n if (classInstance.type.isUnmanaged || ctorInstance.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(reportNode);\n let expr = this.compileCallDirect(\n ctorInstance,\n argumentExpressions,\n reportNode,\n this.makeZero(this.options.usizeType),\n constraints\n );\n if (getExpressionType(expr) != TypeRef.None) { // possibly WILL_DROP\n this.currentType = classInstance.type; // important because a super ctor could be called\n }\n return expr;\n }\n\n private compilePropertyAccessExpression(\n expression: PropertyAccessExpression,\n ctxType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n\n this.maybeCompileEnclosingSource(expression);\n\n let resolver = this.resolver;\n let target = resolver.lookupExpression(expression, flow, ctxType); // reports\n if (!target) return module.unreachable();\n let thisExpression = resolver.currentThisExpression;\n if (target.hasDecorator(DecoratorFlags.Unsafe)) this.checkUnsafe(expression);\n\n switch (target.kind) {\n case ElementKind.Global: { // static field\n let global = target;\n if (!this.compileGlobalLazy(global, expression)) {\n return module.unreachable();\n }\n let globalType = global.type;\n assert(globalType != Type.void);\n if (this.pendingElements.has(global)) {\n this.error(\n DiagnosticCode.Variable_0_used_before_its_declaration,\n expression.range,\n global.internalName\n );\n this.currentType = globalType;\n return module.unreachable();\n }\n if (global.is(CommonFlags.Inlined)) {\n return this.compileInlineConstant(global, ctxType, constraints);\n }\n let expr = module.global_get(global.internalName, globalType.toRef());\n if (global.is(CommonFlags.DefinitelyAssigned) && globalType.isReference && !globalType.isNullableReference) {\n expr = this.makeRuntimeNonNullCheck(expr, globalType, expression);\n }\n this.currentType = globalType;\n return expr;\n }\n case ElementKind.EnumValue: { // enum value\n let enumValue = target;\n let parent = assert(enumValue.parent);\n assert(parent.kind == ElementKind.Enum);\n let parentEnum = parent;\n if (!this.compileEnum(parentEnum)) {\n this.currentType = Type.i32;\n return this.module.unreachable();\n }\n this.currentType = Type.i32;\n if (enumValue.is(CommonFlags.Inlined)) {\n assert(enumValue.constantValueKind == ConstantValueKind.Integer);\n return this.compileInlineConstant(enumValue, ctxType, constraints);\n }\n assert(enumValue.type == Type.i32);\n return module.global_get(enumValue.internalName, TypeRef.I32);\n }\n case ElementKind.PropertyPrototype: {\n let propertyPrototype = target;\n let propertyInstance = this.resolver.resolveProperty(propertyPrototype);\n if (!propertyInstance) return module.unreachable();\n target = propertyInstance;\n // fall-through\n }\n case ElementKind.Property: {\n let propertyInstance = target;\n if (propertyInstance.isField) {\n if (\n flow.sourceFunction.is(CommonFlags.Constructor) &&\n assert(thisExpression).kind == NodeKind.This &&\n !flow.isThisFieldFlag(propertyInstance, FieldFlags.Initialized) &&\n !propertyInstance.is(CommonFlags.DefinitelyAssigned)\n ) {\n this.errorRelated(\n DiagnosticCode.Property_0_is_used_before_being_assigned,\n expression.range,\n propertyInstance.identifierNode.range,\n propertyInstance.internalName\n );\n }\n }\n let getterInstance = propertyInstance.getterInstance;\n if (!getterInstance) return module.unreachable(); // failed earlier\n let thisArg: ExpressionRef = 0;\n if (getterInstance.is(CommonFlags.Instance)) {\n thisArg = this.compileExpression(\n assert(thisExpression),\n assert(getterInstance.signature.thisType),\n Constraints.ConvImplicit | Constraints.IsThis\n );\n }\n return this.compileCallDirect(getterInstance, [], expression, thisArg);\n }\n case ElementKind.FunctionPrototype: {\n let functionPrototype = target;\n let functionInstance = this.resolver.resolveFunction(functionPrototype, null);\n if (!functionInstance) return module.unreachable();\n if (!this.compileFunction(functionInstance)) return module.unreachable();\n this.currentType = functionInstance.type;\n let offset = this.ensureRuntimeFunction(functionInstance);\n return this.options.isWasm64\n ? module.i64(i64_low(offset), i64_high(offset))\n : module.i32(i64_low(offset));\n }\n }\n this.error(\n DiagnosticCode.Expression_does_not_compile_to_a_value_at_runtime,\n expression.range\n );\n return this.module.unreachable();\n }\n\n private compileTernaryExpression(\n expression: TernaryExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let ifThen = expression.ifThen;\n let ifElse = expression.ifElse;\n\n let condExpr = this.compileExpression(expression.condition, Type.bool);\n let condExprTrueish = this.makeIsTrueish(condExpr, this.currentType, expression.condition);\n // Try to eliminate unnecesssary branches if the condition is constant\n // FIXME: skips common denominator, inconsistently picking branch type\n let condKind = this.evaluateCondition(condExprTrueish);\n if (condKind == ConditionKind.True) {\n return module.maybeDropCondition(condExprTrueish, this.compileExpression(ifThen, contextualType));\n }\n if (condKind == ConditionKind.False) {\n return module.maybeDropCondition(condExprTrueish, this.compileExpression(ifElse, contextualType));\n }\n\n let outerFlow = this.currentFlow;\n let ifThenFlow = outerFlow.forkThen(condExpr);\n this.currentFlow = ifThenFlow;\n let ifThenExpr = this.compileExpression(ifThen, contextualType);\n let ifThenType = this.currentType;\n\n let ifElseFlow = outerFlow.forkElse(condExpr);\n this.currentFlow = ifElseFlow;\n let ifElseExpr = this.compileExpression(ifElse, contextualType == Type.auto ? ifThenType : contextualType);\n let ifElseType = this.currentType;\n\n if (contextualType == Type.void) { // values, including type mismatch, are irrelevant\n if (ifThenType != Type.void) {\n ifThenExpr = module.drop(ifThenExpr);\n ifThenType = Type.void;\n }\n if (ifElseType != Type.void) {\n ifElseExpr = module.drop(ifElseExpr);\n ifElseType = Type.void;\n }\n this.currentType = Type.void;\n } else {\n let commonType = Type.commonType(ifThenType, ifElseType, contextualType);\n if (!commonType) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n ifElse.range, ifElseType.toString(), ifThenType.toString()\n );\n this.currentType = contextualType;\n return module.unreachable();\n }\n ifThenExpr = this.convertExpression(ifThenExpr, ifThenType, commonType, false, ifThen);\n ifThenType = commonType;\n ifElseExpr = this.convertExpression(ifElseExpr, ifElseType, commonType, false, ifElse);\n ifElseType = commonType;\n this.currentType = commonType;\n }\n\n outerFlow.inheritAlternatives(ifThenFlow, ifElseFlow);\n this.currentFlow = outerFlow;\n\n return module.if(condExprTrueish, ifThenExpr, ifElseExpr);\n }\n\n private compileUnaryPostfixExpression(\n expression: UnaryPostfixExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n\n // make a getter for the expression (also obtains the type)\n let getValue = this.compileExpression( // reports\n expression.operand,\n contextualType.exceptVoid,\n Constraints.None\n );\n\n // if the value isn't dropped, a temp. local is required to remember the original value,\n // except if a static overload is found, which reverses the use of a temp. (see below)\n let tempLocal: Local | null = null;\n if (contextualType != Type.void) {\n tempLocal = flow.getTempLocal(this.currentType);\n getValue = module.local_tee(\n tempLocal.index,\n getValue,\n this.currentType.isManaged\n );\n }\n\n let expr: ExpressionRef;\n\n switch (expression.operator) {\n case Token.Plus_Plus: {\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.PostfixInc);\n if (overload) {\n let isInstance = overload.is(CommonFlags.Instance);\n if (tempLocal && !isInstance) { // revert: static overload simply returns\n getValue = getLocalSetValue(getValue);\n tempLocal = null;\n }\n expr = this.compileUnaryOverload(overload, expression.operand, getValue, expression);\n if (isInstance) break;\n return expr; // here\n }\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"++\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n switch (this.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n expr = module.binary(\n BinaryOp.AddI32,\n getValue,\n module.i32(1)\n );\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n expr = module.binary(\n BinaryOp.AddI64,\n getValue,\n module.i64(1)\n );\n break;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n expr = module.binary(\n BinaryOp.AddSize,\n getValue,\n this.makeOne(this.currentType)\n );\n break;\n }\n case TypeKind.F32: {\n expr = module.binary(\n BinaryOp.AddF32,\n getValue,\n module.f32(1)\n );\n break;\n }\n case TypeKind.F64: {\n expr = module.binary(\n BinaryOp.AddF64,\n getValue,\n module.f64(1)\n );\n break;\n }\n default: {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"++\", this.currentType.toString()\n );\n return module.unreachable();\n }\n }\n break;\n }\n case Token.Minus_Minus: {\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.PostfixDec);\n if (overload) {\n let isInstance = overload.is(CommonFlags.Instance);\n if (tempLocal && !isInstance) { // revert: static overload simply returns\n getValue = getLocalSetValue(getValue);\n tempLocal = null;\n }\n expr = this.compileUnaryOverload(overload, expression.operand, getValue, expression);\n if (overload.is(CommonFlags.Instance)) break;\n return expr; // here\n }\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"--\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n switch (this.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n expr = module.binary(\n BinaryOp.SubI32,\n getValue,\n module.i32(1)\n );\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n expr = module.binary(\n BinaryOp.SubI64,\n getValue,\n module.i64(1)\n );\n break;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n expr = module.binary(\n BinaryOp.SubSize,\n getValue,\n this.makeOne(this.currentType)\n );\n break;\n }\n case TypeKind.F32: {\n expr = module.binary(\n BinaryOp.SubF32,\n getValue,\n module.f32(1)\n );\n break;\n }\n case TypeKind.F64: {\n expr = module.binary(\n BinaryOp.SubF64,\n getValue,\n module.f64(1)\n );\n break;\n }\n default: {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"--\", this.currentType.toString()\n );\n return module.unreachable();\n }\n }\n break;\n }\n default: {\n assert(false);\n return module.unreachable();\n }\n }\n\n let resolver = this.resolver;\n let target = resolver.lookupExpression(expression.operand, flow); // reports\n if (!target) {\n return module.unreachable();\n }\n\n // simplify if dropped anyway\n if (!tempLocal) {\n return this.makeAssignment(\n target,\n expr,\n this.currentType,\n expression.operand,\n resolver.currentThisExpression,\n resolver.currentElementExpression,\n false\n );\n }\n\n // otherwise use the temp. local for the intermediate value (always possibly overflows)\n let setValue = this.makeAssignment(\n target,\n expr, // includes a tee of getValue to tempLocal\n this.currentType,\n expression.operand,\n resolver.currentThisExpression,\n resolver.currentElementExpression,\n false\n );\n\n this.currentType = tempLocal.type;\n let typeRef = tempLocal.type.toRef();\n\n return module.block(null, [\n setValue,\n module.local_get(tempLocal.index, typeRef)\n ], typeRef); // result of 'x++' / 'x--' might overflow\n }\n\n private compileUnaryPrefixExpression(\n expression: UnaryPrefixExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let module = this.module;\n let compound = false;\n let expr: ExpressionRef;\n\n switch (expression.operator) {\n case Token.Plus: {\n expr = this.compileExpression(\n expression.operand,\n contextualType.exceptVoid,\n Constraints.None\n );\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Plus);\n if (overload) return this.compileUnaryOverload(overload, expression.operand, expr, expression);\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"+\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n // nop\n break;\n }\n case Token.Minus: {\n let operand = expression.operand;\n if (operand.isNumericLiteral) {\n // implicitly negate integer and float literals. also enables proper checking of literal ranges.\n expr = this.compileLiteralExpression(operand, contextualType, Constraints.None, true);\n // compileExpression normally does this:\n if (this.options.sourceMap) this.addDebugLocation(expr, expression.range);\n break;\n }\n\n expr = this.compileExpression(\n expression.operand,\n contextualType.exceptVoid,\n Constraints.None\n );\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Minus);\n if (overload) return this.compileUnaryOverload(overload, expression.operand, expr, expression);\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"-\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n switch (this.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n expr = module.binary(BinaryOp.SubI32, module.i32(0), expr);\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n expr = module.binary(BinaryOp.SubI64, module.i64(0), expr);\n break;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n expr = module.binary(\n BinaryOp.SubSize,\n this.makeZero(this.currentType),\n expr\n );\n break;\n }\n case TypeKind.F32: {\n expr = module.unary(UnaryOp.NegF32, expr);\n break;\n }\n case TypeKind.F64: {\n expr = module.unary(UnaryOp.NegF64, expr);\n break;\n }\n default: {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"-\", this.currentType.toString()\n );\n expr = module.unreachable();\n }\n }\n break;\n }\n case Token.Plus_Plus: {\n compound = true;\n expr = this.compileExpression(\n expression.operand,\n contextualType.exceptVoid,\n Constraints.None\n );\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.PrefixInc);\n if (overload) {\n expr = this.compileUnaryOverload(overload, expression.operand, expr, expression);\n if (overload.is(CommonFlags.Instance)) break; // re-assign\n return expr; // skip re-assign\n }\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"++\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n switch (this.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n expr = module.binary(BinaryOp.AddI32, expr, this.module.i32(1));\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n expr = module.binary(BinaryOp.AddI64, expr, module.i64(1));\n break;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n expr = module.binary(\n BinaryOp.AddSize,\n expr,\n this.makeOne(this.currentType)\n );\n break;\n }\n case TypeKind.F32: {\n expr = module.binary(BinaryOp.AddF32, expr, module.f32(1));\n break;\n }\n case TypeKind.F64: {\n expr = module.binary(BinaryOp.AddF64, expr, module.f64(1));\n break;\n }\n default: {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"++\", this.currentType.toString()\n );\n expr = module.unreachable();\n }\n }\n break;\n }\n case Token.Minus_Minus: {\n compound = true;\n expr = this.compileExpression(\n expression.operand,\n contextualType.exceptVoid,\n Constraints.None\n );\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.PrefixDec);\n if (overload) {\n expr = this.compileUnaryOverload(overload, expression.operand, expr, expression);\n if (overload.is(CommonFlags.Instance)) break; // re-assign\n return expr; // skip re-assign\n }\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"--\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n switch (this.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n expr = module.binary(BinaryOp.SubI32, expr, module.i32(1));\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n expr = module.binary(BinaryOp.SubI64, expr, module.i64(1));\n break;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n expr = module.binary(\n BinaryOp.SubSize,\n expr,\n this.makeOne(this.currentType)\n );\n break;\n }\n case TypeKind.F32: {\n expr = module.binary(BinaryOp.SubF32, expr, module.f32(1));\n break;\n }\n case TypeKind.F64: {\n expr = module.binary(BinaryOp.SubF64, expr, module.f64(1));\n break;\n }\n default: {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"--\", this.currentType.toString()\n );\n expr = module.unreachable();\n }\n }\n break;\n }\n case Token.Exclamation: {\n expr = this.compileExpression(\n expression.operand,\n contextualType.exceptVoid,\n Constraints.None\n );\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Not);\n if (overload) return this.compileUnaryOverload(overload, expression.operand, expr, expression);\n // fall back to compare by value\n }\n\n expr = module.unary(UnaryOp.EqzI32, this.makeIsTrueish(expr, this.currentType, expression.operand));\n this.currentType = Type.bool;\n break;\n }\n case Token.Tilde: {\n expr = this.compileExpression(\n expression.operand,\n contextualType == Type.void\n ? Type.i32\n : contextualType.isFloatValue\n ? Type.i64\n : contextualType,\n Constraints.None\n );\n\n // check operator overload\n let classReference = this.currentType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseNot);\n if (overload) return this.compileUnaryOverload(overload, expression.operand, expr, expression);\n }\n if (!this.currentType.isValue) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"~\", this.currentType.toString()\n );\n return module.unreachable();\n }\n\n expr = this.convertExpression(expr, this.currentType, this.currentType.intType, false, expression.operand);\n\n switch (this.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n expr = module.binary(BinaryOp.XorI32, expr, module.i32(-1));\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n expr = module.binary(BinaryOp.XorI64, expr, module.i64(-1, -1));\n break;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n expr = module.binary(\n BinaryOp.XorSize,\n expr,\n this.makeNegOne(this.currentType)\n );\n break;\n }\n default: {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n expression.range, \"~\", this.currentType.toString()\n );\n expr = module.unreachable();\n }\n }\n break;\n }\n case Token.TypeOf: {\n return this.compileTypeof(expression, contextualType, constraints);\n }\n case Token.Dot_Dot_Dot: {\n this.error(\n DiagnosticCode.Not_implemented_0,\n expression.range, \"Spread operator\"\n );\n return module.unreachable();\n }\n default: {\n assert(false);\n return module.unreachable();\n }\n }\n if (!compound) return expr;\n let resolver = this.resolver;\n let target = resolver.lookupExpression(expression.operand, this.currentFlow);\n if (!target) return module.unreachable();\n return this.makeAssignment(\n target,\n expr,\n this.currentType,\n expression.operand,\n resolver.currentThisExpression,\n resolver.currentElementExpression,\n contextualType != Type.void\n );\n }\n\n private compileTypeof(\n expression: UnaryPrefixExpression,\n contextualType: Type,\n constraints: Constraints\n ): ExpressionRef {\n let operand = expression.operand;\n let expr: ExpressionRef = 0;\n let stringInstance = this.program.stringInstance;\n let typeString: string;\n if (operand.kind == NodeKind.Null) {\n typeString = \"object\"; // special since `null` without type context is usize\n } else {\n let element = this.resolver.lookupExpression(operand, this.currentFlow, Type.auto, ReportMode.Swallow);\n if (!element) {\n switch (operand.kind) {\n case NodeKind.Identifier: break; // ignore error: typeof doesntExist -> undefined\n case NodeKind.PropertyAccess:\n case NodeKind.ElementAccess: {\n operand = operand.kind == NodeKind.PropertyAccess\n ? (operand).expression\n : (operand).expression;\n let targetType = this.resolver.resolveExpression(operand, this.currentFlow, Type.auto, ReportMode.Report);\n if (!targetType) { // access on non-object\n this.currentType = stringInstance.type;\n return this.module.unreachable();\n }\n // fall-through\n }\n default: {\n expr = this.compileExpression(operand, Type.auto); // may trigger an error\n expr = this.convertExpression(expr, this.currentType, Type.void, true, operand);\n }\n }\n typeString = \"undefined\";\n } else {\n switch (element.kind) {\n case ElementKind.ClassPrototype:\n case ElementKind.Namespace:\n case ElementKind.Enum: {\n typeString = \"object\";\n break;\n }\n case ElementKind.FunctionPrototype: {\n typeString = \"function\";\n break;\n }\n default: {\n expr = this.compileExpression(operand, Type.auto);\n let type = this.currentType;\n expr = this.convertExpression(expr, type, Type.void, true, operand);\n if (type.isReference) {\n let signatureReference = type.getSignature();\n if (signatureReference) {\n typeString = \"function\";\n } else {\n let classReference = type.getClass();\n if (classReference) {\n if (classReference.prototype == stringInstance.prototype) {\n typeString = \"string\";\n } else {\n typeString = \"object\";\n }\n } else {\n typeString = \"externref\"; // TODO?\n }\n }\n } else if (type == Type.bool) {\n typeString = \"boolean\";\n } else if (type.isNumericValue) {\n typeString = \"number\";\n } else {\n typeString = \"undefined\"; // failed to compile?\n }\n break;\n }\n }\n }\n }\n this.currentType = stringInstance.type;\n return expr\n ? this.module.block(null, [ expr, this.ensureStaticString(typeString) ], this.options.sizeTypeRef)\n : this.ensureStaticString(typeString);\n }\n\n /** Makes sure that a 32-bit integer value is wrapped to a valid value of the specified type. */\n ensureSmallIntegerWrap(expr: ExpressionRef, type: Type): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n switch (type.kind) {\n case TypeKind.Bool: {\n if (flow.canOverflow(expr, type)) {\n // bool is special in that it compares to 0 instead of masking with 0x1\n expr = module.binary(BinaryOp.NeI32,\n expr,\n module.i32(0)\n );\n }\n break;\n }\n case TypeKind.I8: {\n if (flow.canOverflow(expr, type)) {\n expr = this.options.hasFeature(Feature.SignExtension)\n ? module.unary(UnaryOp.Extend8I32, expr)\n : module.binary(BinaryOp.ShrI32,\n module.binary(BinaryOp.ShlI32,\n expr,\n module.i32(24)\n ),\n module.i32(24)\n );\n }\n break;\n }\n case TypeKind.I16: {\n if (flow.canOverflow(expr, type)) {\n expr = this.options.hasFeature(Feature.SignExtension)\n ? module.unary(UnaryOp.Extend16I32, expr)\n : module.binary(BinaryOp.ShrI32,\n module.binary(BinaryOp.ShlI32,\n expr,\n module.i32(16)\n ),\n module.i32(16)\n );\n }\n break;\n }\n case TypeKind.U8: {\n if (flow.canOverflow(expr, type)) {\n expr = module.binary(BinaryOp.AndI32,\n expr,\n module.i32(0xff)\n );\n }\n break;\n }\n case TypeKind.U16: {\n if (flow.canOverflow(expr, type)) {\n expr = module.binary(BinaryOp.AndI32,\n expr,\n module.i32(0xffff)\n );\n }\n break;\n }\n }\n return expr;\n }\n\n /** Adds the debug location of the specified expression at the specified range to the source map. */\n addDebugLocation(expr: ExpressionRef, range: Range): void {\n let targetFunction = this.currentFlow.targetFunction;\n let source = range.source;\n if (source.debugInfoIndex < 0) source.debugInfoIndex = this.module.addDebugInfoFile(source.normalizedPath);\n range.debugInfoRef = expr;\n targetFunction.debugLocations.push(range);\n }\n\n /** Checks whether a particular function signature is supported. */\n checkSignatureSupported(signature: Signature, reportNode: FunctionTypeNode): bool {\n let supported = true;\n let explicitThisType = reportNode.explicitThisType;\n if (explicitThisType) {\n if (!this.program.checkTypeSupported(assert(signature.thisType), explicitThisType)) {\n supported = false;\n }\n }\n let parameterTypes = signature.parameterTypes;\n let parameterNodes = reportNode.parameters;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n let parameterReportNode: Node;\n if (parameterNodes.length > i) parameterReportNode = parameterNodes[i];\n else parameterReportNode = reportNode;\n if (!this.program.checkTypeSupported(parameterTypes[i], parameterReportNode)) {\n supported = false;\n }\n }\n if (!this.program.checkTypeSupported(signature.returnType, reportNode.returnType)) {\n supported = false;\n }\n return supported;\n }\n\n /** Evaluates a boolean condition, determining whether it is TRUE, FALSE or UNKNOWN. */\n evaluateCondition(expr: ExpressionRef): ConditionKind {\n let type = getExpressionType(expr);\n if (type == TypeRef.Unreachable)\n return ConditionKind.Unknown;\n\n assert(type == TypeRef.I32);\n let module = this.module;\n let evaled = module.runExpression(expr, ExpressionRunnerFlags.Default);\n if (evaled) {\n return getConstValueI32(evaled)\n ? ConditionKind.True\n : ConditionKind.False;\n }\n return ConditionKind.Unknown;\n }\n\n // === Specialized code generation ==============================================================\n\n /** Makes a constant zero of the specified type. */\n makeZero(type: Type): ExpressionRef {\n let module = this.module;\n switch (type.kind) {\n default: assert(false);\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: return module.i32(0);\n case TypeKind.Isize:\n case TypeKind.Usize: if (type.size != 64) return module.i32(0);\n case TypeKind.I64:\n case TypeKind.U64: return module.i64(0);\n case TypeKind.F32: return module.f32(0);\n case TypeKind.F64: return module.f64(0);\n case TypeKind.V128: return module.v128(v128_zero);\n case TypeKind.Funcref:\n case TypeKind.Externref:\n case TypeKind.Anyref:\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.Stringref:\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter: {\n // TODO: what if not nullable?\n return module.ref_null(type.toRef());\n }\n case TypeKind.I31ref: {\n if (type.is(TypeFlags.Nullable)) return module.ref_null(type.toRef());\n return module.i31_new(module.i32(0));\n }\n }\n }\n\n /** Makes a constant one of the specified type. */\n makeOne(type: Type): ExpressionRef {\n let module = this.module;\n switch (type.kind) {\n default: assert(false);\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: return module.i32(1);\n case TypeKind.Isize:\n case TypeKind.Usize: if (type.size != 64) return module.i32(1);\n case TypeKind.I64:\n case TypeKind.U64: return module.i64(1);\n case TypeKind.F32: return module.f32(1);\n case TypeKind.F64: return module.f64(1);\n case TypeKind.I31ref: return module.i31_new(module.i32(1));\n }\n }\n\n /** Makes a constant negative one of the specified type. */\n makeNegOne(type: Type): ExpressionRef {\n let module = this.module;\n switch (type.kind) {\n default: assert(false);\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: return module.i32(-1);\n case TypeKind.Isize:\n case TypeKind.Usize: if (type.size != 64) return module.i32(-1);\n case TypeKind.I64:\n case TypeKind.U64: return module.i64(-1, -1);\n case TypeKind.F32: return module.f32(-1);\n case TypeKind.F64: return module.f64(-1);\n case TypeKind.V128: return module.v128(v128_ones);\n case TypeKind.I31ref: return module.i31_new(module.i32(-1));\n }\n }\n\n /** Creates a comparison whether an expression is 'true' in a broader sense. */\n makeIsTrueish(expr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {\n let module = this.module;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n expr = this.ensureSmallIntegerWrap(expr, type);\n // fall-through\n }\n case TypeKind.Bool: // not a mask, just != 0\n case TypeKind.I32:\n case TypeKind.U32: return expr;\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.NeI64, expr, module.i64(0));\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return type.size == 64\n ? module.binary(BinaryOp.NeI64, expr, module.i64(0))\n : expr;\n }\n case TypeKind.F32: {\n let options = this.options;\n if (\n options.shrinkLevelHint > 1 &&\n options.hasFeature(Feature.NontrappingF2I)\n ) {\n // Use more compact but slower 5-byte (3 bytes in best case) approach\n // !!(i32.trunc_sat_f32_u(f32.ceil(f32.abs(x))))\n return module.unary(UnaryOp.EqzI32,\n module.unary(UnaryOp.EqzI32,\n module.unary(UnaryOp.TruncSatF32ToU32,\n module.unary(UnaryOp.CeilF32,\n module.unary(UnaryOp.AbsF32, expr)\n )\n )\n )\n );\n } else {\n // 0 < abs(bitCast(x)) <= bitCast(Infinity) or\n // (reinterpret(x) & 0x7FFFFFFF) - 1 <= 0x7F800000 - 1\n //\n // and finally:\n // (reinterpret(x) << 1) - (1 << 1) <= ((0x7F800000 - 1) << 1)\n return module.binary(BinaryOp.LeU32,\n module.binary(BinaryOp.SubI32,\n module.binary(BinaryOp.ShlI32,\n module.unary(UnaryOp.ReinterpretF32ToI32, expr),\n module.i32(1)\n ),\n module.i32(2) // 1 << 1\n ),\n module.i32(0xFEFFFFFE) // (0x7F800000 - 1) << 1\n );\n }\n }\n case TypeKind.F64: {\n let options = this.options;\n if (\n options.shrinkLevelHint > 1 &&\n options.hasFeature(Feature.NontrappingF2I)\n ) {\n // Use more compact but slower 5-byte (3 bytes in best case) approach\n // !!(i32.trunc_sat_f64_u(f64.ceil(f64.abs(x))))\n return module.unary(UnaryOp.EqzI32,\n module.unary(UnaryOp.EqzI32,\n module.unary(UnaryOp.TruncSatF64ToU32,\n module.unary(UnaryOp.CeilF64,\n module.unary(UnaryOp.AbsF64, expr)\n )\n )\n )\n );\n } else {\n // 0 < abs(bitCast(x)) <= bitCast(Infinity) or\n // (reinterpret(x) & 0x7FFFFFFFFFFFFFFF) - 1 <= 0x7FF0000000000000 - 1\n //\n // and finally:\n // (reinterpret(x) << 1) - (1 << 1) <= ((0x7FF0000000000000 - 1) << 1)\n return module.binary(BinaryOp.LeU64,\n module.binary(BinaryOp.SubI64,\n module.binary(BinaryOp.ShlI64,\n module.unary(UnaryOp.ReinterpretF64ToI64, expr),\n module.i64(1)\n ),\n module.i64(2) // 1 << 1\n ),\n module.i64(0xFFFFFFFE, 0xFFDFFFFF) // (0x7FF0000000000000 - 1) << 1\n );\n }\n }\n case TypeKind.V128: {\n return module.unary(UnaryOp.AnyTrueV128, expr);\n }\n case TypeKind.Funcref:\n case TypeKind.Externref:\n case TypeKind.Anyref:\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.I31ref:\n case TypeKind.Stringref:\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter: {\n // Needs to be true (i.e. not zero) when the ref is _not_ null,\n // which means `ref.is_null` returns false (i.e. zero).\n return module.unary(UnaryOp.EqzI32, module.ref_is_null(expr));\n }\n case TypeKind.Void:\n default: {\n this.error(\n DiagnosticCode.An_expression_of_type_0_cannot_be_tested_for_truthiness,\n reportNode.range, type.toString()\n );\n return module.i32(0);\n }\n }\n }\n\n /** Makes a string conversion of the given expression. */\n makeToString(expr: ExpressionRef, type: Type, reportNode: Node): ExpressionRef {\n let stringType = this.program.stringInstance.type;\n if (type == stringType) {\n return expr;\n }\n let classType = type.getClassOrWrapper(this.program);\n if (classType) {\n let toStringInstance = classType.getMethod(\"toString\");\n if (toStringInstance) {\n let toStringSignature = toStringInstance.signature;\n if (!this.checkCallSignature( // reports\n toStringSignature,\n 0,\n true,\n reportNode\n )) {\n this.currentType = stringType;\n return this.module.unreachable();\n }\n if (!type.isStrictlyAssignableTo(assert(toStringSignature.thisType))) {\n this.errorRelated(\n DiagnosticCode.The_this_types_of_each_signature_are_incompatible,\n reportNode.range, toStringInstance.identifierAndSignatureRange\n );\n this.currentType = stringType;\n return this.module.unreachable();\n }\n let toStringReturnType = toStringSignature.returnType;\n if (!toStringReturnType.isStrictlyAssignableTo(stringType)) {\n this.errorRelated(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n reportNode.range, toStringInstance.identifierAndSignatureRange, toStringReturnType.toString(), stringType.toString()\n );\n this.currentType = stringType;\n return this.module.unreachable();\n }\n return this.makeCallDirect(toStringInstance, [ expr ], reportNode);\n }\n }\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n reportNode.range, type.toString(), stringType.toString()\n );\n this.currentType = stringType;\n return this.module.unreachable();\n }\n\n /** Makes an allocation suitable to hold the data of an instance of the given class. */\n makeAllocation(\n classInstance: Class\n ): ExpressionRef {\n let program = this.program;\n assert(classInstance.program == program);\n let module = this.module;\n let options = this.options;\n this.currentType = classInstance.type;\n if (classInstance.hasDecorator(DecoratorFlags.Unmanaged)) {\n let allocInstance = program.allocInstance;\n this.compileFunction(allocInstance);\n return module.call(allocInstance.internalName, [\n options.isWasm64\n ? module.i64(classInstance.nextMemoryOffset)\n : module.i32(classInstance.nextMemoryOffset)\n ], options.sizeTypeRef);\n } else {\n let newInstance = program.newInstance;\n this.compileFunction(newInstance);\n return module.call(newInstance.internalName, [\n options.isWasm64\n ? module.i64(classInstance.nextMemoryOffset)\n : module.i32(classInstance.nextMemoryOffset),\n module.i32(classInstance.id)\n ], options.sizeTypeRef);\n }\n }\n\n /** Makes a conditional allocation where `this` might not have been initialized yet. */\n makeConditionalAllocation(\n classInstance: Class,\n thisIndex: i32\n ): ExpressionRef {\n let module = this.module;\n let classType = classInstance.type;\n let classTypeRef = classType.toRef();\n assert(classTypeRef == this.options.sizeTypeRef);\n return module.if(\n module.unary(classTypeRef == TypeRef.I64 ? UnaryOp.EqzI64 : UnaryOp.EqzI32,\n module.local_get(thisIndex, classTypeRef)\n ),\n module.local_set(thisIndex,\n this.makeAllocation(classInstance),\n classInstance.type.isManaged\n )\n );\n }\n\n /** Makes the initializers for a class's fields within the constructor. */\n makeFieldInitializationInConstructor(\n /** Class being initialized. */\n classInstance: Class,\n /** Statements to append to also being returned. Created if omitted. */\n stmts: ExpressionRef[] = []\n ): ExpressionRef[] {\n let members = classInstance.members;\n if (!members) return stmts;\n\n let module = this.module;\n let flow = this.currentFlow;\n let isInline = flow.isInline;\n let thisLocalIndex = isInline ? flow.lookupLocal(CommonNames.this_)!.index : 0;\n let sizeTypeRef = this.options.sizeTypeRef;\n let nonParameterFields: Property[] | null = null;\n\n // TODO: for (let member of members.values()) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n if (member.kind != ElementKind.PropertyPrototype) continue;\n // only interested in fields (resolved during class finalization)\n let property = (member).instance;\n if (!property || !property.isField || property.getBoundClassOrInterface() != classInstance) continue;\n assert(!property.isAny(CommonFlags.Const));\n let fieldPrototype = property.prototype;\n let parameterIndex = fieldPrototype.parameterIndex;\n\n // Defer non-parameter fields until parameter fields are initialized\n if (parameterIndex < 0) {\n if (!nonParameterFields) nonParameterFields = new Array();\n nonParameterFields.push(property);\n continue;\n }\n\n // Initialize constructor parameter field\n let fieldType = property.type;\n let fieldTypeRef = fieldType.toRef();\n assert(!fieldPrototype.initializerNode);\n let setterInstance = assert(property.setterInstance);\n let expr = this.makeCallDirect(setterInstance, [\n module.local_get(thisLocalIndex, sizeTypeRef),\n module.local_get(\n isInline\n ? flow.lookupLocal(property.name)!.index\n : 1 + parameterIndex, // `this` is local 0\n fieldTypeRef\n )\n ], setterInstance.identifierNode, true);\n if (this.currentType != Type.void) { // in case\n expr = module.drop(expr);\n }\n stmts.push(expr);\n }\n\n // Initialize deferred non-parameter fields\n if (nonParameterFields) {\n for (let i = 0, k = nonParameterFields.length; i < k; ++i) {\n let field = unchecked(nonParameterFields[i]);\n let fieldType = field.type;\n let fieldPrototype = field.prototype;\n let initializerNode = fieldPrototype.initializerNode;\n assert(fieldPrototype.parameterIndex < 0);\n let setterInstance = assert(field.setterInstance);\n let expr = this.makeCallDirect(setterInstance, [\n module.local_get(thisLocalIndex, sizeTypeRef),\n initializerNode // use initializer if present, otherwise initialize with zero\n ? this.compileExpression(initializerNode, fieldType, Constraints.ConvImplicit)\n : this.makeZero(fieldType)\n ], field.identifierNode, true);\n if (this.currentType != Type.void) { // in case\n expr = module.drop(expr);\n }\n stmts.push(expr);\n }\n }\n\n this.currentType = Type.void;\n return stmts;\n }\n\n /** Makes a call to `abort`, if present, otherwise creates a trap. */\n makeAbort(\n /** Message argument of type string, if any. */\n message: Expression | null,\n /** Code location to report when aborting. */\n codeLocation: Node\n ): ExpressionRef {\n let program = this.program;\n let abortInstance = program.abortInstance;\n if (!abortInstance || !this.compileFunction(abortInstance)) return this.module.unreachable();\n\n let stringInstance = program.stringInstance;\n let messageArg: ExpressionRef;\n if (message) {\n messageArg = this.compileExpression(message, stringInstance.type, Constraints.ConvImplicit);\n } else {\n messageArg = this.makeZero(stringInstance.type);\n }\n\n return this.makeStaticAbort(messageArg, codeLocation);\n }\n\n /** Makes a call to `abort`, if present, otherwise creates a trap. */\n makeStaticAbort(\n /** Message argument of type string. May be zero. */\n messageExpr: ExpressionRef,\n /** Code location to report when aborting. */\n codeLocation: Node\n ): ExpressionRef {\n let program = this.program;\n let module = this.module;\n let abortInstance = program.abortInstance;\n if (!abortInstance || !this.compileFunction(abortInstance)) return module.unreachable();\n\n let filenameExpr = this.ensureStaticString(codeLocation.range.source.normalizedPath);\n let range = codeLocation.range;\n let source = range.source;\n return module.block(null, [\n module.call(\n abortInstance.internalName, [\n messageExpr,\n filenameExpr,\n module.i32(source.lineAt(range.start)),\n module.i32(source.columnAt())\n ],\n TypeRef.None\n ),\n module.unreachable()\n ]);\n }\n\n /** Makes a runtime non-null check, e.g. on `possiblyNull` or `possiblyNull!`. */\n makeRuntimeNonNullCheck(\n /** Expression being checked. */\n expr: ExpressionRef,\n /** Type of the expression. */\n type: Type,\n /** Report node. */\n reportNode: Node\n ): ExpressionRef {\n let module = this.module;\n let flow = this.currentFlow;\n let temp = flow.getTempLocal(type);\n let tempIndex = temp.index;\n if (!flow.canOverflow(expr, type)) flow.setLocalFlag(tempIndex, LocalFlags.Wrapped);\n flow.setLocalFlag(tempIndex, LocalFlags.NonNull);\n\n let staticAbortCallExpr = this.makeStaticAbort(\n this.ensureStaticString(\"Unexpected 'null' (not assigned or failed cast)\"),\n reportNode\n ); // TODO: throw\n\n if (type.isExternalReference) {\n let nonNullExpr = module.local_get(tempIndex, type.toRef());\n if (this.options.hasFeature(Feature.GC)) {\n nonNullExpr = module.ref_as_nonnull(nonNullExpr);\n }\n expr = module.if(\n module.ref_is_null(\n module.local_tee(tempIndex, expr, false)\n ),\n staticAbortCallExpr,\n nonNullExpr\n );\n } else {\n expr = module.if(\n module.local_tee(tempIndex, expr, type.isManaged),\n module.local_get(tempIndex, type.toRef()),\n staticAbortCallExpr\n );\n }\n this.currentType = type.nonNullableType;\n return expr;\n }\n\n /** Makes a runtime downcast check, e.g. on `parent`. */\n makeRuntimeDowncastCheck(\n /** Expression being downcast. */\n expr: ExpressionRef,\n /** Type of the expression. */\n type: Type,\n /** Type casting to. */\n toType: Type,\n /** Report node. */\n reportNode: Node\n ): ExpressionRef {\n assert(toType.isReference && toType.nonNullableType.isAssignableTo(type));\n let module = this.module;\n let flow = this.currentFlow;\n let temp = flow.getTempLocal(type);\n let tempIndex = temp.index;\n\n let staticAbortCallExpr = this.makeStaticAbort(\n this.ensureStaticString(\"invalid downcast\"),\n reportNode\n ); // TODO: throw\n\n if (!toType.isNullableReference || flow.isNonnull(expr, type)) {\n // Simplify if the value cannot be `null`. If toType is non-nullable, a\n // null-check would have been emitted separately so is not necessary here.\n // instanceof(t = expr) ? t : abort()\n expr = module.if(\n module.call(this.prepareInstanceOf(toType.classReference!), [\n module.local_tee(tempIndex, expr, type.isManaged)\n ], TypeRef.I32),\n module.local_get(tempIndex, type.toRef()),\n staticAbortCallExpr\n );\n } else {\n // !(t = expr) ? 0 : instanceof(t) ? t : abort()\n expr = module.if(\n module.unary(\n UnaryOp.EqzI32,\n module.local_tee(tempIndex, expr, type.isManaged)\n ),\n module.usize(0),\n module.if(\n module.call(this.prepareInstanceOf(toType.classReference!), [\n module.local_get(tempIndex, type.toRef()),\n ], TypeRef.I32),\n module.local_get(tempIndex, type.toRef()),\n staticAbortCallExpr\n )\n );\n }\n this.currentType = toType;\n return expr;\n }\n}\n\n// helpers\n\nfunction mangleImportName(\n element: Element,\n declaration: DeclarationStatement\n): void {\n // by default, use the file name as the module name\n mangleImportName_moduleName = declaration.range.source.simplePath;\n // and the internal name of the element within that file as the element name\n mangleImportName_elementName = mangleInternalName(\n element.name, element.parent, element.is(CommonFlags.Instance), true\n );\n // override module name if a `module` statement is present\n let overriddenModuleName = declaration.overriddenModuleName;\n if (overriddenModuleName) mangleImportName_moduleName = overriddenModuleName;\n\n if (!element.hasDecorator(DecoratorFlags.External)) return;\n\n let program = element.program;\n let decorator = assert(findDecorator(DecoratorKind.External, declaration.decorators));\n let args = decorator.args;\n if (args && args.length > 0) {\n let arg = args[0];\n // if one argument is given, override just the element name\n // if two arguments are given, override both module and element name\n if (arg.isLiteralKind(LiteralKind.String)) {\n mangleImportName_elementName = (arg).value;\n if (args.length >= 2) {\n arg = args[1];\n if (arg.isLiteralKind(LiteralKind.String)) {\n mangleImportName_moduleName = mangleImportName_elementName;\n mangleImportName_elementName = (arg).value;\n if (args.length > 2) {\n program.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n decorator.range, \"2\", args.length.toString()\n );\n }\n } else {\n program.error(\n DiagnosticCode.String_literal_expected,\n arg.range\n );\n }\n }\n } else {\n program.error(\n DiagnosticCode.String_literal_expected,\n arg.range\n );\n }\n } else {\n program.error(\n DiagnosticCode.Expected_at_least_0_arguments_but_got_1,\n decorator.range, \"1\", \"0\"\n );\n }\n}\n","/**\n * @fileoverview Various character and text utility.\n * @license Apache-2.0\n */\n\n/** An enum of named character codes. */\nexport const enum CharCode {\n\n Null = 0,\n LineFeed = 0x0A,\n CarriageReturn = 0x0D,\n LineSeparator = 0x2028,\n ParagraphSeparator = 0x2029,\n NextLine = 0x0085,\n\n Space = 0x20,\n NonBreakingSpace = 0xA0,\n EnQuad = 0x2000,\n EmQuad = 0x2001,\n EnSpace = 0x2002,\n EmSpace = 0x2003,\n ThreePerEmSpace = 0x2004,\n FourPerEmSpace = 0x2005,\n SixPerEmSpace = 0x2006,\n FigureSpace = 0x2007,\n PunctuationSpace = 0x2008,\n ThinSpace = 0x2009,\n HairSpace = 0x200A,\n ZeroWidthSpace = 0x200B,\n NarrowNoBreakSpace = 0x202F,\n IdeographicSpace = 0x3000,\n MathematicalSpace = 0x205F,\n Ogham = 0x1680,\n\n _ = 0x5F,\n\n _0 = 0x30,\n _1 = 0x31,\n _2 = 0x32,\n _3 = 0x33,\n _4 = 0x34,\n _5 = 0x35,\n _6 = 0x36,\n _7 = 0x37,\n _8 = 0x38,\n _9 = 0x39,\n\n a = 0x61,\n b = 0x62,\n c = 0x63,\n d = 0x64,\n e = 0x65,\n f = 0x66,\n g = 0x67,\n h = 0x68,\n i = 0x69,\n j = 0x6A,\n k = 0x6B,\n l = 0x6C,\n m = 0x6D,\n n = 0x6E,\n o = 0x6F,\n p = 0x70,\n q = 0x71,\n r = 0x72,\n s = 0x73,\n t = 0x74,\n u = 0x75,\n v = 0x76,\n w = 0x77,\n x = 0x78,\n y = 0x79,\n z = 0x7A,\n\n A = 0x41,\n B = 0x42,\n C = 0x43,\n D = 0x44,\n E = 0x45,\n F = 0x46,\n G = 0x47,\n H = 0x48,\n I = 0x49,\n J = 0x4A,\n K = 0x4B,\n L = 0x4C,\n M = 0x4D,\n N = 0x4E,\n O = 0x4F,\n P = 0x50,\n Q = 0x51,\n R = 0x52,\n S = 0x53,\n T = 0x54,\n U = 0x55,\n V = 0x56,\n W = 0x57,\n X = 0x58,\n Y = 0x59,\n Z = 0x5a,\n\n Ampersand = 0x26,\n Asterisk = 0x2A,\n At = 0x40,\n Backslash = 0x5C,\n Backtick = 0x60,\n Bar = 0x7C,\n Caret = 0x5E,\n CloseBrace = 0x7D,\n CloseBracket = 0x5D,\n CloseParen = 0x29,\n Colon = 0x3A,\n Comma = 0x2C,\n Dollar = 0x24,\n Dot = 0x2E,\n DoubleQuote = 0x22,\n Equals = 0x3D,\n Exclamation = 0x21,\n GreaterThan = 0x3E,\n Hash = 0x23,\n LessThan = 0x3C,\n Minus = 0x2D,\n OpenBrace = 0x7B,\n OpenBracket = 0x5B,\n OpenParen = 0x28,\n Percent = 0x25,\n Plus = 0x2B,\n Question = 0x3F,\n Semicolon = 0x3B,\n SingleQuote = 0x27,\n Slash = 0x2F,\n Tilde = 0x7E,\n\n Backspace = 0x08,\n FormFeed = 0x0C,\n ByteOrderMark = 0xFEFF,\n Tab = 0x09,\n VerticalTab = 0x0B\n}\n\n/** Tests if the specified character code is some sort of line break. */\nexport function isLineBreak(c: i32): bool {\n switch (c) {\n case CharCode.LineFeed:\n case CharCode.CarriageReturn:\n case CharCode.LineSeparator:\n case CharCode.ParagraphSeparator: {\n return true;\n }\n default: {\n return false;\n }\n }\n}\n\n/** Tests if the specified character code is some sort of white space. */\nexport function isWhiteSpace(c: i32): bool {\n // NOTE: Calling code assumes that there are no supplementary whitespaces.\n // If Unicode ever adds one, uses of this function must be updated to\n // conditionally advance by two code units, i.e. using `numCodeUnits`.\n switch (c) {\n case CharCode.Space:\n case CharCode.Tab:\n case CharCode.VerticalTab:\n case CharCode.FormFeed:\n case CharCode.NonBreakingSpace:\n case CharCode.NextLine:\n case CharCode.Ogham:\n case CharCode.NarrowNoBreakSpace:\n case CharCode.MathematicalSpace:\n case CharCode.IdeographicSpace:\n case CharCode.ByteOrderMark: {\n return true;\n }\n default: {\n return c >= CharCode.EnQuad && c <= CharCode.ZeroWidthSpace;\n }\n }\n}\n\n/** First high (lead) surrogate. */\nexport const SURROGATE_HIGH = 0xD800;\n\n/** First low (trail) surrogate. */\nexport const SURROGATE_LOW = 0xDC00;\n\n/** Tests if a code unit or code point is a surrogate. */\nexport function isSurrogate(c: i32): bool {\n // F800: 11111 0 0000000000 Mask\n // D800: 11011 X XXXXXXXXXX Any surrogate\n return (c & 0xF800) == SURROGATE_HIGH;\n}\n\n/** Tests if a surrogate is a high (lead) surrogate. */\nexport function isSurrogateHigh(c: i32): bool {\n // D800-DBFF\n return c < SURROGATE_LOW;\n}\n\n/** Tests if a surrogate is a low (trail) surrogate. */\nexport function isSurrogateLow(c: i32): bool {\n // DC00-DFFF\n return c >= SURROGATE_LOW;\n}\n\n/** Tests if a code unit or code point is a high (lead) surrogate. */\nexport function isHighSurrogate(c: i32): bool {\n // FC00: 11111 1 0000000000 Mask\n // D800: 11011 0 XXXXXXXXXX High/Lead surrogate\n return (c & 0xFC00) == SURROGATE_HIGH;\n}\n\n/** Tests if a code unit or code point is a low (trail) surrogate. */\nexport function isLowSurrogate(c: i32): bool {\n // FC00: 11111 1 0000000000 Mask\n // DC00: 11011 1 XXXXXXXXXX Low/Trail surrogate\n return (c & 0xFC00) == SURROGATE_LOW;\n}\n\n/** Converts a surrogate pair to its respective code point. */\nexport function combineSurrogates(hi: i32, lo: i32): i32 {\n return 0x10000 + ((hi & 0x3FF) << 10) | (lo & 0x3FF);\n}\n\n/** Gets the number of UTF-16 code units of the specified code point. */\nexport function numCodeUnits(cp: i32): i32 {\n return 1 + i32(cp > 0xffff);\n}\n\nexport function isAlpha(c: i32): bool {\n let c0 = c | 32; // unify uppercases and lowercases a|A - z|Z\n return c0 >= CharCode.a && c0 <= CharCode.z;\n}\n\n/** Tests if the specified character code is a valid decimal digit. */\nexport function isDecimal(c: i32): bool {\n return c >= CharCode._0 && c <= CharCode._9;\n}\n\n/** Tests if the specified character code is a valid octal digit. */\nexport function isOctal(c: i32): bool {\n return c >= CharCode._0 && c <= CharCode._7;\n}\n\n/** Tests if the specified character code is a valid hexadecimal symbol [a-f]. */\nexport function isHexBase(c: i32): bool {\n let c0 = c | 32; // unify uppercases and lowercases a|A - f|F\n return c0 >= CharCode.a && c0 <= CharCode.f;\n}\n\n/** Tests if the specified character code is a valid hexadecimal digit. */\nexport function isHexOrDecimal(c: i32): bool {\n return isDecimal(c) || isHexBase(c);\n}\n\n/** Tests if the specified character code is trivially alphanumeric. */\nexport function isAlphaOrDecimal(c: i32): bool {\n return isAlpha(c) || isDecimal(c);\n}\n\n/** Tests if the specified code point is a valid start of an identifier. */\nexport function isIdentifierStart(cp: i32): bool {\n return isAlpha(cp)\n || cp == CharCode._\n || cp == CharCode.Dollar\n || cp >= unicodeIdentifierStartMin && cp <= unicodeIdentifierStartMax\n && lookupInUnicodeMap(cp, unicodeIdentifierStart);\n}\n\n/** Tests if the specified code point is a valid part of an identifier. */\nexport function isIdentifierPart(cp: i32): bool {\n return isAlphaOrDecimal(cp)\n || cp == CharCode._\n || cp == CharCode.Dollar\n || cp >= unicodeIdentifierPartMin && cp <= unicodeIdentifierPartMax\n && lookupInUnicodeMap(cp, unicodeIdentifierPart);\n}\n\n/** Tests if the specified string is a valid identifer. */\nexport function isIdentifier(str: string): bool {\n let len = str.length;\n if (!len) return false;\n let cp = str.codePointAt(0);\n if (!isIdentifierStart(cp)) return false;\n let i = numCodeUnits(cp);\n while (i < len) {\n cp = str.codePointAt(i);\n if (!isIdentifierPart(cp)) return false;\n i += numCodeUnits(cp);\n }\n return true;\n}\n\n/** Unicode 14.0 ID_Start/Other_ID_Start ranges */\nconst unicodeIdentifierStart: i32[] = [/*\n| from ... to | from ... to | from ... to | from ... to |*/\n 170 , 170 , 181 , 181 , 186 , 186 , 192 , 214 ,\n 216 , 246 , 248 , 705 , 710 , 721 , 736 , 740 ,\n 748 , 748 , 750 , 750 , 880 , 884 , 886 , 887 ,\n 890 , 893 , 895 , 895 , 902 , 902 , 904 , 906 ,\n 908 , 908 , 910 , 929 , 931 , 1013 , 1015 , 1153 ,\n 1162 , 1327 , 1329 , 1366 , 1369 , 1369 , 1376 , 1416 ,\n 1488 , 1514 , 1519 , 1522 , 1568 , 1610 , 1646 , 1647 ,\n 1649 , 1747 , 1749 , 1749 , 1765 , 1766 , 1774 , 1775 ,\n 1786 , 1788 , 1791 , 1791 , 1808 , 1808 , 1810 , 1839 ,\n 1869 , 1957 , 1969 , 1969 , 1994 , 2026 , 2036 , 2037 ,\n 2042 , 2042 , 2048 , 2069 , 2074 , 2074 , 2084 , 2084 ,\n 2088 , 2088 , 2112 , 2136 , 2144 , 2154 , 2160 , 2183 ,\n 2185 , 2190 , 2208 , 2249 , 2308 , 2361 , 2365 , 2365 ,\n 2384 , 2384 , 2392 , 2401 , 2417 , 2432 , 2437 , 2444 ,\n 2447 , 2448 , 2451 , 2472 , 2474 , 2480 , 2482 , 2482 ,\n 2486 , 2489 , 2493 , 2493 , 2510 , 2510 , 2524 , 2525 ,\n 2527 , 2529 , 2544 , 2545 , 2556 , 2556 , 2565 , 2570 ,\n 2575 , 2576 , 2579 , 2600 , 2602 , 2608 , 2610 , 2611 ,\n 2613 , 2614 , 2616 , 2617 , 2649 , 2652 , 2654 , 2654 ,\n 2674 , 2676 , 2693 , 2701 , 2703 , 2705 , 2707 , 2728 ,\n 2730 , 2736 , 2738 , 2739 , 2741 , 2745 , 2749 , 2749 ,\n 2768 , 2768 , 2784 , 2785 , 2809 , 2809 , 2821 , 2828 ,\n 2831 , 2832 , 2835 , 2856 , 2858 , 2864 , 2866 , 2867 ,\n 2869 , 2873 , 2877 , 2877 , 2908 , 2909 , 2911 , 2913 ,\n 2929 , 2929 , 2947 , 2947 , 2949 , 2954 , 2958 , 2960 ,\n 2962 , 2965 , 2969 , 2970 , 2972 , 2972 , 2974 , 2975 ,\n 2979 , 2980 , 2984 , 2986 , 2990 , 3001 , 3024 , 3024 ,\n 3077 , 3084 , 3086 , 3088 , 3090 , 3112 , 3114 , 3129 ,\n 3133 , 3133 , 3160 , 3162 , 3165 , 3165 , 3168 , 3169 ,\n 3200 , 3200 , 3205 , 3212 , 3214 , 3216 , 3218 , 3240 ,\n 3242 , 3251 , 3253 , 3257 , 3261 , 3261 , 3293 , 3294 ,\n 3296 , 3297 , 3313 , 3314 , 3332 , 3340 , 3342 , 3344 ,\n 3346 , 3386 , 3389 , 3389 , 3406 , 3406 , 3412 , 3414 ,\n 3423 , 3425 , 3450 , 3455 , 3461 , 3478 , 3482 , 3505 ,\n 3507 , 3515 , 3517 , 3517 , 3520 , 3526 , 3585 , 3632 ,\n 3634 , 3635 , 3648 , 3654 , 3713 , 3714 , 3716 , 3716 ,\n 3718 , 3722 , 3724 , 3747 , 3749 , 3749 , 3751 , 3760 ,\n 3762 , 3763 , 3773 , 3773 , 3776 , 3780 , 3782 , 3782 ,\n 3804 , 3807 , 3840 , 3840 , 3904 , 3911 , 3913 , 3948 ,\n 3976 , 3980 , 4096 , 4138 , 4159 , 4159 , 4176 , 4181 ,\n 4186 , 4189 , 4193 , 4193 , 4197 , 4198 , 4206 , 4208 ,\n 4213 , 4225 , 4238 , 4238 , 4256 , 4293 , 4295 , 4295 ,\n 4301 , 4301 , 4304 , 4346 , 4348 , 4680 , 4682 , 4685 ,\n 4688 , 4694 , 4696 , 4696 , 4698 , 4701 , 4704 , 4744 ,\n 4746 , 4749 , 4752 , 4784 , 4786 , 4789 , 4792 , 4798 ,\n 4800 , 4800 , 4802 , 4805 , 4808 , 4822 , 4824 , 4880 ,\n 4882 , 4885 , 4888 , 4954 , 4992 , 5007 , 5024 , 5109 ,\n 5112 , 5117 , 5121 , 5740 , 5743 , 5759 , 5761 , 5786 ,\n 5792 , 5866 , 5870 , 5880 , 5888 , 5905 , 5919 , 5937 ,\n 5952 , 5969 , 5984 , 5996 , 5998 , 6000 , 6016 , 6067 ,\n 6103 , 6103 , 6108 , 6108 , 6176 , 6264 , 6272 , 6312 ,\n 6314 , 6314 , 6320 , 6389 , 6400 , 6430 , 6480 , 6509 ,\n 6512 , 6516 , 6528 , 6571 , 6576 , 6601 , 6656 , 6678 ,\n 6688 , 6740 , 6823 , 6823 , 6917 , 6963 , 6981 , 6988 ,\n 7043 , 7072 , 7086 , 7087 , 7098 , 7141 , 7168 , 7203 ,\n 7245 , 7247 , 7258 , 7293 , 7296 , 7304 , 7312 , 7354 ,\n 7357 , 7359 , 7401 , 7404 , 7406 , 7411 , 7413 , 7414 ,\n 7418 , 7418 , 7424 , 7615 , 7680 , 7957 , 7960 , 7965 ,\n 7968 , 8005 , 8008 , 8013 , 8016 , 8023 , 8025 , 8025 ,\n 8027 , 8027 , 8029 , 8029 , 8031 , 8061 , 8064 , 8116 ,\n 8118 , 8124 , 8126 , 8126 , 8130 , 8132 , 8134 , 8140 ,\n 8144 , 8147 , 8150 , 8155 , 8160 , 8172 , 8178 , 8180 ,\n 8182 , 8188 , 8305 , 8305 , 8319 , 8319 , 8336 , 8348 ,\n 8450 , 8450 , 8455 , 8455 , 8458 , 8467 , 8469 , 8469 ,\n 8472 , 8477 , 8484 , 8484 , 8486 , 8486 , 8488 , 8488 ,\n 8490 , 8505 , 8508 , 8511 , 8517 , 8521 , 8526 , 8526 ,\n 8544 , 8584 , 11264 , 11492 , 11499 , 11502 , 11506 , 11507 ,\n 11520 , 11557 , 11559 , 11559 , 11565 , 11565 , 11568 , 11623 ,\n 11631 , 11631 , 11648 , 11670 , 11680 , 11686 , 11688 , 11694 ,\n 11696 , 11702 , 11704 , 11710 , 11712 , 11718 , 11720 , 11726 ,\n 11728 , 11734 , 11736 , 11742 , 12293 , 12295 , 12321 , 12329 ,\n 12337 , 12341 , 12344 , 12348 , 12353 , 12438 , 12443 , 12447 ,\n 12449 , 12538 , 12540 , 12543 , 12549 , 12591 , 12593 , 12686 ,\n 12704 , 12735 , 12784 , 12799 , 13312 , 19903 , 19968 , 42124 ,\n 42192 , 42237 , 42240 , 42508 , 42512 , 42527 , 42538 , 42539 ,\n 42560 , 42606 , 42623 , 42653 , 42656 , 42735 , 42775 , 42783 ,\n 42786 , 42888 , 42891 , 42954 , 42960 , 42961 , 42963 , 42963 ,\n 42965 , 42969 , 42994 , 43009 , 43011 , 43013 , 43015 , 43018 ,\n 43020 , 43042 , 43072 , 43123 , 43138 , 43187 , 43250 , 43255 ,\n 43259 , 43259 , 43261 , 43262 , 43274 , 43301 , 43312 , 43334 ,\n 43360 , 43388 , 43396 , 43442 , 43471 , 43471 , 43488 , 43492 ,\n 43494 , 43503 , 43514 , 43518 , 43520 , 43560 , 43584 , 43586 ,\n 43588 , 43595 , 43616 , 43638 , 43642 , 43642 , 43646 , 43695 ,\n 43697 , 43697 , 43701 , 43702 , 43705 , 43709 , 43712 , 43712 ,\n 43714 , 43714 , 43739 , 43741 , 43744 , 43754 , 43762 , 43764 ,\n 43777 , 43782 , 43785 , 43790 , 43793 , 43798 , 43808 , 43814 ,\n 43816 , 43822 , 43824 , 43866 , 43868 , 43881 , 43888 , 44002 ,\n 44032 , 55203 , 55216 , 55238 , 55243 , 55291 , 63744 , 64109 ,\n 64112 , 64217 , 64256 , 64262 , 64275 , 64279 , 64285 , 64285 ,\n 64287 , 64296 , 64298 , 64310 , 64312 , 64316 , 64318 , 64318 ,\n 64320 , 64321 , 64323 , 64324 , 64326 , 64433 , 64467 , 64829 ,\n 64848 , 64911 , 64914 , 64967 , 65008 , 65019 , 65136 , 65140 ,\n 65142 , 65276 , 65313 , 65338 , 65345 , 65370 , 65382 , 65470 ,\n 65474 , 65479 , 65482 , 65487 , 65490 , 65495 , 65498 , 65500 ,\n 65536 , 65547 , 65549 , 65574 , 65576 , 65594 , 65596 , 65597 ,\n 65599 , 65613 , 65616 , 65629 , 65664 , 65786 , 65856 , 65908 ,\n 66176 , 66204 , 66208 , 66256 , 66304 , 66335 , 66349 , 66378 ,\n 66384 , 66421 , 66432 , 66461 , 66464 , 66499 , 66504 , 66511 ,\n 66513 , 66517 , 66560 , 66717 , 66736 , 66771 , 66776 , 66811 ,\n 66816 , 66855 , 66864 , 66915 , 66928 , 66938 , 66940 , 66954 ,\n 66956 , 66962 , 66964 , 66965 , 66967 , 66977 , 66979 , 66993 ,\n 66995 , 67001 , 67003 , 67004 , 67072 , 67382 , 67392 , 67413 ,\n 67424 , 67431 , 67456 , 67461 , 67463 , 67504 , 67506 , 67514 ,\n 67584 , 67589 , 67592 , 67592 , 67594 , 67637 , 67639 , 67640 ,\n 67644 , 67644 , 67647 , 67669 , 67680 , 67702 , 67712 , 67742 ,\n 67808 , 67826 , 67828 , 67829 , 67840 , 67861 , 67872 , 67897 ,\n 67968 , 68023 , 68030 , 68031 , 68096 , 68096 , 68112 , 68115 ,\n 68117 , 68119 , 68121 , 68149 , 68192 , 68220 , 68224 , 68252 ,\n 68288 , 68295 , 68297 , 68324 , 68352 , 68405 , 68416 , 68437 ,\n 68448 , 68466 , 68480 , 68497 , 68608 , 68680 , 68736 , 68786 ,\n 68800 , 68850 , 68864 , 68899 , 69248 , 69289 , 69296 , 69297 ,\n 69376 , 69404 , 69415 , 69415 , 69424 , 69445 , 69488 , 69505 ,\n 69552 , 69572 , 69600 , 69622 , 69635 , 69687 , 69745 , 69746 ,\n 69749 , 69749 , 69763 , 69807 , 69840 , 69864 , 69891 , 69926 ,\n 69956 , 69956 , 69959 , 69959 , 69968 , 70002 , 70006 , 70006 ,\n 70019 , 70066 , 70081 , 70084 , 70106 , 70106 , 70108 , 70108 ,\n 70144 , 70161 , 70163 , 70187 , 70272 , 70278 , 70280 , 70280 ,\n 70282 , 70285 , 70287 , 70301 , 70303 , 70312 , 70320 , 70366 ,\n 70405 , 70412 , 70415 , 70416 , 70419 , 70440 , 70442 , 70448 ,\n 70450 , 70451 , 70453 , 70457 , 70461 , 70461 , 70480 , 70480 ,\n 70493 , 70497 , 70656 , 70708 , 70727 , 70730 , 70751 , 70753 ,\n 70784 , 70831 , 70852 , 70853 , 70855 , 70855 , 71040 , 71086 ,\n 71128 , 71131 , 71168 , 71215 , 71236 , 71236 , 71296 , 71338 ,\n 71352 , 71352 , 71424 , 71450 , 71488 , 71494 , 71680 , 71723 ,\n 71840 , 71903 , 71935 , 71942 , 71945 , 71945 , 71948 , 71955 ,\n 71957 , 71958 , 71960 , 71983 , 71999 , 71999 , 72001 , 72001 ,\n 72096 , 72103 , 72106 , 72144 , 72161 , 72161 , 72163 , 72163 ,\n 72192 , 72192 , 72203 , 72242 , 72250 , 72250 , 72272 , 72272 ,\n 72284 , 72329 , 72349 , 72349 , 72368 , 72440 , 72704 , 72712 ,\n 72714 , 72750 , 72768 , 72768 , 72818 , 72847 , 72960 , 72966 ,\n 72968 , 72969 , 72971 , 73008 , 73030 , 73030 , 73056 , 73061 ,\n 73063 , 73064 , 73066 , 73097 , 73112 , 73112 , 73440 , 73458 ,\n 73648 , 73648 , 73728 , 74649 , 74752 , 74862 , 74880 , 75075 ,\n 77712 , 77808 , 77824 , 78894 , 82944 , 83526 , 92160 , 92728 ,\n 92736 , 92766 , 92784 , 92862 , 92880 , 92909 , 92928 , 92975 ,\n 92992 , 92995 , 93027 , 93047 , 93053 , 93071 , 93760 , 93823 ,\n 93952 , 94026 , 94032 , 94032 , 94099 , 94111 , 94176 , 94177 ,\n 94179 , 94179 , 94208 , 100343, 100352, 101589, 101632, 101640,\n 110576, 110579, 110581, 110587, 110589, 110590, 110592, 110882,\n 110928, 110930, 110948, 110951, 110960, 111355, 113664, 113770,\n 113776, 113788, 113792, 113800, 113808, 113817, 119808, 119892,\n 119894, 119964, 119966, 119967, 119970, 119970, 119973, 119974,\n 119977, 119980, 119982, 119993, 119995, 119995, 119997, 120003,\n 120005, 120069, 120071, 120074, 120077, 120084, 120086, 120092,\n 120094, 120121, 120123, 120126, 120128, 120132, 120134, 120134,\n 120138, 120144, 120146, 120485, 120488, 120512, 120514, 120538,\n 120540, 120570, 120572, 120596, 120598, 120628, 120630, 120654,\n 120656, 120686, 120688, 120712, 120714, 120744, 120746, 120770,\n 120772, 120779, 122624, 122654, 123136, 123180, 123191, 123197,\n 123214, 123214, 123536, 123565, 123584, 123627, 124896, 124902,\n 124904, 124907, 124909, 124910, 124912, 124926, 124928, 125124,\n 125184, 125251, 125259, 125259, 126464, 126467, 126469, 126495,\n 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514,\n 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530,\n 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543,\n 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553,\n 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562,\n 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583,\n 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619,\n 126625, 126627, 126629, 126633, 126635, 126651, 131072, 173791,\n 173824, 177976, 177984, 178205, 178208, 183969, 183984, 191456,\n 194560, 195101, 196608, 201546,\n];\nconst unicodeIdentifierStartMin = 170;\nconst unicodeIdentifierStartMax = 201546;\n\n/** Unicode 14.0 ID_Continue/Other_ID_Continue + ID_Start/Other_ID_Start ranges*/\nconst unicodeIdentifierPart: i32[] = [/*\n| from ... to | from ... to | from ... to | from ... to |*/\n 170 , 170 , 181 , 181 , 183 , 183 , 186 , 186 ,\n 192 , 214 , 216 , 246 , 248 , 705 , 710 , 721 ,\n 736 , 740 , 748 , 748 , 750 , 750 , 768 , 884 ,\n 886 , 887 , 890 , 893 , 895 , 895 , 902 , 906 ,\n 908 , 908 , 910 , 929 , 931 , 1013 , 1015 , 1153 ,\n 1155 , 1159 , 1162 , 1327 , 1329 , 1366 , 1369 , 1369 ,\n 1376 , 1416 , 1425 , 1469 , 1471 , 1471 , 1473 , 1474 ,\n 1476 , 1477 , 1479 , 1479 , 1488 , 1514 , 1519 , 1522 ,\n 1552 , 1562 , 1568 , 1641 , 1646 , 1747 , 1749 , 1756 ,\n 1759 , 1768 , 1770 , 1788 , 1791 , 1791 , 1808 , 1866 ,\n 1869 , 1969 , 1984 , 2037 , 2042 , 2042 , 2045 , 2045 ,\n 2048 , 2093 , 2112 , 2139 , 2144 , 2154 , 2160 , 2183 ,\n 2185 , 2190 , 2200 , 2273 , 2275 , 2403 , 2406 , 2415 ,\n 2417 , 2435 , 2437 , 2444 , 2447 , 2448 , 2451 , 2472 ,\n 2474 , 2480 , 2482 , 2482 , 2486 , 2489 , 2492 , 2500 ,\n 2503 , 2504 , 2507 , 2510 , 2519 , 2519 , 2524 , 2525 ,\n 2527 , 2531 , 2534 , 2545 , 2556 , 2556 , 2558 , 2558 ,\n 2561 , 2563 , 2565 , 2570 , 2575 , 2576 , 2579 , 2600 ,\n 2602 , 2608 , 2610 , 2611 , 2613 , 2614 , 2616 , 2617 ,\n 2620 , 2620 , 2622 , 2626 , 2631 , 2632 , 2635 , 2637 ,\n 2641 , 2641 , 2649 , 2652 , 2654 , 2654 , 2662 , 2677 ,\n 2689 , 2691 , 2693 , 2701 , 2703 , 2705 , 2707 , 2728 ,\n 2730 , 2736 , 2738 , 2739 , 2741 , 2745 , 2748 , 2757 ,\n 2759 , 2761 , 2763 , 2765 , 2768 , 2768 , 2784 , 2787 ,\n 2790 , 2799 , 2809 , 2815 , 2817 , 2819 , 2821 , 2828 ,\n 2831 , 2832 , 2835 , 2856 , 2858 , 2864 , 2866 , 2867 ,\n 2869 , 2873 , 2876 , 2884 , 2887 , 2888 , 2891 , 2893 ,\n 2901 , 2903 , 2908 , 2909 , 2911 , 2915 , 2918 , 2927 ,\n 2929 , 2929 , 2946 , 2947 , 2949 , 2954 , 2958 , 2960 ,\n 2962 , 2965 , 2969 , 2970 , 2972 , 2972 , 2974 , 2975 ,\n 2979 , 2980 , 2984 , 2986 , 2990 , 3001 , 3006 , 3010 ,\n 3014 , 3016 , 3018 , 3021 , 3024 , 3024 , 3031 , 3031 ,\n 3046 , 3055 , 3072 , 3084 , 3086 , 3088 , 3090 , 3112 ,\n 3114 , 3129 , 3132 , 3140 , 3142 , 3144 , 3146 , 3149 ,\n 3157 , 3158 , 3160 , 3162 , 3165 , 3165 , 3168 , 3171 ,\n 3174 , 3183 , 3200 , 3203 , 3205 , 3212 , 3214 , 3216 ,\n 3218 , 3240 , 3242 , 3251 , 3253 , 3257 , 3260 , 3268 ,\n 3270 , 3272 , 3274 , 3277 , 3285 , 3286 , 3293 , 3294 ,\n 3296 , 3299 , 3302 , 3311 , 3313 , 3314 , 3328 , 3340 ,\n 3342 , 3344 , 3346 , 3396 , 3398 , 3400 , 3402 , 3406 ,\n 3412 , 3415 , 3423 , 3427 , 3430 , 3439 , 3450 , 3455 ,\n 3457 , 3459 , 3461 , 3478 , 3482 , 3505 , 3507 , 3515 ,\n 3517 , 3517 , 3520 , 3526 , 3530 , 3530 , 3535 , 3540 ,\n 3542 , 3542 , 3544 , 3551 , 3558 , 3567 , 3570 , 3571 ,\n 3585 , 3642 , 3648 , 3662 , 3664 , 3673 , 3713 , 3714 ,\n 3716 , 3716 , 3718 , 3722 , 3724 , 3747 , 3749 , 3749 ,\n 3751 , 3773 , 3776 , 3780 , 3782 , 3782 , 3784 , 3789 ,\n 3792 , 3801 , 3804 , 3807 , 3840 , 3840 , 3864 , 3865 ,\n 3872 , 3881 , 3893 , 3893 , 3895 , 3895 , 3897 , 3897 ,\n 3902 , 3911 , 3913 , 3948 , 3953 , 3972 , 3974 , 3991 ,\n 3993 , 4028 , 4038 , 4038 , 4096 , 4169 , 4176 , 4253 ,\n 4256 , 4293 , 4295 , 4295 , 4301 , 4301 , 4304 , 4346 ,\n 4348 , 4680 , 4682 , 4685 , 4688 , 4694 , 4696 , 4696 ,\n 4698 , 4701 , 4704 , 4744 , 4746 , 4749 , 4752 , 4784 ,\n 4786 , 4789 , 4792 , 4798 , 4800 , 4800 , 4802 , 4805 ,\n 4808 , 4822 , 4824 , 4880 , 4882 , 4885 , 4888 , 4954 ,\n 4957 , 4959 , 4969 , 4977 , 4992 , 5007 , 5024 , 5109 ,\n 5112 , 5117 , 5121 , 5740 , 5743 , 5759 , 5761 , 5786 ,\n 5792 , 5866 , 5870 , 5880 , 5888 , 5909 , 5919 , 5940 ,\n 5952 , 5971 , 5984 , 5996 , 5998 , 6000 , 6002 , 6003 ,\n 6016 , 6099 , 6103 , 6103 , 6108 , 6109 , 6112 , 6121 ,\n 6155 , 6157 , 6159 , 6169 , 6176 , 6264 , 6272 , 6314 ,\n 6320 , 6389 , 6400 , 6430 , 6432 , 6443 , 6448 , 6459 ,\n 6470 , 6509 , 6512 , 6516 , 6528 , 6571 , 6576 , 6601 ,\n 6608 , 6618 , 6656 , 6683 , 6688 , 6750 , 6752 , 6780 ,\n 6783 , 6793 , 6800 , 6809 , 6823 , 6823 , 6832 , 6845 ,\n 6847 , 6862 , 6912 , 6988 , 6992 , 7001 , 7019 , 7027 ,\n 7040 , 7155 , 7168 , 7223 , 7232 , 7241 , 7245 , 7293 ,\n 7296 , 7304 , 7312 , 7354 , 7357 , 7359 , 7376 , 7378 ,\n 7380 , 7418 , 7424 , 7957 , 7960 , 7965 , 7968 , 8005 ,\n 8008 , 8013 , 8016 , 8023 , 8025 , 8025 , 8027 , 8027 ,\n 8029 , 8029 , 8031 , 8061 , 8064 , 8116 , 8118 , 8124 ,\n 8126 , 8126 , 8130 , 8132 , 8134 , 8140 , 8144 , 8147 ,\n 8150 , 8155 , 8160 , 8172 , 8178 , 8180 , 8182 , 8188 ,\n 8255 , 8256 , 8276 , 8276 , 8305 , 8305 , 8319 , 8319 ,\n 8336 , 8348 , 8400 , 8412 , 8417 , 8417 , 8421 , 8432 ,\n 8450 , 8450 , 8455 , 8455 , 8458 , 8467 , 8469 , 8469 ,\n 8472 , 8477 , 8484 , 8484 , 8486 , 8486 , 8488 , 8488 ,\n 8490 , 8505 , 8508 , 8511 , 8517 , 8521 , 8526 , 8526 ,\n 8544 , 8584 , 11264 , 11492 , 11499 , 11507 , 11520 , 11557 ,\n 11559 , 11559 , 11565 , 11565 , 11568 , 11623 , 11631 , 11631 ,\n 11647 , 11670 , 11680 , 11686 , 11688 , 11694 , 11696 , 11702 ,\n 11704 , 11710 , 11712 , 11718 , 11720 , 11726 , 11728 , 11734 ,\n 11736 , 11742 , 11744 , 11775 , 12293 , 12295 , 12321 , 12335 ,\n 12337 , 12341 , 12344 , 12348 , 12353 , 12438 , 12441 , 12447 ,\n 12449 , 12538 , 12540 , 12543 , 12549 , 12591 , 12593 , 12686 ,\n 12704 , 12735 , 12784 , 12799 , 13312 , 19903 , 19968 , 42124 ,\n 42192 , 42237 , 42240 , 42508 , 42512 , 42539 , 42560 , 42607 ,\n 42612 , 42621 , 42623 , 42737 , 42775 , 42783 , 42786 , 42888 ,\n 42891 , 42954 , 42960 , 42961 , 42963 , 42963 , 42965 , 42969 ,\n 42994 , 43047 , 43052 , 43052 , 43072 , 43123 , 43136 , 43205 ,\n 43216 , 43225 , 43232 , 43255 , 43259 , 43259 , 43261 , 43309 ,\n 43312 , 43347 , 43360 , 43388 , 43392 , 43456 , 43471 , 43481 ,\n 43488 , 43518 , 43520 , 43574 , 43584 , 43597 , 43600 , 43609 ,\n 43616 , 43638 , 43642 , 43714 , 43739 , 43741 , 43744 , 43759 ,\n 43762 , 43766 , 43777 , 43782 , 43785 , 43790 , 43793 , 43798 ,\n 43808 , 43814 , 43816 , 43822 , 43824 , 43866 , 43868 , 43881 ,\n 43888 , 44010 , 44012 , 44013 , 44016 , 44025 , 44032 , 55203 ,\n 55216 , 55238 , 55243 , 55291 , 63744 , 64109 , 64112 , 64217 ,\n 64256 , 64262 , 64275 , 64279 , 64285 , 64296 , 64298 , 64310 ,\n 64312 , 64316 , 64318 , 64318 , 64320 , 64321 , 64323 , 64324 ,\n 64326 , 64433 , 64467 , 64829 , 64848 , 64911 , 64914 , 64967 ,\n 65008 , 65019 , 65024 , 65039 , 65056 , 65071 , 65075 , 65076 ,\n 65101 , 65103 , 65136 , 65140 , 65142 , 65276 , 65296 , 65305 ,\n 65313 , 65338 , 65343 , 65343 , 65345 , 65370 , 65382 , 65470 ,\n 65474 , 65479 , 65482 , 65487 , 65490 , 65495 , 65498 , 65500 ,\n 65536 , 65547 , 65549 , 65574 , 65576 , 65594 , 65596 , 65597 ,\n 65599 , 65613 , 65616 , 65629 , 65664 , 65786 , 65856 , 65908 ,\n 66045 , 66045 , 66176 , 66204 , 66208 , 66256 , 66272 , 66272 ,\n 66304 , 66335 , 66349 , 66378 , 66384 , 66426 , 66432 , 66461 ,\n 66464 , 66499 , 66504 , 66511 , 66513 , 66517 , 66560 , 66717 ,\n 66720 , 66729 , 66736 , 66771 , 66776 , 66811 , 66816 , 66855 ,\n 66864 , 66915 , 66928 , 66938 , 66940 , 66954 , 66956 , 66962 ,\n 66964 , 66965 , 66967 , 66977 , 66979 , 66993 , 66995 , 67001 ,\n 67003 , 67004 , 67072 , 67382 , 67392 , 67413 , 67424 , 67431 ,\n 67456 , 67461 , 67463 , 67504 , 67506 , 67514 , 67584 , 67589 ,\n 67592 , 67592 , 67594 , 67637 , 67639 , 67640 , 67644 , 67644 ,\n 67647 , 67669 , 67680 , 67702 , 67712 , 67742 , 67808 , 67826 ,\n 67828 , 67829 , 67840 , 67861 , 67872 , 67897 , 67968 , 68023 ,\n 68030 , 68031 , 68096 , 68099 , 68101 , 68102 , 68108 , 68115 ,\n 68117 , 68119 , 68121 , 68149 , 68152 , 68154 , 68159 , 68159 ,\n 68192 , 68220 , 68224 , 68252 , 68288 , 68295 , 68297 , 68326 ,\n 68352 , 68405 , 68416 , 68437 , 68448 , 68466 , 68480 , 68497 ,\n 68608 , 68680 , 68736 , 68786 , 68800 , 68850 , 68864 , 68903 ,\n 68912 , 68921 , 69248 , 69289 , 69291 , 69292 , 69296 , 69297 ,\n 69376 , 69404 , 69415 , 69415 , 69424 , 69456 , 69488 , 69509 ,\n 69552 , 69572 , 69600 , 69622 , 69632 , 69702 , 69734 , 69749 ,\n 69759 , 69818 , 69826 , 69826 , 69840 , 69864 , 69872 , 69881 ,\n 69888 , 69940 , 69942 , 69951 , 69956 , 69959 , 69968 , 70003 ,\n 70006 , 70006 , 70016 , 70084 , 70089 , 70092 , 70094 , 70106 ,\n 70108 , 70108 , 70144 , 70161 , 70163 , 70199 , 70206 , 70206 ,\n 70272 , 70278 , 70280 , 70280 , 70282 , 70285 , 70287 , 70301 ,\n 70303 , 70312 , 70320 , 70378 , 70384 , 70393 , 70400 , 70403 ,\n 70405 , 70412 , 70415 , 70416 , 70419 , 70440 , 70442 , 70448 ,\n 70450 , 70451 , 70453 , 70457 , 70459 , 70468 , 70471 , 70472 ,\n 70475 , 70477 , 70480 , 70480 , 70487 , 70487 , 70493 , 70499 ,\n 70502 , 70508 , 70512 , 70516 , 70656 , 70730 , 70736 , 70745 ,\n 70750 , 70753 , 70784 , 70853 , 70855 , 70855 , 70864 , 70873 ,\n 71040 , 71093 , 71096 , 71104 , 71128 , 71133 , 71168 , 71232 ,\n 71236 , 71236 , 71248 , 71257 , 71296 , 71352 , 71360 , 71369 ,\n 71424 , 71450 , 71453 , 71467 , 71472 , 71481 , 71488 , 71494 ,\n 71680 , 71738 , 71840 , 71913 , 71935 , 71942 , 71945 , 71945 ,\n 71948 , 71955 , 71957 , 71958 , 71960 , 71989 , 71991 , 71992 ,\n 71995 , 72003 , 72016 , 72025 , 72096 , 72103 , 72106 , 72151 ,\n 72154 , 72161 , 72163 , 72164 , 72192 , 72254 , 72263 , 72263 ,\n 72272 , 72345 , 72349 , 72349 , 72368 , 72440 , 72704 , 72712 ,\n 72714 , 72758 , 72760 , 72768 , 72784 , 72793 , 72818 , 72847 ,\n 72850 , 72871 , 72873 , 72886 , 72960 , 72966 , 72968 , 72969 ,\n 72971 , 73014 , 73018 , 73018 , 73020 , 73021 , 73023 , 73031 ,\n 73040 , 73049 , 73056 , 73061 , 73063 , 73064 , 73066 , 73102 ,\n 73104 , 73105 , 73107 , 73112 , 73120 , 73129 , 73440 , 73462 ,\n 73648 , 73648 , 73728 , 74649 , 74752 , 74862 , 74880 , 75075 ,\n 77712 , 77808 , 77824 , 78894 , 82944 , 83526 , 92160 , 92728 ,\n 92736 , 92766 , 92768 , 92777 , 92784 , 92862 , 92864 , 92873 ,\n 92880 , 92909 , 92912 , 92916 , 92928 , 92982 , 92992 , 92995 ,\n 93008 , 93017 , 93027 , 93047 , 93053 , 93071 , 93760 , 93823 ,\n 93952 , 94026 , 94031 , 94087 , 94095 , 94111 , 94176 , 94177 ,\n 94179 , 94180 , 94192 , 94193 , 94208 , 100343, 100352, 101589,\n 101632, 101640, 110576, 110579, 110581, 110587, 110589, 110590,\n 110592, 110882, 110928, 110930, 110948, 110951, 110960, 111355,\n 113664, 113770, 113776, 113788, 113792, 113800, 113808, 113817,\n 113821, 113822, 118528, 118573, 118576, 118598, 119141, 119145,\n 119149, 119154, 119163, 119170, 119173, 119179, 119210, 119213,\n 119362, 119364, 119808, 119892, 119894, 119964, 119966, 119967,\n 119970, 119970, 119973, 119974, 119977, 119980, 119982, 119993,\n 119995, 119995, 119997, 120003, 120005, 120069, 120071, 120074,\n 120077, 120084, 120086, 120092, 120094, 120121, 120123, 120126,\n 120128, 120132, 120134, 120134, 120138, 120144, 120146, 120485,\n 120488, 120512, 120514, 120538, 120540, 120570, 120572, 120596,\n 120598, 120628, 120630, 120654, 120656, 120686, 120688, 120712,\n 120714, 120744, 120746, 120770, 120772, 120779, 120782, 120831,\n 121344, 121398, 121403, 121452, 121461, 121461, 121476, 121476,\n 121499, 121503, 121505, 121519, 122624, 122654, 122880, 122886,\n 122888, 122904, 122907, 122913, 122915, 122916, 122918, 122922,\n 123136, 123180, 123184, 123197, 123200, 123209, 123214, 123214,\n 123536, 123566, 123584, 123641, 124896, 124902, 124904, 124907,\n 124909, 124910, 124912, 124926, 124928, 125124, 125136, 125142,\n 125184, 125259, 125264, 125273, 126464, 126467, 126469, 126495,\n 126497, 126498, 126500, 126500, 126503, 126503, 126505, 126514,\n 126516, 126519, 126521, 126521, 126523, 126523, 126530, 126530,\n 126535, 126535, 126537, 126537, 126539, 126539, 126541, 126543,\n 126545, 126546, 126548, 126548, 126551, 126551, 126553, 126553,\n 126555, 126555, 126557, 126557, 126559, 126559, 126561, 126562,\n 126564, 126564, 126567, 126570, 126572, 126578, 126580, 126583,\n 126585, 126588, 126590, 126590, 126592, 126601, 126603, 126619,\n 126625, 126627, 126629, 126633, 126635, 126651, 130032, 130041,\n 131072, 173791, 173824, 177976, 177984, 178205, 178208, 183969,\n 183984, 191456, 194560, 195101, 196608, 201546, 917760, 917999,\n];\nconst unicodeIdentifierPartMin = 170;\nconst unicodeIdentifierPartMax = 917999;\n\nfunction lookupInUnicodeMap(code: i32, map: i32[]): bool {\n let lo = 0;\n let hi = map.length;\n while (lo + 1 < hi) {\n let mid = lo + ((hi - lo) >>> 1);\n mid -= (mid & 1);\n let midVal = map[mid];\n if (midVal <= code && code <= map[mid + 1]) {\n return true;\n }\n if (code < midVal) {\n hi = mid;\n } else {\n lo = mid + 2;\n }\n }\n return false;\n}\n\n/** Creates an indentation matching the number of specified levels. */\nconst indentX1 = \" \";\nconst indentX2 = \" \";\nconst indentX3 = \" \";\nconst indentX4 = \" \";\nconst indentCache = new Map();\n\nexport function indent(sb: string[], level: i32): void {\n if (level <= 4) {\n switch (level) {\n case 1: sb.push(indentX1); break;\n case 2: sb.push(indentX2); break;\n case 3: sb.push(indentX3); break;\n case 4: sb.push(indentX4); break;\n }\n } else {\n let indents: string;\n // Limit number of indent entries to 1024 for avoiding unnecessary\n // memory consumetion\n if (indentCache.size <= 1024) {\n if (indentCache.has(level)) {\n indents = assert(indentCache.get(level));\n } else {\n indentCache.set(level, (indents = indentX1.repeat(level)));\n }\n } else {\n indents = indentX1.repeat(level);\n }\n sb.push(indents);\n }\n}\n\n/** Escapes a string using the specified kind of quote. */\nexport function escapeString(str: string, quote: CharCode): string {\n let sb = new Array();\n let off = 0;\n let i = 0;\n for (let k = str.length; i < k;) {\n switch (str.charCodeAt(i)) {\n case CharCode.Null: {\n if (i > off) sb.push(str.substring(off, off = i + 1));\n sb.push(\"\\\\0\");\n off = ++i;\n break;\n }\n case CharCode.Backspace: {\n if (i > off) sb.push(str.substring(off, i));\n off = ++i;\n sb.push(\"\\\\b\");\n break;\n }\n case CharCode.Tab: {\n if (i > off) sb.push(str.substring(off, i));\n off = ++i;\n sb.push(\"\\\\t\");\n break;\n }\n case CharCode.LineFeed: {\n if (i > off) sb.push(str.substring(off, i));\n off = ++i;\n sb.push(\"\\\\n\");\n break;\n }\n case CharCode.VerticalTab: {\n if (i > off) sb.push(str.substring(off, i));\n off = ++i;\n sb.push(\"\\\\v\");\n break;\n }\n case CharCode.FormFeed: {\n if (i > off) sb.push(str.substring(off, i));\n off = ++i;\n sb.push(\"\\\\f\");\n break;\n }\n case CharCode.CarriageReturn: {\n if (i > off) sb.push(str.substring(off, i));\n sb.push(\"\\\\r\");\n off = ++i;\n break;\n }\n case CharCode.DoubleQuote: {\n if (quote == CharCode.DoubleQuote) {\n if (i > off) sb.push(str.substring(off, i));\n sb.push(\"\\\\\\\"\");\n off = ++i;\n } else {\n ++i;\n }\n break;\n }\n case CharCode.SingleQuote: {\n if (quote == CharCode.SingleQuote) {\n if (i > off) sb.push(str.substring(off, i));\n sb.push(\"\\\\'\");\n off = ++i;\n } else {\n ++i;\n }\n break;\n }\n case CharCode.Backslash: {\n if (i > off) sb.push(str.substring(off, i));\n sb.push(\"\\\\\\\\\");\n off = ++i;\n break;\n }\n case CharCode.Backtick: {\n if (quote == CharCode.Backtick) {\n if (i > off) sb.push(str.substring(off, i));\n sb.push(\"\\\\`\");\n off = ++i;\n } else {\n ++i;\n }\n break;\n }\n default: {\n ++i;\n break;\n }\n }\n }\n if (i > off) sb.push(str.substring(off, i));\n return sb.join(\"\");\n}\n","/// \n\nimport { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from \"./rt/common\";\nimport { Runtime } from \"shared/runtime\";\nimport { idof } from \"./builtins\";\nimport { E_INVALIDLENGTH } from \"./util/error\";\n\nexport abstract class ArrayBufferView {\n\n readonly buffer: ArrayBuffer;\n @unsafe readonly dataStart: usize;\n readonly byteLength: i32;\n\n get byteOffset(): i32 {\n return (this.dataStart - changetype(this.buffer));\n }\n\n protected constructor(length: i32, alignLog2: i32) {\n if (length > BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);\n let buffer = changetype(__new(length = length << alignLog2, idof()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(buffer), 0, length);\n }\n this.buffer = buffer; // links\n this.dataStart = changetype(buffer);\n this.byteLength = length;\n }\n}\n\n@final export class ArrayBuffer {\n\n static isView(value: T): bool {\n if (isNullable()) {\n if (changetype(value) == 0) return false;\n }\n if (value instanceof Int8Array) return true;\n if (value instanceof Uint8Array) return true;\n if (value instanceof Uint8ClampedArray) return true;\n if (value instanceof Int16Array) return true;\n if (value instanceof Uint16Array) return true;\n if (value instanceof Int32Array) return true;\n if (value instanceof Uint32Array) return true;\n if (value instanceof Int64Array) return true;\n if (value instanceof Uint64Array) return true;\n if (value instanceof Float32Array) return true;\n if (value instanceof Float64Array) return true;\n if (value instanceof DataView) return true;\n return false;\n }\n\n constructor(length: i32) {\n if (length > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH);\n let buffer = changetype(__new(length, idof()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(buffer), 0, length);\n }\n return buffer;\n }\n\n get byteLength(): i32 {\n return changetype(changetype(this) - TOTAL_OVERHEAD).rtSize;\n }\n\n slice(begin: i32 = 0, end: i32 = BLOCK_MAXSIZE): ArrayBuffer {\n let length = this.byteLength;\n begin = begin < 0 ? max(length + begin, 0) : min(begin, length);\n end = end < 0 ? max(length + end , 0) : min(end , length);\n let outSize = max(end - begin, 0);\n let out = changetype(__new(outSize, idof()));\n memory.copy(changetype(out), changetype(this) + begin, outSize);\n return out;\n }\n\n toString(): string {\n return \"[object ArrayBuffer]\";\n }\n}\n","export function HASH(key: T): u32 {\n if (isString()) {\n return hashStr(changetype(key));\n } else if (isReference()) {\n if (sizeof() == 4) return hash32(changetype(key));\n if (sizeof() == 8) return hash64(changetype(key));\n } else if (isFloat()) {\n if (sizeof() == 4) return hash32(reinterpret(f32(key)));\n if (sizeof() == 8) return hash64(reinterpret(f64(key)));\n } else {\n if (sizeof() <= 4) return hash32(u32(key), sizeof());\n if (sizeof() == 8) return hash64(u64(key));\n }\n return unreachable();\n}\n\n// XXHash 32-bit as a starting point, see: https://cyan4973.github.io/xxHash\n\n// primes\n// @ts-ignore: decorator\n@inline const XXH32_P1: u32 = 2654435761;\n// @ts-ignore: decorator\n@inline const XXH32_P2: u32 = 2246822519;\n// @ts-ignore: decorator\n@inline const XXH32_P3: u32 = 3266489917;\n// @ts-ignore: decorator\n@inline const XXH32_P4: u32 = 668265263;\n// @ts-ignore: decorator\n@inline const XXH32_P5: u32 = 374761393;\n// @ts-ignore: decorator\n@inline const XXH32_SEED: u32 = 0;\n\n// @ts-ignore: decorator\n@inline\nfunction hash32(key: u32, len: u32 = 4): u32 {\n let h: u32 = XXH32_SEED + XXH32_P5 + len;\n h += key * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n h ^= h >> 15;\n h *= XXH32_P2;\n h ^= h >> 13;\n h *= XXH32_P3;\n h ^= h >> 16;\n return h;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction hash64(key: u64): u32 {\n let h: u32 = XXH32_SEED + XXH32_P5 + 8;\n h += key * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n h += (key >> 32) * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n h ^= h >> 15;\n h *= XXH32_P2;\n h ^= h >> 13;\n h *= XXH32_P3;\n h ^= h >> 16;\n return h;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction mix(h: u32, key: u32): u32 {\n return rotl(h + key * XXH32_P2, 13) * XXH32_P1;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction hashStr(key: string): u32 {\n if (changetype(key) == 0) return XXH32_SEED;\n\n let h: u32 = key.length << 1;\n let len: usize = h;\n let pos = changetype(key);\n\n if (len >= 16) {\n let s1 = XXH32_SEED + XXH32_P1 + XXH32_P2;\n let s2 = XXH32_SEED + XXH32_P2;\n let s3 = XXH32_SEED;\n let s4 = XXH32_SEED - XXH32_P1;\n\n let end = len + pos - 16;\n while (pos <= end) {\n s1 = mix(s1, load(pos ));\n s2 = mix(s2, load(pos, 4));\n s3 = mix(s3, load(pos, 8));\n s4 = mix(s4, load(pos, 12));\n pos += 16;\n }\n h += rotl(s1, 1) + rotl(s2, 7) + rotl(s3, 12) + rotl(s4, 18);\n } else {\n h += XXH32_SEED + XXH32_P5;\n }\n\n let end = changetype(key) + len - 4;\n while (pos <= end) {\n h += load(pos) * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n pos += 4;\n }\n\n end = changetype(key) + len;\n while (pos < end) {\n h += load(pos) * XXH32_P5;\n h = rotl(h, 11) * XXH32_P1;\n pos++;\n }\n\n h ^= h >> 15;\n h *= XXH32_P2;\n h ^= h >> 13;\n h *= XXH32_P3;\n h ^= h >> 16;\n return h;\n}\n","/// \n\nimport { HASH } from \"./util/hash\";\nimport { E_KEYNOTFOUND } from \"./util/error\";\n\n// A deterministic hash map based on CloseTable from https://github.com/jorendorff/dht\n\n// @ts-ignore: decorator\n@inline const INITIAL_CAPACITY = 4;\n\n// @ts-ignore: decorator\n@inline const FILL_FACTOR_N = 8;\n\n// @ts-ignore: decorator\n@inline const FILL_FACTOR_D = 3;\n\n// @ts-ignore: decorator\n@inline const FREE_FACTOR_N = 3;\n\n// @ts-ignore: decorator\n@inline const FREE_FACTOR_D = 4;\n\n/** Structure of a map entry. */\n@unmanaged class MapEntry {\n key: K;\n value: V;\n taggedNext: usize; // LSB=1 indicates EMPTY\n}\n\n/** Empty bit. */\n// @ts-ignore: decorator\n@inline const EMPTY: usize = 1 << 0;\n\n/** Size of a bucket. */\n// @ts-ignore: decorator\n@inline const BUCKET_SIZE = sizeof();\n\n/** Computes the alignment of an entry. */\n// @ts-ignore: decorator\n@inline\nfunction ENTRY_ALIGN(): usize {\n // can align to 4 instead of 8 if 32-bit and K/V is <= 32-bits\n const maxkv = sizeof() > sizeof() ? sizeof() : sizeof();\n const align = (maxkv > sizeof() ? maxkv : sizeof()) - 1;\n return align;\n}\n\n/** Computes the aligned size of an entry. */\n// @ts-ignore: decorator\n@inline\nfunction ENTRY_SIZE(): usize {\n const align = ENTRY_ALIGN();\n const size = (offsetof>() + align) & ~align;\n return size;\n}\n\nexport class Map {\n\n // buckets referencing their respective first entry, usize[bucketsMask + 1]\n private buckets: ArrayBuffer = new ArrayBuffer(INITIAL_CAPACITY * BUCKET_SIZE);\n private bucketsMask: u32 = INITIAL_CAPACITY - 1;\n\n // entries in insertion order, MapEntry[entriesCapacity]\n private entries: ArrayBuffer = new ArrayBuffer(INITIAL_CAPACITY * ENTRY_SIZE());\n private entriesCapacity: i32 = INITIAL_CAPACITY;\n private entriesOffset: i32 = 0;\n private entriesCount: i32 = 0;\n\n constructor() {\n /* nop */\n }\n\n get size(): i32 {\n return this.entriesCount;\n }\n\n clear(): void {\n this.buckets = new ArrayBuffer(INITIAL_CAPACITY * BUCKET_SIZE);\n this.bucketsMask = INITIAL_CAPACITY - 1;\n this.entries = new ArrayBuffer(INITIAL_CAPACITY * ENTRY_SIZE());\n this.entriesCapacity = INITIAL_CAPACITY;\n this.entriesOffset = 0;\n this.entriesCount = 0;\n }\n\n private find(key: K, hashCode: u32): MapEntry | null {\n let entry = load>( // unmanaged!\n changetype(this.buckets) + (hashCode & this.bucketsMask) * BUCKET_SIZE\n );\n while (entry) {\n let taggedNext = entry.taggedNext;\n if (!(taggedNext & EMPTY) && entry.key == key) return entry;\n entry = changetype>(taggedNext & ~EMPTY);\n }\n return null;\n }\n\n has(key: K): bool {\n return this.find(key, HASH(key)) != null;\n }\n\n @operator(\"[]\")\n get(key: K): V {\n let entry = this.find(key, HASH(key));\n if (!entry) throw new Error(E_KEYNOTFOUND); // cannot represent `undefined`\n return entry.value;\n }\n\n @operator(\"[]=\")\n set(key: K, value: V): this {\n let hashCode = HASH(key);\n let entry = this.find(key, hashCode); // unmanaged!\n if (entry) {\n entry.value = value;\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n } else {\n // check if rehashing is necessary\n if (this.entriesOffset == this.entriesCapacity) {\n this.rehash(\n this.entriesCount < this.entriesCapacity * FREE_FACTOR_N / FREE_FACTOR_D\n ? this.bucketsMask // just rehash if 1/4+ entries are empty\n : (this.bucketsMask << 1) | 1 // grow capacity to next 2^N\n );\n }\n // append new entry\n let entries = this.entries;\n entry = changetype>(changetype(entries) + (this.entriesOffset++) * ENTRY_SIZE());\n // link with the map\n entry.key = key;\n if (isManaged()) {\n __link(changetype(this), changetype(key), true);\n }\n entry.value = value;\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n ++this.entriesCount;\n // link with previous entry in bucket\n let bucketPtrBase = changetype(this.buckets) + (hashCode & this.bucketsMask) * BUCKET_SIZE;\n entry.taggedNext = load(bucketPtrBase);\n store(bucketPtrBase, changetype(entry));\n }\n return this;\n }\n\n delete(key: K): bool {\n let entry = this.find(key, HASH(key));\n if (!entry) return false;\n entry.taggedNext |= EMPTY;\n --this.entriesCount;\n // check if rehashing is appropriate\n let halfBucketsMask = this.bucketsMask >> 1;\n if (\n halfBucketsMask + 1 >= max(INITIAL_CAPACITY, this.entriesCount) &&\n this.entriesCount < this.entriesCapacity * FREE_FACTOR_N / FREE_FACTOR_D\n ) this.rehash(halfBucketsMask);\n return true;\n }\n\n private rehash(newBucketsMask: u32): void {\n let newBucketsCapacity = (newBucketsMask + 1);\n let newBuckets = new ArrayBuffer(newBucketsCapacity * BUCKET_SIZE);\n let newEntriesCapacity = newBucketsCapacity * FILL_FACTOR_N / FILL_FACTOR_D;\n let newEntries = new ArrayBuffer(newEntriesCapacity * ENTRY_SIZE());\n\n // copy old entries to new entries\n let oldPtr = changetype(this.entries);\n let oldEnd = oldPtr + this.entriesOffset * ENTRY_SIZE();\n let newPtr = changetype(newEntries);\n while (oldPtr != oldEnd) {\n let oldEntry = changetype>(oldPtr);\n if (!(oldEntry.taggedNext & EMPTY)) {\n let newEntry = changetype>(newPtr);\n let oldEntryKey = oldEntry.key;\n newEntry.key = oldEntryKey;\n newEntry.value = oldEntry.value;\n let newBucketIndex = HASH(oldEntryKey) & newBucketsMask;\n let newBucketPtrBase = changetype(newBuckets) + newBucketIndex * BUCKET_SIZE;\n newEntry.taggedNext = load(newBucketPtrBase);\n store(newBucketPtrBase, newPtr);\n newPtr += ENTRY_SIZE();\n }\n oldPtr += ENTRY_SIZE();\n }\n\n this.buckets = newBuckets;\n this.bucketsMask = newBucketsMask;\n this.entries = newEntries;\n this.entriesCapacity = newEntriesCapacity;\n this.entriesOffset = this.entriesCount;\n }\n\n keys(): K[] {\n // FIXME: this is preliminary, needs iterators/closures\n let start = changetype(this.entries);\n let size = this.entriesOffset;\n let keys = new Array(size);\n let length = 0;\n for (let i = 0; i < size; ++i) {\n let entry = changetype>(start + i * ENTRY_SIZE());\n if (!(entry.taggedNext & EMPTY)) {\n unchecked(keys[length++] = entry.key);\n }\n }\n keys.length = length;\n return keys;\n }\n\n values(): V[] {\n // FIXME: this is preliminary, needs iterators/closures\n let start = changetype(this.entries);\n let size = this.entriesOffset;\n let values = new Array(size);\n let length = 0;\n for (let i = 0; i < size; ++i) {\n let entry = changetype>(start + i * ENTRY_SIZE());\n if (!(entry.taggedNext & EMPTY)) {\n unchecked(values[length++] = entry.value);\n }\n }\n values.length = length;\n return values;\n }\n\n toString(): string {\n return \"[object Map]\";\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n __visit(changetype(this.buckets), cookie);\n let entries = changetype(this.entries);\n if (isManaged() || isManaged()) {\n let cur = entries;\n let end = cur + this.entriesOffset * ENTRY_SIZE();\n while (cur < end) {\n let entry = changetype>(cur);\n if (!(entry.taggedNext & EMPTY)) {\n if (isManaged()) {\n let val = changetype(entry.key);\n if (isNullable()) {\n if (val) __visit(val, cookie);\n } else __visit(val, cookie);\n }\n if (isManaged()) {\n let val = changetype(entry.value);\n if (isNullable()) {\n if (val) __visit(val, cookie);\n } else __visit(val, cookie);\n }\n }\n cur += ENTRY_SIZE();\n }\n }\n __visit(entries, cookie);\n }\n}\n","/**\n * @fileoverview Various file path utility.\n * @license Apache-2.0\n */\n\nimport {\n CharCode\n} from \"./text\";\n\nimport {\n PATH_DELIMITER\n} from \"../common\";\n\nconst separator = CharCode.Slash;\n\n/**\n * Normalizes the specified path, removing interior placeholders.\n * Expects a posix-compatible relative path (not Windows compatible).\n */\nexport function normalizePath(path: string): string {\n let pos = 0;\n let len = path.length;\n\n // trim leading './'\n while (pos + 1 < len &&\n path.charCodeAt(pos) == CharCode.Dot &&\n path.charCodeAt(pos + 1) == separator\n ) {\n pos += 2;\n }\n\n if (pos > 0 || len < path.length) {\n path = path.substring(pos, len);\n len -= pos;\n pos = 0;\n }\n\n let atEnd: bool;\n while (pos + 1 < len) {\n atEnd = false;\n\n // we are only interested in '/.' sequences ...\n if (\n path.charCodeAt(pos) == separator &&\n path.charCodeAt(pos + 1) == CharCode.Dot\n ) {\n // '/.' ( '/' | $ )\n atEnd = pos + 2 == len;\n if (atEnd ||\n pos + 2 < len &&\n path.charCodeAt(pos + 2) == separator\n ) {\n path = atEnd\n ? path.substring(0, pos)\n : path.substring(0, pos) + path.substring(pos + 2);\n len -= 2;\n continue;\n }\n\n // '/.' ( './' | '.' $ )\n atEnd = pos + 3 == len;\n if (atEnd && path.charCodeAt(pos + 2) == CharCode.Dot ||\n pos + 3 < len &&\n path.charCodeAt(pos + 2) == CharCode.Dot &&\n path.charCodeAt(pos + 3) == separator\n ) {\n // find preceeding '/'\n let ipos = pos;\n while (--ipos >= 0) {\n if (path.charCodeAt(ipos) == separator) {\n if (pos - ipos != 3 ||\n path.charCodeAt(ipos + 1) != CharCode.Dot ||\n path.charCodeAt(ipos + 2) != CharCode.Dot\n ) { // exclude '..' itself\n path = atEnd\n ? path.substring(0, ipos)\n : path.substring(0, ipos) + path.substring(pos + 3);\n len -= pos + 3 - ipos;\n pos = ipos - 1; // incremented again at end of loop\n }\n break;\n }\n }\n\n // if there's no preceeding '/', trim start if non-empty\n if (ipos < 0 && pos > 0) {\n if (pos != 2 ||\n path.charCodeAt(0) != CharCode.Dot ||\n path.charCodeAt(1) != CharCode.Dot\n ) { // exclude '..' itself\n path = path.substring(pos + 4);\n len = path.length;\n continue;\n }\n }\n }\n }\n pos++;\n }\n return len > 0 ? path : \".\";\n}\n\n/** Resolves the specified path relative to the specified origin. */\nexport function resolvePath(normalizedPath: string, origin: string): string {\n if (normalizedPath.startsWith(\"std/\")) {\n return normalizedPath;\n }\n return normalizePath(\n dirname(origin) + PATH_DELIMITER + normalizedPath\n );\n}\n\n/** Obtains the directory portion of a normalized path. */\nexport function dirname(normalizedPath: string): string {\n let pos = normalizedPath.length;\n if (pos <= 1) {\n if (pos == 0) return \".\";\n if (normalizedPath.charCodeAt(0) == separator) {\n return normalizedPath;\n }\n }\n while (--pos > 0) {\n if (normalizedPath.charCodeAt(pos) == separator) {\n return normalizedPath.substring(0, pos);\n }\n }\n return \".\";\n}\n","/**\n * @fileoverview Terminal utility.\n * @license Apache-2.0\n */\n\n/** Gray terminal color code. */\nexport const COLOR_GRAY = \"\\u001b[90m\";\n/** Red terminal color code. */\nexport const COLOR_RED = \"\\u001b[91m\";\n/** Green terminal color code. */\nexport const COLOR_GREEN = \"\\u001b[92m\";\n/** Yellow terminal color code. */\nexport const COLOR_YELLOW = \"\\u001b[93m\";\n/** Blue terminal color code. */\nexport const COLOR_BLUE = \"\\u001b[94m\";\n/** Magenta terminal color code. */\nexport const COLOR_MAGENTA = \"\\u001b[95m\";\n/** Cyan terminal color code. */\nexport const COLOR_CYAN = \"\\u001b[96m\";\n/** White terminal color code. */\nexport const COLOR_WHITE = \"\\u001b[97m\";\n/** Terminal color reset code. */\nexport const COLOR_RESET = \"\\u001b[0m\";\n\n/** Whether terminal colors are enabled or not. */\nlet colorsEnabled = true;\n\n/** Checks whether terminal colors are enabled or not. */\nexport function isColorsEnabled(): bool {\n return colorsEnabled;\n}\n\n/** Sets whether terminal colors are enabled or not. */\nexport function setColorsEnabled(isEnabled: bool): bool {\n let wasEnabled = isEnabled;\n colorsEnabled = isEnabled;\n return wasEnabled;\n}\n\n/** Wraps the specified text in the specified terminal color code. */\nexport function colorize(text: string, color: string): string {\n return colorsEnabled ? color + text + COLOR_RESET : text;\n}\n","import { COMPARATOR, SORT } from \"./util/sort\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_NOTIMPLEMENTED } from \"./util/error\";\nimport { joinIntegerArray, joinFloatArray } from \"./util/string\";\nimport { REVERSE, FILL } from \"./util/bytes\";\nimport { idof } from \"./builtins\";\nimport { ArrayBufferView } from \"./arraybuffer\";\n\nexport class Int8Array extends ArrayBufferView {\n [key: number]: i8;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength;\n }\n\n @operator(\"[]\")\n private __get(index: i32): i8 {\n if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + index);\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): i8 {\n return load(this.dataStart + index);\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: native): void {\n if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + index, value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: native): void {\n store(this.dataStart + index, value);\n }\n\n at(index: i32): i8 {\n let len = this.byteLength;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + index);\n }\n\n includes(searchElement: i8, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: i8, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: i8, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array {\n FILL(this.dataStart, this.length, u8(value), start, end);\n return this;\n }\n\n sort(comparator: (a: i8, b: i8) => i32 = COMPARATOR()): Int8Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int8Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int8Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: i8, index: i32, array: Int8Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: i8, index: i32, self: Int8Array) => i8): Int8Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: i8, index: i32, self: Int8Array) => bool): Int8Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: i8, index: i32, self: Int8Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: i8, index: i32, self: Int8Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: i8, index: i32, self: Int8Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: i8, index: i32, self: Int8Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: i8, index: i32, self: Int8Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Int8Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n toString(): string {\n return this.join();\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int8Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Uint8Array extends ArrayBufferView {\n [key: number]: u8;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength;\n }\n\n @operator(\"[]\")\n private __get(index: i32): u8 {\n if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + index);\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): u8 {\n return load(this.dataStart + index);\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: native): void {\n if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + index, value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: native): void {\n store(this.dataStart + index, value);\n }\n\n at(index: i32): u8 {\n let len = this.byteLength;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + index);\n }\n\n includes(searchElement: u8, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: u8, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: u8, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array {\n FILL(this.dataStart, this.length, u8(value), start, end);\n return this;\n }\n\n sort(comparator: (a: u8, b: u8) => i32 = COMPARATOR()): Uint8Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint8Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: u8, index: i32, array: Uint8Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: u8, index: i32, self: Uint8Array) => u8): Uint8Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: u8, index: i32, self: Uint8Array) => bool): Uint8Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: u8, index: i32, self: Uint8Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: u8, index: i32, self: Uint8Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: u8, index: i32, self: Uint8Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: u8, index: i32, self: Uint8Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: u8, index: i32, self: Uint8Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Uint8Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint8Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Uint8ClampedArray extends ArrayBufferView {\n [key: number]: u8;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength;\n }\n\n @operator(\"[]\")\n private __get(index: i32): u8 {\n if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + index);\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): u8 {\n return load(this.dataStart + index);\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: native): void {\n if (index >= this.byteLength) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + index, ~(value >> 31) & (((255 - value) >> 31) | value));\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: native): void {\n store(this.dataStart + index, ~(value >> 31) & (((255 - value) >> 31) | value));\n }\n\n at(index: i32): u8 {\n let len = this.byteLength;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + index);\n }\n\n includes(searchElement: u8, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: u8, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: u8, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {\n value = ~(value >> 31) & (((255 - value) >> 31) | value);\n FILL(this.dataStart, this.length, u8(value), start, end);\n return this;\n }\n\n sort(comparator: (a: u8, b: u8) => i32 = COMPARATOR()): Uint8ClampedArray {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {\n return SLICE(this, begin, end);\n }\n\n subarray(start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {\n return SUBARRAY(this, start, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint8ClampedArray {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: u8, index: i32, array: Uint8ClampedArray) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: u8, index: i32, array: Uint8ClampedArray) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: u8, index: i32, self: Uint8ClampedArray) => u8): Uint8ClampedArray {\n return MAP(this, fn);\n }\n\n filter(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): Uint8ClampedArray {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: u8, index: i32, self: Uint8ClampedArray) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: u8, index: i32, self: Uint8ClampedArray) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Uint8ClampedArray {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint8ClampedArray {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Int16Array extends ArrayBufferView {\n [key: number]: i16;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): i16 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): i16 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: native): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: native): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): i16 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: i16, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: i16, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: i16, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array {\n FILL(this.dataStart, this.length, u16(value), start, end);\n return this;\n }\n\n sort(comparator: (a: i16, b: i16) => i32 = COMPARATOR()): Int16Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int16Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int16Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: i16, index: i32, array: Int16Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: i16, index: i32, self: Int16Array) => i16): Int16Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: i16, index: i32, self: Int16Array) => bool): Int16Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: i16, index: i32, self: Int16Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: i16, index: i32, self: Int16Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: i16, index: i32, self: Int16Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: i16, index: i32, self: Int16Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: i16, index: i32, self: Int16Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Int16Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int16Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Uint16Array extends ArrayBufferView {\n [key: number]: u16;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): u16 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): u16 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: native): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: native): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): u16 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: u16, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: u16, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: u16, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array {\n FILL(this.dataStart, this.length, u16(value), start, end);\n return this;\n }\n\n sort(comparator: (a: u16, b: u16) => i32 = COMPARATOR()): Uint16Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint16Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint16Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: u16, index: i32, array: Uint16Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: u16, index: i32, self: Uint16Array) => u16): Uint16Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: u16, index: i32, self: Uint16Array) => bool): Uint16Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: u16, index: i32, self: Uint16Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: u16, index: i32, self: Uint16Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: u16, index: i32, self: Uint16Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: u16, index: i32, self: Uint16Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: u16, index: i32, self: Uint16Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Uint16Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint16Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Int32Array extends ArrayBufferView {\n [key: number]: i32;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): i32 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): i32 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: i32): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: i32): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): i32 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: i32, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: i32, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: i32, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: i32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array {\n FILL(this.dataStart, this.length, u32(value), start, end);\n return this;\n }\n\n sort(comparator: (a: i32, b: i32) => i32 = COMPARATOR()): Int32Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int32Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int32Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: i32, index: i32, array: Int32Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: i32, index: i32, self: Int32Array) => i32): Int32Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: i32, index: i32, self: Int32Array) => bool): Int32Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: i32, index: i32, self: Int32Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: i32, index: i32, self: Int32Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: i32, index: i32, self: Int32Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: i32, index: i32, self: Int32Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: i32, index: i32, self: Int32Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Int32Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int32Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Uint32Array extends ArrayBufferView {\n [key: number]: u32;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): u32 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): u32 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: u32): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: u32): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): u32 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: u32, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: u32, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: u32, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: u32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array {\n FILL(this.dataStart, this.length, value, start, end);\n return this;\n }\n\n sort(comparator: (a: u32, b: u32) => i32 = COMPARATOR()): Uint32Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint32Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint32Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: u32, index: i32, array: Uint32Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: u32, index: i32, self: Uint32Array) => u32): Uint32Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: u32, index: i32, self: Uint32Array) => bool): Uint32Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: u32, index: i32, self: Uint32Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: u32, index: i32, self: Uint32Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: u32, index: i32, self: Uint32Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: u32, index: i32, self: Uint32Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: u32, index: i32, self: Uint32Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Uint32Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint32Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Int64Array extends ArrayBufferView {\n [key: number]: i64;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): i64 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): i64 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: i64): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: i64): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): i64 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: i64, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: i64, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: i64, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: i64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array {\n FILL(this.dataStart, this.length, u64(value), start, end);\n return this;\n }\n\n sort(comparator: (a: i64, b: i64) => i32 = COMPARATOR()): Int64Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Int64Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Int64Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: i64, index: i32, array: Int64Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: i64, index: i32, self: Int64Array) => i64): Int64Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: i64, index: i32, self: Int64Array) => bool): Int64Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: i64, index: i32, self: Int64Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: i64, index: i32, self: Int64Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: i64, index: i32, self: Int64Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: i64, index: i32, self: Int64Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: i64, index: i32, self: Int64Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Int64Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Int64Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Uint64Array extends ArrayBufferView {\n [key: number]: u64;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): u64 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): u64 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: u64): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: u64): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): u64 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: u64, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: u64, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: u64, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: u64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array {\n FILL(this.dataStart, this.length, value, start, end);\n return this;\n }\n\n sort(comparator: (a: u64, b: u64) => i32 = COMPARATOR()): Uint64Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Uint64Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Uint64Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: u64, index: i32, array: Uint64Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: u64, index: i32, self: Uint64Array) => u64): Uint64Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: u64, index: i32, self: Uint64Array) => bool): Uint64Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: u64, index: i32, self: Uint64Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: u64, index: i32, self: Uint64Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: u64, index: i32, self: Uint64Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: u64, index: i32, self: Uint64Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: u64, index: i32, self: Uint64Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Uint64Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinIntegerArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Uint64Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Float32Array extends ArrayBufferView {\n [key: number]: f32;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): f32 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): f32 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: f32): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: f32): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): f32 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: f32, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: f32, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: f32, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: f32, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array {\n FILL(this.dataStart, this.length, value, start, end);\n return this;\n }\n\n sort(comparator: (a: f32, b: f32) => i32 = COMPARATOR()): Float32Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float32Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Float32Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: f32, index: i32, array: Float32Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: f32, index: i32, self: Float32Array) => f32): Float32Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: f32, index: i32, self: Float32Array) => bool): Float32Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: f32, index: i32, self: Float32Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: f32, index: i32, self: Float32Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: f32, index: i32, self: Float32Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: f32, index: i32, self: Float32Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: f32, index: i32, self: Float32Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Float32Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinFloatArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Float32Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\nexport class Float64Array extends ArrayBufferView {\n [key: number]: f64;\n\n // @ts-ignore: decorator\n @lazy\n static readonly BYTES_PER_ELEMENT: i32 = sizeof();\n\n constructor(length: i32) {\n super(length, alignof());\n }\n\n get length(): i32 {\n return this.byteLength >>> alignof();\n }\n\n @operator(\"[]\")\n private __get(index: i32): f64 {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n @unsafe @operator(\"{}\")\n private __uget(index: i32): f64 {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\")\n private __set(index: i32, value: f64): void {\n if (index >= this.byteLength >>> alignof()) throw new RangeError(E_INDEXOUTOFRANGE);\n store(this.dataStart + (index << alignof()), value);\n }\n\n @unsafe @operator(\"{}=\")\n private __uset(index: i32, value: f64): void {\n store(this.dataStart + (index << alignof()), value);\n }\n\n at(index: i32): f64 {\n let len = this.byteLength >>> alignof();\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n return load(this.dataStart + (index << alignof()));\n }\n\n includes(searchElement: f64, fromIndex: i32 = 0): bool {\n return INCLUDES(this, searchElement, fromIndex);\n }\n\n indexOf(searchElement: f64, fromIndex: i32 = 0): i32 {\n return INDEX_OF(this, searchElement, fromIndex);\n }\n\n lastIndexOf(searchElement: f64, fromIndex: i32 = this.length): i32 {\n return LAST_INDEX_OF(this, searchElement, fromIndex);\n }\n\n fill(value: f64, start: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array {\n FILL(this.dataStart, this.length, value, start, end);\n return this;\n }\n\n sort(comparator: (a: f64, b: f64) => i32 = COMPARATOR()): Float64Array {\n SORT(this.dataStart, this.length, comparator);\n return this;\n }\n\n slice(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array {\n return SLICE(this, begin, end);\n }\n\n subarray(begin: i32 = 0, end: i32 = i32.MAX_VALUE): Float64Array {\n return SUBARRAY(this, begin, end);\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Float64Array {\n return COPY_WITHIN(this, target, start, end);\n }\n\n reduce(\n fn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T,\n initialValue: T,\n ): T {\n return REDUCE(this, fn, initialValue);\n }\n\n reduceRight(\n fn: (accumulator: T, value: f64, index: i32, array: Float64Array) => T,\n initialValue: T,\n ): T {\n return REDUCE_RIGHT(this, fn, initialValue);\n }\n\n map(fn: (value: f64, index: i32, self: Float64Array) => f64): Float64Array {\n return MAP(this, fn);\n }\n\n filter(fn: (value: f64, index: i32, self: Float64Array) => bool): Float64Array {\n return FILTER(this, fn);\n }\n\n findIndex(fn: (value: f64, index: i32, self: Float64Array) => bool): i32 {\n return FIND_INDEX(this, fn);\n }\n\n findLastIndex(fn: (value: f64, index: i32, self: Float64Array) => bool): i32 {\n return FIND_LAST_INDEX(this, fn);\n }\n\n some(fn: (value: f64, index: i32, self: Float64Array) => bool): bool {\n return SOME(this, fn);\n }\n\n every(fn: (value: f64, index: i32, self: Float64Array) => bool): bool {\n return EVERY(this, fn);\n }\n\n forEach(fn: (value: f64, index: i32, self: Float64Array) => void): void {\n FOREACH(this, fn);\n }\n\n reverse(): Float64Array {\n REVERSE(this.dataStart, this.length);\n return this;\n }\n\n join(separator: string = \",\"): string {\n return joinFloatArray(this.dataStart, this.length, separator);\n }\n\n set>(source: U, offset: i32 = 0): void {\n SET(this, source, offset);\n }\n\n toString(): string {\n return this.join();\n }\n\n static wrap(buffer: ArrayBuffer, byteOffset: i32 = 0, length: i32 = -1): Float64Array {\n return WRAP(buffer, byteOffset, length);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction SLICE(\n array: TArray,\n start: i32,\n end: i32\n): TArray {\n let len = array.length;\n start = start < 0 ? max(start + len, 0) : min(start, len);\n end = end < 0 ? max(end + len, 0) : min(end , len);\n len = max(end - start, 0);\n let slice = instantiate(len);\n memory.copy(\n slice.dataStart,\n array.dataStart + (start << alignof()),\n len << alignof()\n );\n return slice;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction SUBARRAY(\n array: TArray,\n begin: i32,\n end: i32\n): TArray {\n let len = array.length;\n begin = begin < 0 ? max(len + begin, 0) : min(begin, len);\n end = end < 0 ? max(len + end, 0) : min(end, len);\n end = max(end, begin);\n\n let out = changetype(__new(offsetof(), idof()));\n let buf = changetype(array.buffer);\n store(changetype(out), buf, offsetof(\"buffer\"));\n __link(changetype(out), buf, false);\n store(changetype(out), array.dataStart + (begin << alignof()), offsetof(\"dataStart\"));\n store(changetype(out), (end - begin) << alignof(), offsetof(\"byteLength\"));\n return out;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction COPY_WITHIN(\n array: TArray,\n target: i32,\n start: i32,\n end: i32\n): TArray {\n let len = array.length;\n let ptr = array.dataStart;\n\n end = min(end, len);\n let to = target < 0 ? max(len + target, 0) : min(target, len);\n let from = start < 0 ? max(len + start, 0) : min(start, len);\n let last = end < 0 ? max(len + end, 0) : min(end, len);\n let count = min(last - from, len - to);\n\n memory.copy(\n ptr + (to << alignof()),\n ptr + (from << alignof()),\n count << alignof()\n );\n return array;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction REDUCE(\n array: TArray,\n fn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,\n initialValue: TRet\n): TRet {\n let ptr = array.dataStart;\n for (let i = 0, k = array.length; i < k; i++) {\n initialValue = fn(initialValue, load(ptr + (i << alignof())), i, array);\n }\n return initialValue;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction REDUCE_RIGHT(\n array: TArray,\n fn: (accumulator: TRet, value: T, index: i32, array: TArray) => TRet,\n initialValue: TRet\n): TRet {\n let ptr = array.dataStart;\n for (let i = array.length - 1; i >= 0; i--) {\n initialValue = fn(initialValue, load(ptr + (i << alignof())), i, array);\n }\n return initialValue;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction MAP(\n array: TArray,\n fn: (value: T, index: i32, self: TArray) => T,\n): TArray {\n let len = array.length;\n let ptr = array.dataStart;\n\n let byteLength = len << alignof();\n let out = changetype(__new(offsetof(), idof()));\n let buf = changetype(__new(byteLength, idof()));\n for (let i = 0; i < len; i++) {\n store(\n changetype(buf) + (i << alignof()),\n fn(load(ptr + (i << alignof())), i, array)\n );\n }\n store(changetype(out), changetype(buf), offsetof(\"buffer\"));\n __link(changetype(out), changetype(buf), false);\n store(changetype(out), changetype(buf), offsetof(\"dataStart\"));\n store(changetype(out), byteLength, offsetof(\"byteLength\"));\n return out;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction FILTER(\n array: TArray,\n fn: (value: T, index: i32, self: TArray) => bool,\n): TArray {\n let len = array.length;\n let out = changetype(__new(offsetof(), idof()));\n let buf = changetype(__new(len << alignof(), idof()));\n let dataStart = array.dataStart;\n let j: usize = 0;\n for (let i = 0; i < len; i++) {\n let value = load(dataStart + (i << alignof()));\n if (fn(value, i, array)) {\n store(\n changetype(buf) + (j++ << alignof()),\n value\n );\n }\n }\n // shrink output buffer\n let byteLength = j << alignof();\n let data = __renew(changetype(buf), byteLength);\n store(changetype(out), data, offsetof(\"buffer\"));\n __link(changetype(out), data, false);\n store(changetype(out), byteLength, offsetof(\"byteLength\"));\n store(changetype(out), data, offsetof(\"dataStart\"));\n return out;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction FIND_INDEX(\n array: TArray,\n fn: (value: T, index: i32, array: TArray) => bool,\n): i32 {\n let ptr = array.dataStart;\n for (let i = 0, k = array.length; i < k; i++) {\n if (fn(load(ptr + (i << alignof())), i, array)) return i;\n }\n return -1;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction FIND_LAST_INDEX(\n array: TArray,\n fn: (value: T, index: i32, array: TArray) => bool,\n): i32 {\n let ptr = array.dataStart;\n for (let i = array.length - 1; i >= 0; --i) {\n if (fn(load(ptr + (i << alignof())), i, array)) return i;\n }\n return -1;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction INCLUDES(\n array: TArray,\n searchElement: T,\n fromIndex: i32,\n): bool {\n if (isFloat()) {\n let index: isize = fromIndex;\n let len: isize = array.length;\n if (len == 0 || index >= len) return false;\n if (index < 0) index = max(len + index, 0);\n let dataStart = array.dataStart;\n while (index < len) {\n let elem = load(dataStart + (index << alignof()));\n // @ts-ignore\n if (elem == searchElement || isNaN(elem) & isNaN(searchElement)) return true;\n ++index;\n }\n return false;\n } else {\n return INDEX_OF(array, searchElement, fromIndex) >= 0;\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction INDEX_OF(\n array: TArray,\n searchElement: T,\n fromIndex: i32,\n): i32 {\n let index: isize = fromIndex;\n let len: isize = array.length;\n if (len == 0 || index >= len) return -1;\n if (index < 0) index = max(len + index, 0);\n let dataStart = array.dataStart;\n while (index < len) {\n if (load(dataStart + (index << alignof())) == searchElement) return index;\n ++index;\n }\n return -1;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction LAST_INDEX_OF(\n array: TArray,\n searchElement: T,\n fromIndex: i32,\n): i32 {\n let index: isize = fromIndex;\n let len: isize = array.length;\n if (len == 0) return -1;\n if (index < 0) index = len + index; // no need to clamp\n else if (index >= len) index = len - 1;\n let dataStart = array.dataStart;\n while (index >= 0) {\n if (load(dataStart + (index << alignof())) == searchElement) return index;\n --index;\n }\n return -1;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction SOME(\n array: TArray,\n fn: (value: T, index: i32, array: TArray) => bool,\n): bool {\n let ptr = array.dataStart;\n for (let i = 0, k = array.length; i < k; i++) {\n if (fn(load(ptr + (i << alignof())), i, array)) return true;\n }\n return false;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction EVERY(\n array: TArray,\n fn: (value: T, index: i32, array: TArray) => bool,\n): bool {\n let ptr = array.dataStart;\n for (let i = 0, k = array.length; i < k; i++) {\n if (fn(load(ptr + (i << alignof())), i, array)) continue;\n return false;\n }\n return true;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction FOREACH(\n array: TArray,\n fn: (value: T, index: i32, array: TArray) => void,\n): void {\n let ptr = array.dataStart;\n for (let i = 0, k = array.length; i < k; i++) {\n fn(load(ptr + (i << alignof())), i, array);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction WRAP(\n buffer: ArrayBuffer,\n byteOffset: i32 = 0,\n len: i32 = -1\n): TArray {\n let byteLength: i32;\n let bufferByteLength = buffer.byteLength;\n const mask: u32 = sizeof() - 1;\n if (i32(byteOffset > bufferByteLength) | (byteOffset & mask)) {\n throw new RangeError(E_INDEXOUTOFRANGE);\n }\n if (len < 0) {\n if (len == -1) {\n if (bufferByteLength & mask) {\n throw new RangeError(E_INVALIDLENGTH);\n }\n byteLength = bufferByteLength - byteOffset;\n } else {\n throw new RangeError(E_INVALIDLENGTH);\n }\n } else {\n byteLength = len << alignof();\n if (byteOffset + byteLength > bufferByteLength) {\n throw new RangeError(E_INVALIDLENGTH);\n }\n }\n let out = changetype(__new(offsetof(), idof()));\n store(changetype(out), changetype(buffer), offsetof(\"buffer\"));\n __link(changetype(out), changetype(buffer), false);\n store(changetype(out), byteLength, offsetof(\"byteLength\"));\n store(changetype(out), changetype(buffer) + byteOffset, offsetof(\"dataStart\"));\n return out;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction SET<\n TArray extends ArrayLike,\n UArray extends ArrayLike\n>(\n target: TArray,\n source: UArray,\n offset: i32 = 0\n): void {\n // need to assert at compile time that U is not a reference or a function\n if (isReference>()) {\n ERROR(E_NOTIMPLEMENTED);\n }\n let sourceLen = source.length;\n if (offset < 0 || sourceLen + offset > target.length) {\n // offset is out of bounds\n throw new RangeError(E_INDEXOUTOFRANGE);\n }\n // @ts-ignore: dataStart\n let targetStart = target.dataStart + (offset << (alignof>()));\n // @ts-ignore: dataStart\n let sourceStart = source.dataStart;\n // if the types align and match, use memory.copy() instead of manual loop\n if (\n isInteger>() == isInteger>() &&\n alignof>() == alignof>() &&\n !(isSigned>() && target instanceof Uint8ClampedArray)\n ) {\n memory.copy(targetStart, sourceStart, sourceLen << (alignof>()));\n } else {\n for (let i = 0; i < sourceLen; i++) {\n let ptr = targetStart + (i << (alignof>()));\n let value = load>(sourceStart + (i << (alignof>())));\n // if TArray is Uint8ClampedArray, then values must be clamped\n if (target instanceof Uint8ClampedArray) {\n if (isFloat>()) {\n store>(ptr,\n isFinite>(value)\n ? >max>(0, min>(255, value))\n : 0\n );\n } else {\n if (!isSigned>()) {\n store>(ptr, min>(255, value));\n } else if (sizeof>() <= 4) {\n store>(ptr, ~(value >> 31) & (((255 - value) >> 31) | value));\n } else {\n store>(ptr, ~(value >> 63) & (((255 - value) >> 63) | value));\n }\n }\n } else {\n if (isFloat>() && !isFloat>()) {\n store>(ptr, isFinite>(value) ? >value : 0);\n } else {\n store>(ptr, >value);\n }\n }\n }\n }\n}\n","/**\n * @fileoverview Various vector utility.\n * @license Apache-2.0\n */\n\n/** v128 zero constant. */\nexport const v128_zero = new Uint8Array(16);\n/** v128 all ones constant. */\nexport const v128_ones = new Uint8Array(16).fill(0xFF);\n","export function REVERSE(ptr: usize, len: usize): void {\n if (len > 1) {\n let\n i: usize = 0,\n tail: usize,\n hlen: usize = len >> 1;\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (sizeof() == 1) {\n // TODO: Decide later: Does we need this fast path cases?\n //\n // if (len == 4) {\n // store(ptr, bswap(load(ptr)));\n // return;\n // }\n // if (len == 8) {\n // store(ptr, bswap(load(ptr)));\n // return;\n // }\n tail = len - 8;\n while (i + 7 < hlen) {\n let front = ptr + i;\n let back = ptr + tail - i;\n let temp = bswap(load(front));\n store(front, bswap(load(back)));\n store(back, temp);\n i += 8;\n }\n }\n\n if (sizeof() == 2) {\n tail = len - 2;\n while (i + 1 < hlen) {\n let front = ptr + (i << 1);\n let back = ptr + (tail - i << 1);\n let temp = rotr(load(back), 16);\n store(back, rotr(load(front), 16));\n store(front, temp);\n i += 2;\n }\n }\n }\n\n tail = len - 1;\n while (i < hlen) {\n let front = ptr + (i << alignof());\n let back = ptr + (tail - i << alignof());\n let temp = load(front);\n store(front, load(back));\n store(back, temp);\n i++;\n }\n }\n}\n\nexport function FILL(\n ptr: usize,\n len: usize,\n value: T,\n start: isize,\n end: isize\n): void {\n start = start < 0 ? max(len + start, 0) : min(start, len);\n end = end < 0 ? max(len + end, 0) : min(end, len);\n\n if (sizeof() == 1) {\n if (start < end) {\n memory.fill(\n ptr + start,\n u8(value),\n (end - start)\n );\n }\n } else {\n if (ASC_SHRINK_LEVEL <= 1) {\n if (isInteger()) {\n // @ts-ignore\n if (value == 0 | value == -1) {\n if (start < end) {\n memory.fill(\n ptr + (start << alignof()),\n u8(value),\n (end - start) << alignof()\n );\n }\n return;\n }\n } else if (isFloat()) {\n // for floating non-negative zeros we can use fast memory.fill\n if ((sizeof() == 4 && reinterpret(f32(value)) == 0) ||\n (sizeof() == 8 && reinterpret(f64(value)) == 0)) {\n if (start < end) {\n memory.fill(\n ptr + (start << alignof()),\n 0,\n (end - start) << alignof()\n );\n }\n return;\n }\n }\n }\n for (; start < end; ++start) {\n store(ptr + (start << alignof()), value);\n }\n }\n}\n","/**\n * @fileoverview A TypeScript tokenizer modified for AssemblyScript.\n *\n * The `Tokenizer` scans over a source file and returns one syntactic token\n * at a time that the parser will combine to an abstract syntax tree.\n *\n * It skips over trivia like comments and whitespace and provides a general\n * mark/reset mechanism for the parser to utilize on ambiguous tokens, with\n * one token of lookahead otherwise.\n *\n * @license Apache-2.0\n */\n\nimport {\n Range,\n DiagnosticCode,\n DiagnosticMessage,\n DiagnosticEmitter\n} from \"./diagnostics\";\n\nimport {\n Source,\n CommentKind\n} from \"./ast\";\n\nimport {\n CharCode,\n isLineBreak,\n isWhiteSpace,\n isIdentifierStart,\n isIdentifierPart,\n isDecimal,\n isOctal,\n isHexBase,\n isHighSurrogate,\n combineSurrogates,\n numCodeUnits\n} from \"./util\";\n\n/** Named token types. */\nexport const enum Token {\n\n // keywords\n // discarded: ANY, BOOLEAN, NEVER, NUMBER, STRING, SYMBOL, UNDEFINED, LESSTHAN_SLASH\n\n Abstract,\n As,\n Async,\n Await, // ES2017\n Break, // ES2017\n Case, // ES2017\n Catch, // ES2017\n Class, // ES2017\n Const, // ES2017\n Continue, // ES2017\n Constructor,\n Debugger, // ES2017\n Declare,\n Default, // ES2017\n Delete, // ES2017\n Do, // ES2017\n Else, // ES2017\n Enum, // ES2017 future\n Export, // ES2017\n Extends, // ES2017\n False, // ES\n Finally, // ES2017\n For, // ES2017\n From, // AS possible identifier\n Function, // ES2017\n Get,\n If, // ES2017\n Implements, // ES2017 non-lexical\n Import, // ES2017\n In, // ES2017\n InstanceOf, // ES2017\n Interface, // ES2017 non-lexical\n Is,\n KeyOf,\n Let, // ES2017 non-lexical\n Module, // AS possible identifier\n Namespace, // AS possible identifier\n New, // ES2017\n Null, // ES\n Of,\n Override,\n Package, // ES2017 non-lexical\n Private, // ES2017 non-lexical\n Protected, // ES2017 non-lexical\n Public, // ES2017 non-lexical\n Readonly,\n Return, // ES2017\n Set,\n Static, // ES2017 non-lexical\n Super, // ES2017\n Switch, // ES2017\n This, // ES2017\n Throw, // ES2017\n True, // ES\n Try, // ES2017\n Type, // AS possible identifier\n TypeOf, // ES2017\n Var, // ES2017\n Void, // ES2017\n While, // ES2017\n With, // ES2017\n Yield, // ES2017\n\n // punctuation\n\n OpenBrace,\n CloseBrace,\n OpenParen,\n CloseParen,\n OpenBracket,\n CloseBracket,\n Dot,\n Dot_Dot_Dot,\n Semicolon,\n Comma,\n LessThan,\n GreaterThan,\n LessThan_Equals,\n GreaterThan_Equals,\n Equals_Equals,\n Exclamation_Equals,\n Equals_Equals_Equals,\n Exclamation_Equals_Equals,\n Equals_GreaterThan,\n Plus,\n Minus,\n Asterisk_Asterisk,\n Asterisk,\n Slash,\n Percent,\n Plus_Plus,\n Minus_Minus,\n LessThan_LessThan,\n GreaterThan_GreaterThan,\n GreaterThan_GreaterThan_GreaterThan,\n Ampersand,\n Bar,\n Caret,\n Exclamation,\n Tilde,\n Ampersand_Ampersand,\n Bar_Bar,\n Question,\n Colon,\n Equals,\n Plus_Equals,\n Minus_Equals,\n Asterisk_Equals,\n Asterisk_Asterisk_Equals,\n Slash_Equals,\n Percent_Equals,\n LessThan_LessThan_Equals,\n GreaterThan_GreaterThan_Equals,\n GreaterThan_GreaterThan_GreaterThan_Equals,\n Ampersand_Equals,\n Bar_Equals,\n Caret_Equals,\n At,\n\n // literals\n\n Identifier,\n StringLiteral,\n IntegerLiteral,\n FloatLiteral,\n TemplateLiteral,\n\n // meta\n\n Invalid,\n EndOfFile\n}\n\nexport const enum IdentifierHandling {\n Default,\n Prefer,\n Always\n}\n\nexport function tokenFromKeyword(text: string): Token {\n let len = text.length;\n assert(len);\n switch (text.charCodeAt(0)) {\n case CharCode.a: {\n if (len == 5) {\n if (text == \"async\") return Token.Async;\n if (text == \"await\") return Token.Await;\n break;\n }\n if (text == \"as\") return Token.As;\n if (text == \"abstract\") return Token.Abstract;\n break;\n }\n case CharCode.b: {\n if (text == \"break\") return Token.Break;\n break;\n }\n case CharCode.c: {\n if (len == 5) {\n if (text == \"const\") return Token.Const;\n if (text == \"class\") return Token.Class;\n if (text == \"catch\") return Token.Catch;\n break;\n }\n if (text == \"case\") return Token.Case;\n if (text == \"continue\") return Token.Continue;\n if (text == \"constructor\") return Token.Constructor;\n break;\n }\n case CharCode.d: {\n if (len == 7) {\n if (text == \"default\") return Token.Default;\n if (text == \"declare\") return Token.Declare;\n break;\n }\n if (text == \"do\") return Token.Do;\n if (text == \"delete\") return Token.Delete;\n if (text == \"debugger\") return Token.Debugger;\n break;\n }\n case CharCode.e: {\n if (len == 4) {\n if (text == \"else\") return Token.Else;\n if (text == \"enum\") return Token.Enum;\n break;\n }\n if (text == \"export\") return Token.Export;\n if (text == \"extends\") return Token.Extends;\n break;\n }\n case CharCode.f: {\n if (len <= 5) {\n if (text == \"false\") return Token.False;\n if (text == \"for\") return Token.For;\n if (text == \"from\") return Token.From;\n break;\n }\n if (text == \"function\") return Token.Function;\n if (text == \"finally\") return Token.Finally;\n break;\n }\n case CharCode.g: {\n if (text == \"get\") return Token.Get;\n break;\n }\n case CharCode.i: {\n if (len == 2) {\n if (text == \"if\") return Token.If;\n if (text == \"in\") return Token.In;\n if (text == \"is\") return Token.Is;\n break;\n }\n switch (text.charCodeAt(3)) {\n case CharCode.l: {\n if (text == \"implements\") return Token.Implements;\n break;\n }\n case CharCode.o: {\n if (text == \"import\") return Token.Import;\n break;\n }\n case CharCode.t: {\n if (text == \"instanceof\") return Token.InstanceOf;\n break;\n }\n case CharCode.e: {\n if (text == \"interface\") return Token.Interface;\n break;\n }\n }\n break;\n }\n case CharCode.k: {\n if (text == \"keyof\") return Token.KeyOf;\n break;\n }\n case CharCode.l: {\n if (text == \"let\") return Token.Let;\n break;\n }\n case CharCode.m: {\n if (text == \"module\") return Token.Module;\n break;\n }\n case CharCode.n: {\n if (text == \"new\") return Token.New;\n if (text == \"null\") return Token.Null;\n if (text == \"namespace\") return Token.Namespace;\n break;\n }\n case CharCode.o: {\n if (text == \"of\") return Token.Of;\n if (text == \"override\") return Token.Override;\n break;\n }\n case CharCode.p: {\n if (len == 7) {\n if (text == \"private\") return Token.Private;\n if (text == \"package\") return Token.Package;\n break;\n }\n if (text == \"public\") return Token.Public;\n if (text == \"protected\") return Token.Protected;\n break;\n }\n case CharCode.r: {\n if (text == \"return\") return Token.Return;\n if (text == \"readonly\") return Token.Readonly;\n break;\n }\n case CharCode.s: {\n if (len == 6) {\n if (text == \"switch\") return Token.Switch;\n if (text == \"static\") return Token.Static;\n break;\n }\n if (text == \"set\") return Token.Set;\n if (text == \"super\") return Token.Super;\n break;\n }\n case CharCode.t: {\n if (len == 4) {\n if (text == \"true\") return Token.True;\n if (text == \"this\") return Token.This;\n if (text == \"type\") return Token.Type;\n break;\n }\n if (text == \"try\") return Token.Try;\n if (text == \"throw\") return Token.Throw;\n if (text == \"typeof\") return Token.TypeOf;\n break;\n }\n case CharCode.v: {\n if (text == \"var\") return Token.Var;\n if (text == \"void\") return Token.Void;\n break;\n }\n case CharCode.w: {\n if (text == \"while\") return Token.While;\n if (text == \"with\") return Token.With;\n break;\n }\n case CharCode.y: {\n if (text == \"yield\") return Token.Yield;\n break;\n }\n }\n return Token.Invalid;\n}\n\nexport function tokenIsAlsoIdentifier(token: Token): bool {\n switch (token) {\n case Token.Abstract:\n case Token.As:\n case Token.Constructor:\n case Token.Declare:\n case Token.Delete:\n case Token.From:\n case Token.For:\n case Token.Get:\n case Token.InstanceOf:\n case Token.Is:\n case Token.KeyOf:\n case Token.Module:\n case Token.Namespace:\n case Token.Null:\n case Token.Readonly:\n case Token.Set:\n case Token.Type:\n case Token.Void: return true;\n default: return false;\n }\n}\n\nexport function isIllegalVariableIdentifier(name: string): bool {\n assert(name.length);\n switch (name.charCodeAt(0)) {\n case CharCode.d: return name == \"delete\";\n case CharCode.f: return name == \"for\";\n case CharCode.i: return name == \"instanceof\";\n case CharCode.n: return name == \"null\";\n case CharCode.v: return name == \"void\";\n }\n return false;\n}\n\nexport function operatorTokenToString(token: Token): string {\n switch (token) {\n case Token.Delete: return \"delete\";\n case Token.In: return \"in\";\n case Token.InstanceOf: return \"instanceof\";\n case Token.New: return \"new\";\n case Token.TypeOf: return \"typeof\";\n case Token.Void: return \"void\";\n case Token.Yield: return \"yield\";\n case Token.Dot_Dot_Dot: return \"...\";\n case Token.Comma: return \",\";\n case Token.LessThan: return \"<\";\n case Token.GreaterThan: return \">\";\n case Token.LessThan_Equals: return \"<=\";\n case Token.GreaterThan_Equals: return \">=\";\n case Token.Equals_Equals: return \"==\";\n case Token.Exclamation_Equals: return \"!=\";\n case Token.Equals_Equals_Equals: return \"===\";\n case Token.Exclamation_Equals_Equals: return \"!==\";\n case Token.Plus: return \"+\";\n case Token.Minus: return \"-\";\n case Token.Asterisk_Asterisk: return \"**\";\n case Token.Asterisk: return \"*\";\n case Token.Slash: return \"/\";\n case Token.Percent: return \"%\";\n case Token.Plus_Plus: return \"++\";\n case Token.Minus_Minus: return \"--\";\n case Token.LessThan_LessThan: return \"<<\";\n case Token.GreaterThan_GreaterThan: return \">>\";\n case Token.GreaterThan_GreaterThan_GreaterThan: return \">>>\";\n case Token.Ampersand: return \"&\";\n case Token.Bar: return \"|\";\n case Token.Caret: return \"^\";\n case Token.Exclamation: return \"!\";\n case Token.Tilde: return \"~\";\n case Token.Ampersand_Ampersand: return \"&&\";\n case Token.Bar_Bar: return \"||\";\n case Token.Equals: return \"=\";\n case Token.Plus_Equals: return \"+=\";\n case Token.Minus_Equals: return \"-=\";\n case Token.Asterisk_Equals: return \"*=\";\n case Token.Asterisk_Asterisk_Equals: return \"**=\";\n case Token.Slash_Equals: return \"/=\";\n case Token.Percent_Equals: return \"%=\";\n case Token.LessThan_LessThan_Equals: return \"<<=\";\n case Token.GreaterThan_GreaterThan_Equals: return \">>=\";\n case Token.GreaterThan_GreaterThan_GreaterThan_Equals: return \">>>=\";\n case Token.Ampersand_Equals: return \"&=\";\n case Token.Bar_Equals: return \"|=\";\n case Token.Caret_Equals: return \"^=\";\n default: {\n assert(false);\n return \"\";\n }\n }\n}\n\n/** Handler for intercepting comments while tokenizing. */\nexport type CommentHandler = (kind: CommentKind, text: string, range: Range) => void;\n\n/** Whether a token begins on a new line, if known. */\nenum OnNewLine {\n No,\n Yes,\n Unknown\n}\n\n/** Tokenizes a source to individual {@link Token}s. */\nexport class Tokenizer extends DiagnosticEmitter {\n\n source: Source;\n end: i32 = 0;\n\n pos: i32 = 0;\n token: Token = -1;\n tokenPos: i32 = 0;\n\n nextToken: Token = -1;\n nextTokenPos: i32 = 0;\n nextTokenOnNewLine: OnNewLine = OnNewLine.Unknown;\n\n onComment: CommentHandler | null = null;\n\n /** Constructs a new tokenizer. */\n constructor(source: Source, diagnostics: DiagnosticMessage[] | null = null) {\n super(diagnostics);\n\n if (!diagnostics) diagnostics = [];\n this.diagnostics = diagnostics;\n this.source = source;\n\n let text = source.text;\n let end = text.length;\n let pos = 0;\n // skip bom\n if (\n pos < end &&\n text.charCodeAt(pos) == CharCode.ByteOrderMark\n ) {\n ++pos;\n }\n\n // skip shebang\n if (\n pos + 1 < end &&\n text.charCodeAt(pos) == CharCode.Hash &&\n text.charCodeAt(pos + 1) == CharCode.Exclamation\n ) {\n pos += 2;\n while (\n pos < end &&\n text.charCodeAt(pos) != CharCode.LineFeed\n ) {\n ++pos;\n }\n // 'next' now starts at lf or eof\n }\n this.pos = pos;\n this.end = end;\n }\n\n next(identifierHandling: IdentifierHandling = IdentifierHandling.Default): Token {\n this.clearNextToken();\n let token: Token;\n do token = this.unsafeNext(identifierHandling);\n while (token == Token.Invalid);\n this.token = token;\n return token;\n }\n\n private unsafeNext(\n identifierHandling: IdentifierHandling = IdentifierHandling.Default,\n maxTokenLength: i32 = i32.MAX_VALUE\n ): Token {\n let text = this.source.text;\n let end = this.end;\n let pos = this.pos;\n while (pos < end) {\n this.tokenPos = pos;\n let c = text.charCodeAt(pos);\n switch (c) {\n case CharCode.CarriageReturn: {\n if (!(\n ++pos < end &&\n text.charCodeAt(pos) == CharCode.LineFeed\n )) break;\n // otherwise fall-through\n }\n case CharCode.LineFeed:\n case CharCode.Tab:\n case CharCode.VerticalTab:\n case CharCode.FormFeed:\n case CharCode.Space: {\n ++pos;\n break;\n }\n case CharCode.Exclamation: {\n ++pos;\n if (\n maxTokenLength > 1 && pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n ++pos;\n if (\n maxTokenLength > 2 && pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.Exclamation_Equals_Equals;\n }\n this.pos = pos;\n return Token.Exclamation_Equals;\n }\n this.pos = pos;\n return Token.Exclamation;\n }\n case CharCode.DoubleQuote:\n case CharCode.SingleQuote: {\n this.pos = pos;\n return Token.StringLiteral;\n }\n case CharCode.Backtick: {\n this.pos = pos;\n return Token.TemplateLiteral;\n }\n case CharCode.Percent: {\n ++pos;\n if (\n maxTokenLength > 1 && pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.Percent_Equals;\n }\n this.pos = pos;\n return Token.Percent;\n }\n case CharCode.Ampersand: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Ampersand) {\n this.pos = pos + 1;\n return Token.Ampersand_Ampersand;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.Ampersand_Equals;\n }\n }\n this.pos = pos;\n return Token.Ampersand;\n }\n case CharCode.OpenParen: {\n this.pos = pos + 1;\n return Token.OpenParen;\n }\n case CharCode.CloseParen: {\n this.pos = pos + 1;\n return Token.CloseParen;\n }\n case CharCode.Asterisk: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.Asterisk_Equals;\n }\n if (chr == CharCode.Asterisk) {\n ++pos;\n if (\n maxTokenLength > 2 && pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.Asterisk_Asterisk_Equals;\n }\n this.pos = pos;\n return Token.Asterisk_Asterisk;\n }\n }\n this.pos = pos;\n return Token.Asterisk;\n }\n case CharCode.Plus: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Plus) {\n this.pos = pos + 1;\n return Token.Plus_Plus;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.Plus_Equals;\n }\n }\n this.pos = pos;\n return Token.Plus;\n }\n case CharCode.Comma: {\n this.pos = pos + 1;\n return Token.Comma;\n }\n case CharCode.Minus: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Minus) {\n this.pos = pos + 1;\n return Token.Minus_Minus;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.Minus_Equals;\n }\n }\n this.pos = pos;\n return Token.Minus;\n }\n case CharCode.Dot: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (isDecimal(chr)) {\n this.pos = pos - 1;\n return Token.FloatLiteral; // expects a call to readFloat\n }\n if (\n maxTokenLength > 2 && pos + 1 < end &&\n chr == CharCode.Dot &&\n text.charCodeAt(pos + 1) == CharCode.Dot\n ) {\n this.pos = pos + 2;\n return Token.Dot_Dot_Dot;\n }\n }\n this.pos = pos;\n return Token.Dot;\n }\n case CharCode.Slash: {\n let commentStartPos = pos;\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Slash) { // single-line\n let commentKind = CommentKind.Line;\n if (\n pos + 1 < end &&\n text.charCodeAt(pos + 1) == CharCode.Slash\n ) {\n ++pos;\n commentKind = CommentKind.Triple;\n }\n while (++pos < end) {\n if (text.charCodeAt(pos) == CharCode.LineFeed) {\n ++pos;\n break;\n }\n }\n if (this.onComment) {\n this.onComment(\n commentKind,\n text.substring(commentStartPos, pos),\n this.range(commentStartPos, pos)\n );\n }\n break;\n }\n if (chr == CharCode.Asterisk) { // multi-line\n let closed = false;\n while (++pos < end) {\n c = text.charCodeAt(pos);\n if (\n c == CharCode.Asterisk &&\n pos + 1 < end &&\n text.charCodeAt(pos + 1) == CharCode.Slash\n ) {\n pos += 2;\n closed = true;\n break;\n }\n }\n if (!closed) {\n this.error(\n DiagnosticCode._0_expected,\n this.range(pos), \"*/\"\n );\n } else if (this.onComment) {\n this.onComment(\n CommentKind.Block,\n text.substring(commentStartPos, pos),\n this.range(commentStartPos, pos)\n );\n }\n break;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.Slash_Equals;\n }\n }\n this.pos = pos;\n return Token.Slash;\n }\n case CharCode._0:\n case CharCode._1:\n case CharCode._2:\n case CharCode._3:\n case CharCode._4:\n case CharCode._5:\n case CharCode._6:\n case CharCode._7:\n case CharCode._8:\n case CharCode._9: {\n this.pos = pos;\n return this.testInteger()\n ? Token.IntegerLiteral // expects a call to readInteger\n : Token.FloatLiteral; // expects a call to readFloat\n }\n case CharCode.Colon: {\n this.pos = pos + 1;\n return Token.Colon;\n }\n case CharCode.Semicolon: {\n this.pos = pos + 1;\n return Token.Semicolon;\n }\n case CharCode.LessThan: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.LessThan) {\n ++pos;\n if (\n maxTokenLength > 2 &&\n pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.LessThan_LessThan_Equals;\n }\n this.pos = pos;\n return Token.LessThan_LessThan;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.LessThan_Equals;\n }\n }\n this.pos = pos;\n return Token.LessThan;\n }\n case CharCode.Equals: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Equals) {\n ++pos;\n if (\n maxTokenLength > 2 &&\n pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.Equals_Equals_Equals;\n }\n this.pos = pos;\n return Token.Equals_Equals;\n }\n if (chr == CharCode.GreaterThan) {\n this.pos = pos + 1;\n return Token.Equals_GreaterThan;\n }\n }\n this.pos = pos;\n return Token.Equals;\n }\n case CharCode.GreaterThan: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.GreaterThan) {\n ++pos;\n if (maxTokenLength > 2 && pos < end) {\n chr = text.charCodeAt(pos);\n if (chr == CharCode.GreaterThan) {\n ++pos;\n if (\n maxTokenLength > 3 && pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.GreaterThan_GreaterThan_GreaterThan_Equals;\n }\n this.pos = pos;\n return Token.GreaterThan_GreaterThan_GreaterThan;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.GreaterThan_GreaterThan_Equals;\n }\n }\n this.pos = pos;\n return Token.GreaterThan_GreaterThan;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.GreaterThan_Equals;\n }\n }\n this.pos = pos;\n return Token.GreaterThan;\n }\n case CharCode.Question: {\n this.pos = pos + 1;\n return Token.Question;\n }\n case CharCode.OpenBracket: {\n this.pos = pos + 1;\n return Token.OpenBracket;\n }\n case CharCode.CloseBracket: {\n this.pos = pos + 1;\n return Token.CloseBracket;\n }\n case CharCode.Caret: {\n ++pos;\n if (\n maxTokenLength > 1 && pos < end &&\n text.charCodeAt(pos) == CharCode.Equals\n ) {\n this.pos = pos + 1;\n return Token.Caret_Equals;\n }\n this.pos = pos;\n return Token.Caret;\n }\n case CharCode.OpenBrace: {\n this.pos = pos + 1;\n return Token.OpenBrace;\n }\n case CharCode.Bar: {\n ++pos;\n if (maxTokenLength > 1 && pos < end) {\n let chr = text.charCodeAt(pos);\n if (chr == CharCode.Bar) {\n this.pos = pos + 1;\n return Token.Bar_Bar;\n }\n if (chr == CharCode.Equals) {\n this.pos = pos + 1;\n return Token.Bar_Equals;\n }\n }\n this.pos = pos;\n return Token.Bar;\n }\n case CharCode.CloseBrace: {\n this.pos = pos + 1;\n return Token.CloseBrace;\n }\n case CharCode.Tilde: {\n this.pos = pos + 1;\n return Token.Tilde;\n }\n case CharCode.At: {\n this.pos = pos + 1;\n return Token.At;\n }\n default: {\n // Unicode-aware from here on\n if (isHighSurrogate(c) && pos + 1 < end) {\n c = combineSurrogates(c, text.charCodeAt(pos + 1));\n }\n if (isIdentifierStart(c)) {\n let posBefore = pos;\n while (\n (pos += numCodeUnits(c)) < end &&\n isIdentifierPart(c = text.codePointAt(pos))\n ) { /* nop */ }\n if (identifierHandling != IdentifierHandling.Always) {\n let maybeKeywordToken = tokenFromKeyword(text.substring(posBefore, pos));\n if (\n maybeKeywordToken != Token.Invalid &&\n !(\n identifierHandling == IdentifierHandling.Prefer &&\n tokenIsAlsoIdentifier(maybeKeywordToken)\n )\n ) {\n this.pos = pos;\n return maybeKeywordToken;\n }\n }\n this.pos = posBefore;\n return Token.Identifier;\n } else if (isWhiteSpace(c)) {\n ++pos; // assume no supplementary whitespaces\n break;\n }\n let start = pos;\n pos += numCodeUnits(c);\n this.error(\n DiagnosticCode.Invalid_character,\n this.range(start, pos)\n );\n this.pos = pos;\n return Token.Invalid;\n }\n }\n }\n this.pos = pos;\n return Token.EndOfFile;\n }\n\n peek(\n identifierHandling: IdentifierHandling = IdentifierHandling.Default,\n maxCompoundLength: i32 = i32.MAX_VALUE\n ): Token {\n let nextToken = this.nextToken;\n if (nextToken < 0) {\n let posBefore = this.pos;\n let tokenBefore = this.token;\n let tokenPosBefore = this.tokenPos;\n do nextToken = this.unsafeNext(identifierHandling, maxCompoundLength);\n while (nextToken == Token.Invalid);\n this.nextToken = nextToken;\n this.nextTokenPos = this.tokenPos;\n this.nextTokenOnNewLine = OnNewLine.Unknown;\n this.pos = posBefore;\n this.token = tokenBefore;\n this.tokenPos = tokenPosBefore;\n }\n return nextToken;\n }\n\n peekOnNewLine(): bool {\n switch (this.nextTokenOnNewLine) {\n case OnNewLine.No: return false;\n case OnNewLine.Yes: return true;\n }\n this.peek();\n let text = this.source.text;\n for (let pos = this.pos, end = this.nextTokenPos; pos < end; ++pos) {\n if (isLineBreak(text.charCodeAt(pos))) {\n this.nextTokenOnNewLine = OnNewLine.Yes;\n return true;\n }\n }\n this.nextTokenOnNewLine = OnNewLine.No;\n return false;\n }\n\n skipIdentifier(identifierHandling: IdentifierHandling = IdentifierHandling.Prefer): bool {\n return this.skip(Token.Identifier, identifierHandling);\n }\n\n skip(token: Token, identifierHandling: IdentifierHandling = IdentifierHandling.Default): bool {\n let posBefore = this.pos;\n let tokenBefore = this.token;\n let tokenPosBefore = this.tokenPos;\n let maxCompoundLength = i32.MAX_VALUE;\n if (token == Token.GreaterThan) { // where parsing type arguments\n maxCompoundLength = 1;\n }\n let nextToken: Token;\n do nextToken = this.unsafeNext(identifierHandling, maxCompoundLength);\n while (nextToken == Token.Invalid);\n if (nextToken == token) {\n this.token = token;\n this.clearNextToken();\n return true;\n } else {\n this.pos = posBefore;\n this.token = tokenBefore;\n this.tokenPos = tokenPosBefore;\n return false;\n }\n }\n\n mark(): State {\n let state = reusableState;\n if (state) {\n reusableState = null;\n state.pos = this.pos;\n state.token = this.token;\n state.tokenPos = this.tokenPos;\n } else {\n state = new State(this.pos, this.token, this.tokenPos);\n }\n return state;\n }\n\n discard(state: State): void {\n reusableState = state;\n }\n\n reset(state: State): void {\n this.pos = state.pos;\n this.token = state.token;\n this.tokenPos = state.tokenPos;\n this.clearNextToken();\n }\n\n clearNextToken(): void {\n this.nextToken = -1;\n this.nextTokenPos = 0;\n this.nextTokenOnNewLine = OnNewLine.Unknown;\n }\n\n range(start: i32 = -1, end: i32 = -1): Range {\n if (start < 0) {\n start = this.tokenPos;\n end = this.pos;\n } else if (end < 0) {\n end = start;\n }\n let range = new Range(start, end);\n range.source = this.source;\n return range;\n }\n\n readIdentifier(): string {\n let text = this.source.text;\n let end = this.end;\n let pos = this.pos;\n let start = pos;\n let c = text.codePointAt(pos);\n assert(isIdentifierStart(c));\n while (\n (pos += numCodeUnits(c)) < end &&\n isIdentifierPart(c = text.codePointAt(pos))\n );\n this.pos = pos;\n return text.substring(start, pos);\n }\n\n readingTemplateString: bool = false;\n readStringStart: i32 = 0;\n readStringEnd: i32 = 0;\n\n readString(quote: i32 = 0, isTaggedTemplate: bool = false): string {\n let text = this.source.text;\n let end = this.end;\n let pos = this.pos;\n if (!quote) quote = text.charCodeAt(pos++);\n let start = pos;\n this.readStringStart = start;\n let result = \"\";\n\n while (true) {\n if (pos >= end) {\n result += text.substring(start, pos);\n this.error(\n DiagnosticCode.Unterminated_string_literal,\n this.range(start - 1, end)\n );\n this.readStringEnd = end;\n break;\n }\n let c = text.charCodeAt(pos);\n if (c == quote) {\n this.readStringEnd = pos;\n result += text.substring(start, pos++);\n break;\n }\n if (c == CharCode.Backslash) {\n result += text.substring(start, pos);\n this.pos = pos; // save\n result += this.readEscapeSequence(isTaggedTemplate);\n pos = this.pos; // restore\n start = pos;\n continue;\n }\n if (quote == CharCode.Backtick) {\n if (c == CharCode.Dollar && pos + 1 < end && text.charCodeAt(pos + 1) == CharCode.OpenBrace) {\n result += text.substring(start, pos);\n this.readStringEnd = pos;\n this.pos = pos + 2;\n this.readingTemplateString = true;\n return result;\n }\n } else if (isLineBreak(c)) {\n result += text.substring(start, pos);\n this.error(\n DiagnosticCode.Unterminated_string_literal,\n this.range(start - 1, pos)\n );\n this.readStringEnd = pos;\n break;\n }\n ++pos;\n }\n this.pos = pos;\n this.readingTemplateString = false;\n return result;\n }\n\n readEscapeSequence(isTaggedTemplate: bool = false): string {\n // for context on isTaggedTemplate, see: https://tc39.es/proposal-template-literal-revision/\n let start = this.pos;\n let end = this.end;\n if (++this.pos >= end) {\n this.error(\n DiagnosticCode.Unexpected_end_of_text,\n this.range(end)\n );\n return \"\";\n }\n\n let text = this.source.text;\n let c = text.charCodeAt(this.pos++);\n switch (c) {\n case CharCode._0: {\n if (isTaggedTemplate && this.pos < end && isDecimal(text.charCodeAt(this.pos))) {\n ++this.pos;\n return text.substring(start, this.pos);\n }\n return \"\\0\";\n }\n case CharCode.b: return \"\\b\";\n case CharCode.t: return \"\\t\";\n case CharCode.n: return \"\\n\";\n case CharCode.v: return \"\\v\";\n case CharCode.f: return \"\\f\";\n case CharCode.r: return \"\\r\";\n case CharCode.SingleQuote: return \"'\";\n case CharCode.DoubleQuote: return \"\\\"\";\n case CharCode.u: {\n if (\n this.pos < end &&\n text.charCodeAt(this.pos) == CharCode.OpenBrace\n ) {\n ++this.pos;\n return this.readExtendedUnicodeEscape(isTaggedTemplate ? start : -1); // \\u{DDDDDDDD}\n }\n return this.readUnicodeEscape(isTaggedTemplate ? start : -1); // \\uDDDD\n }\n case CharCode.x: {\n return this.readHexadecimalEscape(2, isTaggedTemplate ? start : - 1); // \\xDD\n }\n case CharCode.CarriageReturn: {\n if (\n this.pos < end &&\n text.charCodeAt(this.pos) == CharCode.LineFeed\n ) {\n ++this.pos;\n }\n // fall through\n }\n case CharCode.LineFeed:\n case CharCode.LineSeparator:\n case CharCode.ParagraphSeparator: return \"\";\n default: return String.fromCodePoint(c);\n }\n }\n\n readRegexpPattern(): string {\n let text = this.source.text;\n let start = this.pos;\n let end = this.end;\n let escaped = false;\n while (true) {\n if (this.pos >= end) {\n this.error(\n DiagnosticCode.Unterminated_regular_expression_literal,\n this.range(start, end)\n );\n break;\n }\n if (text.charCodeAt(this.pos) == CharCode.Backslash) {\n ++this.pos;\n escaped = true;\n continue;\n }\n let c = text.charCodeAt(this.pos);\n if (!escaped && c == CharCode.Slash) break;\n if (isLineBreak(c)) {\n this.error(\n DiagnosticCode.Unterminated_regular_expression_literal,\n this.range(start, this.pos)\n );\n break;\n }\n ++this.pos;\n escaped = false;\n }\n return text.substring(start, this.pos);\n }\n\n readRegexpFlags(): string {\n let text = this.source.text;\n let start = this.pos;\n let end = this.end;\n let flags = 0;\n while (this.pos < end) {\n let c: i32 = text.charCodeAt(this.pos);\n if (!isIdentifierPart(c)) break;\n ++this.pos;\n\n // make sure each supported flag is unique\n switch (c) {\n case CharCode.g: {\n flags |= flags & 1 ? -1 : 1;\n break;\n }\n case CharCode.i: {\n flags |= flags & 2 ? -1 : 2;\n break;\n }\n case CharCode.m: {\n flags |= flags & 4 ? -1 : 4;\n break;\n }\n default: {\n flags = -1;\n break;\n }\n }\n }\n if (flags == -1) {\n this.error(\n DiagnosticCode.Invalid_regular_expression_flags,\n this.range(start, this.pos)\n );\n }\n return text.substring(start, this.pos);\n }\n\n testInteger(): bool {\n let text = this.source.text;\n let pos = this.pos;\n let end = this.end;\n if (pos + 1 < end && text.charCodeAt(pos) == CharCode._0) {\n switch (text.charCodeAt(pos + 2) | 32) {\n case CharCode.x:\n case CharCode.b:\n case CharCode.o: return true;\n }\n }\n while (pos < end) {\n let c = text.charCodeAt(pos);\n if (c == CharCode.Dot || (c | 32) == CharCode.e) return false;\n if (c != CharCode._ && (c < CharCode._0 || c > CharCode._9)) break;\n // does not validate separator placement (this is done in readXYInteger)\n pos++;\n }\n return true;\n }\n\n readInteger(): i64 {\n let text = this.source.text;\n let pos = this.pos;\n if (pos + 2 < this.end && text.charCodeAt(pos) == CharCode._0) {\n switch (text.charCodeAt(pos + 1) | 32) {\n case CharCode.x: {\n this.pos = pos + 2;\n return this.readHexInteger();\n }\n case CharCode.b: {\n this.pos = pos + 2;\n return this.readBinaryInteger();\n }\n case CharCode.o: {\n this.pos = pos + 2;\n return this.readOctalInteger();\n }\n }\n if (isOctal(text.charCodeAt(pos + 1))) {\n let start = pos;\n this.pos = pos + 1;\n let value = this.readOctalInteger();\n this.error(\n DiagnosticCode.Octal_literals_are_not_allowed_in_strict_mode,\n this.range(start, this.pos)\n );\n return value;\n }\n }\n return this.readDecimalInteger();\n }\n\n readHexInteger(): i64 {\n let text = this.source.text;\n let pos = this.pos;\n let end = this.end;\n let start = pos;\n let sepEnd = start;\n let value = i64_zero;\n let i64_4 = i64_new(4);\n let nextValue = value;\n let overflowOccurred = false;\n\n while (pos < end) {\n let c = text.charCodeAt(pos);\n if (isDecimal(c)) {\n // (value << 4) + c - CharCode._0\n nextValue = i64_add(\n i64_shl(value, i64_4),\n i64_new(c - CharCode._0)\n );\n } else if (isHexBase(c)) {\n // (value << 4) + (c | 32) + (10 - CharCode.a)\n nextValue = i64_add(\n i64_shl(value, i64_4),\n i64_new((c | 32) + (10 - CharCode.a))\n );\n } else if (c == CharCode._) {\n if (sepEnd == pos) {\n this.error(\n sepEnd == start\n ? DiagnosticCode.Numeric_separators_are_not_allowed_here\n : DiagnosticCode.Multiple_consecutive_numeric_separators_are_not_permitted,\n this.range(pos)\n );\n }\n sepEnd = pos + 1;\n } else {\n break;\n }\n if (i64_gt_u(value, nextValue)) {\n // Unsigned overflow occurred\n overflowOccurred = true;\n }\n value = nextValue;\n ++pos;\n }\n if (pos == start) {\n this.error(\n DiagnosticCode.Hexadecimal_digit_expected,\n this.range(start)\n );\n } else if (sepEnd == pos) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(sepEnd - 1)\n );\n }\n if (overflowOccurred) {\n this.error(\n DiagnosticCode.Literal_0_does_not_fit_into_i64_or_u64_types,\n this.range(start - 2, pos),\n this.source.text.substring(start - 2, pos)\n );\n }\n this.pos = pos;\n return value;\n }\n\n readDecimalInteger(): i64 {\n let text = this.source.text;\n let pos = this.pos;\n let end = this.end;\n let start = pos;\n let sepEnd = start;\n let value = i64_zero;\n let i64_10 = i64_new(10);\n let nextValue = value;\n let overflowOccurred = false;\n\n while (pos < end) {\n let c = text.charCodeAt(pos);\n if (isDecimal(c)) {\n // value = value * 10 + c - CharCode._0;\n nextValue = i64_add(\n i64_mul(value, i64_10),\n i64_new(c - CharCode._0)\n );\n } else if (c == CharCode._) {\n if (sepEnd == pos) {\n this.error(\n sepEnd == start\n ? DiagnosticCode.Numeric_separators_are_not_allowed_here\n : DiagnosticCode.Multiple_consecutive_numeric_separators_are_not_permitted,\n this.range(pos)\n );\n } else if (pos - 1 == start && text.charCodeAt(pos - 1) == CharCode._0) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(pos)\n );\n }\n sepEnd = pos + 1;\n } else {\n break;\n }\n if (i64_gt_u(value, nextValue)) {\n // Unsigned overflow occurred\n overflowOccurred = true;\n }\n value = nextValue;\n ++pos;\n }\n if (pos == start) {\n this.error(\n DiagnosticCode.Digit_expected,\n this.range(start)\n );\n } else if (sepEnd == pos) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(sepEnd - 1)\n );\n } else if (overflowOccurred) {\n this.error(\n DiagnosticCode.Literal_0_does_not_fit_into_i64_or_u64_types,\n this.range(start, pos),\n this.source.text.substring(start, pos)\n );\n }\n this.pos = pos;\n return value;\n }\n\n readOctalInteger(): i64 {\n let text = this.source.text;\n let pos = this.pos;\n let end = this.end;\n let start = pos;\n let sepEnd = start;\n let value = i64_zero;\n let i64_3 = i64_new(3);\n let nextValue = value;\n let overflowOccurred = false;\n\n while (pos < end) {\n let c = text.charCodeAt(pos);\n if (isOctal(c)) {\n // (value << 3) + c - CharCode._0\n nextValue = i64_add(\n i64_shl(value, i64_3),\n i64_new(c - CharCode._0)\n );\n } else if (c == CharCode._) {\n if (sepEnd == pos) {\n this.error(\n sepEnd == start\n ? DiagnosticCode.Numeric_separators_are_not_allowed_here\n : DiagnosticCode.Multiple_consecutive_numeric_separators_are_not_permitted,\n this.range(pos)\n );\n }\n sepEnd = pos + 1;\n } else {\n break;\n }\n if (i64_gt_u(value, nextValue)) {\n // Unsigned overflow occurred\n overflowOccurred = true;\n }\n value = nextValue;\n ++pos;\n }\n if (pos == start) {\n this.error(\n DiagnosticCode.Octal_digit_expected,\n this.range(start)\n );\n } else if (sepEnd == pos) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(sepEnd - 1)\n );\n } else if (overflowOccurred) {\n this.error(\n DiagnosticCode.Literal_0_does_not_fit_into_i64_or_u64_types,\n this.range(start - 2, pos),\n this.source.text.substring(start - 2, pos)\n );\n }\n this.pos = pos;\n return value;\n }\n\n readBinaryInteger(): i64 {\n let text = this.source.text;\n let pos = this.pos;\n let end = this.end;\n let start = pos;\n let sepEnd = start;\n let value = i64_zero;\n let nextValue = value;\n let overflowOccurred = false;\n\n while (pos < end) {\n let c = text.charCodeAt(pos);\n if (c == CharCode._0) {\n // value << 1 | 0\n nextValue = i64_shl(value, i64_one);\n } else if (c == CharCode._1) {\n // value << 1 | 1\n nextValue = i64_or(\n i64_shl(value, i64_one),\n i64_one\n );\n } else if (c == CharCode._) {\n if (sepEnd == pos) {\n this.error(\n sepEnd == start\n ? DiagnosticCode.Numeric_separators_are_not_allowed_here\n : DiagnosticCode.Multiple_consecutive_numeric_separators_are_not_permitted,\n this.range(pos)\n );\n }\n sepEnd = pos + 1;\n } else {\n break;\n }\n if (i64_gt(value, nextValue)) {\n // Overflow occurred\n overflowOccurred = true;\n }\n value = nextValue;\n ++pos;\n }\n if (pos == start) {\n this.error(\n DiagnosticCode.Binary_digit_expected,\n this.range(start)\n );\n } else if (sepEnd == pos) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(sepEnd - 1)\n );\n } else if (overflowOccurred) {\n this.error(\n DiagnosticCode.Literal_0_does_not_fit_into_i64_or_u64_types,\n this.range(start - 2, pos),\n this.source.text.substring(start - 2, pos)\n );\n }\n this.pos = pos;\n return value;\n }\n\n readFloat(): f64 {\n // let text = this.source.text;\n // if (text.charCodeAt(this.pos) == CharCode._0 && this.pos + 2 < this.end) {\n // switch (text.charCodeAt(this.pos + 1)) {\n // case CharCode.X:\n // case CharCode.x: {\n // this.pos += 2;\n // return this.readHexFloat();\n // }\n // }\n // }\n return this.readDecimalFloat();\n }\n\n readDecimalFloat(): f64 {\n let text = this.source.text;\n let end = this.end;\n let start = this.pos;\n let sepCount = this.readDecimalFloatPartial(false);\n if (this.pos < end && text.charCodeAt(this.pos) == CharCode.Dot) {\n ++this.pos;\n sepCount += this.readDecimalFloatPartial();\n }\n if (this.pos < end) {\n let c = text.charCodeAt(this.pos);\n if ((c | 32) == CharCode.e) {\n if (\n ++this.pos < end &&\n (c = text.charCodeAt(this.pos)) == CharCode.Minus || c == CharCode.Plus &&\n isDecimal(text.charCodeAt(this.pos + 1))\n ) {\n ++this.pos;\n }\n sepCount += this.readDecimalFloatPartial();\n }\n }\n let result = text.substring(start, this.pos);\n if (sepCount) result = result.replaceAll(\"_\", \"\");\n return parseFloat(result);\n }\n\n /** Reads past one section of a decimal float literal. Returns the number of separators encountered. */\n private readDecimalFloatPartial(allowLeadingZeroSep: bool = true): u32 {\n let text = this.source.text;\n let pos = this.pos;\n let start = pos;\n let end = this.end;\n let sepEnd = start;\n let sepCount = 0;\n\n while (pos < end) {\n let c = text.charCodeAt(pos);\n\n if (c == CharCode._) {\n if (sepEnd == pos) {\n this.error(\n sepEnd == start\n ? DiagnosticCode.Numeric_separators_are_not_allowed_here\n : DiagnosticCode.Multiple_consecutive_numeric_separators_are_not_permitted,\n this.range(pos)\n );\n } else if (!allowLeadingZeroSep && pos - 1 == start && text.charCodeAt(pos - 1) == CharCode._0) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(pos)\n );\n }\n sepEnd = pos + 1;\n ++sepCount;\n } else if (!isDecimal(c)) {\n break;\n }\n ++pos;\n }\n\n if (pos != start && sepEnd == pos) {\n this.error(\n DiagnosticCode.Numeric_separators_are_not_allowed_here,\n this.range(sepEnd - 1)\n );\n }\n\n this.pos = pos;\n return sepCount;\n }\n\n readHexFloat(): f64 {\n throw new Error(\"not implemented\"); // TBD\n }\n\n readHexadecimalEscape(remain: i32 = 2, startIfTaggedTemplate: i32 = -1): string {\n let value = 0;\n let text = this.source.text;\n let pos = this.pos;\n let end = this.end;\n while (pos < end) {\n let c = text.charCodeAt(pos++);\n if (isDecimal(c)) {\n value = (value << 4) + c - CharCode._0;\n } else if (isHexBase(c)) {\n value = (value << 4) + (c | 32) + (10 - CharCode.a);\n } else if (~startIfTaggedTemplate) {\n this.pos = --pos;\n return text.substring(startIfTaggedTemplate, pos);\n } else {\n this.pos = pos;\n this.error(\n DiagnosticCode.Hexadecimal_digit_expected,\n this.range(pos - 1, pos)\n );\n return \"\";\n }\n if (--remain == 0) break;\n }\n if (remain) { // invalid\n this.pos = pos;\n if (~startIfTaggedTemplate) {\n return text.substring(startIfTaggedTemplate, pos);\n }\n this.error(\n DiagnosticCode.Unexpected_end_of_text,\n this.range(pos)\n );\n return \"\";\n }\n this.pos = pos;\n return String.fromCodePoint(value);\n }\n\n checkForIdentifierStartAfterNumericLiteral(): void {\n // TODO: BigInt n\n let pos = this.pos;\n if (pos < this.end && isIdentifierStart(this.source.text.charCodeAt(pos))) {\n this.error(\n DiagnosticCode.An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal,\n this.range(pos)\n );\n }\n }\n\n readUnicodeEscape(startIfTaggedTemplate: i32 = -1): string {\n return this.readHexadecimalEscape(4, startIfTaggedTemplate);\n }\n\n private readExtendedUnicodeEscape(startIfTaggedTemplate: i32 = -1): string {\n let start = this.pos;\n let value = this.readHexInteger();\n let value32 = i64_low(value);\n let invalid = false;\n\n assert(!i64_high(value));\n if (value32 > 0x10FFFF) {\n if (startIfTaggedTemplate == -1) {\n this.error(\n DiagnosticCode.An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive,\n this.range(start, this.pos)\n );\n }\n invalid = true;\n }\n\n let end = this.end;\n let text = this.source.text;\n if (this.pos >= end) {\n if (startIfTaggedTemplate == -1) {\n this.error(\n DiagnosticCode.Unexpected_end_of_text,\n this.range(start, end)\n );\n }\n invalid = true;\n } else if (text.charCodeAt(this.pos) == CharCode.CloseBrace) {\n ++this.pos;\n } else {\n if (startIfTaggedTemplate == -1) {\n this.error(\n DiagnosticCode.Unterminated_Unicode_escape_sequence,\n this.range(start, this.pos)\n );\n }\n invalid = true;\n }\n\n if (invalid) {\n return ~startIfTaggedTemplate\n ? text.substring(startIfTaggedTemplate, this.pos)\n : \"\";\n }\n return String.fromCodePoint(value32);\n }\n}\n\n/** Tokenizer state as returned by {@link Tokenizer#mark} and consumed by {@link Tokenizer#reset}. */\nexport class State {\n constructor(\n /** Current position. */\n public pos: i32,\n /** Current token. */\n public token: Token,\n /** Current token's position. */\n public tokenPos: i32\n ) {}\n}\n\n// Reusable state object to reduce allocations\nlet reusableState: State | null = null;\n","/**\n * @fileoverview A concurrent code flow analyzer.\n *\n * Flows keep track of compilation state and can be queried for various\n * conditions, like whether the current branch always terminates, whether\n * a local is known to be non-null or whether an expression has possibly\n * overflown its value range.\n *\n * To accomplish this, compilation of each function begins with a clean\n * flow populated with initial local states etc. While compilation\n * progresses, statements and expressions update flow state while control\n * constructs fork, potentially add scoped locals and later merge these\n * forked branches as necessary.\n *\n * @license Apache-2.0\n */\n\nimport {\n Type,\n TypeFlags,\n TypeKind\n} from \"./types\";\n\nimport {\n Program,\n Local,\n Function,\n Element,\n ElementKind,\n Class,\n TypedElement,\n mangleInternalName,\n Property,\n PropertyPrototype\n} from \"./program\";\n\nimport {\n TypeRef,\n ExpressionId,\n ExpressionRef,\n BinaryOp,\n UnaryOp,\n\n getExpressionId,\n getLocalGetIndex,\n isLocalTee,\n getLocalSetValue,\n getGlobalGetName,\n getBinaryOp,\n getBinaryLeft,\n getConstValueI32,\n getBinaryRight,\n getUnaryOp,\n getExpressionType,\n getConstValueI64Low,\n getConstValueF32,\n getConstValueF64,\n getLoadBytes,\n isLoadSigned,\n getBlockName,\n getBlockChildCount,\n getBlockChildAt,\n getIfTrue,\n getIfFalse,\n getSelectThen,\n getSelectElse,\n getCallTarget,\n getLocalSetIndex,\n getIfCondition,\n getUnaryValue,\n getCallOperandAt,\n getCallOperandCount,\n isConstZero,\n isConstNonZero\n} from \"./module\";\n\nimport {\n CommonFlags\n} from \"./common\";\n\nimport {\n UncheckedBehavior\n} from \"./compiler\";\n\nimport {\n DiagnosticCode\n} from \"./diagnostics\";\n\nimport {\n Node\n} from \"./ast\";\n\nimport {\n cloneMap\n} from \"./util\";\n\nimport {\n BuiltinNames\n} from \"./builtins\";\n\n/** Control flow flags indicating specific conditions. */\nexport const enum FlowFlags {\n /** No specific conditions. */\n None = 0,\n\n // categorical\n\n /** This flow always returns. */\n Returns = 1 << 0,\n /** This flow always returns a wrapped value. */\n ReturnsWrapped = 1 << 1,\n /** This flow always returns a non-null value. */\n ReturnsNonNull = 1 << 2,\n /** This flow always throws. */\n Throws = 1 << 3,\n /** This flow always breaks. */\n Breaks = 1 << 4,\n /** This flow always continues. */\n Continues = 1 << 5,\n /** This flow always accesses `this`. Constructors only. */\n AccessesThis = 1 << 6,\n /** This flow always calls `super`. Constructors only. */\n CallsSuper = 1 << 7,\n /** This flow always terminates (returns, throws or continues). */\n Terminates = 1 << 8, // Note that this doesn't cover BREAKS, which is separate\n\n // conditional\n\n /** This flow conditionally returns in a child flow. */\n ConditionallyReturns = 1 << 9,\n /** This flow conditionally throws in a child flow. */\n ConditionallyThrows = 1 << 10,\n /** This flow conditionally breaks in a child flow. */\n ConditionallyBreaks = 1 << 11,\n /** This flow conditionally continues in a child flow. */\n ConditionallyContinues = 1 << 12,\n /** This flow conditionally accesses `this` in a child flow. Constructors only. */\n ConditionallyAccessesThis = 1 << 13,\n /** This flow may return a non-this value. Constructors only. */\n MayReturnNonThis = 1 << 14,\n\n // other\n\n /** This is a flow with explicitly disabled bounds checking. */\n UncheckedContext = 1 << 15,\n /** This is a flow compiling a constructor parameter. */\n CtorParamContext = 1 << 16,\n\n // masks\n\n /** Any categorical flag. */\n AnyCategorical = FlowFlags.Returns\n | FlowFlags.ReturnsWrapped\n | FlowFlags.ReturnsNonNull\n | FlowFlags.Throws\n | FlowFlags.Breaks\n | FlowFlags.Continues\n | FlowFlags.AccessesThis\n | FlowFlags.CallsSuper\n | FlowFlags.Terminates,\n\n /** Any conditional flag. */\n AnyConditional = FlowFlags.ConditionallyReturns\n | FlowFlags.ConditionallyThrows\n | FlowFlags.ConditionallyBreaks\n | FlowFlags.ConditionallyContinues\n | FlowFlags.ConditionallyAccessesThis\n}\n\n/** Flags indicating the current state of a local. */\nexport const enum LocalFlags {\n /** No specific conditions. */\n None = 0,\n\n /** Local is constant. */\n Constant = 1 << 0,\n /** Local is properly wrapped. Relevant for small integers. */\n Wrapped = 1 << 1,\n /** Local is non-null. */\n NonNull = 1 << 2,\n /** Local is initialized. */\n Initialized = 1 << 3\n}\n\n/** Flags indicating the current state of a field. */\nexport const enum FieldFlags {\n None = 0,\n Initialized = 1 << 0\n}\n\n/** Condition kinds. */\nexport const enum ConditionKind {\n /** Outcome of the condition is unknown */\n Unknown,\n /** Condition is always true. */\n True,\n /** Condition is always false. */\n False\n}\n\n/** A control flow evaluator. */\nexport class Flow {\n\n /** Creates the default top-level flow of the specified function. */\n static createDefault(targetFunction: Function): Flow {\n let flow = new Flow(targetFunction);\n if (targetFunction.is(CommonFlags.Constructor)) {\n flow.initThisFieldFlags();\n }\n if (targetFunction.program.options.uncheckedBehavior === UncheckedBehavior.Always) {\n flow.set(FlowFlags.UncheckedContext);\n }\n return flow;\n }\n\n /** Creates an inline flow, compiling `inlineFunction` into `targetFunction`. */\n static createInline(targetFunction: Function, inlineFunction: Function): Flow {\n // Note that `targetFunction` and `inlineFunction` can be the same function\n // when it is inlined into itself.\n let flow = new Flow(targetFunction, inlineFunction);\n flow.inlineReturnLabel = `${inlineFunction.internalName}|inlined.${(inlineFunction.nextInlineId++)}`;\n if (inlineFunction.is(CommonFlags.Constructor)) {\n flow.initThisFieldFlags();\n }\n if (targetFunction.program.options.uncheckedBehavior === UncheckedBehavior.Always) {\n flow.set(FlowFlags.UncheckedContext);\n }\n return flow;\n }\n\n private constructor(\n /** Target function this flow generates code into. */\n public targetFunction: Function,\n /** Inline function this flow generates code from, if any. */\n public inlineFunction: Function | null = null\n ) {\n // Setup is performed above so inline ids and field flags are not reset\n // when forking flows, which also uses the constructor.\n }\n\n /** Parent flow. */\n parent: Flow | null = null;\n /** Outer flow. Only relevant for first-class functions. */\n outer: Flow | null = null;\n /** Flow flags indicating specific conditions. */\n flags: FlowFlags = FlowFlags.None;\n /** The label we break to when encountering a continue statement. */\n continueLabel: string | null = null;\n /** The label we break to when encountering a break statement. */\n breakLabel: string | null = null;\n /** Scoped local variables. */\n scopedLocals: Map | null = null;\n /** Local flags. */\n localFlags: LocalFlags[] = [];\n /** Field flags on `this`. Constructors only. */\n thisFieldFlags: Map | null = null;\n /** The label we break to when encountering a return statement, when inlining. */\n inlineReturnLabel: string | null = null;\n /** Alternative flows if a compound expression is true-ish. */\n trueFlows: Map | null = null;\n /** Alternative flows if a compound expression is false-ish. */\n falseFlows: Map | null = null;\n\n /** Tests if this is an inline flow. */\n get isInline(): bool {\n return this.inlineFunction != null;\n }\n\n /** Gets the source function being compiled. Differs from target when inlining. */\n get sourceFunction(): Function {\n // Obtaining the source function is useful when resolving elements relative\n // to their source location. Note that the source function does not necessarily\n // materialize in the binary, as it might be inlined. Code, locals, etc. must\n // always be added to / maintained in the materializing target function instead.\n let inlineFunction = this.inlineFunction;\n if (inlineFunction) return inlineFunction;\n return this.targetFunction;\n }\n\n /** Gets the program this flow belongs to. */\n get program(): Program {\n return this.targetFunction.program;\n }\n\n /** Gets the current return type. */\n get returnType(): Type {\n return this.sourceFunction.signature.returnType;\n }\n\n /** Gets the current contextual type arguments. */\n get contextualTypeArguments(): Map | null {\n return this.sourceFunction.contextualTypeArguments;\n }\n\n /** Tests if this flow has the specified flag or flags. */\n is(flag: FlowFlags): bool { return (this.flags & flag) == flag; }\n /** Tests if this flow has one of the specified flags. */\n isAny(flag: FlowFlags): bool { return (this.flags & flag) != 0; }\n /** Sets the specified flag or flags. */\n set(flag: FlowFlags): void { this.flags |= flag; }\n /** Unsets the specified flag or flags. */\n unset(flag: FlowFlags): void { this.flags &= ~flag; }\n\n deriveConditionalFlags(): FlowFlags {\n let condiFlags = this.flags & FlowFlags.AnyConditional;\n if (this.is(FlowFlags.Returns)) {\n condiFlags |= FlowFlags.ConditionallyReturns;\n }\n if (this.is(FlowFlags.Throws)) {\n condiFlags |= FlowFlags.ConditionallyThrows;\n }\n if (this.is(FlowFlags.Breaks)) {\n condiFlags |= FlowFlags.ConditionallyBreaks;\n }\n if (this.is(FlowFlags.Continues)) {\n condiFlags |= FlowFlags.ConditionallyContinues;\n }\n if (this.is(FlowFlags.AccessesThis)) {\n condiFlags |= FlowFlags.ConditionallyAccessesThis;\n }\n return condiFlags;\n }\n\n /** Forks this flow to a child flow. */\n fork(\n /** Whether a new break context is established, e.g. by a block. */\n newBreakContext: bool = false,\n /** Whether a new continue context is established, e.g. by a loop. */\n newContinueContext: bool = newBreakContext\n ): Flow {\n let branch = new Flow(this.targetFunction, this.inlineFunction);\n branch.parent = this;\n branch.flags = this.flags;\n branch.outer = this.outer;\n if (newBreakContext) {\n branch.flags &= ~(\n FlowFlags.Breaks |\n FlowFlags.ConditionallyBreaks\n );\n } else {\n branch.breakLabel = this.breakLabel;\n }\n if (newContinueContext) {\n branch.flags &= ~(\n FlowFlags.Continues |\n FlowFlags.ConditionallyContinues\n );\n } else {\n branch.continueLabel = this.continueLabel;\n }\n branch.localFlags = this.localFlags.slice();\n if (this.sourceFunction.is(CommonFlags.Constructor)) {\n let thisFieldFlags = assert(this.thisFieldFlags);\n branch.thisFieldFlags = cloneMap(thisFieldFlags);\n } else {\n assert(!this.thisFieldFlags);\n }\n branch.inlineReturnLabel = this.inlineReturnLabel;\n return branch;\n }\n\n /** Forks this flow to a child flow where `condExpr` is true-ish. */\n forkThen(\n /** Condition that turned out to be true. */\n condExpr: ExpressionRef,\n /** Whether a new break context is established, e.g. by a block. */\n newBreakContext: bool = false,\n /** Whether a new continue context is established, e.g. by a loop. */\n newContinueContext: bool = newBreakContext\n ): Flow {\n let flow = this.fork(newBreakContext, newContinueContext);\n let trueFlows = this.trueFlows;\n if (trueFlows && trueFlows.has(condExpr)) {\n flow.inherit(changetype(trueFlows.get(condExpr)));\n }\n flow.inheritNonnullIfTrue(condExpr);\n return flow;\n }\n\n /** Remembers the alternative flow if `condExpr` turns out `true`. */\n noteThen(condExpr: ExpressionRef, trueFlow: Flow): void {\n let trueFlows = this.trueFlows;\n if (!trueFlows) this.trueFlows = trueFlows = new Map();\n trueFlows.set(condExpr, trueFlow);\n }\n\n /** Forks this flow to a child flow where `condExpr` is false-ish. */\n forkElse(\n /** Condition that turned out to be false. */\n condExpr: ExpressionRef\n ): Flow {\n let flow = this.fork();\n let falseFlows = this.falseFlows;\n if (falseFlows && falseFlows.has(condExpr)) {\n flow.inherit(changetype(falseFlows.get(condExpr)));\n }\n flow.inheritNonnullIfFalse(condExpr);\n return flow;\n }\n\n /** Remembers the alternative flow if `condExpr` turns out `false`. */\n noteElse(condExpr: ExpressionRef, falseFlow: Flow): void {\n let falseFlows = this.falseFlows;\n if (!falseFlows) this.falseFlows = falseFlows = new Map();\n falseFlows.set(condExpr, falseFlow);\n }\n\n /** Gets a free temporary local of the specified type. */\n getTempLocal(type: Type): Local {\n let local = this.targetFunction.addLocal(type);\n this.unsetLocalFlag(local.index, ~0);\n return local;\n }\n\n /** Gets the scoped local of the specified name. */\n getScopedLocal(name: string): Local | null {\n let scopedLocals = this.scopedLocals;\n if (scopedLocals && scopedLocals.has(name)) return assert(scopedLocals.get(name));\n return null;\n }\n\n /** Adds a new scoped local of the specified name. */\n addScopedLocal(name: string, type: Type): Local {\n let scopedLocal = this.getTempLocal(type);\n scopedLocal.name = name;\n scopedLocal.internalName = mangleInternalName(name, scopedLocal.parent, false);\n let scopedLocals = this.scopedLocals;\n if (!scopedLocals) this.scopedLocals = scopedLocals = new Map();\n else assert(!scopedLocals.has(name));\n scopedLocal.set(CommonFlags.Scoped);\n scopedLocals.set(name, scopedLocal);\n return scopedLocal;\n }\n\n /** Adds a new scoped dummy local of the specified name. */\n addScopedDummyLocal(name: string, type: Type, declarationNode: Node): Local {\n let scopedDummy = new Local(name, -1, type, this.targetFunction);\n let scopedLocals = this.scopedLocals;\n if (!scopedLocals) this.scopedLocals = scopedLocals = new Map();\n else if (scopedLocals.has(name)) {\n this.program.error(\n DiagnosticCode.Cannot_redeclare_block_scoped_variable_0,\n declarationNode.range, name\n );\n }\n scopedDummy.set(CommonFlags.Scoped);\n scopedLocals.set(name, scopedDummy);\n return scopedDummy;\n }\n\n /** Adds a new scoped alias for the specified local. For example `super` aliased to the `this` local. */\n addScopedAlias(name: string, type: Type, index: i32, reportNode: Node | null = null): Local {\n let scopedLocals = this.scopedLocals;\n if (!scopedLocals) {\n this.scopedLocals = scopedLocals = new Map();\n } else if (scopedLocals.has(name)) {\n let existingLocal = assert(scopedLocals.get(name));\n if (reportNode) {\n if (!existingLocal.declaration.range.source.isNative) {\n this.program.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n reportNode.range,\n existingLocal.declaration.name.range,\n name\n );\n } else {\n this.program.error(\n DiagnosticCode.Duplicate_identifier_0,\n reportNode.range, name\n );\n }\n }\n return existingLocal;\n }\n assert(index < this.targetFunction.localsByIndex.length);\n let scopedAlias = new Local(name, index, type, this.targetFunction);\n scopedAlias.set(CommonFlags.Scoped);\n scopedLocals.set(name, scopedAlias);\n return scopedAlias;\n }\n\n /** Frees a single scoped local by its name. */\n freeScopedDummyLocal(name: string): void {\n let scopedLocals = assert(this.scopedLocals);\n assert(scopedLocals.has(name));\n let local = assert(scopedLocals.get(name));\n assert(local.index == -1);\n scopedLocals.delete(name);\n }\n\n /** Looks up the local of the specified name in the current scope. */\n lookupLocal(name: string): Local | null {\n let current: Flow | null = this;\n do {\n let scope = current.scopedLocals;\n if (scope && scope.has(name)) return assert(scope.get(name));\n current = current.parent;\n } while (current);\n return null;\n }\n\n /** Looks up the element with the specified name relative to the scope of this flow. */\n lookup(name: string): Element | null {\n let element = this.lookupLocal(name);\n if (element) return element;\n return this.sourceFunction.lookup(name);\n }\n\n /** Tests if the local at the specified index has the specified flag or flags. */\n isLocalFlag(index: i32, flag: LocalFlags, defaultIfInlined: bool = true): bool {\n if (index < 0) return defaultIfInlined;\n let localFlags = this.localFlags;\n return index < localFlags.length && (unchecked(localFlags[index]) & flag) == flag;\n }\n\n /** Tests if the local at the specified index has any of the specified flags. */\n isAnyLocalFlag(index: i32, flag: LocalFlags, defaultIfInlined: bool = true): bool {\n if (index < 0) return defaultIfInlined;\n let localFlags = this.localFlags;\n return index < localFlags.length && (unchecked(localFlags[index]) & flag) != 0;\n }\n\n /** Sets the specified flag or flags on the local at the specified index. */\n setLocalFlag(index: i32, flag: LocalFlags): void {\n if (index < 0) return;\n let localFlags = this.localFlags;\n let flags = index < localFlags.length ? unchecked(localFlags[index]) : 0;\n localFlags[index] = flags | flag;\n }\n\n /** Unsets the specified flag or flags on the local at the specified index. */\n unsetLocalFlag(index: i32, flag: LocalFlags): void {\n if (index < 0) return;\n let localFlags = this.localFlags;\n let flags = index < localFlags.length ? unchecked(localFlags[index]) : 0;\n localFlags[index] = flags & ~flag;\n }\n\n /** Initializes `this` field flags. */\n initThisFieldFlags(): void {\n let sourceFunction = this.sourceFunction;\n assert(sourceFunction.is(CommonFlags.Constructor));\n let parent = sourceFunction.parent;\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n this.thisFieldFlags = new Map();\n let members = classInstance.members;\n if (members) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = _values[i];\n if (member.kind != ElementKind.PropertyPrototype) continue;\n // only interested in fields (resolved during class finalization)\n let property = (member).instance;\n if (!property || !property.isField) continue;\n if (\n // guaranteed by super\n property.prototype.parent != classInstance ||\n // has field initializer\n property.initializerNode ||\n // is initialized as a ctor parameter\n property.prototype.parameterIndex != -1 ||\n // is safe to initialize with zero\n property.type.isAny(TypeFlags.Value | TypeFlags.Nullable)\n ) {\n this.setThisFieldFlag(property, FieldFlags.Initialized);\n }\n }\n }\n }\n\n /** Tests if the specified `this` field has the specified flag or flags. */\n isThisFieldFlag(field: Property, flag: FieldFlags): bool {\n let fieldFlags = this.thisFieldFlags;\n if (fieldFlags != null && fieldFlags.has(field)) {\n return (changetype(fieldFlags.get(field)) & flag) == flag;\n }\n return false;\n }\n\n /** Sets the specified flag or flags on the given `this` field. */\n setThisFieldFlag(field: Property, flag: FieldFlags): void {\n let fieldFlags = this.thisFieldFlags;\n if (fieldFlags) {\n assert(this.sourceFunction.is(CommonFlags.Constructor));\n if (fieldFlags.has(field)) {\n let flags = changetype(fieldFlags.get(field));\n fieldFlags.set(field, flags | flag);\n } else {\n fieldFlags.set(field, flag);\n }\n } else {\n assert(!this.sourceFunction.is(CommonFlags.Constructor));\n }\n }\n\n /** Pushes a new control flow label, for example when entering a loop that one can `break` from. */\n pushControlFlowLabel(): i32 {\n let targetFunction = this.targetFunction;\n let id = targetFunction.nextBreakId++;\n let stack = targetFunction.breakStack;\n if (!stack) targetFunction.breakStack = [ id ];\n else stack.push(id);\n return id;\n }\n\n /** Pops the most recent control flow label and validates that it matches. */\n popControlFlowLabel(expectedLabel: i32): void {\n let targetFunction = this.targetFunction;\n let stack = assert(targetFunction.breakStack); // should exist\n assert(stack.length); // should not be empty\n assert(stack.pop() == expectedLabel); // should match\n }\n\n /** Inherits flags of another flow into this one, i.e. a finished inner block. */\n inherit(other: Flow): void {\n assert(other.targetFunction == this.targetFunction);\n let otherFlags = other.flags;\n\n // respective inner flags are irrelevant if contexts differ\n if (this.breakLabel != other.breakLabel) {\n if (otherFlags & (FlowFlags.Breaks | FlowFlags.ConditionallyBreaks)) {\n otherFlags &= ~FlowFlags.Terminates;\n }\n otherFlags &= ~(FlowFlags.Breaks | FlowFlags.ConditionallyBreaks);\n }\n if (this.continueLabel != other.continueLabel) {\n otherFlags &= ~(FlowFlags.Continues | FlowFlags.ConditionallyContinues);\n }\n\n this.flags = this.flags | otherFlags; // what happens before is still true\n this.localFlags = other.localFlags;\n this.thisFieldFlags = other.thisFieldFlags;\n }\n\n\n /** Merges only the side effects of a branch, i.e. when not taken. */\n mergeSideEffects(other: Flow): void {\n assert(other.targetFunction == this.targetFunction);\n\n let thisFlags = this.flags;\n let otherFlags = other.flags;\n let newFlags = FlowFlags.None;\n\n if (thisFlags & FlowFlags.Returns) { // nothing can change that\n newFlags |= FlowFlags.Returns;\n } else if (otherFlags & FlowFlags.Returns) {\n newFlags |= FlowFlags.ConditionallyReturns;\n } else {\n newFlags |= (thisFlags | otherFlags) & FlowFlags.ConditionallyReturns;\n }\n\n // must be the case in both\n newFlags |= thisFlags & otherFlags & FlowFlags.ReturnsWrapped;\n newFlags |= thisFlags & otherFlags & FlowFlags.ReturnsNonNull;\n\n if (thisFlags & FlowFlags.Throws) { // nothing can change that\n newFlags |= FlowFlags.Throws;\n } else if (otherFlags & FlowFlags.Throws) {\n newFlags |= FlowFlags.ConditionallyThrows;\n } else {\n newFlags |= (thisFlags | otherFlags) & FlowFlags.ConditionallyThrows;\n }\n\n if (thisFlags & FlowFlags.Breaks) { // nothing can change that\n newFlags |= FlowFlags.Breaks;\n } else if (other.breakLabel == this.breakLabel) {\n if (otherFlags & FlowFlags.Breaks) {\n newFlags |= FlowFlags.ConditionallyBreaks;\n } else {\n newFlags |= (thisFlags | otherFlags) & FlowFlags.ConditionallyBreaks;\n }\n } else {\n newFlags |= thisFlags & FlowFlags.ConditionallyBreaks;\n }\n\n if (thisFlags & FlowFlags.Continues) { // nothing can change that\n newFlags |= FlowFlags.Continues;\n } else if (other.continueLabel == this.continueLabel) {\n if (otherFlags & FlowFlags.Continues) {\n newFlags |= FlowFlags.ConditionallyContinues;\n } else {\n newFlags |= (thisFlags | otherFlags) & FlowFlags.ConditionallyContinues;\n }\n } else {\n newFlags |= thisFlags & FlowFlags.ConditionallyContinues;\n }\n\n if (thisFlags & FlowFlags.AccessesThis) { // can become conditional\n if (otherFlags & FlowFlags.AccessesThis) {\n newFlags |= FlowFlags.AccessesThis;\n } else {\n newFlags |= FlowFlags.ConditionallyAccessesThis;\n }\n } else if (otherFlags & FlowFlags.AccessesThis) {\n newFlags |= FlowFlags.ConditionallyAccessesThis;\n }\n\n // may be the case in any\n newFlags |= (thisFlags | otherFlags) & FlowFlags.MayReturnNonThis;\n\n // must be the case in both\n newFlags |= thisFlags & otherFlags & FlowFlags.CallsSuper;\n\n if (thisFlags & FlowFlags.Terminates) { // nothing can change that\n newFlags |= FlowFlags.Terminates;\n }\n\n this.flags = newFlags | (thisFlags & (FlowFlags.UncheckedContext | FlowFlags.CtorParamContext));\n }\n\n /** Merges a branch joining again with this flow, i.e. then without else. */\n mergeBranch(other: Flow): void {\n this.mergeSideEffects(other);\n\n // Local flags matter if the branch does not terminate\n let thisLocalFlags = this.localFlags;\n let numThisLocalFlags = thisLocalFlags.length;\n let otherLocalFlags = other.localFlags;\n let numOtherLocalFlags = otherLocalFlags.length;\n let maxLocalFlags = max(numThisLocalFlags, numOtherLocalFlags);\n for (let i = 0; i < maxLocalFlags; ++i) {\n let thisFlags = i < numThisLocalFlags ? thisLocalFlags[i] : 0;\n let otherFlags = i < numOtherLocalFlags ? otherLocalFlags[i] : 0;\n thisLocalFlags[i] = thisFlags & otherFlags & (\n LocalFlags.Constant |\n LocalFlags.Wrapped |\n LocalFlags.NonNull |\n LocalFlags.Initialized\n );\n }\n\n // field flags do not matter here since there's only INITIALIZED, which can\n // only be set if it has been observed prior to entering the branch.\n }\n\n /** Inherits two alternate branches to become this flow, i.e. then with else. */\n inheritAlternatives(left: Flow, right: Flow): void {\n assert(left.targetFunction == right.targetFunction);\n assert(left.targetFunction == this.targetFunction);\n // Differs from `mergeBranch` in that the alternatives are intersected to\n // then become this branch.\n\n let leftFlags = left.flags;\n let rightFlags = right.flags;\n let newFlags = FlowFlags.None;\n\n if (leftFlags & FlowFlags.Returns) {\n if (rightFlags & FlowFlags.Returns) {\n newFlags |= FlowFlags.Returns;\n } else {\n newFlags |= FlowFlags.ConditionallyReturns;\n }\n } else if (rightFlags & FlowFlags.Returns) {\n newFlags |= FlowFlags.ConditionallyReturns;\n } else {\n newFlags |= (leftFlags | rightFlags) & FlowFlags.ConditionallyReturns;\n }\n\n if ((leftFlags & FlowFlags.ReturnsWrapped) && (rightFlags & FlowFlags.ReturnsWrapped)) {\n newFlags |= FlowFlags.ReturnsWrapped;\n }\n\n if ((leftFlags & FlowFlags.ReturnsNonNull) && (rightFlags & FlowFlags.ReturnsNonNull)) {\n newFlags |= FlowFlags.ReturnsNonNull;\n }\n\n if (leftFlags & FlowFlags.Throws) {\n if (rightFlags & FlowFlags.Throws) {\n newFlags |= FlowFlags.Throws;\n } else {\n newFlags |= FlowFlags.ConditionallyThrows;\n }\n } else if (rightFlags & FlowFlags.Throws) {\n newFlags |= FlowFlags.ConditionallyThrows;\n } else {\n newFlags |= (leftFlags | rightFlags) & FlowFlags.ConditionallyThrows;\n }\n\n if (leftFlags & FlowFlags.Breaks) {\n if (rightFlags & FlowFlags.Breaks) {\n newFlags |= FlowFlags.Breaks;\n } else {\n newFlags |= FlowFlags.ConditionallyBreaks;\n }\n } else if (rightFlags & FlowFlags.Breaks) {\n newFlags |= FlowFlags.ConditionallyBreaks;\n } else {\n newFlags |= (leftFlags | rightFlags) & FlowFlags.ConditionallyBreaks;\n }\n\n if (leftFlags & FlowFlags.Continues) {\n if (rightFlags & FlowFlags.Continues) {\n newFlags |= FlowFlags.Continues;\n } else {\n newFlags |= FlowFlags.ConditionallyContinues;\n }\n } else if (rightFlags & FlowFlags.Continues) {\n newFlags |= FlowFlags.ConditionallyContinues;\n } else {\n newFlags |= (leftFlags | rightFlags) & FlowFlags.ConditionallyContinues;\n }\n\n if (leftFlags & FlowFlags.AccessesThis) {\n if (rightFlags & FlowFlags.AccessesThis) {\n newFlags |= FlowFlags.AccessesThis;\n } else {\n newFlags |= FlowFlags.ConditionallyAccessesThis;\n }\n } else if (rightFlags & FlowFlags.AccessesThis) {\n newFlags |= FlowFlags.ConditionallyAccessesThis;\n } else {\n newFlags |= (leftFlags | rightFlags) & FlowFlags.ConditionallyAccessesThis;\n }\n\n newFlags |= (leftFlags | rightFlags) & FlowFlags.MayReturnNonThis;\n\n if ((leftFlags & FlowFlags.CallsSuper) && (rightFlags & FlowFlags.CallsSuper)) {\n newFlags |= FlowFlags.CallsSuper;\n }\n\n if ((leftFlags & FlowFlags.Terminates) && (rightFlags & FlowFlags.Terminates)) {\n newFlags |= FlowFlags.Terminates;\n }\n\n this.flags = newFlags | (this.flags & (FlowFlags.UncheckedContext | FlowFlags.CtorParamContext));\n\n // local flags\n let thisLocalFlags = this.localFlags;\n if (leftFlags & FlowFlags.Terminates) {\n if (!(rightFlags & FlowFlags.Terminates)) {\n let rightLocalFlags = right.localFlags;\n for (let i = 0, k = rightLocalFlags.length; i < k; ++i) {\n thisLocalFlags[i] = rightLocalFlags[i];\n }\n }\n } else if (rightFlags & FlowFlags.Terminates) {\n let leftLocalFlags = left.localFlags;\n for (let i = 0, k = leftLocalFlags.length; i < k; ++i) {\n thisLocalFlags[i] = leftLocalFlags[i];\n }\n } else {\n let leftLocalFlags = left.localFlags;\n let numLeftLocalFlags = leftLocalFlags.length;\n let rightLocalFlags = right.localFlags;\n let numRightLocalFlags = rightLocalFlags.length;\n let maxLocalFlags = max(numLeftLocalFlags, numRightLocalFlags);\n for (let i = 0; i < maxLocalFlags; ++i) {\n let leftFlags = i < numLeftLocalFlags ? leftLocalFlags[i] : 0;\n let rightFlags = i < numRightLocalFlags ? rightLocalFlags[i] : 0;\n thisLocalFlags[i] = leftFlags & rightFlags & (\n LocalFlags.Constant |\n LocalFlags.Wrapped |\n LocalFlags.NonNull |\n LocalFlags.Initialized\n );\n }\n }\n\n // field flags (currently only INITIALIZED, so can simplify)\n let leftFieldFlags = left.thisFieldFlags;\n if (leftFieldFlags) {\n let newFieldFlags = new Map();\n let rightFieldFlags = assert(right.thisFieldFlags);\n for (let _keys = Map_keys(leftFieldFlags), i = 0, k = _keys.length; i < k; ++i) {\n let key = _keys[i];\n let leftFlags = changetype(leftFieldFlags.get(key));\n if (\n (leftFlags & FieldFlags.Initialized) != 0 && rightFieldFlags.has(key) &&\n (changetype(rightFieldFlags.get(key)) & FieldFlags.Initialized)\n ) {\n newFieldFlags.set(key, FieldFlags.Initialized);\n }\n }\n this.thisFieldFlags = newFieldFlags;\n } else {\n assert(!right.thisFieldFlags);\n }\n }\n\n /** Tests if recompilation is needed due to incompatible local flags between loops, and resets if necessary. */\n resetIfNeedsRecompile(\n /** Resulting flow of the current compilation attempt. */\n other: Flow,\n /** Number of locals before the compilation attempt. */\n numLocalsBefore: i32\n ): bool {\n let numThisLocalFlags = this.localFlags.length;\n let numOtherLocalFlags = other.localFlags.length;\n let targetFunction = this.targetFunction;\n assert(targetFunction == other.targetFunction);\n let localsByIndex = targetFunction.localsByIndex;\n assert(localsByIndex == other.targetFunction.localsByIndex);\n let needsRecompile = false;\n for (let i = 0, k = min(numThisLocalFlags, numOtherLocalFlags); i < k; ++i) {\n let local = localsByIndex[i];\n let type = local.type;\n if (type.isShortIntegerValue) {\n if (this.isLocalFlag(i, LocalFlags.Wrapped) && !other.isLocalFlag(i, LocalFlags.Wrapped)) {\n this.unsetLocalFlag(i, LocalFlags.Wrapped); // assume not wrapped\n needsRecompile = true;\n }\n }\n if (type.isNullableReference) {\n if (this.isLocalFlag(i, LocalFlags.NonNull) && !other.isLocalFlag(i, LocalFlags.NonNull)) {\n this.unsetLocalFlag(i, LocalFlags.NonNull); // assume possibly null\n needsRecompile = true;\n }\n }\n }\n if (needsRecompile) {\n // Reset function locals to state before the compilation attempt\n assert(localsByIndex.length >= numLocalsBefore);\n localsByIndex.length = numLocalsBefore;\n if (this.localFlags.length > numLocalsBefore) {\n this.localFlags.length = numLocalsBefore;\n }\n }\n return needsRecompile;\n }\n\n /** Checks if an expression of the specified type is known to be non-null, even if the type might be nullable. */\n isNonnull(expr: ExpressionRef, type: Type): bool {\n if (!type.isNullableReference) return true;\n // below, only teeLocal/getLocal are relevant because these are the only expressions that\n // depend on a dynamic nullable state (flag = LocalFlags.NonNull), while everything else\n // has already been handled by the nullable type check above.\n switch (getExpressionId(expr)) {\n case ExpressionId.LocalSet: {\n if (!isLocalTee(expr)) break;\n let local = this.targetFunction.localsByIndex[getLocalSetIndex(expr)];\n return !local.type.isNullableReference || this.isLocalFlag(local.index, LocalFlags.NonNull, false);\n }\n case ExpressionId.LocalGet: {\n let local = this.targetFunction.localsByIndex[getLocalGetIndex(expr)];\n return !local.type.isNullableReference || this.isLocalFlag(local.index, LocalFlags.NonNull, false);\n }\n }\n return false;\n }\n\n /** Updates local states to reflect that this branch is only taken when `expr` is true-ish. */\n private inheritNonnullIfTrue(\n /** Expression being true. */\n expr: ExpressionRef,\n /** If specified, only set the flag if also nonnull in this flow. */\n iff: Flow | null = null\n ): void {\n // A: `expr` is true-ish -> Q: how did that happen?\n\n // The iff argument is useful in situations like\n //\n // if (!ref) {\n // ref = new Ref();\n // }\n // // inheritNonnullIfFalse(`!ref`, thenFlow) -> ref != null\n //\n\n switch (getExpressionId(expr)) {\n case ExpressionId.LocalSet: {\n if (!isLocalTee(expr)) break;\n let local = this.targetFunction.localsByIndex[getLocalSetIndex(expr)];\n if (!iff || iff.isLocalFlag(local.index, LocalFlags.NonNull)) {\n this.setLocalFlag(local.index, LocalFlags.NonNull);\n }\n this.inheritNonnullIfTrue(getLocalSetValue(expr), iff); // must have been true-ish as well\n break;\n }\n case ExpressionId.LocalGet: {\n let local = this.targetFunction.localsByIndex[getLocalGetIndex(expr)];\n if (!iff || iff.isLocalFlag(local.index, LocalFlags.NonNull)) {\n this.setLocalFlag(local.index, LocalFlags.NonNull);\n }\n break;\n }\n case ExpressionId.If: {\n let ifFalse = getIfFalse(expr);\n if (ifFalse && isConstZero(ifFalse)) {\n // Logical AND: (if (condition ifTrue 0))\n // the only way this had become true is if condition and ifTrue are true\n this.inheritNonnullIfTrue(getIfCondition(expr), iff);\n this.inheritNonnullIfTrue(getIfTrue(expr), iff);\n }\n break;\n }\n case ExpressionId.Unary: {\n switch (getUnaryOp(expr)) {\n case UnaryOp.EqzI32:\n case UnaryOp.EqzI64: {\n this.inheritNonnullIfFalse(getUnaryValue(expr), iff); // !value -> value must have been false\n break;\n }\n }\n break;\n }\n case ExpressionId.Binary: {\n switch (getBinaryOp(expr)) {\n case BinaryOp.EqI32:\n case BinaryOp.EqI64: {\n let left = getBinaryLeft(expr);\n let right = getBinaryRight(expr);\n if (isConstNonZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // TRUE == right -> right must have been true\n } else if (isConstNonZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // left == TRUE -> left must have been true\n }\n break;\n }\n case BinaryOp.NeI32:\n case BinaryOp.NeI64: {\n let left = getBinaryLeft(expr);\n let right = getBinaryRight(expr);\n if (isConstZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // FALSE != right -> right must have been true\n } else if (isConstZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // left != FALSE -> left must have been true\n }\n break;\n }\n }\n break;\n }\n case ExpressionId.Call: {\n // handle string eq/ne/not overloads\n let name = getCallTarget(expr);\n if (name == BuiltinNames.String_eq) {\n assert(getCallOperandCount(expr) == 2);\n let left = getCallOperandAt(expr, 0);\n let right = getCallOperandAt(expr, 1);\n if (isConstNonZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // TRUE == right -> right must have been true\n } else if (isConstNonZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // left == TRUE -> left must have been true\n }\n } else if (name == BuiltinNames.String_ne) {\n assert(getCallOperandCount(expr) == 2);\n let left = getCallOperandAt(expr, 0);\n let right = getCallOperandAt(expr, 1);\n if (isConstZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // FALSE != right -> right must have been true\n } else if (isConstZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // left != FALSE -> left must have been true\n }\n } else if (name == BuiltinNames.String_not) {\n assert(getCallOperandCount(expr) == 1);\n this.inheritNonnullIfFalse(getCallOperandAt(expr, 0), iff); // !value -> value must have been false\n } else if (name == BuiltinNames.tostack) {\n assert(getCallOperandCount(expr) == 1);\n this.inheritNonnullIfTrue(getCallOperandAt(expr, 0), iff);\n }\n break;\n }\n }\n }\n\n /** Updates local states to reflect that this branch is only taken when `expr` is false-ish. */\n private inheritNonnullIfFalse(\n /** Expression being false. */\n expr: ExpressionRef,\n /** If specified, only set the flag if also nonnull in this flow. */\n iff: Flow | null = null\n ): void {\n // A: `expr` is false-ish -> Q: how did that happen?\n switch (getExpressionId(expr)) {\n case ExpressionId.Unary: {\n switch (getUnaryOp(expr)) {\n case UnaryOp.EqzI32:\n case UnaryOp.EqzI64: {\n this.inheritNonnullIfTrue(getUnaryValue(expr), iff); // !value -> value must have been true\n break;\n }\n }\n break;\n }\n case ExpressionId.If: {\n let ifTrue = getIfTrue(expr);\n let ifFalse = getIfFalse(expr);\n if (ifFalse && isConstNonZero(ifTrue)) {\n // Logical OR: (if (condition 1 ifFalse))\n // the only way this had become false is if condition and ifFalse are false\n this.inheritNonnullIfFalse(getIfCondition(expr), iff);\n this.inheritNonnullIfFalse(getIfFalse(expr), iff);\n }\n break;\n }\n case ExpressionId.Binary: {\n switch (getBinaryOp(expr)) {\n // remember: we want to know how the _entire_ expression became FALSE (!)\n case BinaryOp.EqI32:\n case BinaryOp.EqI64: {\n let left = getBinaryLeft(expr);\n let right = getBinaryRight(expr);\n if (isConstZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // !(FALSE == right) -> right must have been true\n } else if (isConstZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // !(left == FALSE) -> left must have been true\n }\n break;\n }\n case BinaryOp.NeI32:\n case BinaryOp.NeI64: {\n let left = getBinaryLeft(expr);\n let right = getBinaryRight(expr);\n if (isConstNonZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // !(TRUE != right) -> right must have been true\n } else if (isConstNonZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // !(left != TRUE) -> left must have been true\n }\n break;\n }\n }\n break;\n }\n case ExpressionId.Call: {\n // handle string eq/ne/not overloads\n let name = getCallTarget(expr);\n if (name == BuiltinNames.String_eq) {\n assert(getCallOperandCount(expr) == 2);\n let left = getCallOperandAt(expr, 0);\n let right = getCallOperandAt(expr, 1);\n if (isConstZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // !(FALSE == right) -> right must have been true\n } else if (isConstZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // !(left == FALSE) -> left must have been true\n }\n } else if (name == BuiltinNames.String_ne) {\n assert(getCallOperandCount(expr) == 2);\n let left = getCallOperandAt(expr, 0);\n let right = getCallOperandAt(expr, 1);\n if (isConstNonZero(left)) {\n this.inheritNonnullIfTrue(right, iff); // !(TRUE != right) -> right must have been true\n } else if (isConstNonZero(right)) {\n this.inheritNonnullIfTrue(left, iff); // !(left != TRUE) -> left must have been true\n }\n } else if (name == BuiltinNames.String_not) {\n assert(getCallOperandCount(expr) == 1);\n this.inheritNonnullIfTrue(getCallOperandAt(expr, 0), iff); // !(!value) -> value must have been true\n } else if (name == BuiltinNames.tostack) {\n assert(getCallOperandCount(expr) == 1);\n this.inheritNonnullIfFalse(getCallOperandAt(expr, 0), iff);\n }\n break;\n }\n }\n }\n\n /**\n * Tests if an expression can possibly overflow in the context of this flow. Assumes that the\n * expression might already have overflown and returns `false` only if the operation neglects\n * any possible combination of garbage bits being present.\n */\n canOverflow(expr: ExpressionRef, type: Type): bool {\n // TODO: the following catches most common and a few uncommon cases, but there are additional\n // opportunities here, obviously.\n\n // types other than i8, u8, i16, u16 and bool do not overflow\n if (!type.isShortIntegerValue) return false;\n\n let operand: ExpressionRef;\n switch (getExpressionId(expr)) {\n\n // overflows if the local isn't wrapped or the conversion does\n case ExpressionId.LocalGet: {\n let local = this.targetFunction.localsByIndex[getLocalGetIndex(expr)];\n return !this.isLocalFlag(local.index, LocalFlags.Wrapped, true)\n || canConversionOverflow(local.type, type);\n }\n\n // overflows if the value does\n case ExpressionId.LocalSet: { // tee\n assert(isLocalTee(expr));\n return this.canOverflow(getLocalSetValue(expr), type);\n }\n\n // overflows if the conversion does (globals are wrapped on set)\n case ExpressionId.GlobalGet: {\n // TODO: this is inefficient because it has to read a string\n let global = assert(this.program.elementsByName.get(assert(getGlobalGetName(expr))));\n assert(global.kind == ElementKind.Global || global.kind == ElementKind.EnumValue);\n return canConversionOverflow((global).type, type);\n }\n\n case ExpressionId.Binary: {\n switch (getBinaryOp(expr)) {\n\n // comparisons do not overflow (result is 0 or 1)\n case BinaryOp.EqI32:\n case BinaryOp.EqI64:\n case BinaryOp.EqF32:\n case BinaryOp.EqF64:\n case BinaryOp.NeI32:\n case BinaryOp.NeI64:\n case BinaryOp.NeF32:\n case BinaryOp.NeF64:\n case BinaryOp.LtI32:\n case BinaryOp.LtU32:\n case BinaryOp.LtI64:\n case BinaryOp.LtU64:\n case BinaryOp.LtF32:\n case BinaryOp.LtF64:\n case BinaryOp.LeI32:\n case BinaryOp.LeU32:\n case BinaryOp.LeI64:\n case BinaryOp.LeU64:\n case BinaryOp.LeF32:\n case BinaryOp.LeF64:\n case BinaryOp.GtI32:\n case BinaryOp.GtU32:\n case BinaryOp.GtI64:\n case BinaryOp.GtU64:\n case BinaryOp.GtF32:\n case BinaryOp.GtF64:\n case BinaryOp.GeI32:\n case BinaryOp.GeU32:\n case BinaryOp.GeI64:\n case BinaryOp.GeU64:\n case BinaryOp.GeF32:\n case BinaryOp.GeF64: return false;\n\n // result won't overflow if one side is 0 or if one side is 1 and the other wrapped\n case BinaryOp.MulI32: {\n return !(\n (\n getExpressionId(operand = getBinaryLeft(expr)) == ExpressionId.Const &&\n (\n getConstValueI32(operand) == 0 ||\n (\n getConstValueI32(operand) == 1 &&\n !this.canOverflow(getBinaryRight(expr), type)\n )\n )\n ) || (\n getExpressionId(operand = getBinaryRight(expr)) == ExpressionId.Const &&\n (\n getConstValueI32(operand) == 0 ||\n (\n getConstValueI32(operand) == 1 &&\n !this.canOverflow(getBinaryLeft(expr), type)\n )\n )\n )\n );\n }\n\n // result won't overflow if one side is a constant less than this type's mask or one side\n // is wrapped\n case BinaryOp.AndI32: {\n // note that computeSmallIntegerMask returns the mask minus the MSB for signed types\n // because signed value garbage bits must be guaranteed to be equal to the MSB.\n return !(\n (\n (\n getExpressionId(operand = getBinaryLeft(expr)) == ExpressionId.Const &&\n getConstValueI32(operand) <= type.computeSmallIntegerMask(Type.i32)\n ) || !this.canOverflow(operand, type)\n ) || (\n (\n getExpressionId(operand = getBinaryRight(expr)) == ExpressionId.Const &&\n getConstValueI32(operand) <= type.computeSmallIntegerMask(Type.i32)\n ) || !this.canOverflow(operand, type)\n )\n );\n }\n\n // overflows if the shift doesn't clear potential garbage bits\n case BinaryOp.ShlI32: {\n let shift = 32 - type.size;\n return getExpressionId(operand = getBinaryRight(expr)) != ExpressionId.Const\n || getConstValueI32(operand) < shift;\n }\n\n // overflows if the value does and the shift doesn't clear potential garbage bits\n case BinaryOp.ShrI32: {\n let shift = 32 - type.size;\n return this.canOverflow(getBinaryLeft(expr), type) && (\n getExpressionId(operand = getBinaryRight(expr)) != ExpressionId.Const ||\n getConstValueI32(operand) < shift\n );\n }\n\n // overflows if the shift does not clear potential garbage bits. if an unsigned value is\n // wrapped, it can't overflow.\n case BinaryOp.ShrU32: {\n let shift = 32 - type.size;\n return type.isSignedIntegerValue\n ? !(\n getExpressionId(operand = getBinaryRight(expr)) == ExpressionId.Const &&\n getConstValueI32(operand) > shift // must clear MSB\n )\n : this.canOverflow(getBinaryLeft(expr), type) &&\n !(\n getExpressionId(operand = getBinaryRight(expr)) == ExpressionId.Const &&\n getConstValueI32(operand) >= shift // can leave MSB\n );\n }\n\n // overflows if any side does\n case BinaryOp.DivU32:\n case BinaryOp.RemI32:\n case BinaryOp.RemU32: {\n return this.canOverflow(getBinaryLeft(expr), type)\n || this.canOverflow(getBinaryRight(expr), type);\n }\n }\n break;\n }\n\n case ExpressionId.Unary: {\n switch (getUnaryOp(expr)) {\n\n // comparisons do not overflow (result is 0 or 1)\n case UnaryOp.EqzI32:\n case UnaryOp.EqzI64: return false;\n\n // overflow if the maximum result (32) cannot be represented in the target type\n case UnaryOp.ClzI32:\n case UnaryOp.CtzI32:\n case UnaryOp.PopcntI32: return type.size < 7;\n\n // sign extensions overflow if result can have high garbage bits in the target type\n case UnaryOp.Extend8I32: return type.size < (type.isUnsignedIntegerValue ? 32 : 8);\n case UnaryOp.Extend8I64: return type.size < (type.isUnsignedIntegerValue ? 64 : 8);\n case UnaryOp.Extend16I32: return type.size < (type.isUnsignedIntegerValue ? 32 : 16);\n case UnaryOp.Extend16I64: return type.size < (type.isUnsignedIntegerValue ? 64 : 16);\n case UnaryOp.Extend32I64: return type.size < (type.isUnsignedIntegerValue ? 64 : 32);\n }\n break;\n }\n\n // overflows if the value cannot be represented in the target type\n case ExpressionId.Const: {\n let value: i32 = 0;\n switch (getExpressionType(expr)) {\n case TypeRef.I32: { value = getConstValueI32(expr); break; }\n case TypeRef.I64: { value = getConstValueI64Low(expr); break; } // discards upper bits\n case TypeRef.F32: { value = i32(getConstValueF32(expr)); break; }\n case TypeRef.F64: { value = i32(getConstValueF64(expr)); break; }\n case TypeRef.V128: return false;\n default: assert(false);\n }\n switch (type.kind) {\n case TypeKind.Bool: return (value & ~1) != 0;\n case TypeKind.I8: return value < i8.MIN_VALUE || value > i8.MAX_VALUE;\n case TypeKind.I16: return value < i16.MIN_VALUE || value > i16.MAX_VALUE;\n case TypeKind.U8: return value < 0 || value > u8.MAX_VALUE;\n case TypeKind.U16: return value < 0 || value > u16.MAX_VALUE;\n }\n break;\n }\n\n // overflows if the conversion does\n case ExpressionId.Load: {\n let fromType: Type;\n let signed = isLoadSigned(expr);\n switch (getLoadBytes(expr)) {\n case 1: { fromType = signed ? Type.i8 : Type.u8; break; }\n case 2: { fromType = signed ? Type.i16 : Type.u16; break; }\n default: { fromType = signed ? Type.i32 : Type.u32; break; }\n }\n return canConversionOverflow(fromType, type);\n }\n\n // overflows if the result does, which is either\n // - the last expression of the block, by contract, if the block doesn't have a label\n // - the last expression or the value of an inner br if the block has a label (TODO)\n case ExpressionId.Block: {\n if (!getBlockName(expr)) {\n let size = assert(getBlockChildCount(expr));\n let last = getBlockChildAt(expr, size - 1);\n return this.canOverflow(last, type);\n }\n break;\n }\n\n // overflows if either side does\n case ExpressionId.If: {\n return this.canOverflow(getIfTrue(expr), type)\n || this.canOverflow(assert(getIfFalse(expr)), type);\n }\n\n // overflows if either side does\n case ExpressionId.Select: {\n return this.canOverflow(getSelectThen(expr), type)\n || this.canOverflow(getSelectElse(expr), type);\n }\n\n // overflows if the call does not return a wrapped value or the conversion does\n case ExpressionId.Call: {\n let program = this.program;\n let instancesByName = program.instancesByName;\n let instanceName = assert(getCallTarget(expr));\n if (instancesByName.has(instanceName)) {\n let instance = assert(instancesByName.get(instanceName));\n assert(instance.kind == ElementKind.Function);\n let functionInstance = instance;\n let returnType = functionInstance.signature.returnType;\n return !functionInstance.flow.is(FlowFlags.ReturnsWrapped)\n || canConversionOverflow(returnType, type);\n }\n return false; // assume no overflow for builtins\n }\n\n // doesn't technically overflow\n case ExpressionId.Unreachable: return false;\n }\n return true;\n }\n\n toString(): string {\n let levels = 0;\n let parent = this.parent;\n while (parent) {\n parent = parent.parent;\n ++levels;\n }\n let sb = new Array();\n if (this.is(FlowFlags.Returns)) sb.push(\"RETURNS\");\n if (this.is(FlowFlags.ReturnsWrapped)) sb.push(\"RETURNS_WRAPPED\");\n if (this.is(FlowFlags.ReturnsNonNull)) sb.push(\"RETURNS_NONNULL\");\n if (this.is(FlowFlags.Throws)) sb.push(\"THROWS\");\n if (this.is(FlowFlags.Breaks)) sb.push(\"BREAKS\");\n if (this.is(FlowFlags.Continues)) sb.push(\"CONTINUES\");\n if (this.is(FlowFlags.AccessesThis)) sb.push(\"ACCESSES_THIS\");\n if (this.is(FlowFlags.CallsSuper)) sb.push(\"CALLS_SUPER\");\n if (this.is(FlowFlags.Terminates)) sb.push(\"TERMINATES\");\n if (this.is(FlowFlags.ConditionallyReturns)) sb.push(\"CONDITIONALLY_RETURNS\");\n if (this.is(FlowFlags.ConditionallyThrows)) sb.push(\"CONDITIONALLY_THROWS\");\n if (this.is(FlowFlags.ConditionallyBreaks)) sb.push(\"CONDITIONALLY_BREAKS\");\n if (this.is(FlowFlags.ConditionallyContinues)) sb.push(\"CONDITIONALLY_CONTINUES\");\n if (this.is(FlowFlags.ConditionallyAccessesThis)) sb.push(\"CONDITIONALLY_ACCESSES_THIS\");\n if (this.is(FlowFlags.MayReturnNonThis)) sb.push(\"MAY_RETURN_NONTHIS\");\n return `Flow(${this.sourceFunction})[${levels}] ${sb.join(\" \")}`;\n }\n}\n\n/** Tests if a conversion from one type to another can technically overflow. */\nfunction canConversionOverflow(fromType: Type, toType: Type): bool {\n return toType.isShortIntegerValue && (\n !fromType.isIntegerValue || // i.e. float to small int\n fromType.size > toType.size || // larger int to small int\n fromType.isSignedIntegerValue != toType.isSignedIntegerValue // signedness mismatch\n );\n}\n","/**\n * @fileoverview AssemblyScript's intermediate representation.\n *\n * The compiler uses Binaryen IR, which is fairly low level, as its\n * primary intermediate representation, with the following structures\n * holding any higher level information that cannot be represented by\n * Binaryen IR alone, for example higher level types.\n *\n * Similar to the AST being composed of `Node`s in `Source`s, the IR is\n * composed of `Element`s in a `Program`. Each class or function is\n * represented by a \"prototype\" holding all the relevant information,\n * including each's concrete instances. If a class or function is not\n * generic, there is exactly one instance, otherwise there is one for\n * each concrete set of type arguments.\n *\n * @license Apache-2.0\n */\n\n// Element Base class of all elements\n// ├─DeclaredElement Base class of elements with a declaration\n// │ ├─TypedElement Base class of elements resolving to a type\n// │ │ ├─TypeDefinition Type alias declaration\n// │ │ ├─VariableLikeElement Base class of all variable-like elements\n// │ │ │ ├─EnumValue Enum value\n// │ │ │ ├─Global File global\n// │ │ │ ├─Local Function local\n// │ │ │ └─Property Class property (incl. instance fields)\n// │ │ ├─IndexSignature Class index signature\n// │ │ ├─Function Concrete function instance\n// │ │ └─Class Concrete class instance\n// │ ├─Namespace Namespace with static members\n// │ ├─FunctionPrototype Prototype of concrete function instances\n// │ ├─PropertyPrototype Prototype of concrete property instances\n// │ └─ClassPrototype Prototype of concrete classe instances\n// └─File File, analogous to Source in the AST\n\nimport {\n CommonFlags,\n PATH_DELIMITER,\n STATIC_DELIMITER,\n INSTANCE_DELIMITER,\n GETTER_PREFIX,\n SETTER_PREFIX,\n INNER_DELIMITER,\n INDEX_SUFFIX,\n STUB_DELIMITER,\n CommonNames,\n Feature,\n Target,\n featureToString\n} from \"./common\";\n\nimport {\n Options\n} from \"./compiler\";\n\nimport {\n Range,\n DiagnosticCode,\n DiagnosticMessage,\n DiagnosticEmitter\n} from \"./diagnostics\";\n\nimport {\n Type,\n TypeKind,\n Signature,\n TypeFlags\n} from \"./types\";\n\nimport {\n Token\n} from \"./tokenizer\";\n\nimport {\n Node,\n NodeKind,\n Source,\n SourceKind,\n DecoratorNode,\n DecoratorKind,\n TypeParameterNode,\n TypeNode,\n NamedTypeNode,\n FunctionTypeNode,\n ArrowKind,\n\n Expression,\n IdentifierExpression,\n LiteralKind,\n StringLiteralExpression,\n\n Statement,\n ClassDeclaration,\n DeclarationStatement,\n EnumDeclaration,\n EnumValueDeclaration,\n ExportMember,\n ExportDefaultStatement,\n ExportStatement,\n FieldDeclaration,\n FunctionDeclaration,\n ImportDeclaration,\n ImportStatement,\n InterfaceDeclaration,\n MethodDeclaration,\n NamespaceDeclaration,\n TypeDeclaration,\n VariableDeclaration,\n VariableLikeDeclarationStatement,\n VariableStatement,\n ParameterKind,\n ParameterNode,\n TypeName\n} from \"./ast\";\n\nimport {\n Module,\n FunctionRef,\n MemorySegment,\n getFunctionName\n} from \"./module\";\n\nimport {\n CharCode,\n writeI8,\n writeI16,\n writeI32,\n writeF32,\n writeF64,\n writeI64,\n writeI32AsI64,\n writeI64AsI32\n} from \"./util\";\n\nimport {\n Resolver\n} from \"./resolver\";\n\nimport {\n Flow,\n LocalFlags\n} from \"./flow\";\n\nimport {\n Parser\n} from \"./parser\";\n\nimport {\n BuiltinNames,\n builtinFunctions,\n builtinVariables_onAccess\n} from \"./builtins\";\n\n// Memory manager constants\nconst AL_SIZE = 16;\nconst AL_MASK = AL_SIZE - 1;\n\n/** Represents a yet unresolved `import`. */\nclass QueuedImport {\n constructor(\n /** File being imported into. */\n public localFile: File,\n /** Identifier within the local file. */\n public localIdentifier: IdentifierExpression,\n /** Identifier within the other file. Is an `import *` if not set. */\n public foreignIdentifier: IdentifierExpression | null,\n /** Path to the other file. */\n public foreignPath: string,\n /** Alternative path to the other file. */\n public foreignPathAlt: string\n ) {}\n}\n\n/** Represents a yet unresolved `export`. */\nclass QueuedExport {\n constructor(\n /** Identifier within the local file. */\n public localIdentifier: IdentifierExpression,\n /** Identifier within the other file. */\n public foreignIdentifier: IdentifierExpression,\n /** Path to the other file if a re-export. */\n public foreignPath: string | null,\n /** Alternative path to the other file if a re-export. */\n public foreignPathAlt: string | null\n ) {}\n}\n\n/** Represents a yet unresolved `export *`. */\nclass QueuedExportStar {\n // stored in a map with localFile as the key\n constructor(\n /** Path to the other file. */\n public foreignPath: string,\n /** Alternative path to the other file. */\n public foreignPathAlt: string,\n /** Reference to the path literal for reporting. */\n public pathLiteral: StringLiteralExpression\n ) {}\n}\n\n/** Represents the kind of an operator overload. */\nexport enum OperatorKind {\n Invalid,\n\n // indexed access\n IndexedGet, // a[]\n IndexedSet, // a[]=b\n UncheckedIndexedGet, // unchecked(a[])\n UncheckedIndexedSet, // unchecked(a[]=b)\n\n // binary\n Add, // a + b\n Sub, // a - b\n Mul, // a * b\n Div, // a / b\n Rem, // a % b\n Pow, // a ** b\n BitwiseAnd, // a & b\n BitwiseOr, // a | b\n BitwiseXor, // a ^ b\n BitwiseShl, // a << b\n BitwiseShr, // a >> b\n BitwiseShrU, // a >>> b\n Eq, // a == b, a === b\n Ne, // a != b, a !== b\n Gt, // a > b\n Ge, // a >= b\n Lt, // a < b\n Le, // a <= b\n\n // unary prefix\n Plus, // +a\n Minus, // -a\n Not, // !a\n BitwiseNot, // ~a\n PrefixInc, // ++a\n PrefixDec, // --a\n\n // unary postfix\n PostfixInc, // a++\n PostfixDec // a--\n\n // not overridable:\n // LogicalAnd // a && b\n // LogicalOr // a || b\n}\n\nexport namespace OperatorKind {\n\n /** Returns the operator kind represented by the specified decorator and string argument. */\n export function fromDecorator(decoratorKind: DecoratorKind, arg: string): OperatorKind {\n assert(arg.length);\n switch (decoratorKind) {\n case DecoratorKind.Operator:\n case DecoratorKind.OperatorBinary: {\n switch (arg.charCodeAt(0)) {\n case CharCode.OpenBracket: {\n if (arg == \"[]\") return OperatorKind.IndexedGet;\n if (arg == \"[]=\") return OperatorKind.IndexedSet;\n break;\n }\n case CharCode.OpenBrace: {\n if (arg == \"{}\") return OperatorKind.UncheckedIndexedGet;\n if (arg == \"{}=\") return OperatorKind.UncheckedIndexedSet;\n break;\n }\n case CharCode.Plus: {\n if (arg == \"+\") return OperatorKind.Add;\n break;\n }\n case CharCode.Minus: {\n if (arg == \"-\") return OperatorKind.Sub;\n break;\n }\n case CharCode.Asterisk: {\n if (arg == \"*\") return OperatorKind.Mul;\n if (arg == \"**\") return OperatorKind.Pow;\n break;\n }\n case CharCode.Slash: {\n if (arg == \"/\") return OperatorKind.Div;\n break;\n }\n case CharCode.Percent: {\n if (arg == \"%\") return OperatorKind.Rem;\n break;\n }\n case CharCode.Ampersand: {\n if (arg == \"&\") return OperatorKind.BitwiseAnd;\n break;\n }\n case CharCode.Bar: {\n if (arg == \"|\") return OperatorKind.BitwiseOr;\n break;\n }\n case CharCode.Caret: {\n if (arg == \"^\") return OperatorKind.BitwiseXor;\n break;\n }\n case CharCode.Equals: {\n if (arg == \"==\") return OperatorKind.Eq;\n break;\n }\n case CharCode.Exclamation: {\n if (arg == \"!=\") return OperatorKind.Ne;\n break;\n }\n case CharCode.GreaterThan: {\n if (arg == \">\") return OperatorKind.Gt;\n if (arg == \">=\") return OperatorKind.Ge;\n if (arg == \">>\") return OperatorKind.BitwiseShr;\n if (arg == \">>>\") return OperatorKind.BitwiseShrU;\n break;\n }\n case CharCode.LessThan: {\n if (arg == \"<\") return OperatorKind.Lt;\n if (arg == \"<=\") return OperatorKind.Le;\n if (arg == \"<<\") return OperatorKind.BitwiseShl;\n break;\n }\n }\n break;\n }\n case DecoratorKind.OperatorPrefix: {\n switch (arg.charCodeAt(0)) {\n case CharCode.Plus: {\n if (arg == \"+\") return OperatorKind.Plus;\n if (arg == \"++\") return OperatorKind.PrefixInc;\n break;\n }\n case CharCode.Minus: {\n if (arg == \"-\") return OperatorKind.Minus;\n if (arg == \"--\") return OperatorKind.PrefixDec;\n break;\n }\n case CharCode.Exclamation: {\n if (arg == \"!\") return OperatorKind.Not;\n break;\n }\n case CharCode.Tilde: {\n if (arg == \"~\") return OperatorKind.BitwiseNot;\n break;\n }\n }\n break;\n }\n case DecoratorKind.OperatorPostfix: {\n switch (arg.charCodeAt(0)) {\n case CharCode.Plus: {\n if (arg == \"++\") return OperatorKind.PostfixInc;\n break;\n }\n case CharCode.Minus: {\n if (arg == \"--\") return OperatorKind.PostfixDec;\n break;\n }\n }\n break;\n }\n }\n return OperatorKind.Invalid;\n }\n\n /** Converts a binary operator token to the respective operator kind. */\n export function fromBinaryToken(token: Token): OperatorKind {\n switch (token) {\n case Token.Plus:\n case Token.Plus_Equals: return OperatorKind.Add;\n case Token.Minus:\n case Token.Minus_Equals: return OperatorKind.Sub;\n case Token.Asterisk:\n case Token.Asterisk_Equals: return OperatorKind.Mul;\n case Token.Slash:\n case Token.Slash_Equals: return OperatorKind.Div;\n case Token.Percent:\n case Token.Percent_Equals: return OperatorKind.Rem;\n case Token.Asterisk_Asterisk:\n case Token.Asterisk_Asterisk_Equals: return OperatorKind.Pow;\n case Token.Ampersand:\n case Token.Ampersand_Equals: return OperatorKind.BitwiseAnd;\n case Token.Bar:\n case Token.Bar_Equals: return OperatorKind.BitwiseOr;\n case Token.Caret:\n case Token.Caret_Equals: return OperatorKind.BitwiseXor;\n case Token.LessThan_LessThan:\n case Token.LessThan_LessThan_Equals: return OperatorKind.BitwiseShl;\n case Token.GreaterThan_GreaterThan:\n case Token.GreaterThan_GreaterThan_Equals: return OperatorKind.BitwiseShr;\n case Token.GreaterThan_GreaterThan_GreaterThan:\n case Token.GreaterThan_GreaterThan_GreaterThan_Equals: return OperatorKind.BitwiseShrU;\n case Token.Equals_Equals: return OperatorKind.Eq;\n case Token.Exclamation_Equals: return OperatorKind.Ne;\n case Token.GreaterThan: return OperatorKind.Gt;\n case Token.GreaterThan_Equals: return OperatorKind.Ge;\n case Token.LessThan: return OperatorKind.Lt;\n case Token.LessThan_Equals: return OperatorKind.Le;\n }\n return OperatorKind.Invalid;\n }\n\n /** Converts a unary prefix operator token to the respective operator kind. */\n export function fromUnaryPrefixToken(token: Token): OperatorKind {\n switch (token) {\n case Token.Plus: return OperatorKind.Plus;\n case Token.Minus: return OperatorKind.Minus;\n case Token.Exclamation: return OperatorKind.Not;\n case Token.Tilde: return OperatorKind.BitwiseNot;\n case Token.Plus_Plus: return OperatorKind.PrefixInc;\n case Token.Minus_Minus: return OperatorKind.PrefixDec;\n }\n return OperatorKind.Invalid;\n }\n\n /** Converts a unary postfix operator token to the respective operator kind. */\n export function fromUnaryPostfixToken(token: Token): OperatorKind {\n switch (token) {\n case Token.Plus_Plus: return OperatorKind.PostfixInc;\n case Token.Minus_Minus: return OperatorKind.PostfixDec;\n }\n return OperatorKind.Invalid;\n }\n}\n\n/** Represents an AssemblyScript program. */\nexport class Program extends DiagnosticEmitter {\n\n /** Constructs a new program, optionally inheriting parser diagnostics. */\n constructor(\n /** Compiler options. */\n public options: Options,\n /** Shared array of diagnostic messages (emitted so far). */\n diagnostics: DiagnosticMessage[] | null = null\n ) {\n super(diagnostics);\n this.module = Module.create(options.stackSize > 0, options.sizeTypeRef); \n this.parser = new Parser(this.diagnostics, this.sources);\n this.resolver = new Resolver(this);\n let nativeFile = new File(this, Source.native);\n this.nativeFile = nativeFile;\n this.filesByName.set(nativeFile.internalName, nativeFile);\n }\n\n /** Module instance. */\n module: Module;\n /** Parser instance. */\n parser!: Parser;\n /** Resolver instance. */\n resolver!: Resolver;\n /** Array of sources. */\n sources: Source[] = [];\n /** Diagnostic offset used where successively obtaining the next diagnostic. */\n diagnosticsOffset: i32 = 0;\n /** Special native code file. */\n nativeFile!: File;\n /** Next class id. */\n nextClassId: u32 = 0;\n /** Next signature id. */\n nextSignatureId: i32 = 0;\n /** An indicator if the program has been initialized. */\n initialized: bool = false;\n\n // Lookup maps\n\n /** Files by unique internal name. */\n filesByName: Map = new Map();\n /** Elements by unique internal name in element space. */\n elementsByName: Map = new Map();\n /** Elements by declaration. */\n elementsByDeclaration: Map = new Map();\n /** Element instances by unique internal name. */\n instancesByName: Map = new Map();\n /** Classes wrapping basic types like `i32`. */\n wrapperClasses: Map = new Map();\n /** Managed classes contained in the program, by id. */\n managedClasses: Map = new Map();\n /** A set of unique function signatures contained in the program, by id. */\n uniqueSignatures: Map = new Map();\n /** Module imports. */\n moduleImports: Map> = new Map();\n\n // Standard library\n\n /** Gets the standard `ArrayBufferView` instance. */\n get arrayBufferViewInstance(): Class {\n let cached = this._arrayBufferViewInstance;\n if (!cached) this._arrayBufferViewInstance = cached = this.requireClass(CommonNames.ArrayBufferView);\n return cached;\n }\n private _arrayBufferViewInstance: Class | null = null;\n\n /** Gets the standard `ArrayBuffer` instance. */\n get arrayBufferInstance(): Class {\n let cached = this._arrayBufferInstance;\n if (!cached) this._arrayBufferInstance = cached = this.requireClass(CommonNames.ArrayBuffer);\n return cached;\n }\n private _arrayBufferInstance: Class | null = null;\n\n /** Gets the standard `Array` prototype. */\n get arrayPrototype(): ClassPrototype {\n let cached = this._arrayPrototype;\n if (!cached) this._arrayPrototype = cached = this.require(CommonNames.Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _arrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `StaticArray` prototype. */\n get staticArrayPrototype(): ClassPrototype {\n let cached = this._staticArrayPrototype;\n if (!cached) this._staticArrayPrototype = cached = this.require(CommonNames.StaticArray, ElementKind.ClassPrototype);\n return cached;\n }\n private _staticArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Set` prototype. */\n get setPrototype(): ClassPrototype {\n let cached = this._setPrototype;\n if (!cached) this._setPrototype = cached = this.require(CommonNames.Set, ElementKind.ClassPrototype);\n return cached;\n }\n private _setPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Map` prototype. */\n get mapPrototype(): ClassPrototype {\n let cached = this._mapPrototype;\n if (!cached) this._mapPrototype = cached = this.require(CommonNames.Map, ElementKind.ClassPrototype);\n return cached;\n }\n private _mapPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Function` prototype. */\n get functionPrototype(): ClassPrototype {\n let cached = this._functionPrototype;\n if (!cached) this._functionPrototype = cached = this.require(CommonNames.Function, ElementKind.ClassPrototype);\n return cached;\n }\n private _functionPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Int8Array` prototype. */\n get int8ArrayPrototype(): ClassPrototype {\n let cached = this._int8ArrayPrototype;\n if (!cached) this._int8ArrayPrototype = cached = this.require(CommonNames.Int8Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _int8ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Int16Array` prototype. */\n get int16ArrayPrototype(): ClassPrototype {\n let cached = this._int16ArrayPrototype;\n if (!cached) this._int16ArrayPrototype = cached = this.require(CommonNames.Int16Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _int16ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Int32Array` prototype. */\n get int32ArrayPrototype(): ClassPrototype {\n let cached = this._int32ArrayPrototype;\n if (!cached) this._int32ArrayPrototype = cached = this.require(CommonNames.Int32Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _int32ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Int64Array` prototype. */\n get int64ArrayPrototype(): ClassPrototype {\n let cached = this._int64ArrayPrototype;\n if (!cached) this._int64ArrayPrototype = cached = this.require(CommonNames.Int64Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _int64ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Uint8Array` prototype. */\n get uint8ArrayPrototype(): ClassPrototype {\n let cached = this._uint8ArrayPrototype;\n if (!cached) this._uint8ArrayPrototype = cached = this.require(CommonNames.Uint8Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _uint8ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Uint8ClampedArray` prototype. */\n get uint8ClampedArrayPrototype(): ClassPrototype {\n let cached = this._uint8ClampedArrayPrototype;\n if (!cached) this._uint8ClampedArrayPrototype = cached = this.require(CommonNames.Uint8ClampedArray, ElementKind.ClassPrototype);\n return cached;\n }\n private _uint8ClampedArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Uint16Array` prototype. */\n get uint16ArrayPrototype(): ClassPrototype {\n let cached = this._uint16ArrayPrototype;\n if (!cached) this._uint16ArrayPrototype = cached = this.require(CommonNames.Uint16Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _uint16ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Uint32Array` prototype. */\n get uint32ArrayPrototype(): ClassPrototype {\n let cached = this._uint32ArrayPrototype;\n if (!cached) this._uint32ArrayPrototype = cached = this.require(CommonNames.Uint32Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _uint32ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Uint64Array` prototype. */\n get uint64ArrayPrototype(): ClassPrototype {\n let cached = this._uint64ArrayPrototype;\n if (!cached) this._uint64ArrayPrototype = cached = this.require(CommonNames.Uint64Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _uint64ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Float32Array` prototype. */\n get float32ArrayPrototype(): ClassPrototype {\n let cached = this._float32ArrayPrototype;\n if (!cached) this._float32ArrayPrototype = cached = this.require(CommonNames.Float32Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _float32ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Float64Array` prototype. */\n get float64ArrayPrototype(): ClassPrototype {\n let cached = this._float64ArrayPrototype;\n if (!cached) this._float64ArrayPrototype = cached = this.require(CommonNames.Float64Array, ElementKind.ClassPrototype);\n return cached;\n }\n private _float64ArrayPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `String` instance. */\n get stringInstance(): Class {\n let cached = this._stringInstance;\n if (!cached) this._stringInstance = cached = this.requireClass(CommonNames.String);\n return cached;\n }\n private _stringInstance: Class | null = null;\n\n /** Gets the standard `RegExp` instance. */\n get regexpInstance(): Class {\n let cached = this._regexpInstance;\n if (!cached) this._regexpInstance = cached = this.requireClass(CommonNames.RegExp);\n return cached;\n }\n private _regexpInstance: Class | null = null;\n\n /** Gets the standard `Object` prototype. */\n get objectPrototype(): ClassPrototype {\n let cached = this._objectPrototype;\n if (!cached) this._objectPrototype = cached = this.require(CommonNames.Object, ElementKind.ClassPrototype);\n return cached;\n }\n private _objectPrototype: ClassPrototype | null = null;\n\n /** Gets the standard `Object` instance. */\n get objectInstance(): Class {\n let cached = this._objectInstance;\n if (!cached) this._objectInstance = cached = this.requireClass(CommonNames.Object);\n return cached;\n }\n private _objectInstance: Class | null = null;\n\n /** Gets the standard `TemplateStringsArray` instance. */\n get templateStringsArrayInstance(): Class {\n let cached = this._templateStringsArrayInstance;\n if (!cached) this._templateStringsArrayInstance = cached = this.requireClass(CommonNames.TemplateStringsArray);\n return cached;\n }\n private _templateStringsArrayInstance: Class | null = null;\n\n /** Gets the standard `abort` instance, if not explicitly disabled. */\n get abortInstance(): Function | null {\n let prototype = this.lookup(CommonNames.abort);\n if (!prototype || prototype.kind != ElementKind.FunctionPrototype) return null;\n return this.resolver.resolveFunction(prototype, null);\n }\n\n // Runtime interface\n\n /** Gets the runtime `__alloc(size: usize): usize` instance. */\n get allocInstance(): Function {\n let cached = this._allocInstance;\n if (!cached) this._allocInstance = cached = this.requireFunction(CommonNames.alloc);\n return cached;\n }\n private _allocInstance: Function | null = null;\n\n /** Gets the runtime `__realloc(ptr: usize, newSize: usize): usize` instance. */\n get reallocInstance(): Function {\n let cached = this._reallocInstance;\n if (!cached) this._reallocInstance = cached = this.requireFunction(CommonNames.realloc);\n return cached;\n }\n private _reallocInstance: Function | null = null;\n\n /** Gets the runtime `__free(ptr: usize): void` instance. */\n get freeInstance(): Function {\n let cached = this._freeInstance;\n if (!cached) this._freeInstance = cached = this.requireFunction(CommonNames.free);\n return cached;\n }\n private _freeInstance: Function | null = null;\n\n /** Gets the runtime `__new(size: usize, id: u32): usize` instance. */\n get newInstance(): Function {\n let cached = this._newInstance;\n if (!cached) this._newInstance = cached = this.requireFunction(CommonNames.new_);\n return cached;\n }\n private _newInstance: Function | null = null;\n\n /** Gets the runtime `__renew(ptr: usize, size: usize): usize` instance. */\n get renewInstance(): Function {\n let cached = this._renewInstance;\n if (!cached) this._renewInstance = cached = this.requireFunction(CommonNames.renew);\n return cached;\n }\n private _renewInstance: Function | null = null;\n\n /** Gets the runtime `__link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void` instance. */\n get linkInstance(): Function {\n let cached = this._linkInstance;\n if (!cached) this._linkInstance = cached = this.requireFunction(CommonNames.link);\n return cached;\n }\n private _linkInstance: Function | null = null;\n\n /** Gets the runtime `__collect(): void` instance. */\n get collectInstance(): Function {\n let cached = this._collectInstance;\n if (!cached) this._collectInstance = cached = this.requireFunction(CommonNames.collect);\n return cached;\n }\n private _collectInstance: Function | null = null;\n\n /** Gets the runtime `__visit(ptr: usize, cookie: u32): void` instance. */\n get visitInstance(): Function {\n let cached = this._visitInstance;\n if (!cached) this._visitInstance = cached = this.requireFunction(CommonNames.visit);\n return cached;\n }\n private _visitInstance: Function | null = null;\n\n /** Gets the runtime `__newBuffer(size: usize, id: u32, data: usize = 0): usize` instance. */\n get newBufferInstance(): Function {\n let cached = this._newBufferInstance;\n if (!cached) this._newBufferInstance = cached = this.requireFunction(CommonNames.newBuffer);\n return cached;\n }\n private _newBufferInstance: Function | null = null;\n\n /** Gets the runtime `__newArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize` instance. */\n get newArrayInstance(): Function {\n let cached = this._newArrayInstance;\n if (!cached) this._newArrayInstance = cached = this.requireFunction(CommonNames.newArray);\n return cached;\n }\n private _newArrayInstance: Function | null = null;\n\n /** Gets the runtime's internal `BLOCK` instance. */\n get BLOCKInstance(): Class {\n let cached = this._BLOCKInstance;\n if (!cached) this._BLOCKInstance = cached = this.requireClass(CommonNames.BLOCK);\n return cached;\n }\n private _BLOCKInstance: Class | null = null;\n\n /** Gets the runtime's internal `OBJECT` instance. */\n get OBJECTInstance(): Class {\n let cached = this._OBJECTInstance;\n if (!cached) this._OBJECTInstance = cached = this.requireClass(CommonNames.OBJECT);\n return cached;\n }\n private _OBJECTInstance: Class | null = null;\n\n // Utility\n\n /** Obtains the source matching the specified internal path. */\n getSource(internalPath: string): string | null {\n let sources = this.sources;\n for (let i = 0; i < sources.length; ++i) {\n let source = sources[i];\n if (source.internalPath == internalPath) return source.text;\n }\n return null;\n }\n\n /** Gets the overhead of a memory manager block. */\n get blockOverhead(): i32 {\n // BLOCK | data...\n // ^ 16b alignment\n return this.BLOCKInstance.nextMemoryOffset;\n }\n\n /** Gets the overhead of a managed object, excl. block overhead, incl. alignment. */\n get objectOverhead(): i32 {\n // OBJECT+align | data...\n // └ 0 ┘ ^ 16b alignment\n return (this.OBJECTInstance.nextMemoryOffset - this.blockOverhead + AL_MASK) & ~AL_MASK;\n }\n\n /** Gets the total overhead of a managed object, incl. block overhead. */\n get totalOverhead(): i32 {\n // BLOCK | OBJECT+align | data...\n // └ = TOTAL ┘ ^ 16b alignment\n return this.blockOverhead + this.objectOverhead;\n }\n\n searchFunctionByRef(ref: FunctionRef): Function | null {\n const modifiedFunctionName = getFunctionName(ref);\n if (modifiedFunctionName) {\n const instancesByName = this.instancesByName;\n if (instancesByName.has(modifiedFunctionName)) {\n const element = assert(instancesByName.get(modifiedFunctionName));\n if (element.kind == ElementKind.Function) {\n return element;\n }\n }\n }\n return null;\n }\n\n /** Computes the next properly aligned offset of a memory manager block, given the current bump offset. */\n computeBlockStart(currentOffset: i32): i32 {\n let blockOverhead = this.blockOverhead;\n return ((currentOffset + blockOverhead + AL_MASK) & ~AL_MASK) - blockOverhead;\n }\n\n /** Computes the next properly aligned offset of a memory manager block, given the current bump offset. */\n computeBlockStart64(currentOffset: i64): i64 {\n let blockOverhead = i64_new(this.blockOverhead);\n return i64_sub(i64_align(i64_add(currentOffset, blockOverhead), AL_SIZE), blockOverhead);\n }\n\n /** Computes the size of a memory manager block, excl. block overhead. */\n computeBlockSize(payloadSize: i32, isManaged: bool): i32 {\n // see: std/rt/tlsf.ts, computeSize; becomes mmInfo\n if (isManaged) payloadSize += this.objectOverhead;\n // we know that payload must be aligned, and that block sizes must be chosen\n // so that blocks are adjacent with the next payload aligned. hence, block\n // size is payloadSize rounded up to where the next block would start:\n let blockSize = this.computeBlockStart(payloadSize);\n // make sure that block size is valid according to TLSF requirements\n let blockOverhead = this.blockOverhead;\n let blockMinsize = ((3 * this.options.usizeType.byteSize + blockOverhead + AL_MASK) & ~AL_MASK) - blockOverhead;\n if (blockSize < blockMinsize) blockSize = blockMinsize;\n const blockMaxsize = 1 << 30; // 1 << (FL_BITS + SB_BITS - 1), exclusive\n const tagsMask = 3;\n if (blockSize >= blockMaxsize || (blockSize & tagsMask) != 0) {\n throw new Error(\"invalid block size\");\n }\n return blockSize;\n }\n\n /** Creates a native variable declaration. */\n makeNativeVariableDeclaration(\n /** The simple name of the variable */\n name: string,\n /** Flags indicating specific traits, e.g. `CONST`. */\n flags: CommonFlags = CommonFlags.None\n ): VariableDeclaration {\n let range = Source.native.range;\n return Node.createVariableDeclaration(\n Node.createIdentifierExpression(name, range),\n null, flags, null, null, range\n );\n }\n\n /** Creates a native type declaration. */\n makeNativeTypeDeclaration(\n /** The simple name of the type. */\n name: string,\n /** Flags indicating specific traits, e.g. `GENERIC`. */\n flags: CommonFlags = CommonFlags.None\n ): TypeDeclaration {\n let range = Source.native.range;\n let identifier = Node.createIdentifierExpression(name, range);\n return Node.createTypeDeclaration(\n identifier,\n null, flags, null,\n Node.createOmittedType(range),\n range\n );\n }\n\n // a dummy signature for programmatically generated native functions\n private nativeDummySignature: FunctionTypeNode | null = null;\n\n /** Creates a native function declaration. */\n makeNativeFunctionDeclaration(\n /** The simple name of the function. */\n name: string,\n /** Flags indicating specific traits, e.g. `DECLARE`. */\n flags: CommonFlags = CommonFlags.None\n ): FunctionDeclaration {\n let range = Source.native.range;\n let signature = this.nativeDummySignature;\n if (!signature) {\n this.nativeDummySignature = signature = Node.createFunctionType([],\n Node.createNamedType( // ^ AST signature doesn't really matter, is overridden anyway\n Node.createSimpleTypeName(CommonNames.void_, range),\n null, false, range\n ),\n null, false, range\n );\n }\n return Node.createFunctionDeclaration(\n Node.createIdentifierExpression(name, range),\n null, flags, null, signature, null, ArrowKind.None, range\n );\n }\n\n /** Creates a native namespace declaration. */\n makeNativeNamespaceDeclaration(\n /** The simple name of the namespace. */\n name: string,\n /** Flags indicating specific traits, e.g. `EXPORT`. */\n flags: CommonFlags = CommonFlags.None\n ): NamespaceDeclaration {\n let range = Source.native.range;\n return Node.createNamespaceDeclaration(\n Node.createIdentifierExpression(name, range),\n null, flags, [], range\n );\n }\n\n /** Creates a native function. */\n makeNativeFunction(\n /** The simple name of the function. */\n name: string,\n /** Concrete function signature. */\n signature: Signature,\n /** Parent element, usually a file, class or namespace. */\n parent: Element = this.nativeFile,\n /** Flags indicating specific traits, e.g. `GENERIC`. */\n flags: CommonFlags = CommonFlags.None,\n /** Decorator flags representing built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None\n ): Function {\n return new Function(\n name,\n new FunctionPrototype(\n name,\n parent,\n this.makeNativeFunctionDeclaration(name, flags),\n decoratorFlags\n ),\n null,\n signature\n );\n }\n\n /** Gets the (possibly merged) program element linked to the specified declaration. */\n getElementByDeclaration(declaration: DeclarationStatement): DeclaredElement | null {\n let elementsByDeclaration = this.elementsByDeclaration;\n return elementsByDeclaration.has(declaration)\n ? assert(elementsByDeclaration.get(declaration))\n : null;\n }\n\n /** Initializes the program and its elements prior to compilation. */\n initialize(): void {\n if (this.initialized) return;\n this.initialized = true;\n\n let options = this.options;\n\n // register native types\n this.registerNativeType(CommonNames.i8, Type.i8);\n this.registerNativeType(CommonNames.i16, Type.i16);\n this.registerNativeType(CommonNames.i32, Type.i32);\n this.registerNativeType(CommonNames.i64, Type.i64);\n this.registerNativeType(CommonNames.isize, options.isizeType);\n this.registerNativeType(CommonNames.u8, Type.u8);\n this.registerNativeType(CommonNames.u16, Type.u16);\n this.registerNativeType(CommonNames.u32, Type.u32);\n this.registerNativeType(CommonNames.u64, Type.u64);\n this.registerNativeType(CommonNames.usize, options.usizeType);\n this.registerNativeType(CommonNames.bool, Type.bool);\n this.registerNativeType(CommonNames.f32, Type.f32);\n this.registerNativeType(CommonNames.f64, Type.f64);\n this.registerNativeType(CommonNames.void_, Type.void);\n this.registerNativeType(CommonNames.number, Type.f64); // alias\n this.registerNativeType(CommonNames.boolean, Type.bool); // alias\n this.nativeFile.add(CommonNames.native, new TypeDefinition(\n CommonNames.native,\n this.nativeFile,\n this.makeNativeTypeDeclaration(CommonNames.native, CommonFlags.Export | CommonFlags.Generic),\n DecoratorFlags.Builtin\n ));\n this.nativeFile.add(CommonNames.indexof, new TypeDefinition(\n CommonNames.indexof,\n this.nativeFile,\n this.makeNativeTypeDeclaration(CommonNames.indexof, CommonFlags.Export | CommonFlags.Generic),\n DecoratorFlags.Builtin\n ));\n this.nativeFile.add(CommonNames.valueof, new TypeDefinition(\n CommonNames.valueof,\n this.nativeFile,\n this.makeNativeTypeDeclaration(CommonNames.valueof, CommonFlags.Export | CommonFlags.Generic),\n DecoratorFlags.Builtin\n ));\n this.nativeFile.add(CommonNames.returnof, new TypeDefinition(\n CommonNames.returnof,\n this.nativeFile,\n this.makeNativeTypeDeclaration(CommonNames.returnof, CommonFlags.Export | CommonFlags.Generic),\n DecoratorFlags.Builtin\n ));\n this.nativeFile.add(CommonNames.nonnull, new TypeDefinition(\n CommonNames.nonnull,\n this.nativeFile,\n this.makeNativeTypeDeclaration(CommonNames.nonnull, CommonFlags.Export | CommonFlags.Generic),\n DecoratorFlags.Builtin\n ));\n\n // The following types might not be enabled by compiler options, so the\n // compiler needs to check this condition whenever such a value is created\n // respectively stored or loaded.\n this.registerNativeType(CommonNames.v128, Type.v128);\n this.registerNativeType(CommonNames.funcref, Type.funcref);\n this.registerNativeType(CommonNames.externref, Type.externref);\n this.registerNativeType(CommonNames.anyref, Type.anyref);\n this.registerNativeType(CommonNames.eqref, Type.eqref);\n this.registerNativeType(CommonNames.structref, Type.structref);\n this.registerNativeType(CommonNames.arrayref, Type.arrayref);\n this.registerNativeType(CommonNames.i31ref, Type.i31ref);\n this.registerNativeType(CommonNames.stringref, Type.stringref);\n this.registerNativeType(CommonNames.stringview_wtf8, Type.stringview_wtf8);\n this.registerNativeType(CommonNames.stringview_wtf16, Type.stringview_wtf16);\n this.registerNativeType(CommonNames.stringview_iter, Type.stringview_iter);\n\n // register compiler hints\n this.registerConstantInteger(CommonNames.ASC_TARGET, Type.i32,\n i64_new(options.isWasm64 ? Target.Wasm64 : Target.Wasm32));\n this.registerConstantInteger(CommonNames.ASC_RUNTIME, Type.i32,\n i64_new(options.runtime));\n this.registerConstantInteger(CommonNames.ASC_NO_ASSERT, Type.bool,\n i64_new(options.noAssert ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_MEMORY_BASE, Type.i32,\n i64_new(options.memoryBase, 0));\n this.registerConstantInteger(CommonNames.ASC_TABLE_BASE, Type.i32,\n i64_new(options.tableBase, 0));\n this.registerConstantInteger(CommonNames.ASC_OPTIMIZE_LEVEL, Type.i32,\n i64_new(options.optimizeLevelHint, 0));\n this.registerConstantInteger(CommonNames.ASC_SHRINK_LEVEL, Type.i32,\n i64_new(options.shrinkLevelHint, 0));\n this.registerConstantInteger(CommonNames.ASC_LOW_MEMORY_LIMIT, Type.i32,\n i64_new(options.lowMemoryLimit, 0));\n this.registerConstantInteger(CommonNames.ASC_EXPORT_RUNTIME, Type.bool,\n i64_new(options.exportRuntime ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_VERSION_MAJOR, Type.i32,\n i64_new(options.bundleMajorVersion));\n this.registerConstantInteger(CommonNames.ASC_VERSION_MINOR, Type.i32,\n i64_new(options.bundleMinorVersion));\n this.registerConstantInteger(CommonNames.ASC_VERSION_PATCH, Type.i32,\n i64_new(options.bundlePatchVersion));\n\n // register feature hints\n this.registerConstantInteger(CommonNames.ASC_FEATURE_SIGN_EXTENSION, Type.bool,\n i64_new(options.hasFeature(Feature.SignExtension) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_MUTABLE_GLOBALS, Type.bool,\n i64_new(options.hasFeature(Feature.MutableGlobals) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_NONTRAPPING_F2I, Type.bool,\n i64_new(options.hasFeature(Feature.NontrappingF2I) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_BULK_MEMORY, Type.bool,\n i64_new(options.hasFeature(Feature.BulkMemory) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_SIMD, Type.bool,\n i64_new(options.hasFeature(Feature.Simd) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_THREADS, Type.bool,\n i64_new(options.hasFeature(Feature.Threads) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_EXCEPTION_HANDLING, Type.bool,\n i64_new(options.hasFeature(Feature.ExceptionHandling) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_TAIL_CALLS, Type.bool,\n i64_new(options.hasFeature(Feature.TailCalls) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_REFERENCE_TYPES, Type.bool,\n i64_new(options.hasFeature(Feature.ReferenceTypes) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_MULTI_VALUE, Type.bool,\n i64_new(options.hasFeature(Feature.MultiValue) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_GC, Type.bool,\n i64_new(options.hasFeature(Feature.GC) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_MEMORY64, Type.bool,\n i64_new(options.hasFeature(Feature.Memory64) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_RELAXED_SIMD, Type.bool,\n i64_new(options.hasFeature(Feature.RelaxedSimd) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_EXTENDED_CONST, Type.bool,\n i64_new(options.hasFeature(Feature.ExtendedConst) ? 1 : 0, 0));\n this.registerConstantInteger(CommonNames.ASC_FEATURE_STRINGREF, Type.bool,\n i64_new(options.hasFeature(Feature.Stringref) ? 1 : 0, 0));\n\n // remember deferred elements\n let queuedImports = new Array();\n let queuedExports = new Map>();\n let queuedExportsStar = new Map();\n let queuedExtends = new Array();\n let queuedImplements = new Array();\n\n // initialize relevant declaration-like statements of the entire program\n for (let i = 0, k = this.sources.length; i < k; ++i) {\n let source = this.sources[i];\n let file = new File(this, source);\n this.filesByName.set(file.internalName, file);\n let statements = source.statements;\n for (let j = 0, l = statements.length; j < l; ++j) {\n let statement = statements[j];\n switch (statement.kind) {\n case NodeKind.Export: {\n this.initializeExports(statement, file, queuedExports, queuedExportsStar);\n break;\n }\n case NodeKind.ExportDefault: {\n this.initializeExportDefault(statement, file, queuedExtends, queuedImplements);\n break;\n }\n case NodeKind.Import: {\n this.initializeImports(statement, file, queuedImports, queuedExports);\n break;\n }\n case NodeKind.Variable: {\n this.initializeVariables(statement, file);\n break;\n }\n case NodeKind.ClassDeclaration: {\n this.initializeClass(statement, file, queuedExtends, queuedImplements);\n break;\n }\n case NodeKind.EnumDeclaration: {\n this.initializeEnum(statement, file);\n break;\n }\n case NodeKind.FunctionDeclaration: {\n this.initializeFunction(statement, file);\n break;\n }\n case NodeKind.InterfaceDeclaration: {\n this.initializeInterface(statement, file, queuedExtends);\n break;\n }\n case NodeKind.NamespaceDeclaration: {\n this.initializeNamespace(statement, file, queuedExtends, queuedImplements);\n break;\n }\n case NodeKind.TypeDeclaration: {\n this.initializeTypeDefinition(statement, file);\n break;\n }\n }\n }\n }\n\n // queued exports * should be linkable now that all files have been processed\n // TODO: for (let [file, starExports] of queuedExportsStar) {\n for (let _keys = Map_keys(queuedExportsStar), i = 0, k = _keys.length; i < k; ++i) {\n let file = _keys[i];\n let starExports = assert(queuedExportsStar.get(file));\n for (let j = 0, l = starExports.length; j < l; ++j) {\n let exportStar = unchecked(starExports[j]);\n let foreignFile = this.lookupForeignFile(exportStar.foreignPath, exportStar.foreignPathAlt);\n if (!foreignFile) {\n this.error(\n DiagnosticCode.File_0_not_found,\n exportStar.pathLiteral.range, exportStar.pathLiteral.value\n );\n continue;\n }\n file.ensureExportStar(foreignFile);\n }\n }\n\n // queued imports should be resolvable now through traversing exports and queued exports.\n // note that imports may depend upon imports, so repeat until there's no more progress.\n do {\n let i = 0, madeProgress = false;\n while (i < queuedImports.length) {\n let queuedImport = queuedImports[i];\n let localIdentifier = queuedImport.localIdentifier;\n let foreignIdentifier = queuedImport.foreignIdentifier;\n // File must be found here, as it would otherwise already have been reported by the parser\n let foreignFile = assert(this.lookupForeignFile(queuedImport.foreignPath, queuedImport.foreignPathAlt));\n if (foreignIdentifier) { // i.e. import { foo [as bar] } from \"./baz\"\n let element = this.lookupForeign(\n foreignIdentifier.text,\n foreignFile,\n queuedExports\n );\n if (element) {\n queuedImport.localFile.add(\n localIdentifier.text,\n element,\n localIdentifier // isImport\n );\n queuedImports.splice(i, 1);\n madeProgress = true;\n } else {\n ++i;\n }\n } else { // i.e. import * as bar from \"./bar\"\n let localFile = queuedImport.localFile;\n let localName = localIdentifier.text;\n localFile.add(\n localName,\n foreignFile.asAliasNamespace(\n localName,\n localFile,\n localIdentifier\n ),\n localIdentifier // isImport\n );\n queuedImports.splice(i, 1);\n madeProgress = true;\n }\n }\n if (!madeProgress) {\n // report queued imports we were unable to resolve\n for (let j = 0, l = queuedImports.length; j < l; ++j) {\n let queuedImport = queuedImports[j];\n let foreignIdentifier = queuedImport.foreignIdentifier;\n if (foreignIdentifier) {\n this.error(\n DiagnosticCode.Module_0_has_no_exported_member_1,\n foreignIdentifier.range, queuedImport.foreignPath, foreignIdentifier.text\n );\n }\n }\n break;\n }\n } while (true);\n\n // queued exports should be resolvable now that imports are finalized\n // TODO: for (let [file, exports] of queuedExports) {\n for (let _keys = Map_keys(queuedExports), i = 0, k = _keys.length; i < k; ++i) {\n let file = unchecked(_keys[i]);\n let exports = assert(queuedExports.get(file));\n // TODO: for (let [exportName, queuedExport] of exports) {\n for (let exportNames = Map_keys(exports), j = 0, l = exportNames.length; j < l; ++j) {\n let exportName = unchecked(exportNames[j]);\n let queuedExport = assert(exports.get(exportName));\n let localName = queuedExport.localIdentifier.text;\n let foreignPath = queuedExport.foreignPath;\n if (foreignPath) { // i.e. export { foo [as bar] } from \"./baz\"\n // File must be found here, as it would otherwise already have been reported by the parser\n let foreignFile = assert(this.lookupForeignFile(foreignPath, assert(queuedExport.foreignPathAlt)));\n let element = this.lookupForeign(localName, foreignFile, queuedExports);\n if (element) {\n file.ensureExport(exportName, element);\n } else {\n this.error(\n DiagnosticCode.Module_0_has_no_exported_member_1,\n queuedExport.localIdentifier.range,\n foreignPath, localName\n );\n }\n } else { // i.e. export { foo [as bar] }\n let element = file.getMember(localName);\n if (element) {\n file.ensureExport(exportName, element);\n } else {\n let globalElement = this.lookup(localName);\n if (globalElement && isDeclaredElement(globalElement.kind)) { // export { memory }\n file.ensureExport(exportName, globalElement);\n } else {\n this.error(\n DiagnosticCode.Module_0_has_no_exported_member_1,\n queuedExport.foreignIdentifier.range,\n file.internalName, queuedExport.foreignIdentifier.text\n );\n }\n }\n }\n }\n }\n\n // register foundational classes with fixed ids\n assert(this.objectInstance.id == 0);\n assert(this.arrayBufferInstance.id == 1);\n assert(this.stringInstance.id == 2);\n assert(this.arrayBufferViewInstance.id == 3);\n\n // register classes backing basic types\n this.registerWrapperClass(Type.i8, CommonNames.I8);\n this.registerWrapperClass(Type.i16, CommonNames.I16);\n this.registerWrapperClass(Type.i32, CommonNames.I32);\n this.registerWrapperClass(Type.i64, CommonNames.I64);\n this.registerWrapperClass(options.isizeType, CommonNames.Isize);\n this.registerWrapperClass(Type.u8, CommonNames.U8);\n this.registerWrapperClass(Type.u16, CommonNames.U16);\n this.registerWrapperClass(Type.u32, CommonNames.U32);\n this.registerWrapperClass(Type.u64, CommonNames.U64);\n this.registerWrapperClass(options.usizeType, CommonNames.Usize);\n this.registerWrapperClass(Type.bool, CommonNames.Bool);\n this.registerWrapperClass(Type.f32, CommonNames.F32);\n this.registerWrapperClass(Type.f64, CommonNames.F64);\n if (options.hasFeature(Feature.Simd)) this.registerWrapperClass(Type.v128, CommonNames.V128);\n if (options.hasFeature(Feature.ReferenceTypes)) {\n this.registerWrapperClass(Type.funcref, CommonNames.Funcref);\n this.registerWrapperClass(Type.externref, CommonNames.Externref);\n if (options.hasFeature(Feature.GC)) {\n this.registerWrapperClass(Type.anyref, CommonNames.Anyref);\n this.registerWrapperClass(Type.eqref, CommonNames.Eqref);\n this.registerWrapperClass(Type.structref, CommonNames.Structref);\n this.registerWrapperClass(Type.arrayref, CommonNames.Arrayref);\n this.registerWrapperClass(Type.i31ref, CommonNames.I31ref);\n }\n }\n\n // resolve prototypes of extended classes or interfaces\n let resolver = this.resolver;\n for (let i = 0, k = queuedExtends.length; i < k; ++i) {\n let thisPrototype = queuedExtends[i];\n let extendsNode = assert(thisPrototype.extendsNode); // must be present if in queuedExtends\n let baseElement = resolver.resolveTypeName(extendsNode.name, thisPrototype.parent);\n if (!baseElement) continue;\n if (thisPrototype.kind == ElementKind.ClassPrototype) {\n if (baseElement.kind == ElementKind.ClassPrototype) {\n let basePrototype = baseElement;\n if (basePrototype.hasDecorator(DecoratorFlags.Final)) {\n this.error(\n DiagnosticCode.Class_0_is_final_and_cannot_be_extended,\n extendsNode.range, basePrototype.identifierNode.text\n );\n }\n if (\n basePrototype.hasDecorator(DecoratorFlags.Unmanaged) !=\n thisPrototype.hasDecorator(DecoratorFlags.Unmanaged)\n ) {\n this.error(\n DiagnosticCode.Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa,\n Range.join(thisPrototype.identifierNode.range, extendsNode.range)\n );\n }\n if (!thisPrototype.extends(basePrototype)) {\n thisPrototype.basePrototype = basePrototype;\n } else {\n this.error(\n DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression,\n basePrototype.identifierNode.range,\n basePrototype.identifierNode.text,\n );\n }\n } else {\n this.error(\n DiagnosticCode.A_class_may_only_extend_another_class,\n extendsNode.range\n );\n }\n } else if (thisPrototype.kind == ElementKind.InterfacePrototype) {\n if (baseElement.kind == ElementKind.InterfacePrototype) {\n const basePrototype = baseElement;\n if (!thisPrototype.extends(basePrototype)) {\n thisPrototype.basePrototype = basePrototype;\n } else {\n this.error(\n DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression,\n basePrototype.identifierNode.range,\n basePrototype.identifierNode.text,\n );\n }\n } else {\n this.error(\n DiagnosticCode.An_interface_can_only_extend_an_interface,\n extendsNode.range\n );\n }\n }\n }\n\n // check override\n for (let i = 0, k = queuedExtends.length; i < k; i++) {\n let prototype = queuedExtends[i];\n let instanesMembers = prototype.instanceMembers;\n if (instanesMembers) {\n let members = Map_values(instanesMembers);\n for (let j = 0, k = members.length; j < k; j++) {\n let member = members[j];\n let declaration = member.declaration;\n if (declaration.is(CommonFlags.Override)) {\n let basePrototype = prototype.basePrototype;\n let hasOverride = false;\n while (basePrototype) {\n let instanceMembers = basePrototype.instanceMembers;\n if (instanceMembers) {\n if (instanceMembers.has(member.name)) {\n hasOverride = true;\n break;\n }\n }\n basePrototype = basePrototype.basePrototype;\n }\n if (!hasOverride) {\n let basePrototype = assert(prototype.basePrototype);\n this.error(\n DiagnosticCode.This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0,\n declaration.name.range,\n basePrototype.name\n );\n }\n }\n }\n }\n }\n\n // resolve prototypes of implemented interfaces\n for (let i = 0, k = queuedImplements.length; i < k; ++i) {\n let thisPrototype = queuedImplements[i];\n let implementsNodes = assert(thisPrototype.implementsNodes); // must be present if in queuedImplements\n for (let j = 0, l = implementsNodes.length; j < l; ++j) {\n let implementsNode = implementsNodes[j];\n let interfaceElement = resolver.resolveTypeName(implementsNode.name, thisPrototype.parent);\n if (!interfaceElement) continue;\n if (interfaceElement.kind == ElementKind.InterfacePrototype) {\n let interfacePrototype = interfaceElement;\n let interfacePrototypes = thisPrototype.interfacePrototypes;\n if (!interfacePrototypes) thisPrototype.interfacePrototypes = interfacePrototypes = new Array();\n interfacePrototypes.push(interfacePrototype);\n } else {\n this.error(\n DiagnosticCode.A_class_can_only_implement_an_interface,\n implementsNode.range\n );\n }\n }\n }\n\n // process overrides in extended classes and implemented interfaces\n for (let i = 0, k = queuedExtends.length; i < k; ++i) {\n let thisPrototype = queuedExtends[i];\n let basePrototype = thisPrototype.basePrototype;\n if (basePrototype) {\n this.processOverrides(thisPrototype, basePrototype);\n }\n }\n for (let i = 0, k = queuedImplements.length; i < k; ++i) {\n let thisPrototype = queuedImplements[i];\n let basePrototype = thisPrototype.basePrototype;\n let interfacePrototypes = thisPrototype.interfacePrototypes;\n if (basePrototype) {\n this.processOverrides(thisPrototype, basePrototype);\n }\n if (interfacePrototypes) {\n for (let j = 0, l = interfacePrototypes.length; j < l; ++j) {\n this.processOverrides(thisPrototype, interfacePrototypes[j]);\n }\n }\n }\n\n // set up global aliases\n {\n let globalAliases = options.globalAliases;\n if (!globalAliases) globalAliases = new Map();\n if (!globalAliases.has(CommonNames.abort)) {\n globalAliases.set(CommonNames.abort, BuiltinNames.abort);\n }\n if (!globalAliases.has(CommonNames.trace)) {\n globalAliases.set(CommonNames.trace, BuiltinNames.trace);\n }\n if (!globalAliases.has(CommonNames.seed)) {\n globalAliases.set(CommonNames.seed, BuiltinNames.seed);\n }\n if (!globalAliases.has(CommonNames.Math)) {\n globalAliases.set(CommonNames.Math, CommonNames.NativeMath);\n }\n if (!globalAliases.has(CommonNames.Mathf)) {\n globalAliases.set(CommonNames.Mathf, CommonNames.NativeMathf);\n }\n // TODO: for (let [alias, name] of globalAliases) {\n for (let _keys = Map_keys(globalAliases), i = 0, k = _keys.length; i < k; ++i) {\n let alias = unchecked(_keys[i]);\n let name = changetype(globalAliases.get(alias));\n assert(name != null);\n if (!name.length) {\n this.elementsByName.delete(alias);\n continue;\n }\n let firstChar = name.charCodeAt(0);\n if (firstChar >= CharCode._0 && firstChar <= CharCode._9) {\n this.registerConstantInteger(alias, Type.i32, i64_new(parseInt(name, 10)));\n } else {\n let elementsByName = this.elementsByName;\n if (elementsByName.has(name)) {\n elementsByName.set(alias, assert(elementsByName.get(name)));\n } else {\n this.error(DiagnosticCode.Element_0_not_found, null, name);\n }\n }\n }\n }\n\n // mark module exports, i.e. to apply proper wrapping behavior on the boundaries\n // TODO: for (let file of this.filesByName.values()) {\n for (let _values = Map_values(this.filesByName), i = 0, k = _values.length; i < k; ++i) {\n let file = unchecked(_values[i]);\n if (file.source.sourceKind == SourceKind.UserEntry) {\n this.markModuleExports(file);\n }\n }\n }\n\n /** Processes overridden members by this class in a base class. */\n private processOverrides(\n thisPrototype: ClassPrototype,\n basePrototype: ClassPrototype,\n ): void {\n // Note that we don't know concrete instances of class members, yet. Type\n // checking of concrete (generic) instances happens upon resolve.\n let thisInstanceMembers = thisPrototype.instanceMembers;\n if (thisInstanceMembers) {\n let thisMembers = Map_values(thisInstanceMembers);\n let seen: Set | null = null;\n do {\n let baseInstanceMembers = basePrototype.instanceMembers;\n if (baseInstanceMembers) {\n for (let j = 0, l = thisMembers.length; j < l; ++j) {\n let thisMember = thisMembers[j];\n if (baseInstanceMembers.has(thisMember.name)) {\n let baseMember = assert(baseInstanceMembers.get(thisMember.name));\n this.doProcessOverride(thisPrototype, thisMember, basePrototype, baseMember);\n }\n }\n }\n // A class can have a base class and multiple interfaces, but from the\n // base member alone we only get one. Make sure we don't miss any.\n let baseInterfacePrototypes = basePrototype.interfacePrototypes;\n if (baseInterfacePrototypes) {\n for (let i = 0, k = baseInterfacePrototypes.length; i < k; ++i) {\n let baseInterfacePrototype = baseInterfacePrototypes[i];\n if (baseInterfacePrototype != basePrototype) {\n this.processOverrides(thisPrototype, baseInterfacePrototype);\n }\n }\n }\n let nextPrototype = basePrototype.basePrototype;\n if (!nextPrototype) break;\n // Break on circular inheritance. Is diagnosed later, when resolved.\n if (!seen) seen = new Set();\n seen.add(basePrototype);\n if (seen.has(nextPrototype)) break;\n // Otherwise traverse to next base prototype.\n basePrototype = nextPrototype;\n } while (true);\n }\n }\n\n /** Processes a single overridden member by this class in a base class. */\n private doProcessOverride(\n thisClass: ClassPrototype,\n thisMember: DeclaredElement,\n baseClass: ClassPrototype,\n baseMember: DeclaredElement\n ): void {\n // Constructors and private members do not override\n if (thisMember.isAny(CommonFlags.Constructor | CommonFlags.Private)) return;\n if (\n thisMember.kind == ElementKind.FunctionPrototype &&\n baseMember.kind == ElementKind.FunctionPrototype\n ) {\n let thisMethod = thisMember;\n let baseMethod = baseMember;\n if (!thisMethod.visibilityEquals(baseMethod)) {\n this.errorRelated(\n DiagnosticCode.Overload_signatures_must_all_be_public_private_or_protected,\n thisMethod.identifierNode.range, baseMethod.identifierNode.range\n );\n }\n baseMember.set(CommonFlags.Overridden);\n let overrides = baseMethod.unboundOverrides;\n if (!overrides) baseMethod.unboundOverrides = overrides = new Set();\n overrides.add(thisMember);\n let baseMethodInstances = baseMethod.instances;\n if (baseMethodInstances) {\n for (let _values = Map_values(baseMethodInstances), a = 0, b = _values.length; a < b; ++a) {\n let baseMethodInstance = _values[a];\n baseMethodInstance.set(CommonFlags.Overridden);\n }\n }\n } else if (\n thisMember.kind == ElementKind.PropertyPrototype &&\n baseMember.kind == ElementKind.PropertyPrototype\n ) {\n let thisProperty = thisMember;\n let baseProperty = baseMember;\n if (!thisProperty.visibilityEquals(baseProperty)) {\n this.errorRelated(\n DiagnosticCode.Overload_signatures_must_all_be_public_private_or_protected,\n thisProperty.identifierNode.range, baseProperty.identifierNode.range\n );\n }\n if (baseProperty.parent.kind != ElementKind.InterfacePrototype) {\n // Interface fields/properties can be implemented by either, but other\n // members must match to retain compatiblity with TS/JS.\n let thisIsField = thisProperty.isField;\n if (thisIsField != baseProperty.isField) {\n if (thisIsField) { // base is property\n this.errorRelated(\n DiagnosticCode._0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property,\n thisProperty.identifierNode.range, baseProperty.identifierNode.range,\n thisProperty.name, baseClass.internalName, thisClass.internalName\n );\n } else { // this is property, base is field\n this.errorRelated(\n DiagnosticCode._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor,\n thisProperty.identifierNode.range, baseProperty.identifierNode.range,\n thisProperty.name, baseClass.internalName, thisClass.internalName\n );\n }\n return;\n } else if (thisIsField) { // base is also field\n // Fields don't override other fields and can only be redeclared\n return;\n }\n }\n baseProperty.set(CommonFlags.Overridden);\n let baseGetter = baseProperty.getterPrototype;\n if (baseGetter) {\n baseGetter.set(CommonFlags.Overridden);\n let thisGetter = thisProperty.getterPrototype;\n if (thisGetter) {\n let overrides = baseGetter.unboundOverrides;\n if (!overrides) baseGetter.unboundOverrides = overrides = new Set();\n overrides.add(thisGetter);\n }\n let baseGetterInstances = baseGetter.instances;\n if (baseGetterInstances) {\n for (let _values = Map_values(baseGetterInstances), a = 0, b = _values.length; a < b; ++a) {\n let baseGetterInstance = _values[a];\n baseGetterInstance.set(CommonFlags.Overridden);\n }\n }\n }\n let baseSetter = baseProperty.setterPrototype;\n if (baseSetter && thisProperty.setterPrototype) {\n baseSetter.set(CommonFlags.Overridden);\n let thisSetter = thisProperty.setterPrototype;\n if (thisSetter) {\n let overrides = baseSetter.unboundOverrides;\n if (!overrides) baseSetter.unboundOverrides = overrides = new Set();\n overrides.add(thisSetter);\n }\n let baseSetterInstances = baseSetter.instances;\n if (baseSetterInstances) {\n for (let _values = Map_values(baseSetterInstances), a = 0, b = _values.length; a < b; ++a) {\n let baseSetterInstance = _values[a];\n baseSetterInstance.set(CommonFlags.Overridden);\n }\n }\n }\n } else {\n this.errorRelated(\n DiagnosticCode.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n thisMember.name, thisClass.internalName, baseClass.internalName\n );\n }\n }\n\n /** Looks up the element of the specified name in the global scope. */\n lookup(name: string): Element | null {\n let elements = this.elementsByName;\n if (elements.has(name)) return assert(elements.get(name));\n return null;\n }\n\n /** Requires that a global library element of the specified kind is present and returns it. */\n private require(name: string, kind: ElementKind): Element {\n let element = this.lookup(name);\n if (!element) throw new Error(`Missing standard library component: ${name}`);\n if (element.kind != kind) throw Error(`Invalid standard library component kind: ${name}`);\n return element;\n }\n\n /** Requires that a global variable is present and returns it. */\n requireGlobal(name: string): Global {\n return this.require(name, ElementKind.Global);\n }\n\n /** Requires that a non-generic global class is present and returns it. */\n requireClass(name: string): Class {\n let prototype = this.require(name, ElementKind.ClassPrototype);\n let resolved = this.resolver.resolveClass(prototype, null);\n if (!resolved) throw new Error(`Invalid standard library class: ${name}`);\n return resolved;\n }\n\n /** Requires that a global function is present and returns it. */\n requireFunction(name: string, typeArguments: Type[] | null = null): Function {\n let prototype = this.require(name, ElementKind.FunctionPrototype);\n let resolved = this.resolver.resolveFunction(prototype, typeArguments);\n if (!resolved) throw new Error(`Invalid standard library function: ${name}`);\n return resolved;\n }\n\n /** Marks all exports of the specified file as module exports. */\n private markModuleExports(file: File): void {\n let exports = file.exports;\n if (exports) {\n // TODO: for (let element of exports.values()) {\n for (let _values = Map_values(exports), j = 0, l = _values.length; j < l; ++j) {\n let element = unchecked(_values[j]);\n this.markModuleExport(element);\n }\n }\n let exportsStar = file.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n this.markModuleExports(exportsStar[i]);\n }\n }\n }\n\n /** Marks an element and its children as a module export. */\n private markModuleExport(element: Element): void {\n element.set(CommonFlags.ModuleExport);\n switch (element.kind) {\n case ElementKind.ClassPrototype: {\n let instanceMembers = (element).instanceMembers;\n if (instanceMembers) {\n // TODO: for (let member of instanceMembers.values()) {\n for (let _values = Map_values(instanceMembers), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n this.markModuleExport(member);\n }\n }\n break;\n }\n case ElementKind.PropertyPrototype: {\n let propertyPrototype = element;\n let getterPrototype = propertyPrototype.getterPrototype;\n if (getterPrototype) this.markModuleExport(getterPrototype);\n let setterPrototype = propertyPrototype.setterPrototype;\n if (setterPrototype) this.markModuleExport(setterPrototype);\n break;\n }\n case ElementKind.Property:\n case ElementKind.Function:\n case ElementKind.Class: assert(false); // assumes that there are no instances yet\n }\n let staticMembers = element.members;\n if (staticMembers) {\n // TODO: for (let member of staticMembers.values()) {\n for (let _values = Map_values(staticMembers), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n this.markModuleExport(member);\n }\n }\n }\n\n /** Marks an element as a module import. */\n markModuleImport(moduleName: string, name: string, element: Element): void {\n element.set(CommonFlags.ModuleImport);\n let moduleImports = this.moduleImports;\n let module: Map;\n if (moduleImports.has(moduleName)) {\n module = assert(moduleImports.get(moduleName));\n } else {\n module = new Map();\n moduleImports.set(moduleName, module);\n }\n module.set(name, element);\n }\n\n /** Registers a native type with the program. */\n private registerNativeType(name: string, type: Type): void {\n let element = new TypeDefinition(\n name,\n this.nativeFile,\n this.makeNativeTypeDeclaration(name, CommonFlags.Export),\n DecoratorFlags.Builtin\n );\n element.setType(type);\n this.nativeFile.add(name, element);\n }\n\n /** Registers the wrapper class of a non-class type. */\n private registerWrapperClass(type: Type, className: string): void {\n let wrapperClasses = this.wrapperClasses;\n assert(!type.isInternalReference && !wrapperClasses.has(type));\n let element = assert(this.lookup(className));\n assert(element.kind == ElementKind.ClassPrototype);\n let classElement = assert(this.resolver.resolveClass(element, null));\n classElement.wrappedType = type;\n wrapperClasses.set(type, classElement);\n }\n\n /** Registers a constant integer value within the global scope. */\n registerConstantInteger(name: string, type: Type, value: i64): void {\n assert(type.isIntegerInclReference);\n let global = new Global(\n name,\n this.nativeFile,\n DecoratorFlags.Lazy,\n this.makeNativeVariableDeclaration(name, CommonFlags.Const | CommonFlags.Export)\n );\n global.setConstantIntegerValue(value, type);\n this.nativeFile.add(name, global);\n }\n\n /** Registers a constant float value within the global scope. */\n private registerConstantFloat(name: string, type: Type, value: f64): void {\n assert(type.isFloatValue);\n let global = new Global(\n name,\n this.nativeFile,\n DecoratorFlags.Lazy,\n this.makeNativeVariableDeclaration(name, CommonFlags.Const | CommonFlags.Export)\n );\n global.setConstantFloatValue(value, type);\n this.nativeFile.add(name, global);\n }\n\n /** Ensures that the given global element exists. Attempts to merge duplicates. */\n ensureGlobal(name: string, element: DeclaredElement): DeclaredElement {\n let elementsByName = this.elementsByName;\n if (elementsByName.has(name)) {\n let existing = assert(elementsByName.get(name));\n // NOTE: this is effectively only performed when merging native types with\n // their respective namespaces in std/builtins, but can also trigger when a\n // user has multiple global elements of the same name in different files,\n // which might result in unexpected shared symbols accross files. considering\n // this a wonky feature for now that we might want to revisit later.\n if (existing != element) {\n let merged = tryMerge(existing, element);\n if (!merged) {\n if (isDeclaredElement(existing.kind)) {\n this.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n element.identifierNode.range,\n (existing).declaration.name.range,\n name\n );\n } else {\n this.error(\n DiagnosticCode.Duplicate_identifier_0,\n element.identifierNode.range, name\n );\n }\n return element;\n }\n element = merged;\n }\n }\n elementsByName.set(name, element);\n return element;\n }\n\n /** Tries to locate a foreign file given its normalized path. */\n private lookupForeignFile(\n /** Normalized path to the other file. */\n foreignPath: string,\n /** Alternative normalized path to the other file. */\n foreignPathAlt: string\n ): File | null {\n let filesByName = this.filesByName;\n return filesByName.has(foreignPath)\n ? assert(filesByName.get(foreignPath))\n : filesByName.has(foreignPathAlt)\n ? assert(filesByName.get(foreignPathAlt))\n : null;\n }\n\n /** Tries to locate a foreign element by traversing exports and queued exports. */\n private lookupForeign(\n /** Identifier within the other file. */\n foreignName: string,\n /** The other file. */\n foreignFile: File,\n /** So far queued exports. */\n queuedExports: Map>\n ): DeclaredElement | null {\n do {\n // check if already resolved\n let element = foreignFile.lookupExport(foreignName);\n if (element) return element;\n\n // follow queued exports\n if (queuedExports.has(foreignFile)) {\n let fileQueuedExports = assert(queuedExports.get(foreignFile));\n if (fileQueuedExports.has(foreignName)) {\n let queuedExport = assert(fileQueuedExports.get(foreignName));\n let queuedExportForeignPath = queuedExport.foreignPath;\n\n // re-exported from another file\n if (queuedExportForeignPath) {\n let otherFile = this.lookupForeignFile(queuedExportForeignPath, assert(queuedExport.foreignPathAlt));\n if (!otherFile) return null;\n foreignName = queuedExport.localIdentifier.text;\n foreignFile = otherFile;\n continue;\n }\n\n // exported from this file\n element = foreignFile.getMember(queuedExport.localIdentifier.text);\n if (element) return element;\n }\n }\n break;\n } while (true);\n\n // follow star exports\n let exportsStar = foreignFile.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n let element = this.lookupForeign(foreignName, exportsStar[i], queuedExports);\n if (element) return element;\n }\n }\n return null;\n }\n\n /** Validates that only supported decorators are present. */\n private checkDecorators(\n /** Decorators present on an element. */\n decorators: DecoratorNode[] | null,\n /** Accepted decorator flags. Emits diagnostics if any other decorators are present. */\n acceptedFlags: DecoratorFlags\n ): DecoratorFlags {\n let flags = DecoratorFlags.None;\n if (decorators) {\n for (let i = 0, k = decorators.length; i < k; ++i) {\n let decorator = decorators[i];\n let kind = DecoratorKind.fromNode(decorator.name);\n let flag = DecoratorFlags.fromKind(kind);\n if (flag) {\n if (!(acceptedFlags & flag)) {\n this.error(\n DiagnosticCode.Decorator_0_is_not_valid_here,\n decorator.range, decorator.name.range.toString()\n );\n } else if (flags & flag) {\n this.error(\n DiagnosticCode.Duplicate_decorator,\n decorator.range\n );\n } else {\n flags |= flag;\n }\n }\n }\n }\n return flags;\n }\n\n /** Checks whether a particular feature is enabled. */\n checkFeatureEnabled(feature: Feature, reportNode: Node): bool {\n if (!this.options.hasFeature(feature)) {\n this.error(\n DiagnosticCode.Feature_0_is_not_enabled,\n reportNode.range, featureToString(feature)\n );\n return false;\n }\n return true;\n }\n\n /** Checks whether a particular type is supported. */\n checkTypeSupported(type: Type, reportNode: Node): bool {\n switch (type.kind) {\n case TypeKind.V128: return this.checkFeatureEnabled(Feature.Simd, reportNode);\n case TypeKind.Funcref:\n case TypeKind.Externref:\n return this.checkFeatureEnabled(Feature.ReferenceTypes, reportNode);\n case TypeKind.Anyref:\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.I31ref: {\n return this.checkFeatureEnabled(Feature.ReferenceTypes, reportNode)\n && this.checkFeatureEnabled(Feature.GC, reportNode);\n }\n case TypeKind.Stringref:\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter: {\n return this.checkFeatureEnabled(Feature.ReferenceTypes, reportNode)\n && this.checkFeatureEnabled(Feature.Stringref, reportNode);\n }\n }\n let classReference = type.getClass();\n if (classReference) {\n do {\n let typeArguments = classReference.typeArguments;\n if (typeArguments) {\n for (let i = 0, k = typeArguments.length; i < k; ++i) {\n if (!this.checkTypeSupported(typeArguments[i], reportNode)) {\n return false;\n }\n }\n }\n classReference = classReference.base;\n } while (classReference);\n } else {\n let signatureReference = type.getSignature();\n if (signatureReference) {\n let thisType = signatureReference.thisType;\n if (thisType) {\n if (!this.checkTypeSupported(thisType, reportNode)) {\n return false;\n }\n }\n let parameterTypes = signatureReference.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (!this.checkTypeSupported(parameterTypes[i], reportNode)) {\n return false;\n }\n }\n let returnType = signatureReference.returnType;\n if (!this.checkTypeSupported(returnType, reportNode)) {\n return false;\n }\n }\n }\n return true;\n }\n\n /** Initializes a class declaration. */\n private initializeClass(\n /** The declaration to initialize. */\n declaration: ClassDeclaration,\n /** Parent element, usually a file or namespace. */\n parent: Element,\n /** So far queued `extends` clauses. */\n queuedExtends: ClassPrototype[],\n /** So far queued `implements` clauses. */\n queuedImplements: ClassPrototype[]\n ): ClassPrototype | null {\n let name = declaration.name.text;\n let element = new ClassPrototype(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators,\n DecoratorFlags.Global |\n DecoratorFlags.Final |\n DecoratorFlags.Unmanaged\n )\n );\n if (!parent.add(name, element)) return null;\n\n // remember classes that implement interfaces\n let implementsTypes = declaration.implementsTypes;\n if (implementsTypes) {\n let numImplementsTypes = implementsTypes.length;\n if (numImplementsTypes) {\n // cannot implement interfaces when unmanaged\n if (element.hasDecorator(DecoratorFlags.Unmanaged)) {\n this.error(\n DiagnosticCode.Unmanaged_classes_cannot_implement_interfaces,\n Range.join(\n declaration.name.range,\n implementsTypes[numImplementsTypes - 1].range\n )\n );\n } else {\n queuedImplements.push(element);\n }\n }\n }\n\n // remember classes that extend another class\n if (declaration.extendsType) {\n queuedExtends.push(element);\n } else if (\n !element.hasDecorator(DecoratorFlags.Unmanaged) &&\n element.internalName != BuiltinNames.Object\n ) {\n element.implicitlyExtendsObject = true;\n }\n\n // initialize members\n let memberDeclarations = declaration.members;\n for (let i = 0, k = memberDeclarations.length; i < k; ++i) {\n let memberDeclaration = memberDeclarations[i];\n switch (memberDeclaration.kind) {\n case NodeKind.FieldDeclaration: {\n this.initializeField(memberDeclaration, element);\n break;\n }\n case NodeKind.MethodDeclaration: {\n let methodDeclaration = memberDeclaration;\n if (memberDeclaration.isAny(CommonFlags.Get | CommonFlags.Set)) {\n this.initializeProperty(methodDeclaration, element);\n } else {\n let method = this.initializeMethod(methodDeclaration, element);\n if (method && methodDeclaration.name.kind == NodeKind.Constructor) {\n element.constructorPrototype = method;\n }\n }\n break;\n }\n case NodeKind.IndexSignature: break; // ignored for now\n default: assert(false); // class member expected\n }\n }\n return element;\n }\n\n /** Initializes a field of a class or interface. */\n private initializeField(\n /** The declaration to initialize. */\n declaration: FieldDeclaration,\n /** Parent class. */\n parent: ClassPrototype\n ): void {\n let name = declaration.name.text;\n let decorators = declaration.decorators;\n let element: DeclaredElement;\n let acceptedFlags: DecoratorFlags = DecoratorFlags.Unsafe;\n if (parent.is(CommonFlags.Ambient)) {\n acceptedFlags |= DecoratorFlags.External;\n }\n if (declaration.is(CommonFlags.Static)) { // global variable\n assert(parent.kind != ElementKind.InterfacePrototype);\n acceptedFlags |= DecoratorFlags.Lazy;\n if (declaration.is(CommonFlags.Readonly)) {\n acceptedFlags |= DecoratorFlags.Inline;\n }\n element = new Global(\n name,\n parent,\n this.checkDecorators(decorators, acceptedFlags),\n declaration\n );\n if (!parent.add(name, element)) return;\n } else { // actual instance field\n assert(!declaration.isAny(CommonFlags.Abstract | CommonFlags.Get | CommonFlags.Set));\n element = PropertyPrototype.forField(\n name,\n parent,\n declaration,\n this.checkDecorators(decorators, acceptedFlags)\n );\n if (!parent.addInstance(name, element)) return;\n }\n }\n\n /** Initializes a method of a class or interface. */\n private initializeMethod(\n /** The declaration to initialize. */\n declaration: MethodDeclaration,\n /** Parent class. */\n parent: ClassPrototype\n ): FunctionPrototype | null {\n let name = declaration.name.text;\n let isStatic = declaration.is(CommonFlags.Static);\n let acceptedFlags = DecoratorFlags.Inline | DecoratorFlags.Unsafe;\n if (!declaration.is(CommonFlags.Generic)) {\n acceptedFlags |= DecoratorFlags.OperatorBinary\n | DecoratorFlags.OperatorPrefix\n | DecoratorFlags.OperatorPostfix;\n }\n if (parent.is(CommonFlags.Ambient)) {\n acceptedFlags |= DecoratorFlags.External;\n }\n if (declaration.range.source.isLibrary) {\n acceptedFlags |= DecoratorFlags.Builtin;\n }\n let element = new FunctionPrototype(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators, acceptedFlags)\n );\n if (element.hasDecorator(DecoratorFlags.Builtin) && !builtinFunctions.has(element.internalName)) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n declaration.range, `Builtin '${element.internalName}'`\n );\n }\n if (isStatic) { // global function\n assert(declaration.name.kind != NodeKind.Constructor);\n if (!parent.add(name, element)) return null;\n } else { // actual instance method\n if (!parent.addInstance(name, element)) return null;\n }\n this.checkOperatorOverloads(declaration.decorators, element, parent);\n return element;\n }\n\n /** Checks that operator overloads are generally valid, if present. */\n private checkOperatorOverloads(\n /** Decorators to check. */\n decorators: DecoratorNode[] | null,\n /** Decorated method. */\n prototype: FunctionPrototype,\n /** Parent class. */\n classPrototype: ClassPrototype\n ): void {\n if (decorators) {\n for (let i = 0, k = decorators.length; i < k; ++i) {\n let decorator: DecoratorNode = decorators[i]; // FIXME: why does tsc want a type here?\n switch (decorator.decoratorKind) {\n case DecoratorKind.Operator:\n case DecoratorKind.OperatorBinary:\n case DecoratorKind.OperatorPrefix:\n case DecoratorKind.OperatorPostfix: {\n let args = decorator.args;\n let numArgs = args ? args.length : 0;\n if (numArgs == 1) {\n let firstArg = (decorator.args)[0];\n if (firstArg.isLiteralKind(LiteralKind.String)) {\n let text = (firstArg).value;\n let kind = OperatorKind.fromDecorator(decorator.decoratorKind, text);\n if (kind == OperatorKind.Invalid) {\n this.error(\n DiagnosticCode._0_is_not_a_valid_operator,\n firstArg.range, text\n );\n } else {\n let overloads = classPrototype.operatorOverloadPrototypes;\n if (overloads.has(kind)) {\n this.error(\n DiagnosticCode.Duplicate_function_implementation,\n firstArg.range\n );\n } else {\n prototype.operatorKind = kind;\n overloads.set(kind, prototype);\n }\n }\n } else {\n this.error(\n DiagnosticCode.String_literal_expected,\n firstArg.range\n );\n }\n } else {\n this.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n decorator.range, \"1\", numArgs.toString()\n );\n }\n }\n }\n }\n }\n }\n\n /** Ensures that the property introduced by the specified getter or setter exists.*/\n private ensureProperty(\n /** The declaration of the getter or setter introducing the property. */\n declaration: MethodDeclaration,\n /** Parent class. */\n parent: ClassPrototype\n ): PropertyPrototype | null {\n let name = declaration.name.text;\n if (declaration.is(CommonFlags.Static)) {\n let parentMembers = parent.members;\n if (parentMembers && parentMembers.has(name)) {\n let element = assert(parentMembers.get(name));\n if (element.kind == ElementKind.PropertyPrototype) return element;\n } else {\n let element = new PropertyPrototype(name, parent, declaration);\n if (!parent.add(name, element)) return null;\n return element;\n }\n } else {\n let parentMembers = parent.instanceMembers;\n if (parentMembers && parentMembers.has(name)) {\n let element = assert(parentMembers.get(name));\n if (element.kind == ElementKind.PropertyPrototype) return element;\n } else {\n let element = new PropertyPrototype(name, parent, declaration);\n if (!parent.addInstance(name, element)) return null;\n return element;\n }\n }\n this.error(\n DiagnosticCode.Duplicate_property_0,\n declaration.name.range, name\n );\n return null;\n }\n\n /** Initializes a property of a class. */\n private initializeProperty(\n /** The declaration of the getter or setter. */\n declaration: MethodDeclaration,\n /** Parent class. */\n parent: ClassPrototype\n ): void {\n let property = this.ensureProperty(declaration, parent);\n if (!property) return;\n let name = declaration.name.text;\n let isGetter = declaration.is(CommonFlags.Get);\n if (isGetter) {\n if (property.getterPrototype) {\n this.error(\n DiagnosticCode.Duplicate_property_0,\n declaration.name.range, name\n );\n return;\n }\n } else {\n if (property.setterPrototype) {\n this.error(\n DiagnosticCode.Duplicate_property_0,\n declaration.name.range, name\n );\n return;\n }\n }\n let element = new FunctionPrototype(\n (isGetter ? GETTER_PREFIX : SETTER_PREFIX) + name,\n property.parent, // same level as property\n declaration,\n this.checkDecorators(declaration.decorators,\n DecoratorFlags.Inline | DecoratorFlags.Unsafe\n )\n );\n if (isGetter) {\n property.getterPrototype = element;\n } else {\n property.setterPrototype = element;\n }\n }\n\n /** Initializes an enum. */\n private initializeEnum(\n /** The declaration to initialize. */\n declaration: EnumDeclaration,\n /** Parent element, usually a file or namespace. */\n parent: Element\n ): Enum | null {\n let name = declaration.name.text;\n let element = new Enum(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators,\n DecoratorFlags.Global |\n DecoratorFlags.Inline |\n DecoratorFlags.Lazy\n )\n );\n if (!parent.add(name, element)) return null;\n let values = declaration.values;\n for (let i = 0, k = values.length; i < k; ++i) {\n this.initializeEnumValue(values[i], element);\n }\n return element;\n }\n\n /** Initializes an enum value. */\n private initializeEnumValue(\n /** The declaration to initialize. */\n declaration: EnumValueDeclaration,\n /** Parent enum. */\n parent: Enum\n ): void {\n let name = declaration.name.text;\n let element = new EnumValue(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators,\n DecoratorFlags.None\n )\n );\n if (!parent.add(name, element)) return;\n }\n\n /** Initializes an `export` statement. */\n private initializeExports(\n /** The statement to initialize. */\n statement: ExportStatement,\n /** Parent file. */\n parent: File,\n /** So far queued `export`s. */\n queuedExports: Map>,\n /** So far queued `export *`s. */\n queuedExportsStar: Map\n ): void {\n let members = statement.members;\n if (members) { // export { foo, bar } [from \"./baz\"]\n for (let i = 0, k = members.length; i < k; ++i) {\n this.initializeExport(members[i], parent, statement.internalPath, queuedExports);\n }\n } else { // export * from \"./baz\"\n let queued: QueuedExportStar[];\n if (queuedExportsStar.has(parent)) queued = assert(queuedExportsStar.get(parent));\n else queuedExportsStar.set(parent, queued = []);\n let foreignPath = statement.internalPath!; // must be set for export *\n queued.push(new QueuedExportStar(\n foreignPath,\n foreignPath.endsWith(INDEX_SUFFIX) // strip or add index depending on what's already present\n ? foreignPath.substring(0, foreignPath.length - INDEX_SUFFIX.length)\n : foreignPath + INDEX_SUFFIX,\n assert(statement.path)\n ));\n }\n }\n\n /** Initializes a single `export` member. Does not handle `export *`. */\n private initializeExport(\n /** The member to initialize. */\n member: ExportMember,\n /** Local file. */\n localFile: File,\n /** Path to the other file, if present. */\n foreignPath: string | null,\n /** So far queued `export`s. */\n queuedExports: Map>\n ): void {\n let localName = member.localName.text;\n let foreignName = member.exportedName.text;\n\n // check for duplicates\n let element = localFile.lookupExport(foreignName);\n if (element) {\n this.error(\n DiagnosticCode.Export_declaration_conflicts_with_exported_declaration_of_0,\n member.exportedName.range, foreignName\n );\n return;\n }\n // local element, i.e. export { foo [as bar] }\n if (foreignPath == null) {\n\n // resolve right away if the local element already exists\n if (element = localFile.getMember(localName)) {\n localFile.ensureExport(foreignName, element);\n\n // otherwise queue it\n } else {\n let queued: Map;\n if (queuedExports.has(localFile)) queued = assert(queuedExports.get(localFile));\n else queuedExports.set(localFile, queued = new Map());\n queued.set(foreignName, new QueuedExport(\n member.localName,\n member.exportedName,\n null, null\n ));\n }\n\n // foreign element, i.e. export { foo } from \"./bar\"\n } else {\n let queued: Map;\n if (queuedExports.has(localFile)) queued = assert(queuedExports.get(localFile));\n else queuedExports.set(localFile, queued = new Map());\n queued.set(foreignName, new QueuedExport(\n member.localName,\n member.exportedName,\n foreignPath,\n foreignPath.endsWith(INDEX_SUFFIX) // strip or add index depending on what's already present\n ? foreignPath.substring(0, foreignPath.length - INDEX_SUFFIX.length)\n : foreignPath + INDEX_SUFFIX\n ));\n }\n }\n\n private initializeExportDefault(\n /** The statement to initialize. */\n statement: ExportDefaultStatement,\n /** Parent file. */\n parent: File,\n /** So far queued `extends` clauses. */\n queuedExtends: Array,\n /** So far queued `implements` clauses. */\n queuedImplements: ClassPrototype[]\n ): void {\n let declaration = statement.declaration;\n let element: DeclaredElement | null = null;\n switch (declaration.kind) {\n case NodeKind.EnumDeclaration: {\n element = this.initializeEnum(declaration, parent);\n break;\n }\n case NodeKind.FunctionDeclaration: {\n element = this.initializeFunction(declaration, parent);\n break;\n }\n case NodeKind.ClassDeclaration: {\n element = this.initializeClass(declaration, parent, queuedExtends, queuedImplements);\n break;\n }\n case NodeKind.InterfaceDeclaration: {\n element = this.initializeInterface(declaration, parent, queuedExtends);\n break;\n }\n case NodeKind.NamespaceDeclaration: {\n element = this.initializeNamespace(declaration, parent, queuedExtends, queuedImplements);\n break;\n }\n default: assert(false);\n }\n if (element) {\n let exports = parent.exports;\n if (!exports) parent.exports = exports = new Map();\n else {\n if (exports.has(\"default\")) {\n let existing = assert(exports.get(\"default\"));\n this.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n declaration.name.range,\n existing.declaration.name.range,\n \"default\"\n );\n return;\n }\n }\n exports.set(\"default\", element);\n }\n }\n\n /** Initializes an `import` statement. */\n private initializeImports(\n /** The statement to initialize. */\n statement: ImportStatement,\n /** Parent file. */\n parent: File,\n /** So far queued `import`s. */\n queuedImports: QueuedImport[],\n /** So far queued `export`s. */\n queuedExports: Map>\n ): void {\n let declarations = statement.declarations;\n if (declarations) { // import { foo [as bar] } from \"./baz\"\n for (let i = 0, k = declarations.length; i < k; ++i) {\n this.initializeImport(\n declarations[i],\n parent,\n statement.internalPath,\n queuedImports,\n queuedExports\n );\n }\n } else {\n let namespaceName = statement.namespaceName;\n if (namespaceName) { // import * as foo from \"./bar\"\n queuedImports.push(new QueuedImport(\n parent,\n namespaceName,\n null, // indicates import *\n statement.internalPath,\n statement.internalPath + INDEX_SUFFIX\n ));\n } else {\n // import \"./foo\"\n }\n }\n }\n\n /** Initializes a single `import` declaration. Does not handle `import *`. */\n private initializeImport( // { foo [as bar] }\n /** The declaration to initialize. */\n declaration: ImportDeclaration,\n /** Parent file. */\n parent: File,\n /** Path to the other file. */\n foreignPath: string,\n /** So far queued `import`s. */\n queuedImports: QueuedImport[],\n /** So far queued `export`s. */\n queuedExports: Map>\n ): void {\n let foreignPathAlt = foreignPath.endsWith(INDEX_SUFFIX) // strip or add index depending on what's already present\n ? foreignPath.substring(0, foreignPath.length - INDEX_SUFFIX.length)\n : foreignPath + INDEX_SUFFIX;\n\n // resolve right away if the element exists\n let foreignFile = this.lookupForeignFile(foreignPath, foreignPathAlt);\n if (foreignFile) {\n let element = this.lookupForeign(declaration.foreignName.text, foreignFile, queuedExports);\n if (element) {\n parent.add(declaration.name.text, element, declaration.name /* isImport */);\n return;\n }\n }\n\n // otherwise queue it\n queuedImports.push(new QueuedImport(\n parent,\n declaration.name,\n declaration.foreignName,\n foreignPath,\n foreignPathAlt\n ));\n }\n\n /** Initializes a function. Does not handle methods. */\n private initializeFunction(\n /** The declaration to initialize. */\n declaration: FunctionDeclaration,\n /** Parent element, usually a file or namespace. */\n parent: Element\n ): FunctionPrototype | null {\n let name = declaration.name.text;\n let validDecorators = DecoratorFlags.Unsafe;\n if (declaration.is(CommonFlags.Ambient)) {\n validDecorators |= DecoratorFlags.External | DecoratorFlags.ExternalJs;\n } else {\n validDecorators |= DecoratorFlags.Inline;\n if (declaration.range.source.isLibrary || declaration.is(CommonFlags.Export)) {\n validDecorators |= DecoratorFlags.Lazy;\n }\n }\n if (!declaration.is(CommonFlags.Instance)) {\n if (parent.kind != ElementKind.ClassPrototype) {\n validDecorators |= DecoratorFlags.Global;\n }\n }\n if (declaration.range.source.isLibrary) {\n validDecorators |= DecoratorFlags.Builtin;\n }\n let element = new FunctionPrototype(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators, validDecorators)\n );\n if (element.hasDecorator(DecoratorFlags.Builtin) && !builtinFunctions.has(element.internalName)) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n declaration.range, `Builtin '${element.internalName}'`\n );\n }\n if (!parent.add(name, element)) return null;\n return element;\n }\n\n /** Initializes an interface. */\n private initializeInterface(\n /** The declaration to initialize. */\n declaration: InterfaceDeclaration,\n /** Parent element, usually a file or namespace. */\n parent: Element,\n /** So far queued `extends` clauses. */\n queuedExtends: ClassPrototype[],\n ): InterfacePrototype | null {\n let name = declaration.name.text;\n let element = new InterfacePrototype(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators,\n DecoratorFlags.Global\n )\n );\n if (!parent.add(name, element)) return null;\n\n // remember interfaces that extend another interface\n if (declaration.extendsType) queuedExtends.push(element);\n\n let memberDeclarations = declaration.members;\n for (let i = 0, k = memberDeclarations.length; i < k; ++i) {\n let memberDeclaration = memberDeclarations[i];\n switch (memberDeclaration.kind) {\n case NodeKind.FieldDeclaration: {\n this.initializeFieldAsProperty(memberDeclaration, element);\n break;\n }\n case NodeKind.MethodDeclaration: {\n let methodDeclaration = memberDeclaration;\n if (memberDeclaration.isAny(CommonFlags.Get | CommonFlags.Set)) {\n this.initializeProperty(methodDeclaration, element);\n } else {\n this.initializeMethod(methodDeclaration, element);\n }\n break;\n }\n default: assert(false); // interface member expected\n }\n }\n return element;\n }\n\n /** Initializes a field of an interface, as a property. */\n private initializeFieldAsProperty(\n /** Field declaration. */\n declaration: FieldDeclaration,\n /** Parent interface. */\n parent: InterfacePrototype\n ): void {\n let typeNode = declaration.type;\n if (!typeNode) typeNode = Node.createOmittedType(declaration.name.range.atEnd);\n this.initializeProperty(\n Node.createMethodDeclaration(\n declaration.name,\n declaration.decorators,\n declaration.flags | CommonFlags.Get,\n null,\n Node.createFunctionType(\n [],\n typeNode,\n null,\n false,\n declaration.range\n ),\n null,\n declaration.range\n ),\n parent\n );\n if (!declaration.is(CommonFlags.Readonly)) {\n this.initializeProperty(\n Node.createMethodDeclaration(\n declaration.name,\n declaration.decorators,\n declaration.flags | CommonFlags.Set,\n null,\n Node.createFunctionType(\n [\n Node.createParameter(\n ParameterKind.Default,\n declaration.name,\n typeNode,\n null,\n declaration.name.range\n )\n ],\n Node.createOmittedType(declaration.name.range.atEnd),\n null,\n false,\n declaration.range\n ),\n null,\n declaration.range\n ),\n parent\n );\n }\n }\n\n /** Initializes a namespace. */\n private initializeNamespace(\n /** The declaration to initialize. */\n declaration: NamespaceDeclaration,\n /** Parent element, usually a file or another namespace. */\n parent: Element,\n /** So far queued `extends` clauses. */\n queuedExtends: ClassPrototype[],\n /** So far queued `implements` clauses. */\n queuedImplements: ClassPrototype[]\n ): DeclaredElement | null {\n let name = declaration.name.text;\n let original = new Namespace(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators, DecoratorFlags.Global)\n );\n if (!parent.add(name, original)) return null;\n let element = assert(parent.getMember(name)); // possibly merged\n let members = declaration.members;\n for (let i = 0, k = members.length; i < k; ++i) {\n let member = members[i];\n switch (member.kind) {\n case NodeKind.ClassDeclaration: {\n this.initializeClass(member, original, queuedExtends, queuedImplements);\n break;\n }\n case NodeKind.EnumDeclaration: {\n this.initializeEnum(member, original);\n break;\n }\n case NodeKind.FunctionDeclaration: {\n this.initializeFunction(member, original);\n break;\n }\n case NodeKind.InterfaceDeclaration: {\n this.initializeInterface(member, original, queuedExtends);\n break;\n }\n case NodeKind.NamespaceDeclaration: {\n this.initializeNamespace(member, original, queuedExtends, queuedImplements);\n break;\n }\n case NodeKind.TypeDeclaration: {\n this.initializeTypeDefinition(member, original);\n break;\n }\n case NodeKind.Variable: {\n this.initializeVariables(member, original);\n break;\n }\n default: assert(false); // namespace member expected\n }\n }\n if (original != element) copyMembers(original, element); // keep original parent\n return element;\n }\n\n /** Initializes a `type` definition. */\n private initializeTypeDefinition(\n /** The declaration to initialize. */\n declaration: TypeDeclaration,\n /** Parent element, usually a file or namespace. */\n parent: Element\n ): void {\n let name = declaration.name.text;\n let element = new TypeDefinition(\n name,\n parent,\n declaration,\n this.checkDecorators(declaration.decorators, DecoratorFlags.None)\n );\n parent.add(name, element); // reports\n }\n\n /** Initializes a variable statement. */\n private initializeVariables(\n /** The statement to initialize. */\n statement: VariableStatement,\n /** Parent element, usually a file or namespace. */\n parent: Element\n ): void {\n let declarations = statement.declarations;\n for (let i = 0, k = declarations.length; i < k; ++i) {\n let declaration = declarations[i];\n let name = declaration.name.text;\n let acceptedFlags = DecoratorFlags.Global | DecoratorFlags.Lazy;\n if (declaration.is(CommonFlags.Ambient)) {\n acceptedFlags |= DecoratorFlags.External;\n }\n if (declaration.is(CommonFlags.Const)) {\n acceptedFlags |= DecoratorFlags.Inline;\n }\n if (declaration.range.source.isLibrary) {\n acceptedFlags |= DecoratorFlags.Builtin;\n }\n let element = new Global(\n name,\n parent,\n this.checkDecorators(declaration.decorators, acceptedFlags),\n declaration\n );\n if (element.hasDecorator(DecoratorFlags.Builtin) && !builtinVariables_onAccess.has(element.internalName)) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n declaration.range, `Builtin '${element.internalName}'`\n );\n }\n if (!parent.add(name, element)) continue; // reports\n }\n }\n\n /** Determines the element type of a built-in array. */\n // determineBuiltinArrayType(target: Class): Type | null {\n // switch (target.internalName) {\n // case BuiltinSymbols.Int8Array: return Type.i8;\n // case BuiltinSymbols.Uint8ClampedArray:\n // case BuiltinSymbols.Uint8Array: return Type.u8;\n // case BuiltinSymbols.Int16Array: return Type.i16;\n // case BuiltinSymbols.Uint16Array: return Type.u16;\n // case BuiltinSymbols.Int32Array: return Type.i32;\n // case BuiltinSymbols.Uint32Array: return Type.u32;\n // case BuiltinSymbols.Int64Array: return Type.i64;\n // case BuiltinSymbols.Uint64Array: return Type.u64;\n // case BuiltinSymbols.Float32Array: return Type.f32;\n // case BuiltinSymbols.Float64Array: return Type.f64;\n // }\n // let current: Class | null = target;\n // let arrayPrototype = this.arrayPrototype;\n // do {\n // if (current.prototype == arrayPrototype) { // Array\n // let typeArguments = assert(current.typeArguments);\n // assert(typeArguments.length == 1);\n // return typeArguments[0];\n // }\n // } while (current = current.base);\n // return null;\n // }\n}\n\n/** Indicates the specific kind of an {@link Element}. */\nexport const enum ElementKind {\n /** A {@link Global}. */\n Global,\n /** A {@link Local}. */\n Local,\n /** An {@link Enum}. */\n Enum,\n /** An {@link EnumValue}. */\n EnumValue,\n /** A {@link FunctionPrototype}. */\n FunctionPrototype,\n /** A {@link Function}. */\n Function,\n /** A {@link ClassPrototype}. */\n ClassPrototype,\n /** A {@link Class}. */\n Class,\n /** An {@link InterfacePrototype}. */\n InterfacePrototype,\n /** An {@link Interface}. */\n Interface,\n /** A {@link PropertyPrototype}. */\n PropertyPrototype,\n /** A {@link Property}. */\n Property,\n /** A {@link Namespace}. */\n Namespace,\n /** A {@link File}. */\n File,\n /** A {@link TypeDefinition}. */\n TypeDefinition,\n /** An {@link IndexSignature}. */\n IndexSignature\n}\n\n/** Indicates built-in decorators that are present. */\nexport enum DecoratorFlags {\n /** No flags set. */\n None = 0,\n /** Is a program global. */\n Global = 1 << 0,\n /** Is a binary operator overload. */\n OperatorBinary = 1 << 1,\n /** Is a unary prefix operator overload. */\n OperatorPrefix = 1 << 2,\n /** Is a unary postfix operator overload. */\n OperatorPostfix = 1 << 3,\n /** Is an unmanaged class. */\n Unmanaged = 1 << 4,\n /** Is a final class. */\n Final = 1 << 5,\n /** Is always inlined. */\n Inline = 1 << 6,\n /** Is using a different external name. */\n External = 1 << 7,\n /** Has external JavaScript code. */\n ExternalJs = 1 << 8,\n /** Is a builtin. */\n Builtin = 1 << 9,\n /** Is compiled lazily. */\n Lazy = 1 << 10,\n /** Is considered unsafe code. */\n Unsafe = 1 << 11\n}\n\nexport namespace DecoratorFlags {\n\n /** Translates a decorator kind to the respective decorator flag. */\n export function fromKind(kind: DecoratorKind): DecoratorFlags {\n switch (kind) {\n case DecoratorKind.Global: return DecoratorFlags.Global;\n case DecoratorKind.Operator:\n case DecoratorKind.OperatorBinary: return DecoratorFlags.OperatorBinary;\n case DecoratorKind.OperatorPrefix: return DecoratorFlags.OperatorPrefix;\n case DecoratorKind.OperatorPostfix: return DecoratorFlags.OperatorPostfix;\n case DecoratorKind.Unmanaged: return DecoratorFlags.Unmanaged;\n case DecoratorKind.Final: return DecoratorFlags.Final;\n case DecoratorKind.Inline: return DecoratorFlags.Inline;\n case DecoratorKind.External: return DecoratorFlags.External;\n case DecoratorKind.ExternalJs: return DecoratorFlags.ExternalJs;\n case DecoratorKind.Builtin: return DecoratorFlags.Builtin;\n case DecoratorKind.Lazy: return DecoratorFlags.Lazy;\n case DecoratorKind.Unsafe: return DecoratorFlags.Unsafe;\n default: return DecoratorFlags.None;\n }\n }\n}\n\n/** Base class of all program elements. */\nexport abstract class Element {\n\n /** Parent element. */\n parent!: Element;\n /** Common flags indicating specific traits. */\n flags: CommonFlags = CommonFlags.None;\n /** Decorator flags indicating annotated traits. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None;\n /** Member elements. */\n members: Map | null = null;\n /** Shadowing type in type space, if any. */\n shadowType: TypeDefinition | null = null;\n\n /** Constructs a new program element. */\n protected constructor(\n /** Specific element kind. */\n public kind: ElementKind,\n /** Simple name. */\n public name: string,\n /** Internal name referring to this element. */\n public internalName: string,\n /** Containing {@link Program}. */\n public program: Program,\n /** Parent element. */\n parent: Element | null\n ) {\n this.program = program;\n this.name = name;\n this.internalName = internalName;\n if (parent) {\n this.parent = parent;\n } else {\n assert(this.kind == ElementKind.File);\n this.parent = this; // special case to keep this.parent non-nullable\n }\n }\n\n /** Gets the enclosing file. */\n get file(): File {\n let current: Element = this;\n do {\n current = current.parent;\n if (current.kind == ElementKind.File) return current;\n } while (true);\n }\n\n /** Tests if this element has a specific flag or flags. */\n is(flag: CommonFlags): bool { return (this.flags & flag) == flag; }\n /** Tests if this element has any of the specified flags. */\n isAny(flags: CommonFlags): bool { return (this.flags & flags) != 0; }\n /** Sets a specific flag or flags. */\n set(flag: CommonFlags): void { this.flags |= flag; }\n /** Unsets the specific flag or flags. */\n unset(flag: CommonFlags): void {this.flags &= ~flag; }\n /** Tests if this element has a specific decorator flag or flags. */\n hasDecorator(flag: DecoratorFlags): bool { return (this.decoratorFlags & flag) == flag; }\n /** Tests if this element has any of the specified decorator flags. */\n hasAnyDecorator(flags: DecoratorFlags): bool { return (this.decoratorFlags & flags) != 0; }\n\n /** Get the member with the specified name, if any. */\n getMember(name: string): DeclaredElement | null {\n let members = this.members;\n if (members && members.has(name)) return assert(members.get(name));\n return null;\n }\n\n /** Looks up the element with the specified name relative to this element. */\n lookup(name: string, isType: bool = false): Element | null {\n return this.parent.lookup(name, isType);\n }\n\n /** Adds an element as a member of this one. Reports and returns `false` if a duplicate. */\n add(name: string, element: DeclaredElement, localIdentifierIfImport: IdentifierExpression | null = null): bool {\n let originalDeclaration = element.declaration;\n let members = this.members;\n if (!members) this.members = members = new Map();\n else if (members.has(name)) {\n let existing = assert(members.get(name));\n if (existing.parent != this) {\n // override non-own element\n } else {\n let merged = tryMerge(existing, element);\n if (merged) {\n element = merged; // use merged element\n } else {\n let reportedIdentifier = localIdentifierIfImport\n ? localIdentifierIfImport\n : element.identifierNode;\n if (isDeclaredElement(existing.kind)) {\n this.program.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n reportedIdentifier.range,\n (existing).identifierNode.range,\n reportedIdentifier.text\n );\n } else {\n this.program.error(\n DiagnosticCode.Duplicate_identifier_0,\n reportedIdentifier.range, reportedIdentifier.text\n );\n }\n return false;\n }\n }\n }\n members.set(name, element);\n let program = this.program;\n if (element.kind != ElementKind.FunctionPrototype || !(element).isBound) {\n // prefer unbound prototypes in global lookup maps\n program.elementsByName.set(element.internalName, element);\n program.elementsByDeclaration.set(originalDeclaration, element);\n }\n return true;\n }\n\n /** Checks if this element is public, explicitly or implicitly. */\n get isPublic(): bool {\n return !this.isAny(CommonFlags.Private | CommonFlags.Protected);\n }\n\n /** Checks if this element is implicitly public, i.e. not explicitly declared to be. */\n get isImplicitlyPublic(): bool {\n return this.isPublic && !this.is(CommonFlags.Public);\n }\n\n /** Checks if the visibility of this element equals the specified. */\n visibilityEquals(other: Element): bool {\n if (this.isPublic == other.isPublic) return true;\n const vis = CommonFlags.Private | CommonFlags.Protected;\n return (this.flags & vis) == (other.flags & vis);\n }\n\n /** Tests if this element is bound to a class. */\n get isBound(): bool {\n let parent = this.parent;\n switch (parent.kind) {\n case ElementKind.Class:\n case ElementKind.Interface: return true;\n }\n return false;\n }\n\n /** Gets the class or interface this element is bound to, if any. */\n getBoundClassOrInterface(): Class | null {\n let parent = this.parent;\n switch (parent.kind) {\n case ElementKind.Class:\n case ElementKind.Interface: return parent;\n }\n return null;\n }\n\n /** Returns a string representation of this element. */\n toString(): string {\n return `${this.internalName}, kind=${this.kind}`;\n }\n}\n\n// Kinds of all declared elements\nlet declaredElements = new Set();\n\n/** Tests if the specified element kind indicates a declared element. */\nexport function isDeclaredElement(kind: ElementKind): bool {\n return declaredElements.has(kind);\n}\n\n/** Base class of elements with an associated declaration statement. */\nexport abstract class DeclaredElement extends Element {\n\n /** Constructs a new declared program element. */\n protected constructor(\n /** Specific element kind. */\n kind: ElementKind,\n /** Simple name. */\n name: string,\n /** Internal name referring to this element. */\n internalName: string,\n /** Containing {@link Program}. */\n program: Program,\n /** Parent element. */\n parent: Element | null,\n /** Declaration reference. */\n public declaration: DeclarationStatement\n ) {\n super(kind, name, internalName, program, parent);\n declaredElements.add(kind);\n // It is necessary to have access to identifiers of all members and exports\n // for reporting purposes and this is the lowest common denominator. Comes\n // at the expense of not having more specific type information in derived\n // classes, though. Instead, derived classes implement getters for other\n // important AST nodes directly through manual casting, allowing the resolver\n // etc. to not worry about actual declarations.\n this.declaration = declaration;\n this.flags = declaration.flags; // inherit\n }\n\n /** Tests if this element is a library element. */\n get isDeclaredInLibrary(): bool {\n return this.declaration.range.source.isLibrary;\n }\n\n /** Gets the associated identifier node. */\n get identifierNode(): IdentifierExpression {\n return this.declaration.name;\n }\n\n /** Gets the signature node, if applicable, along the identifier node. */\n get identifierAndSignatureRange(): Range {\n let declaration = this.declaration;\n let identifierNode = declaration.name;\n if (declaration.kind == NodeKind.FunctionDeclaration || declaration.kind == NodeKind.MethodDeclaration) {\n let signatureNode = (declaration).signature;\n if (identifierNode.range.source == signatureNode.range.source) {\n return Range.join(identifierNode.range, signatureNode.range);\n }\n }\n return identifierNode.range;\n }\n\n /** Gets the assiciated decorator nodes. */\n get decoratorNodes(): DecoratorNode[] | null {\n return this.declaration.decorators;\n }\n}\n\n// Kinds of all typed elements\nlet typedElements = new Set();\n\n/** Checks if the specified element kind indicates a typed element. */\nexport function isTypedElement(kind: ElementKind): bool {\n return typedElements.has(kind);\n}\n\n/** Base class of elements that can be resolved to a concrete type. */\nexport abstract class TypedElement extends DeclaredElement {\n\n /** Resolved type. Set once `is(RESOLVED)`, otherwise void. */\n type: Type = Type.void;\n\n constructor(\n /** Specific element kind. */\n kind: ElementKind,\n /** Simple name. */\n name: string,\n /** Internal name referring to this element. */\n internalName: string,\n /** Containing {@link Program}. */\n program: Program,\n /** Parent element. */\n parent: Element | null,\n /** Declaration reference. */\n declaration: DeclarationStatement\n ) {\n super(kind, name, internalName, program, parent, declaration);\n typedElements.add(kind);\n }\n\n /** Sets the resolved type of this element. */\n setType(type: Type): void {\n assert(!this.is(CommonFlags.Resolved));\n this.type = type;\n this.set(CommonFlags.Resolved);\n }\n}\n\n/** A file representing the implicit top-level namespace of a source. */\nexport class File extends Element {\n\n /** File exports. */\n exports: Map | null = null;\n /** File re-exports. */\n exportsStar: File[] | null = null;\n /** Top-level start function of this file. */\n startFunction!: Function;\n /** Array of `import * as X` alias namespaces of this file. */\n aliasNamespaces: Array = new Array();\n\n /** Constructs a new file. */\n constructor(\n /** Program this file belongs to. */\n program: Program,\n /** Source of this file. */\n public source: Source\n ) {\n super(\n ElementKind.File,\n source.normalizedPath,\n source.internalPath,\n program,\n null // special case for files\n );\n this.source = source;\n assert(!program.filesByName.has(this.internalName));\n program.filesByName.set(this.internalName, this);\n let startFunction = this.program.makeNativeFunction(\n `start:${this.internalName}`,\n Signature.create(program, [], Type.void),\n this\n );\n startFunction.internalName = startFunction.name;\n this.startFunction = startFunction;\n }\n\n /* @override */\n add(name: string, element: DeclaredElement, localIdentifierIfImport: IdentifierExpression | null = null): bool {\n if (element.hasDecorator(DecoratorFlags.Global)) {\n element = this.program.ensureGlobal(name, element); // possibly merged globally\n }\n if (!super.add(name, element, localIdentifierIfImport)) return false;\n element = assert(this.getMember(name)); // possibly merged locally\n if (element.is(CommonFlags.Export) && !localIdentifierIfImport) {\n this.ensureExport(\n element.name,\n element\n );\n }\n return true;\n }\n\n /* @override */\n getMember(name: string): DeclaredElement | null {\n let element = super.getMember(name);\n if (element) return element;\n let exportsStar = this.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n if (element = exportsStar[i].getMember(name)) return element;\n }\n }\n return null;\n }\n\n /* @override */\n lookup(name: string, isType: bool = false): Element | null {\n let element = this.getMember(name);\n if (element) return element;\n return this.program.lookup(name); // has no meaningful parent\n }\n\n /** Ensures that an element is an export of this file. */\n ensureExport(name: string, element: DeclaredElement): void {\n let exports = this.exports;\n if (!exports) this.exports = exports = new Map();\n exports.set(name, element);\n if (this.source.sourceKind == SourceKind.LibraryEntry) this.program.ensureGlobal(name, element);\n\n // Also, add to the namespaces that capture our exports\n for(let i = 0; i < this.aliasNamespaces.length; i++) {\n let ns = this.aliasNamespaces[i];\n ns.add(name, element);\n }\n }\n\n /** Ensures that another file is a re-export of this file. */\n ensureExportStar(file: File): void {\n let exportsStar = this.exportsStar;\n if (!exportsStar) this.exportsStar = exportsStar = [];\n else if (exportsStar.includes(file)) return;\n exportsStar.push(file);\n }\n\n /** Looks up the export of the specified name. */\n lookupExport(name: string): DeclaredElement | null {\n let exports = this.exports;\n if (exports && exports.has(name)) return assert(exports.get(name));\n let exportsStar = this.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n let element = exportsStar[i].lookupExport(name);\n if (element) return element;\n }\n }\n return null;\n }\n\n /** Creates an imported namespace from this file. */\n asAliasNamespace(\n name: string,\n parent: Element,\n localIdentifier: IdentifierExpression\n ): Namespace {\n let declaration = this.program.makeNativeNamespaceDeclaration(name);\n declaration.name = localIdentifier;\n let ns = new Namespace(name, parent, declaration);\n ns.set(CommonFlags.Scoped);\n this.copyExportsToNamespace(ns);\n // NOTE: Some exports are still queued, and can't yet be added here,\n // so we remember all the alias namespaces and add to them as well\n // when adding an element to the file.\n this.aliasNamespaces.push(ns);\n return ns;\n }\n\n /** Recursively copies the exports of this file to the specified namespace. */\n private copyExportsToNamespace(ns: Namespace): void {\n let exports = this.exports;\n if (exports) {\n // TODO: for (let [memberName, member] of exports) {\n for (let _keys = Map_keys(exports), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let member = assert(exports.get(memberName));\n ns.add(memberName, member);\n }\n }\n let exportsStar = this.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n exportsStar[i].copyExportsToNamespace(ns);\n }\n }\n }\n}\n\n/** A type definition. */\nexport class TypeDefinition extends TypedElement {\n\n /** Constructs a new type definition. */\n constructor(\n /** Simple name. */\n name: string,\n /** Parent element, usually a file or namespace. */\n parent: Element,\n /** Declaration reference. */\n declaration: TypeDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None\n ) {\n super(\n ElementKind.TypeDefinition,\n name,\n mangleInternalName(name, parent, false),\n parent.program,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n }\n\n /** Gets the associated type parameter nodes. */\n get typeParameterNodes(): TypeParameterNode[] | null {\n return (this.declaration).typeParameters;\n }\n\n /** Gets the associated type node. */\n get typeNode(): TypeNode {\n return (this.declaration).type;\n }\n}\n\n/** A namespace that differs from a file in being user-declared with a name. */\nexport class Namespace extends DeclaredElement {\n\n /** Constructs a new namespace. */\n constructor(\n /** Simple name. */\n name: string,\n /** Parent element, usually a file or another namespace. */\n parent: Element,\n /** Declaration reference. */\n declaration: NamespaceDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None\n ) {\n super(\n ElementKind.Namespace,\n name,\n mangleInternalName(name, parent, false),\n parent.program,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n }\n\n /* @override */\n lookup(name: string, isType: bool = false): Element | null {\n let member = this.getMember(name);\n if (member) return member;\n return super.lookup(name, isType);\n }\n}\n\n/** An enum. */\nexport class Enum extends TypedElement {\n\n /** Constructs a new enum. */\n constructor(\n /** Simple name. */\n name: string,\n /** Parent element, usually a file or namespace. */\n parent: Element,\n /** Declaration reference. */\n declaration: EnumDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None\n ) {\n super(\n ElementKind.Enum,\n name,\n mangleInternalName(name, parent, false),\n parent.program,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n this.setType(Type.i32);\n }\n\n /* @override */\n lookup(name: string, isType: bool = false): Element | null {\n let member = this.getMember(name);\n if (member) return member;\n return super.lookup(name, isType);\n }\n}\n\n/** Indicates the kind of an inlined constant value. */\nexport const enum ConstantValueKind {\n /** No constant value. */\n None,\n /** Constant integer value. */\n Integer,\n /** Constant float value. */\n Float\n}\n\n/** Base class of all variable-like program elements. */\nexport abstract class VariableLikeElement extends TypedElement {\n\n /** Constant value kind. */\n constantValueKind: ConstantValueKind = ConstantValueKind.None;\n /** Constant integer value, if applicable. */\n constantIntegerValue: i64 = i64_zero;\n /** Constant float value, if applicable. */\n constantFloatValue: f64 = 0;\n\n /** Constructs a new variable-like element. */\n protected constructor(\n /** Specific element kind. */\n kind: ElementKind,\n /** Simple name. */\n name: string,\n /** Parent element, usually a file, namespace or class. */\n parent: Element,\n /** Declaration reference. Creates a native declaration if omitted. */\n declaration: VariableLikeDeclarationStatement = parent.program.makeNativeVariableDeclaration(name)\n ) {\n super(\n kind,\n name,\n mangleInternalName(name, parent, declaration.is(CommonFlags.Instance)),\n parent.program,\n parent,\n declaration\n );\n this.flags = declaration.flags;\n }\n\n /** Gets the associated type node.s */\n get typeNode(): TypeNode | null {\n return (this.declaration).type;\n }\n\n /** Gets the associated initializer node. */\n get initializerNode(): Expression | null {\n return (this.declaration).initializer;\n }\n\n /** Applies a constant integer value to this element. */\n setConstantIntegerValue(value: i64, type: Type): void {\n assert(type.isIntegerInclReference);\n this.type = type;\n this.constantValueKind = ConstantValueKind.Integer;\n this.constantIntegerValue = value;\n this.set(CommonFlags.Const | CommonFlags.Inlined | CommonFlags.Resolved);\n }\n\n /** Applies a constant float value to this element. */\n setConstantFloatValue(value: f64, type: Type): void {\n assert(type.isFloatValue);\n this.type = type;\n this.constantValueKind = ConstantValueKind.Float;\n this.constantFloatValue = value;\n this.set(CommonFlags.Const | CommonFlags.Inlined | CommonFlags.Resolved);\n }\n}\n\n/** An enum value. */\nexport class EnumValue extends VariableLikeElement {\n\n /** Constructs a new enum value. */\n constructor(\n /** Simple name. */\n name: string,\n /** Parent enum. */\n parent: Enum,\n /** Declaration reference. */\n declaration: EnumValueDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None\n ) {\n super(\n ElementKind.EnumValue,\n name,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n this.setType(Type.i32);\n }\n\n /** Whether this enum value is immutable. */\n isImmutable: bool = false;\n\n /** Gets the associated value node. */\n get valueNode(): Expression | null {\n return (this.declaration).initializer;\n }\n}\n\n/** A global variable. */\nexport class Global extends VariableLikeElement {\n\n /** Constructs a new global variable. */\n constructor(\n /** Simple name. */\n name: string,\n /** Parent element, usually a file, namespace or static class. */\n parent: Element,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags,\n /** Declaration reference. Creates a native declaration if omitted. */\n declaration: VariableLikeDeclarationStatement = parent.program.makeNativeVariableDeclaration(name)\n ) {\n super(\n ElementKind.Global,\n name,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n }\n}\n\n/** A function parameter. */\nexport class Parameter {\n /** Constructs a new function parameter. */\n constructor(\n /** Parameter name. */\n public name: string,\n /** Parameter type. */\n public type: Type,\n /** Parameter initializer, if present. */\n public initializer: Expression | null = null\n ) {}\n}\n\n/** A local variable. */\nexport class Local extends VariableLikeElement {\n\n /** Original name of the (temporary) local. */\n private originalName: string;\n\n /** Constructs a new local variable. */\n constructor(\n /** Simple name. */\n name: string,\n /** Zero-based index within the enclosing function. `-1` indicates a dummy local. */\n public index: i32,\n /** Resolved type. */\n type: Type,\n /** Parent function. */\n parent: Function,\n /** Declaration reference. */\n declaration: VariableLikeDeclarationStatement = parent.program.makeNativeVariableDeclaration(name)\n ) {\n super(\n ElementKind.Local,\n name,\n parent,\n declaration\n );\n this.originalName = name;\n this.index = index;\n assert(type != Type.void);\n this.setType(type);\n }\n}\n\n/** A yet unresolved function prototype. */\nexport class FunctionPrototype extends DeclaredElement {\n\n /** Operator kind, if an overload. */\n operatorKind: OperatorKind = OperatorKind.Invalid;\n /** Already resolved instances. */\n instances: Map | null = null;\n /** Methods overriding this one, if any. These are unbound. */\n unboundOverrides: Set | null = null;\n\n /** Clones of this prototype that are bound to specific classes. */\n private boundPrototypes: Map | null = null;\n\n /** Constructs a new function prototype. */\n constructor(\n /** Simple name */\n name: string,\n /** Parent element, usually a file, namespace or class (if a method). */\n parent: Element,\n /** Declaration reference. */\n declaration: FunctionDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None\n ) {\n super(\n ElementKind.FunctionPrototype,\n name,\n mangleInternalName(name, parent, declaration.is(CommonFlags.Instance)),\n parent.program,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n }\n\n /** Gets the associated type parameter nodes. */\n get typeParameterNodes(): TypeParameterNode[] | null {\n return (this.declaration).typeParameters;\n }\n\n /** Gets the associated function type node. */\n get functionTypeNode(): FunctionTypeNode {\n return (this.declaration).signature;\n }\n\n /** Gets the associated body node. */\n get bodyNode(): Statement | null {\n return (this.declaration).body;\n }\n\n /** Gets the arrow function kind. */\n get arrowKind(): ArrowKind {\n return (this.declaration).arrowKind;\n }\n\n /** Creates a clone of this prototype that is bound to a concrete class instead. */\n toBound(classInstance: Class): FunctionPrototype {\n assert(this.is(CommonFlags.Instance));\n assert(!this.isBound);\n let boundPrototypes = this.boundPrototypes;\n if (!boundPrototypes) this.boundPrototypes = boundPrototypes = new Map();\n else if (boundPrototypes.has(classInstance)) return assert(boundPrototypes.get(classInstance));\n let declaration = this.declaration;\n assert(declaration.kind == NodeKind.MethodDeclaration);\n let bound = new FunctionPrototype(\n this.name,\n classInstance, // now bound\n declaration,\n this.decoratorFlags\n );\n bound.flags = this.flags;\n bound.operatorKind = this.operatorKind;\n bound.unboundOverrides = this.unboundOverrides;\n // NOTE: this.instances holds instances per bound class / unbound\n boundPrototypes.set(classInstance, bound);\n return bound;\n }\n\n /** Gets the resolved instance for the specified instance key, if already resolved. */\n getResolvedInstance(instanceKey: string): Function | null {\n let instances = this.instances;\n if (instances && instances.has(instanceKey)) return assert(instances.get(instanceKey));\n return null;\n }\n\n /** Sets the resolved instance for the specified instance key. */\n setResolvedInstance(instanceKey: string, instance: Function): void {\n let instances = this.instances;\n if (!instances) this.instances = instances = new Map();\n else assert(!instances.has(instanceKey));\n instances.set(instanceKey, instance);\n }\n}\n\n/** A resolved function. */\nexport class Function extends TypedElement {\n\n /** Function prototype. */\n prototype: FunctionPrototype;\n /** Function signature. */\n signature: Signature;\n /** Array of locals by index. */\n localsByIndex: Local[] = [];\n /** Concrete type arguments. */\n typeArguments: Type[] | null;\n /** Contextual type arguments. */\n contextualTypeArguments: Map | null;\n /** Default control flow. */\n flow!: Flow;\n /** Remembered debug locations. */\n debugLocations: Range[] = [];\n /** Function reference, if compiled. */\n ref: FunctionRef = 0;\n /** Varargs stub for calling with omitted arguments. */\n varargsStub: Function | null = null;\n /** Stub for calling overrides. */\n overrideStub: Function | null = null;\n /** Runtime memory segment, if created. */\n memorySegment: MemorySegment | null = null;\n /** Original function, if a stub. Otherwise `this`. */\n original!: Function;\n\n /** Counting id of inline operations involving this function. */\n nextInlineId: i32 = 0;\n /** Counting id of anonymous inner functions. */\n nextAnonymousId: i32 = 0;\n\n /** Constructs a new concrete function. */\n constructor(\n /** Name incl. type parameters, i.e. `foo`. */\n nameInclTypeParameters: string,\n /** Respective function prototype. */\n prototype: FunctionPrototype,\n /** Concrete type arguments. */\n typeArguments: Type[] | null,\n /** Concrete signature. */\n signature: Signature, // pre-resolved\n /** Contextual type arguments inherited from its parent class, if any. */\n contextualTypeArguments: Map | null = null\n ) {\n super(\n ElementKind.Function,\n nameInclTypeParameters,\n mangleInternalName(nameInclTypeParameters, prototype.parent, prototype.is(CommonFlags.Instance)),\n prototype.program,\n prototype.parent,\n prototype.declaration\n );\n this.prototype = prototype;\n this.typeArguments = typeArguments;\n this.signature = signature;\n this.flags = prototype.flags | CommonFlags.Resolved;\n this.decoratorFlags = prototype.decoratorFlags;\n this.contextualTypeArguments = contextualTypeArguments;\n this.original = this;\n let program = prototype.program;\n this.type = signature.type;\n let flow = Flow.createDefault(this);\n this.flow = flow;\n if (!prototype.is(CommonFlags.Ambient)) {\n let localIndex = 0;\n let thisType = signature.thisType;\n if (thisType) {\n let local = new Local(\n CommonNames.this_,\n localIndex++,\n thisType,\n this\n );\n let scopedLocals = this.flow.scopedLocals;\n if (!scopedLocals) this.flow.scopedLocals = scopedLocals = new Map();\n scopedLocals.set(CommonNames.this_, local);\n this.localsByIndex[local.index] = local;\n flow.setLocalFlag(local.index, LocalFlags.Initialized);\n }\n let parameterTypes = signature.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n let parameterType = parameterTypes[i];\n let parameterName = this.getParameterName(i);\n let local = new Local(\n parameterName,\n localIndex++,\n parameterType,\n this\n );\n let scopedLocals = this.flow.scopedLocals;\n if (!scopedLocals) this.flow.scopedLocals = scopedLocals = new Map();\n scopedLocals.set(parameterName, local);\n this.localsByIndex[local.index] = local;\n flow.setLocalFlag(local.index, LocalFlags.Initialized);\n }\n }\n registerConcreteElement(program, this);\n }\n\n /** Gets the types of additional locals that are not parameters. */\n getNonParameterLocalTypes(): Type[] {\n let localsByIndex = this.localsByIndex;\n let signature = this.signature;\n let numTotal = localsByIndex.length;\n let numFixed = signature.parameterTypes.length;\n if (signature.thisType) ++numFixed;\n let numAdditional = numTotal - numFixed;\n let types = new Array(numAdditional);\n for (let i = 0; i < numAdditional; ++i) {\n types[i] = localsByIndex[numFixed + i].type;\n }\n return types;\n }\n\n /** Gets the name of the parameter at the specified index. */\n getParameterName(index: i32): string {\n let parameters = (this.declaration).signature.parameters;\n return parameters.length > index\n ? parameters[index].name.text\n : getDefaultParameterName(index);\n }\n\n /** Creates a stub for use with this function, i.e. for varargs or override calls. */\n newStub(postfix: string, requiredParameters: i32 = this.signature.requiredParameters): Function {\n let stub = new Function(\n this.original.name + STUB_DELIMITER + postfix,\n this.prototype,\n this.typeArguments,\n this.signature.clone(requiredParameters),\n this.contextualTypeArguments\n );\n stub.original = this.original;\n stub.set(this.flags & ~CommonFlags.Compiled | CommonFlags.Stub);\n return stub;\n }\n\n /** Adds a local of the specified type, with an optional name. */\n addLocal(type: Type, name: string | null = null, declaration: VariableDeclaration | null = null): Local {\n // if it has a name, check previously as this method will throw otherwise\n let localsByIndex = this.localsByIndex;\n let localIndex = localsByIndex.length;\n let localName = name != null ? name : localIndex.toString();\n if (!declaration) declaration = this.program.makeNativeVariableDeclaration(localName);\n let local = new Local(localName, localIndex, type, this, declaration);\n if (name) {\n let defaultFlow = this.flow;\n let scopedLocals = defaultFlow.scopedLocals;\n if (!scopedLocals) defaultFlow.scopedLocals = scopedLocals = new Map();\n if (scopedLocals.has(name)) throw new Error(\"duplicate local name\");\n scopedLocals.set(name, local);\n }\n localsByIndex[localIndex] = local;\n return local;\n }\n\n /* @override */\n lookup(name: string, isType: bool = false): Element | null {\n if (!isType) {\n let scopedLocals = this.flow.scopedLocals;\n if (scopedLocals && scopedLocals.has(name)) {\n return assert(scopedLocals.get(name));\n }\n }\n return super.lookup(name, isType);\n }\n\n // used by flows to keep track of break labels\n nextBreakId: i32 = 0;\n breakStack: i32[] | null = null;\n\n /** Finalizes the function once compiled, releasing no longer needed resources. */\n finalize(module: Module, ref: FunctionRef): void {\n this.ref = ref;\n let breakStack = this.breakStack;\n assert(!breakStack || !breakStack.length); // should be empty\n this.breakStack = null;\n this.addDebugInfo(module, ref);\n }\n\n addDebugInfo(module: Module, ref: FunctionRef): void {\n if (this.program.options.sourceMap) {\n let debugLocations = this.debugLocations;\n for (let i = 0, k = debugLocations.length; i < k; ++i) {\n let range = debugLocations[i];\n let source = range.source;\n module.setDebugLocation(\n ref,\n range.debugInfoRef,\n source.debugInfoIndex,\n source.lineAt(range.start),\n source.columnAt() - 1 // source maps are 0-based\n );\n }\n }\n if (this.program.options.debugInfo) {\n let localNameMap = new Set();\n let localsByIndex = this.localsByIndex;\n for (let i = 0, k = localsByIndex.length; i < k; i++) {\n let localName = localsByIndex[i].name;\n if (localNameMap.has(localName)) {\n localName = `${localName}|${i}`;\n }\n localNameMap.add(localName);\n module.setLocalName(ref, i, localName);\n }\n }\n }\n}\n\n/** A property comprised of a getter and a setter function. */\nexport class PropertyPrototype extends DeclaredElement {\n\n /** Field declaration, if a field. */\n fieldDeclaration: FieldDeclaration | null = null;\n /** Getter prototype. */\n getterPrototype: FunctionPrototype | null = null;\n /** Setter prototype. */\n setterPrototype: FunctionPrototype | null = null;\n /** Property instance, if resolved. */\n instance: Property | null = null;\n\n /** Clones of this prototype that are bound to specific classes. */\n private boundPrototypes: Map | null = null;\n\n /** Creates a property prototype representing a field. */\n static forField(\n /** Simple name. */\n name: string,\n /** Parent element. Always a class prototype. */\n parent: ClassPrototype,\n /** Declaration of the field. */\n fieldDeclaration: FieldDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags,\n ): PropertyPrototype {\n // A field is a property with an attached memory offset. Unlike normal\n // properties, accessors for fields are not explicitly declared, so we\n // declare them implicitly here and compile them as built-ins when used.\n // As a result, explicit and implicit accessors can override each other,\n // which is useful when implementing interfaces declaring \"fields\". Such\n // fields are satisfied by either a field or a normal property, so the\n // override stub at the interface needs to handle both interchangeably.\n let nativeRange = Source.native.range;\n let typeNode = fieldDeclaration.type;\n if (!typeNode) typeNode = Node.createOmittedType(fieldDeclaration.name.range.atEnd);\n let getterDeclaration = new MethodDeclaration( // get name(): type\n fieldDeclaration.name,\n fieldDeclaration.decorators,\n fieldDeclaration.flags | CommonFlags.Instance | CommonFlags.Get,\n null,\n new FunctionTypeNode([], typeNode, null, false, nativeRange),\n null,\n nativeRange\n );\n let setterDeclaration = new MethodDeclaration( // set name(name: type)\n fieldDeclaration.name,\n fieldDeclaration.decorators,\n fieldDeclaration.flags | CommonFlags.Instance | CommonFlags.Set,\n null,\n new FunctionTypeNode(\n [\n new ParameterNode(\n ParameterKind.Default,\n fieldDeclaration.name,\n typeNode, null, nativeRange\n )\n ],\n new NamedTypeNode(\n new TypeName(\n new IdentifierExpression(\"\", false, nativeRange),\n null, nativeRange\n ),\n null, false, nativeRange\n ),\n null, false, nativeRange\n ),\n null, nativeRange\n );\n let prototype = new PropertyPrototype(name, parent, getterDeclaration);\n prototype.fieldDeclaration = fieldDeclaration;\n prototype.decoratorFlags = decoratorFlags;\n prototype.getterPrototype = new FunctionPrototype(GETTER_PREFIX + name, parent, getterDeclaration, decoratorFlags);\n prototype.setterPrototype = new FunctionPrototype(SETTER_PREFIX + name, parent, setterDeclaration, decoratorFlags);\n return prototype;\n }\n\n /** Constructs a new property prototype. */\n constructor(\n /** Simple name. */\n name: string,\n /** Parent element. Either a class prototype or instance. */\n parent: Element,\n /** Declaration of the getter or setter introducing the property. */\n firstDeclaration: FunctionDeclaration\n ) {\n super(\n ElementKind.PropertyPrototype,\n name,\n mangleInternalName(name, parent, firstDeclaration.is(CommonFlags.Instance)),\n parent.program,\n parent,\n firstDeclaration\n );\n this.flags &= ~(CommonFlags.Get | CommonFlags.Set);\n }\n\n /** Tests if this property prototype represents a field. */\n get isField(): bool {\n return this.fieldDeclaration != null;\n }\n\n /** Gets the associated type node. */\n get typeNode(): TypeNode | null {\n let fieldDeclaration = this.fieldDeclaration;\n if (fieldDeclaration) return fieldDeclaration.type;\n let getterPrototype = this.getterPrototype;\n if (getterPrototype) {\n let getterDeclaration = getterPrototype.declaration;\n if (getterDeclaration.kind == NodeKind.FunctionDeclaration) {\n return (getterDeclaration).signature.returnType;\n }\n }\n let setterPrototype = this.setterPrototype;\n if (setterPrototype) {\n let setterDeclaration = setterPrototype.declaration;\n if (setterDeclaration.kind == NodeKind.FunctionDeclaration) {\n let setterParameters = (setterDeclaration).signature.parameters;\n if (setterParameters.length) return setterParameters[0].type;\n }\n }\n return null;\n }\n\n /** Gets the associated initializer node. */\n get initializerNode(): Expression | null {\n let fieldDeclaration = this.fieldDeclaration;\n if (fieldDeclaration) return fieldDeclaration.initializer;\n return null;\n }\n\n /** Gets the associated parameter index. Set if declared as a constructor parameter, otherwise `-1`. */\n get parameterIndex(): i32 {\n let fieldDeclaration = this.fieldDeclaration;\n if (fieldDeclaration) return fieldDeclaration.parameterIndex;\n return -1;\n }\n\n /** Gets the respective `this` type. */\n get thisType(): Type {\n let parent = this.parent;\n assert(parent.kind == ElementKind.Class);\n return (parent).type;\n }\n\n /** Creates a clone of this property prototype that is bound to a concrete class. */\n toBound(classInstance: Class): PropertyPrototype {\n assert(this.is(CommonFlags.Instance));\n assert(!this.isBound);\n let boundPrototypes = this.boundPrototypes;\n if (!boundPrototypes) this.boundPrototypes = boundPrototypes = new Map();\n else if (boundPrototypes.has(classInstance)) return assert(boundPrototypes.get(classInstance));\n let firstDeclaration = this.declaration;\n assert(firstDeclaration.kind == NodeKind.MethodDeclaration);\n let bound = new PropertyPrototype(\n this.name,\n classInstance, // now bound\n firstDeclaration\n );\n bound.flags = this.flags;\n bound.fieldDeclaration = this.fieldDeclaration;\n let getterPrototype = this.getterPrototype;\n if (getterPrototype) {\n bound.getterPrototype = getterPrototype.toBound(classInstance);\n }\n let setterPrototype = this.setterPrototype;\n if (setterPrototype) {\n bound.setterPrototype = setterPrototype.toBound(classInstance);\n }\n boundPrototypes.set(classInstance, bound);\n return bound;\n }\n}\n\n/** A resolved property. */\nexport class Property extends VariableLikeElement {\n\n /** Prototype reference. */\n prototype: PropertyPrototype;\n /** Getter instance. */\n getterInstance: Function | null = null;\n /** Setter instance. */\n setterInstance: Function | null = null;\n /** Field memory offset, if a (layed out) instance field. */\n memoryOffset: i32 = -1;\n\n /** Constructs a new property prototype. */\n constructor(\n /** Respective property prototype. */\n prototype: PropertyPrototype,\n /** Parent element, usually a static class prototype or class instance. */\n parent: Element\n ) {\n super(\n ElementKind.Property,\n prototype.name,\n parent,\n prototype.isField\n ? assert(prototype.fieldDeclaration)\n : Node.createVariableDeclaration(\n prototype.identifierNode,\n null,\n prototype.flags & CommonFlags.Instance,\n null, null,\n prototype.identifierNode.range\n )\n );\n this.prototype = prototype;\n this.flags = prototype.flags;\n this.decoratorFlags = prototype.decoratorFlags;\n if (this.is(CommonFlags.Instance)) {\n registerConcreteElement(this.program, this);\n }\n }\n\n /** Tests if this property represents a field. */\n get isField(): bool {\n return this.prototype.isField;\n }\n}\n\n/** A resolved index signature. */\nexport class IndexSignature extends TypedElement {\n\n /** Constructs a new index prototype. */\n constructor(\n /** Parent class. */\n parent: Class\n ) {\n super(\n ElementKind.IndexSignature,\n \"[]\",\n parent.internalName + \"[]\",\n parent.program,\n parent,\n parent.program.makeNativeVariableDeclaration(\"[]\") // is fine\n );\n }\n\n /** Obtains the getter instance. */\n getGetterInstance(isUnchecked: bool): Function | null {\n return (this.parent).lookupOverload(OperatorKind.IndexedGet, isUnchecked);\n }\n\n /** Obtains the setter instance. */\n getSetterInstance(isUnchecked: bool): Function | null {\n return (this.parent).lookupOverload(OperatorKind.IndexedSet, isUnchecked);\n }\n}\n\n/** A yet unresolved class prototype. */\nexport class ClassPrototype extends DeclaredElement {\n\n /** Instance member prototypes. */\n instanceMembers: Map | null = null;\n /** Base class prototype, if applicable. */\n basePrototype: ClassPrototype | null = null;\n /** Interface prototypes, if applicable. */\n interfacePrototypes: InterfacePrototype[] | null = null;\n /** Constructor prototype. */\n constructorPrototype: FunctionPrototype | null = null;\n /** Operator overload prototypes. */\n operatorOverloadPrototypes: Map = new Map();\n /** Already resolved instances. */\n instances: Map | null = null;\n /** Classes extending this class. */\n extenders: Set = new Set();\n /** Whether this class implicitly extends `Object`. */\n implicitlyExtendsObject: bool = false;\n\n constructor(\n /** Simple name. */\n name: string,\n /** Parent element, usually a file or namespace. */\n parent: Element,\n /** Declaration reference. */\n declaration: ClassDeclaration,\n /** Pre-checked flags indicating built-in decorators. */\n decoratorFlags: DecoratorFlags = DecoratorFlags.None,\n _isInterface: bool = false // FIXME\n ) {\n super(\n _isInterface ? ElementKind.InterfacePrototype : ElementKind.ClassPrototype,\n name,\n mangleInternalName(name, parent, declaration.is(CommonFlags.Instance)),\n parent.program,\n parent,\n declaration\n );\n this.decoratorFlags = decoratorFlags;\n }\n\n /** Gets the associated type parameter nodes. */\n get typeParameterNodes(): TypeParameterNode[] | null {\n return (this.declaration).typeParameters;\n }\n /** Gets the associated extends node. */\n get extendsNode(): NamedTypeNode | null {\n return (this.declaration).extendsType;\n }\n /** Gets the associated implements nodes. */\n get implementsNodes(): NamedTypeNode[] | null {\n return (this.declaration).implementsTypes;\n }\n\n /** Tests if this prototype is of a builtin array type (Array/TypedArray). */\n get isBuiltinArray(): bool {\n let arrayBufferViewInstance = this.program.arrayBufferViewInstance;\n return arrayBufferViewInstance && this.extends(arrayBufferViewInstance.prototype);\n }\n\n /** Tests if this prototype extends the specified. */\n extends(basePtototype: ClassPrototype | null): bool {\n let current: ClassPrototype | null = this;\n let seen = new Set();\n do {\n // cannot directly or indirectly extend itself\n if (seen.has(current)) break;\n seen.add(current);\n if (current == basePtototype) return true;\n current = current.basePrototype;\n } while (current);\n return false;\n }\n\n /** Adds an element as an instance member of this one. Returns the previous element if a duplicate. */\n addInstance(name: string, element: DeclaredElement): bool {\n let originalDeclaration = element.declaration;\n let instanceMembers = this.instanceMembers;\n if (!instanceMembers) this.instanceMembers = instanceMembers = new Map();\n else if (instanceMembers.has(name)) {\n let existing = assert(instanceMembers.get(name));\n let merged = tryMerge(existing, element);\n if (!merged) {\n if (isDeclaredElement(existing.kind)) {\n this.program.errorRelated(\n DiagnosticCode.Duplicate_identifier_0,\n element.identifierNode.range,\n (existing).declaration.name.range,\n element.identifierNode.text\n );\n } else {\n this.program.error(\n DiagnosticCode.Duplicate_identifier_0,\n element.identifierNode.range, element.identifierNode.text\n );\n }\n return false;\n }\n element = merged;\n }\n instanceMembers.set(name, element);\n if (element.is(CommonFlags.Export) && this.is(CommonFlags.ModuleExport)) {\n element.set(CommonFlags.ModuleExport); // propagate\n }\n this.program.elementsByDeclaration.set(originalDeclaration, element);\n return true;\n }\n\n /** Gets the resolved instance for the specified instance key, if already resolved. */\n getResolvedInstance(instanceKey: string): Class | null {\n let instances = this.instances;\n if (instances && instances.has(instanceKey)) return instances.get(instanceKey);\n return null;\n }\n\n /** Sets the resolved instance for the specified instance key. */\n setResolvedInstance(instanceKey: string, instance: Class): void {\n let instances = this.instances;\n if (!instances) this.instances = instances = new Map();\n else assert(!instances.has(instanceKey));\n instances.set(instanceKey, instance);\n }\n}\n\n/** A resolved class. */\nexport class Class extends TypedElement {\n\n /** Class prototype. */\n prototype: ClassPrototype;\n /** Resolved type arguments. */\n typeArguments: Type[] | null;\n /** Base class, if any. */\n base: Class | null = null;\n /** Directly implemented interfaces, if any. */\n interfaces: Set | null = null;\n /** Contextual type arguments for fields and methods. */\n contextualTypeArguments: Map | null = null;\n /** Current member memory offset. */\n nextMemoryOffset: u32 = 0;\n /** Constructor instance. */\n constructorInstance: Function | null = null;\n /** Operator overloads. */\n operatorOverloads: Map | null = null;\n /** Index signature, if present. */\n indexSignature: IndexSignature | null = null;\n /** Unique class id. */\n private _id: u32 = 0;\n /** Runtime type information flags. */\n rttiFlags: u32 = 0;\n /** Wrapped type, if a wrapper for a basic type. */\n wrappedType: Type | null = null;\n /** Classes directly or indirectly extending this class, if any. */\n extenders: Set | null = null;\n /** Classes directly or indirectly implementing this interface, if any. */\n implementers: Set | null = null;\n /** Whether the field initialization check has already been performed. */\n didCheckFieldInitialization: bool = false;\n /** Runtime visitor function reference. */\n visitRef: FunctionRef = 0;\n\n /** Gets the unique runtime id of this class. */\n get id(): u32 {\n return this._id; // unmanaged remains 0 (=ArrayBuffer)\n }\n\n /** Tests if this class is of a builtin array type (Array/TypedArray). */\n get isBuiltinArray(): bool {\n return this.prototype.isBuiltinArray;\n }\n\n /** Tests if this class is array-like. */\n get isArrayLike(): bool {\n if (this.isBuiltinArray) return true;\n let lengthField = this.getMember(\"length\");\n if (!lengthField) return false;\n return (\n (\n lengthField.kind == ElementKind.Property &&\n (lengthField).getterInstance != null\n ) || (\n lengthField.kind == ElementKind.PropertyPrototype &&\n (lengthField).getterPrototype != null // TODO: resolve & check type?\n )\n ) && (\n this.lookupOverload(OperatorKind.IndexedGet) != null ||\n this.lookupOverload(OperatorKind.UncheckedIndexedGet) != null\n );\n }\n\n /** Tests if this is an interface. */\n get isInterface(): bool {\n return this.kind == ElementKind.Interface;\n }\n\n /** Constructs a new class. */\n constructor(\n /** Name incl. type parameters, i.e. `Foo`. */\n nameInclTypeParameters: string,\n /** The respective class prototype. */\n prototype: ClassPrototype,\n /** Concrete type arguments, if any. */\n typeArguments: Type[] | null = null,\n _isInterface: bool = false // FIXME\n ) {\n super(\n _isInterface ? ElementKind.Interface : ElementKind.Class,\n nameInclTypeParameters,\n mangleInternalName(nameInclTypeParameters, prototype.parent, prototype.is(CommonFlags.Instance)),\n prototype.program,\n prototype.parent,\n prototype.declaration\n );\n this.prototype = prototype;\n this.flags = prototype.flags;\n this.decoratorFlags = prototype.decoratorFlags;\n this.typeArguments = typeArguments;\n let program = this.program;\n let usizeType = program.options.usizeType;\n let type = new Type(usizeType.kind, usizeType.flags & ~TypeFlags.Value | TypeFlags.Reference, usizeType.size);\n type.classReference = this;\n this.setType(type);\n\n if (!this.hasDecorator(DecoratorFlags.Unmanaged)) {\n let id = program.nextClassId++;\n this._id = id;\n program.managedClasses.set(id, this);\n }\n\n // apply pre-checked instance-specific contextual type arguments\n let typeParameters = prototype.typeParameterNodes;\n if (typeArguments) {\n let numTypeArguments = typeArguments.length;\n if (!typeParameters || numTypeArguments != typeParameters.length) {\n throw new Error(\"type argument count mismatch\");\n }\n if (numTypeArguments) {\n let contextualTypeArguments = this.contextualTypeArguments;\n if (!contextualTypeArguments) this.contextualTypeArguments = contextualTypeArguments = new Map();\n for (let i = 0; i < numTypeArguments; ++i) {\n contextualTypeArguments.set(typeParameters[i].name.text, typeArguments[i]);\n }\n }\n } else if (typeParameters && typeParameters.length > 0) {\n throw new Error(\"type argument count mismatch\");\n }\n registerConcreteElement(program, this);\n }\n\n /** Computes the least upper bound of two class types. */\n static leastUpperBound(a: Class, b: Class): Class | null {\n if (a == b) return a;\n let candidates = new Set();\n candidates.add(a);\n candidates.add(b);\n while (true) {\n let aBase = a.base;\n let bBase = b.base;\n if (!aBase && !bBase) return null; // none\n if (aBase) {\n if (candidates.has(aBase)) return aBase;\n candidates.add(a = aBase);\n }\n if (bBase) {\n if (candidates.has(bBase)) return bBase;\n candidates.add(b = bBase);\n }\n }\n }\n\n /** Sets the base class. */\n setBase(base: Class): void {\n assert(!this.base);\n this.base = base;\n\n // Inherit contextual type arguments from base class\n let inheritedTypeArguments = base.contextualTypeArguments;\n if (inheritedTypeArguments) {\n let contextualTypeArguments = this.contextualTypeArguments;\n // TODO: for (let [baseName, baseType] of inheritedTypeArguments) {\n for (let _keys = Map_keys(inheritedTypeArguments), i = 0, k = _keys.length; i < k; ++i) {\n let baseName = unchecked(_keys[i]);\n let baseType = assert(inheritedTypeArguments.get(baseName));\n if (!contextualTypeArguments) {\n this.contextualTypeArguments = contextualTypeArguments = new Map();\n contextualTypeArguments.set(baseName, baseType);\n } else if (!contextualTypeArguments.has(baseName)) {\n contextualTypeArguments.set(baseName, baseType);\n }\n }\n }\n\n // This class and its extenders now extend each direct or indirect base class\n base.propagateExtenderUp(this);\n let extenders = this.extenders;\n if (extenders) {\n for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) {\n let extender = _values[i];\n base.propagateExtenderUp(extender);\n }\n }\n\n // Direct or indirect base interfaces are now implemented by this class and its extenders\n let nextBase: Class | null = base;\n do {\n let baseInterfaces = nextBase.interfaces;\n if (baseInterfaces) {\n for (let _values = Set_values(baseInterfaces), i = 0, k = _values.length; i < k; ++i) {\n let baseInterface = _values[i];\n this.propagateInterfaceDown(baseInterface);\n }\n }\n nextBase = nextBase.base;\n } while (nextBase);\n }\n\n /** Propagates an extender to this class and its base classes. */\n private propagateExtenderUp(extender: Class): void {\n // Start with this class, adding the extender to it. Repeat for the class's\n // bases that are indirectly extended by the extender.\n let nextBase: Class | null = this;\n do {\n let extenders = nextBase.extenders;\n if (!extenders) nextBase.extenders = extenders = new Set();\n extenders.add(extender);\n nextBase = nextBase.base;\n } while (nextBase);\n }\n\n /** Propagates an interface and its base interfaces to this class and its extenders. */\n private propagateInterfaceDown(iface: Interface): void {\n // Start with the interface itself, adding this class and its extenders to\n // its implementers. Repeat for the interface's bases that are indirectly\n // implemented by means of being extended by the interface.\n let nextIface: Interface | null = iface;\n let extenders = this.extenders;\n do {\n let implementers = nextIface.implementers;\n if (!implementers) nextIface.implementers = implementers = new Set();\n implementers.add(this);\n if (extenders) {\n for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) {\n let extender = _values[i];\n implementers.add(extender);\n }\n }\n nextIface = nextIface.base;\n } while (nextIface);\n }\n\n /** Adds an interface. */\n addInterface(iface: Interface): void {\n let interfaces = this.interfaces;\n if (!interfaces) this.interfaces = interfaces = new Set();\n interfaces.add(iface);\n\n // This class and its extenders now implement the interface and its bases\n this.propagateInterfaceDown(iface);\n }\n\n /** Tests if a value of this class type is assignable to a target of the specified class type. */\n isAssignableTo(target: Class): bool {\n // Q: When does the assignment in the comment below succeed?\n if (target.isInterface) {\n if (this.isInterface) {\n // targetInterface = thisInterface\n return this == target || this.extends(target);\n } else {\n // targetInterface = thisClass\n return this.implements(target);\n }\n } else {\n if (this.isInterface) {\n // targetClass = thisInterface\n return target == this.program.objectInstance;\n } else {\n // targetClass = thisClass\n return this == target || this.extends(target);\n }\n }\n }\n\n /** Tests if any subclass of this class is assignable to a target of the specified class type. */\n hasSubclassAssignableTo(target: Class): bool {\n // Q: When can the cast in the comment below succeed? (while an assignment would not)\n if (target.isInterface) {\n if (this.isInterface) {\n // thisInterface\n return this.hasImplementerImplementing(target);\n } else {\n // thisClass\n return this.hasExtenderImplementing(target);\n }\n } else {\n if (this.isInterface) {\n // thisInterface\n return this.hasImplementer(target);\n } else {\n // thisClass\n return this.hasExtender(target);\n }\n }\n }\n\n /** Looks up the operator overload of the specified kind. */\n lookupOverload(kind: OperatorKind, unchecked: bool = false): Function | null {\n if (unchecked) {\n switch (kind) {\n case OperatorKind.IndexedGet: {\n let uncheckedOverload = this.lookupOverload(OperatorKind.UncheckedIndexedGet);\n if (uncheckedOverload) return uncheckedOverload;\n break;\n }\n case OperatorKind.IndexedSet: {\n let uncheckedOverload = this.lookupOverload(OperatorKind.UncheckedIndexedSet);\n if (uncheckedOverload) return uncheckedOverload;\n break;\n }\n default: assert(false);\n }\n }\n let instance: Class | null = this;\n do {\n let overloads = instance.operatorOverloads;\n if (overloads != null && overloads.has(kind)) {\n return assert(overloads.get(kind));\n }\n instance = instance.base;\n } while (instance);\n return null;\n }\n\n /** Gets the method of the specified name, resolved with the given type arguments. */\n getMethod(name: string, typeArguments: Type[] | null = null): Function | null {\n let member = this.getMember(name);\n if (member && member.kind == ElementKind.FunctionPrototype) {\n return this.program.resolver.resolveFunction(member, typeArguments);\n }\n return null;\n }\n\n /** Calculates the memory offset of the specified field. */\n offsetof(fieldName: string): u32 {\n let member = assert(this.getMember(fieldName));\n assert(member.kind == ElementKind.PropertyPrototype);\n let prototype = member;\n let property = prototype.instance;\n if (property) { // would have failed before\n assert(property.isField && property.memoryOffset >= 0);\n return property.memoryOffset;\n }\n return 0;\n }\n\n /** Creates a buffer suitable to hold a runtime instance of this class. */\n createBuffer(overhead: i32 = 0): Uint8Array {\n let program = this.program;\n let payloadSize = this.nextMemoryOffset + overhead;\n let blockSize = program.computeBlockSize(payloadSize, true); // excl. overhead\n let buffer = new Uint8Array(program.blockOverhead + blockSize);\n let OBJECT = program.OBJECTInstance;\n OBJECT.writeField(\"mmInfo\", blockSize, buffer, 0);\n OBJECT.writeField(\"gcInfo\", 0, buffer, 0);\n OBJECT.writeField(\"gcInfo2\", 0, buffer, 0);\n OBJECT.writeField(\"rtId\", this.id, buffer, 0);\n OBJECT.writeField(\"rtSize\", payloadSize, buffer, 0);\n return buffer;\n }\n\n /** Writes a field value to a buffer and returns the number of bytes written. */\n writeField(name: string, value: T, buffer: Uint8Array, baseOffset: i32 = this.program.totalOverhead): i32 {\n let member = this.getMember(name);\n if (member && member.kind == ElementKind.PropertyPrototype) {\n let prototype = member;\n let property = prototype.instance; // resolved during class finalization\n if (!property) return 0; // failed before\n assert(property.isField && property.memoryOffset >= 0);\n let offset = baseOffset + property.memoryOffset;\n let typeKind = property.type.kind;\n switch (typeKind) {\n case TypeKind.I8:\n case TypeKind.U8: {\n assert(!i64_is(value));\n writeI8(i32(value), buffer, offset);\n return 1;\n }\n case TypeKind.I16:\n case TypeKind.U16: {\n assert(!i64_is(value));\n writeI16(i32(value), buffer, offset);\n return 2;\n }\n case TypeKind.I32:\n case TypeKind.U32: {\n assert(!i64_is(value));\n writeI32(i32(value), buffer, offset);\n return 4;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n if (this.program.options.isWasm64) {\n if (i64_is(value)) {\n writeI64(value, buffer, offset);\n } else {\n writeI32AsI64(i32(value), buffer, offset, typeKind == TypeKind.Usize);\n }\n return 8;\n } else {\n if (i64_is(value)) {\n writeI64AsI32(value, buffer, offset, typeKind == TypeKind.Usize);\n } else {\n writeI32(i32(value), buffer, offset);\n }\n return 4;\n }\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n if (i64_is(value)) {\n writeI64(value, buffer, offset);\n } else {\n writeI32AsI64(i32(value), buffer, offset, typeKind == TypeKind.U64);\n }\n return 8;\n }\n case TypeKind.F32: {\n assert(!i64_is(value));\n writeF32(f32(value), buffer, offset);\n return 4;\n }\n case TypeKind.F64: {\n assert(!i64_is(value));\n writeF64(f64(value), buffer, offset);\n return 8;\n }\n }\n }\n assert(false);\n return 0;\n }\n\n /** Tests if this class extends the specified prototype. */\n extendsPrototype(prototype: ClassPrototype): bool {\n return this.prototype.extends(prototype);\n }\n\n /** Gets the concrete type arguments to the specified extendend prototype. */\n getTypeArgumentsTo(extendedPrototype: ClassPrototype): Type[] | null {\n let current: Class | null = this;\n do {\n if (current.prototype == extendedPrototype) return current.typeArguments;\n current = current.base;\n } while (current);\n return null;\n }\n\n /** Gets the value type of an array. Must be an array. */\n getArrayValueType(): Type {\n let current: Class = this;\n let program = this.program;\n let arrayPrototype = program.arrayPrototype;\n if (this.extendsPrototype(arrayPrototype)) {\n return this.getTypeArgumentsTo(arrayPrototype)![0];\n }\n let staticArrayPrototype = program.staticArrayPrototype;\n if (this.extendsPrototype(staticArrayPrototype)) {\n return this.getTypeArgumentsTo(staticArrayPrototype)![0];\n }\n let abvInstance = program.arrayBufferViewInstance;\n while (current.base != abvInstance) {\n current = assert(current.base);\n }\n let prototype = current.prototype;\n switch (prototype.name.charCodeAt(0)) {\n case CharCode.F: {\n if (prototype == program.float32ArrayPrototype) return Type.f32;\n if (prototype == program.float64ArrayPrototype) return Type.f64;\n break;\n }\n case CharCode.I: {\n if (prototype == program.int8ArrayPrototype) return Type.i8;\n if (prototype == program.int16ArrayPrototype) return Type.i16;\n if (prototype == program.int32ArrayPrototype) return Type.i32;\n if (prototype == program.int64ArrayPrototype) return Type.i64;\n break;\n }\n case CharCode.U: {\n if (prototype == program.uint8ArrayPrototype) return Type.u8;\n if (prototype == program.uint8ClampedArrayPrototype) return Type.u8;\n if (prototype == program.uint16ArrayPrototype) return Type.u16;\n if (prototype == program.uint32ArrayPrototype) return Type.u32;\n if (prototype == program.uint64ArrayPrototype) return Type.u64;\n break;\n }\n }\n assert(false);\n return Type.void;\n }\n\n /** Tests if this class is pointerfree. Useful to know for the GC. */\n get isPointerfree(): bool {\n let program = this.program;\n\n let instanceMembers = this.members;\n if (instanceMembers) {\n\n // Check that there are no managed instance fields\n for (let _values = Map_values(instanceMembers), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n if (member.kind == ElementKind.PropertyPrototype) {\n let prototype = member;\n let property = prototype.instance; // resolved during class finalization\n if (!property) continue; // failed earlier\n if (property.isField && property.type.isManaged) return false;\n }\n }\n\n // Check that this isn't a managed collection\n if (instanceMembers.has(CommonNames.visit)) {\n let prototype = this.prototype;\n if (\n prototype == program.arrayPrototype ||\n prototype == program.staticArrayPrototype ||\n prototype == program.setPrototype ||\n prototype == program.mapPrototype\n ) {\n // Note that we cannot know for sure anymore as soon as the collection\n // is extended, because user code may implement a custom visitor.\n let typeArguments = assert(this.getTypeArgumentsTo(prototype));\n for (let i = 0, k = typeArguments.length; i < k; ++i) {\n if (typeArguments[i].isManaged) return false;\n }\n return true;\n }\n return false; // has a custom __visit\n }\n }\n return true;\n }\n\n /** Tests if this class or interface extends the given class or interface. */\n extends(other: Class): bool {\n return other.hasExtender(this);\n }\n\n /** Tests if this class has a direct or indirect extender matching the given class. */\n hasExtender(other: Class): bool {\n let extenders = this.extenders;\n return extenders != null && extenders.has(other);\n }\n\n /** Tests if this class has a direct or indirect extender that implements the given interface. */\n hasExtenderImplementing(other: Interface): bool {\n let extenders = this.extenders;\n if (extenders) {\n for (let _values = Set_values(extenders), i = 0, k = _values.length; i < k; ++i) {\n let extender = _values[i];\n if (extender.implements(other)) return true;\n }\n }\n return false;\n }\n\n /** Tests if this class directly or indirectly implements the given interface. */\n implements(other: Interface): bool {\n return other.hasImplementer(this);\n }\n\n /** Tests if this interface has a direct or indirect implementer matching the given class. */\n hasImplementer(other: Class): bool {\n let implementers = this.implementers;\n return implementers != null && implementers.has(other);\n }\n\n /** Tests if this interface has an implementer implementing the given interface. */\n hasImplementerImplementing(other: Interface): bool {\n let implementers = this.implementers;\n if (implementers) {\n for (let _values = Set_values(implementers), i = 0, k = _values.length; i < k; ++i) {\n let implementer = _values[i];\n if (implementer.implements(other)) return true;\n }\n }\n return false;\n }\n}\n\n/** A yet unresolved interface. */\nexport class InterfacePrototype extends ClassPrototype {\n\n /** Constructs a new interface prototype. */\n constructor(\n name: string,\n parent: Element,\n declaration: InterfaceDeclaration,\n decoratorFlags: DecoratorFlags\n ) {\n super(\n name,\n parent,\n declaration,\n decoratorFlags,\n true\n );\n }\n}\n\n/** A resolved interface. */\nexport class Interface extends Class { // FIXME\n\n /** Constructs a new interface. */\n constructor(\n /** Name incl. type parameters, i.e. `Foo`. */\n nameInclTypeParameters: string,\n /** The respective class prototype. */\n prototype: InterfacePrototype,\n /** Concrete type arguments, if any. */\n typeArguments: Type[] | null = null,\n ) {\n super(\n nameInclTypeParameters,\n prototype,\n typeArguments,\n true\n );\n }\n}\n\n/** Registers a concrete element with a program. */\nfunction registerConcreteElement(program: Program, element: Element): void {\n assert(!program.instancesByName.has(element.internalName));\n program.instancesByName.set(element.internalName, element);\n}\n\n/** Attempts to merge two elements. Returns the merged element on success. */\nfunction tryMerge(older: Element, newer: Element): DeclaredElement | null {\n // NOTE: some of the following cases are not supported by TS, not sure why exactly.\n // suggesting to just merge what seems to be possible for now and revisit later.\n assert(older.program == newer.program);\n if (newer.members) return null;\n let merged: DeclaredElement | null = null;\n switch (older.kind) {\n case ElementKind.FunctionPrototype: {\n switch (newer.kind) {\n case ElementKind.Namespace: {\n copyMembers(newer, older);\n merged = older;\n break;\n }\n case ElementKind.TypeDefinition: {\n if (!older.shadowType) {\n older.shadowType = newer;\n copyMembers(newer, older);\n merged = older;\n }\n break;\n }\n }\n break;\n }\n case ElementKind.ClassPrototype:\n case ElementKind.Enum: {\n if (newer.kind == ElementKind.Namespace) {\n copyMembers(newer, older);\n merged = older;\n break;\n }\n break;\n }\n case ElementKind.Namespace: {\n switch (newer.kind) {\n case ElementKind.Enum:\n case ElementKind.ClassPrototype: // TS2434\n case ElementKind.FunctionPrototype: { // TS2434\n copyMembers(older, newer);\n merged = newer;\n break;\n }\n case ElementKind.Namespace: {\n copyMembers(newer, older);\n merged = older;\n break;\n }\n case ElementKind.TypeDefinition: {\n if (!older.shadowType) {\n older.shadowType = newer;\n copyMembers(newer, older);\n merged = older;\n }\n break;\n }\n }\n break;\n }\n case ElementKind.Global: {\n if (newer.kind == ElementKind.TypeDefinition) {\n if (!older.shadowType) {\n older.shadowType = newer;\n copyMembers(newer, older);\n merged = older;\n }\n }\n break;\n }\n case ElementKind.TypeDefinition: {\n switch (newer.kind) {\n case ElementKind.Global:\n case ElementKind.FunctionPrototype:\n case ElementKind.Namespace: {\n if (!newer.shadowType) {\n newer.shadowType = older;\n copyMembers(older, newer);\n merged = newer;\n }\n break;\n }\n }\n break;\n }\n }\n if (merged) {\n let olderIsExport = older.is(CommonFlags.Export) || older.hasDecorator(DecoratorFlags.Global);\n let newerIsExport = newer.is(CommonFlags.Export) || newer.hasDecorator(DecoratorFlags.Global);\n if (olderIsExport != newerIsExport) {\n older.program.error(\n DiagnosticCode.Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local,\n merged.identifierNode.range, merged.identifierNode.text\n );\n }\n }\n return merged;\n}\n\n/** Copies the members of `src` to `dest`. */\nfunction copyMembers(src: Element, dest: Element): void {\n let srcMembers = src.members;\n if (srcMembers) {\n let destMembers = dest.members;\n if (!destMembers) dest.members = destMembers = new Map();\n // TODO: for (let [memberName, member] of srcMembers) {\n for (let _keys = Map_keys(srcMembers), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let member = assert(srcMembers.get(memberName));\n destMembers.set(memberName, member);\n }\n }\n}\n\n/** Mangles the internal name of an element with the specified name that is a child of the given parent. */\nexport function mangleInternalName(\n name: string,\n parent: Element,\n isInstance: bool,\n asGlobal: bool = false\n): string {\n switch (parent.kind) {\n case ElementKind.File: {\n if (asGlobal) return name;\n return parent.internalName + PATH_DELIMITER + name;\n }\n case ElementKind.Function: {\n if (asGlobal) return name;\n assert(!isInstance);\n return parent.internalName + INNER_DELIMITER + name;\n }\n case ElementKind.PropertyPrototype: // properties are just containers\n case ElementKind.Property: { //\n parent = parent.parent;\n // fall-through\n }\n default: {\n return (\n mangleInternalName(parent.name, parent.parent, parent.is(CommonFlags.Instance), asGlobal) +\n (isInstance ? INSTANCE_DELIMITER : STATIC_DELIMITER) + name\n );\n }\n }\n}\n\n// Cached default parameter names used where names are unknown.\nlet cachedDefaultParameterNames: string[] = [];\n\n/** Gets the cached default parameter name for the specified index. */\nexport function getDefaultParameterName(index: i32): string {\n for (let i = cachedDefaultParameterNames.length; i <= index; ++i) {\n cachedDefaultParameterNames.push(`$${i}`);\n }\n return cachedDefaultParameterNames[index];\n}\n","/// \n\nimport { HASH } from \"./util/hash\";\n\n// A deterministic hash set based on CloseTable from https://github.com/jorendorff/dht\n\n// @ts-ignore: decorator\n@inline const INITIAL_CAPACITY = 4;\n\n// @ts-ignore: decorator\n@inline const FILL_FACTOR_N = 8;\n\n// @ts-ignore: decorator\n@inline const FILL_FACTOR_D = 3;\n\n// @ts-ignore: decorator\n@inline const FREE_FACTOR_N = 3;\n\n// @ts-ignore: decorator\n@inline const FREE_FACTOR_D = 4;\n\n/** Structure of a set entry. */\n@unmanaged class SetEntry {\n key: K;\n taggedNext: usize; // LSB=1 indicates EMPTY\n}\n\n/** Empty bit. */\n// @ts-ignore: decorator\n@inline const EMPTY: usize = 1 << 0;\n\n/** Size of a bucket. */\n// @ts-ignore: decorator\n@inline const BUCKET_SIZE = sizeof();\n\n/** Computes the alignment of an entry. */\n// @ts-ignore: decorator\n@inline\nfunction ENTRY_ALIGN(): usize {\n // can align to 4 instead of 8 if 32-bit and K is <= 32-bits\n const align = (sizeof() > sizeof() ? sizeof() : sizeof()) - 1;\n return align;\n}\n\n/** Computes the aligned size of an entry. */\n// @ts-ignore: decorator\n@inline\nfunction ENTRY_SIZE(): usize {\n const align = ENTRY_ALIGN();\n const size = (offsetof>() + align) & ~align;\n return size;\n}\n\nexport class Set {\n\n // buckets referencing their respective first entry, usize[bucketsMask + 1]\n private buckets: ArrayBuffer = new ArrayBuffer(INITIAL_CAPACITY * BUCKET_SIZE);\n private bucketsMask: u32 = INITIAL_CAPACITY - 1;\n\n // entries in insertion order, SetEntry[entriesCapacity]\n private entries: ArrayBuffer = new ArrayBuffer(INITIAL_CAPACITY * ENTRY_SIZE());\n private entriesCapacity: i32 = INITIAL_CAPACITY;\n private entriesOffset: i32 = 0;\n private entriesCount: i32 = 0;\n\n constructor() {\n /* nop */\n }\n\n get size(): i32 {\n return this.entriesCount;\n }\n\n clear(): void {\n this.buckets = new ArrayBuffer(INITIAL_CAPACITY * BUCKET_SIZE);\n this.bucketsMask = INITIAL_CAPACITY - 1;\n this.entries = new ArrayBuffer(INITIAL_CAPACITY * ENTRY_SIZE());\n this.entriesCapacity = INITIAL_CAPACITY;\n this.entriesOffset = 0;\n this.entriesCount = 0;\n }\n\n private find(key: T, hashCode: u32): SetEntry | null {\n let entry = load>( // unmanaged!\n changetype(this.buckets) + (hashCode & this.bucketsMask) * BUCKET_SIZE\n );\n while (entry) {\n let taggedNext = entry.taggedNext;\n if (!(taggedNext & EMPTY) && entry.key == key) return entry;\n entry = changetype>(taggedNext & ~EMPTY);\n }\n return null;\n }\n\n @operator(\"[]\")\n has(key: T): bool {\n return this.find(key, HASH(key)) != null;\n }\n\n add(key: T): this {\n let hashCode = HASH(key);\n let entry = this.find(key, hashCode); // unmanaged!\n if (!entry) {\n // check if rehashing is necessary\n if (this.entriesOffset == this.entriesCapacity) {\n this.rehash(\n this.entriesCount < this.entriesCapacity * FREE_FACTOR_N / FREE_FACTOR_D\n ? this.bucketsMask // just rehash if 1/4+ entries are empty\n : (this.bucketsMask << 1) | 1 // grow capacity to next 2^N\n );\n }\n // append new entry\n entry = changetype>(changetype(this.entries) + (this.entriesOffset++) * ENTRY_SIZE());\n entry.key = key;\n if (isManaged()) {\n __link(changetype(this), changetype(key), true);\n }\n ++this.entriesCount;\n // link with previous entry in bucket\n let bucketPtrBase = changetype(this.buckets) + (hashCode & this.bucketsMask) * BUCKET_SIZE;\n entry.taggedNext = load(bucketPtrBase);\n store(bucketPtrBase, changetype(entry));\n }\n return this;\n }\n\n @operator(\"[]=\")\n private __set(key: T, value: bool): void {\n if (value) this.add(key);\n else this.delete(key);\n }\n\n delete(key: T): bool {\n let entry = this.find(key, HASH(key)); // unmanaged!\n if (!entry) return false;\n entry.taggedNext |= EMPTY;\n --this.entriesCount;\n // check if rehashing is appropriate\n let halfBucketsMask = this.bucketsMask >> 1;\n if (\n halfBucketsMask + 1 >= max(INITIAL_CAPACITY, this.entriesCount) &&\n this.entriesCount < this.entriesCapacity * FREE_FACTOR_N / FREE_FACTOR_D\n ) this.rehash(halfBucketsMask);\n return true;\n }\n\n private rehash(newBucketsMask: u32): void {\n let newBucketsCapacity = (newBucketsMask + 1);\n let newBuckets = new ArrayBuffer(newBucketsCapacity * BUCKET_SIZE);\n let newEntriesCapacity = newBucketsCapacity * FILL_FACTOR_N / FILL_FACTOR_D;\n let newEntries = new ArrayBuffer(newEntriesCapacity * ENTRY_SIZE());\n\n // copy old entries to new entries\n let oldPtr = changetype(this.entries);\n let oldEnd = oldPtr + this.entriesOffset * ENTRY_SIZE();\n let newPtr = changetype(newEntries);\n while (oldPtr != oldEnd) {\n let oldEntry = changetype>(oldPtr); // unmanaged!\n if (!(oldEntry.taggedNext & EMPTY)) {\n let newEntry = changetype>(newPtr); // unmanaged!\n let oldEntryKey = oldEntry.key;\n newEntry.key = oldEntryKey;\n let newBucketIndex = HASH(oldEntryKey) & newBucketsMask;\n let newBucketPtrBase = changetype(newBuckets) + newBucketIndex * BUCKET_SIZE;\n newEntry.taggedNext = load(newBucketPtrBase);\n store(newBucketPtrBase, newPtr);\n newPtr += ENTRY_SIZE();\n }\n oldPtr += ENTRY_SIZE();\n }\n\n this.buckets = newBuckets;\n this.bucketsMask = newBucketsMask;\n this.entries = newEntries;\n this.entriesCapacity = newEntriesCapacity;\n this.entriesOffset = this.entriesCount;\n }\n\n values(): T[] {\n // FIXME: this is preliminary, needs iterators/closures\n let start = changetype(this.entries);\n let size = this.entriesOffset;\n let values = new Array(size);\n let length = 0;\n for (let i = 0; i < size; ++i) {\n let entry = changetype>(start + i * ENTRY_SIZE());\n if (!(entry.taggedNext & EMPTY)) {\n unchecked(values[length++] = entry.key);\n }\n }\n values.length = length;\n return values;\n }\n\n toString(): string {\n return \"[object Set]\";\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n __visit(changetype(this.buckets), cookie);\n let entries = changetype(this.entries);\n if (isManaged()) {\n let cur = entries;\n let end = cur + this.entriesOffset * ENTRY_SIZE();\n while (cur < end) {\n let entry = changetype>(cur);\n if (!(entry.taggedNext & EMPTY)) {\n let val = changetype(entry.key);\n if (isNullable()) {\n if (val) __visit(val, cookie);\n } else __visit(val, cookie);\n }\n cur += ENTRY_SIZE();\n }\n }\n __visit(entries, cookie);\n }\n}\n","/**\n * @fileoverview Portable definitions for Binaryen's C-API.\n *\n * tsc uses the .js file next to it, while asc makes it a Wasm import.\n *\n * See: https://github.com/WebAssembly/binaryen/blob/main/src/binaryen-c.h\n *\n * @license Apache-2.0\n */\nmodule \"binaryen\";\n\ntype Ref = usize;\n\nexport type Index = u32;\nexport type ExpressionId = i32;\nexport type FeatureFlags = u32;\nexport type Op = i32;\nexport type ExternalKind = u32;\nexport type SideEffects = u32;\nexport type ExpressionRunnerFlags = u32;\n\nexport type StringRef = Ref;\nexport type Pointer = Ref;\nexport type ArrayRef = Ref;\nexport type TypeRef = Ref;\nexport type HeapTypeRef = Ref;\nexport type PackedType = u32;\nexport type ModuleRef = Ref;\nexport type LiteralRef = Ref;\nexport type ExpressionRef = Ref;\nexport type FunctionRef = Ref;\nexport type ImportRef = Ref;\nexport type ExportRef = Ref;\nexport type GlobalRef = Ref;\nexport type TagRef = Ref;\nexport type TableRef = Ref;\nexport type ElementSegmentRef = Ref;\nexport type RelooperRef = Ref;\nexport type RelooperBlockRef = Ref;\nexport type ExpressionRunnerRef = Ref;\nexport type BinaryenModuleAllocateAndWriteResultRef = Ref;\nexport type TypeBuilderRef = Ref;\nexport type TypeBuilderErrorReason = u32;\nexport type TypeSystem = u32;\n\nexport declare function _BinaryenTypeCreate(types: ArrayRef, numTypes: u32): TypeRef;\nexport declare function _BinaryenTypeArity(type: TypeRef): u32;\nexport declare function _BinaryenTypeExpand(type: TypeRef, typesOut: ArrayRef): void;\nexport declare function _BinaryenTypeGetHeapType(type: TypeRef): HeapTypeRef;\nexport declare function _BinaryenTypeFromHeapType(heapType: HeapTypeRef, nullable: bool): TypeRef;\nexport declare function _BinaryenTypeIsNullable(type: TypeRef): bool;\n\nexport declare function _BinaryenTypeFuncref(): TypeRef;\nexport declare function _BinaryenTypeExternref(): TypeRef;\nexport declare function _BinaryenTypeAnyref(): TypeRef;\nexport declare function _BinaryenTypeEqref(): TypeRef;\nexport declare function _BinaryenTypeStructref(): TypeRef;\nexport declare function _BinaryenTypeArrayref(): TypeRef;\nexport declare function _BinaryenTypeI31ref(): TypeRef;\nexport declare function _BinaryenTypeStringref(): TypeRef;\nexport declare function _BinaryenTypeStringviewWTF8(): TypeRef;\nexport declare function _BinaryenTypeStringviewWTF16(): TypeRef;\nexport declare function _BinaryenTypeStringviewIter(): TypeRef;\nexport declare function _BinaryenTypeNullref(): TypeRef;\nexport declare function _BinaryenTypeNullExternref(): TypeRef;\nexport declare function _BinaryenTypeNullFuncref(): TypeRef;\n\nexport declare function _BinaryenHeapTypeFunc(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeExt(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeAny(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeEq(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeI31(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeStruct(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeArray(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeString(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeStringviewWTF8(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeStringviewWTF16(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeStringviewIter(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeNone(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeNoext(): HeapTypeRef;\nexport declare function _BinaryenHeapTypeNofunc(): HeapTypeRef;\n\nexport declare function _BinaryenHeapTypeIsBasic(heapType: HeapTypeRef): bool;\nexport declare function _BinaryenHeapTypeIsSignature(heapType: HeapTypeRef): bool;\nexport declare function _BinaryenHeapTypeIsStruct(heapType: HeapTypeRef): bool;\nexport declare function _BinaryenHeapTypeIsArray(heapType: HeapTypeRef): bool;\nexport declare function _BinaryenHeapTypeIsBottom(heapType: HeapTypeRef): bool;\nexport declare function _BinaryenHeapTypeGetBottom(heapType: HeapTypeRef): HeapTypeRef;\nexport declare function _BinaryenHeapTypeIsSubType(left: HeapTypeRef, right: HeapTypeRef): bool;\nexport declare function _BinaryenStructTypeGetNumFields(heapType: HeapTypeRef): Index;\nexport declare function _BinaryenStructTypeGetFieldType(heapType: HeapTypeRef, index: Index): TypeRef;\nexport declare function _BinaryenStructTypeGetFieldPackedType(heapType: HeapTypeRef, index: Index): PackedType;\nexport declare function _BinaryenStructTypeIsFieldMutable(heapType: HeapTypeRef, index: Index): bool;\nexport declare function _BinaryenArrayTypeGetElementType(heapType: HeapTypeRef): TypeRef;\nexport declare function _BinaryenArrayTypeGetElementPackedType(heapType: HeapTypeRef): PackedType;\nexport declare function _BinaryenArrayTypeIsElementMutable(heapType: HeapTypeRef): bool;\nexport declare function _BinaryenSignatureTypeGetParams(heapType: HeapTypeRef): TypeRef;\nexport declare function _BinaryenSignatureTypeGetResults(heapType: HeapTypeRef): TypeRef;\n\nexport declare function _BinaryenModuleCreate(): ModuleRef;\nexport declare function _BinaryenModuleDispose(module: ModuleRef): void;\n\nexport declare function _BinaryenSizeofLiteral(): usize;\nexport declare function _BinaryenLiteralInt32(literalOut: LiteralRef, x: i32): void;\nexport declare function _BinaryenLiteralInt64(literalOut: LiteralRef, x: i32, y: i32): void;\nexport declare function _BinaryenLiteralFloat32(literalOut: LiteralRef, x: f32): void;\nexport declare function _BinaryenLiteralFloat64(literalOut: LiteralRef, x: f64): void;\nexport declare function _BinaryenLiteralVec128(literalOut: LiteralRef, x: ArrayRef): void;\nexport declare function _BinaryenLiteralFloat32Bits(literalOut: LiteralRef, x: i32): void;\nexport declare function _BinaryenLiteralFloat64Bits(literalOut: LiteralRef, x: i32, y: i32): void;\n\nexport declare function _BinaryenExpressionGetId(expr: ExpressionRef): ExpressionId;\nexport declare function _BinaryenExpressionGetType(expr: ExpressionRef): TypeRef;\nexport declare function _BinaryenExpressionSetType(expr: ExpressionRef, type: TypeRef): void;\nexport declare function _BinaryenExpressionPrint(expr: ExpressionRef): void;\nexport declare function _BinaryenExpressionCopy(expr: ExpressionRef, module: ModuleRef): ExpressionRef;\nexport declare function _BinaryenExpressionFinalize(expr: ExpressionRef): void;\n\nexport declare function _BinaryenBlock(module: ModuleRef, name: StringRef, childExprs: ArrayRef, numChildren: Index, type: TypeRef): ExpressionRef;\nexport declare function _BinaryenBlockGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenBlockSetName(expr: ExpressionRef, name: StringRef): void;\nexport declare function _BinaryenBlockGetNumChildren(expr: ExpressionRef): Index;\nexport declare function _BinaryenBlockGetChildAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenBlockSetChildAt(expr: ExpressionRef, index: Index, childExpr: ExpressionRef): void;\nexport declare function _BinaryenBlockAppendChild(expr: ExpressionRef, childExpr: ExpressionRef): Index;\nexport declare function _BinaryenBlockInsertChildAt(expr: ExpressionRef, index: Index, childExpr: ExpressionRef): void;\nexport declare function _BinaryenBlockRemoveChildAt(expr: ExpressionRef, index: Index): ExpressionRef;\n\nexport declare function _BinaryenIf(module: ModuleRef, conditionExpr: ExpressionRef, ifTrueExpr: ExpressionRef, ifFalseExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenIfGetCondition(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenIfSetCondition(expr: ExpressionRef, conditionExpr: ExpressionRef): void;\nexport declare function _BinaryenIfGetIfTrue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenIfSetIfTrue(expr: ExpressionRef, ifTrueExpr: ExpressionRef): void;\nexport declare function _BinaryenIfGetIfFalse(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenIfSetIfFalse(expr: ExpressionRef, ifFalseExpr: ExpressionRef): void;\n\nexport declare function _BinaryenLoop(module: ModuleRef, name: StringRef, bodyExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenLoopGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenLoopSetName(expr: ExpressionRef, name: StringRef): void;\nexport declare function _BinaryenLoopGetBody(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenLoopSetBody(expr: ExpressionRef, bodyExpr: ExpressionRef): void;\n\nexport declare function _BinaryenBreak(module: ModuleRef, name: StringRef, conditionExpr: ExpressionRef, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBreakGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenBreakSetName(expr: ExpressionRef, name: StringRef): void;\nexport declare function _BinaryenBreakGetCondition(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBreakSetCondition(expr: ExpressionRef, conditionExpr: ExpressionRef): void;\nexport declare function _BinaryenBreakGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBreakSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenSwitch(module: ModuleRef, names: ArrayRef, numNames: Index, defaultName: StringRef, conditionExpr: ExpressionRef, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSwitchGetNumNames(expr: ExpressionRef): Index;\nexport declare function _BinaryenSwitchGetNameAt(expr: ExpressionRef, index: Index): StringRef;\nexport declare function _BinaryenSwitchSetNameAt(expr: ExpressionRef, index: Index, name: StringRef): void;\nexport declare function _BinaryenSwitchAppendName(expr: ExpressionRef, name: StringRef): Index;\nexport declare function _BinaryenSwitchInsertNameAt(expr: ExpressionRef, index: Index, name: StringRef): void;\nexport declare function _BinaryenSwitchRemoveNameAt(expr: ExpressionRef, index: Index): StringRef;\nexport declare function _BinaryenSwitchGetDefaultName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenSwitchSetDefaultName(expr: ExpressionRef, defaultName: StringRef): void;\nexport declare function _BinaryenSwitchGetCondition(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSwitchSetCondition(expr: ExpressionRef, conditionExpr: ExpressionRef): void;\nexport declare function _BinaryenSwitchGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSwitchSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenCall(module: ModuleRef, targetName: StringRef, operandExprs: ArrayRef, numOperands: Index, returnType: TypeRef): ExpressionRef;\nexport declare function _BinaryenCallGetTarget(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenCallSetTarget(expr: ExpressionRef, targetName: StringRef): void;\nexport declare function _BinaryenCallGetNumOperands(expr: ExpressionRef): Index;\nexport declare function _BinaryenCallGetOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenCallSetOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenCallAppendOperand(expr: ExpressionRef, operandExpr: ExpressionRef): Index;\nexport declare function _BinaryenCallInsertOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenCallRemoveOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenCallIsReturn(expr: ExpressionRef): bool;\nexport declare function _BinaryenCallSetReturn(expr: ExpressionRef, isReturn: bool): void;\n// ^ with return = true\nexport declare function _BinaryenReturnCall(module: ModuleRef, targetName: StringRef, operandExprs: ArrayRef, numOperands: Index, returnType: TypeRef): ExpressionRef;\n\nexport declare function _BinaryenCallIndirect(module: ModuleRef, table: StringRef, targetExpr: ExpressionRef, operandExprs: ArrayRef, numOperands: Index, params: TypeRef, results: TypeRef): ExpressionRef;\nexport declare function _BinaryenCallIndirectGetTable(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenCallIndirectSetTable(expr: ExpressionRef, table: StringRef): void;\nexport declare function _BinaryenCallIndirectGetTarget(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenCallIndirectSetTarget(expr: ExpressionRef, targetExpr: ExpressionRef): void;\nexport declare function _BinaryenCallIndirectGetNumOperands(expr: ExpressionRef): Index;\nexport declare function _BinaryenCallIndirectGetOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenCallIndirectSetOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenCallIndirectAppendOperand(expr: ExpressionRef, operandExpr: ExpressionRef): Index;\nexport declare function _BinaryenCallIndirectInsertOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenCallIndirectRemoveOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenCallIndirectIsReturn(expr: ExpressionRef): bool;\nexport declare function _BinaryenCallIndirectSetReturn(expr: ExpressionRef, isReturn: bool): void;\n// ^ with return = true\nexport declare function _BinaryenReturnCallIndirect(module: ModuleRef, table: StringRef, targetExpr: ExpressionRef, operandExprs: ArrayRef, numOperands: Index, params: TypeRef, results: TypeRef): ExpressionRef;\n\nexport declare function _BinaryenLocalGet(module: ModuleRef, index: Index, type: TypeRef): ExpressionRef;\nexport declare function _BinaryenLocalGetGetIndex(expr: ExpressionRef): Index;\nexport declare function _BinaryenLocalGetSetIndex(expr: ExpressionRef, index: Index): void;\n\nexport declare function _BinaryenLocalSet(module: ModuleRef, index: Index, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenLocalSetIsTee(expr: ExpressionRef): bool;\nexport declare function _BinaryenLocalSetGetIndex(expr: ExpressionRef): Index;\nexport declare function _BinaryenLocalSetSetIndex(expr: ExpressionRef, index: Index): void;\nexport declare function _BinaryenLocalSetGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenLocalSetSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n// ^ with type != none\nexport declare function _BinaryenLocalTee(module: ModuleRef, index: Index, valueExpr: ExpressionRef, type: TypeRef): ExpressionRef;\n\nexport declare function _BinaryenGlobalGet(module: ModuleRef, name: StringRef, type: TypeRef): ExpressionRef;\nexport declare function _BinaryenGlobalGetGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenGlobalGetSetName(expr: ExpressionRef, name: StringRef): void;\n\nexport declare function _BinaryenGlobalSet(module: ModuleRef, name: StringRef, value: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenGlobalSetGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenGlobalSetSetName(expr: ExpressionRef, name: StringRef): void;\nexport declare function _BinaryenGlobalSetGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenGlobalSetSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenMemorySize(module: ModuleRef, memoryName: StringRef, memoryIs64: bool): ExpressionRef;\n\nexport declare function _BinaryenMemoryGrow(module: ModuleRef, delta: ExpressionRef, memoryName: StringRef, memoryIs64: bool): ExpressionRef;\nexport declare function _BinaryenMemoryGrowGetDelta(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryGrowSetDelta(expr: ExpressionRef, delta: ExpressionRef): void;\n\nexport declare function _BinaryenLoad(module: ModuleRef, bytes: u32, signed: bool, offset: u32, align: u32, type: TypeRef, ptrExpr: ExpressionRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenLoadIsAtomic(expr: ExpressionRef): bool;\nexport declare function _BinaryenLoadSetAtomic(expr: ExpressionRef, isAtomic: bool): void;\nexport declare function _BinaryenLoadIsSigned(expr: ExpressionRef): bool;\nexport declare function _BinaryenLoadSetSigned(expr: ExpressionRef, isSigned: bool): void;\nexport declare function _BinaryenLoadGetOffset(expr: ExpressionRef): u32;\nexport declare function _BinaryenLoadSetOffset(expr: ExpressionRef, offset: u32): void;\nexport declare function _BinaryenLoadGetBytes(expr: ExpressionRef): u32;\nexport declare function _BinaryenLoadSetBytes(expr: ExpressionRef, bytes: u32): void;\nexport declare function _BinaryenLoadGetAlign(expr: ExpressionRef): u32;\nexport declare function _BinaryenLoadSetAlign(expr: ExpressionRef, align: u32): void;\nexport declare function _BinaryenLoadGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenLoadSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\n// ^ with atomic = true\nexport declare function _BinaryenAtomicLoad(module: ModuleRef, bytes: Index, offset: Index, type: TypeRef, ptrExpr: ExpressionRef, memoryName: StringRef): ExpressionRef;\n\nexport declare function _BinaryenStore(module: ModuleRef, bytes: u32, offset: u32, align: u32, ptrExpr: ExpressionRef, valueExpr: ExpressionRef, type: TypeRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenStoreIsAtomic(expr: ExpressionRef): bool;\nexport declare function _BinaryenStoreSetAtomic(expr: ExpressionRef, isAtomic: bool): void;\nexport declare function _BinaryenStoreGetBytes(expr: ExpressionRef): u32;\nexport declare function _BinaryenStoreSetBytes(expr: ExpressionRef, bytes: u32): void;\nexport declare function _BinaryenStoreGetOffset(expr: ExpressionRef): u32;\nexport declare function _BinaryenStoreSetOffset(expr: ExpressionRef, offset: u32): void;\nexport declare function _BinaryenStoreGetAlign(expr: ExpressionRef): u32;\nexport declare function _BinaryenStoreSetAlign(expr: ExpressionRef, align: u32): void;\nexport declare function _BinaryenStoreGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStoreSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenStoreGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStoreSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\nexport declare function _BinaryenStoreGetValueType(expr: ExpressionRef): TypeRef;\nexport declare function _BinaryenStoreSetValueType(expr: ExpressionRef, valueType: TypeRef): void;\n// ^ with atomic = true\nexport declare function _BinaryenAtomicStore(module: ModuleRef, bytes: Index, offset: Index, ptrExpr: ExpressionRef, valueExpr: ExpressionRef, type: TypeRef, memoryName: StringRef): ExpressionRef;\n\nexport declare function _BinaryenConst(module: ModuleRef, value: LiteralRef): ExpressionRef;\nexport declare function _BinaryenConstGetValueI32(expr: ExpressionRef): i32;\nexport declare function _BinaryenConstSetValueI32(expr: ExpressionRef, value: i32): void;\nexport declare function _BinaryenConstGetValueI64Low(expr: ExpressionRef): i32;\nexport declare function _BinaryenConstSetValueI64Low(expr: ExpressionRef, value: i32): void;\nexport declare function _BinaryenConstGetValueI64High(expr: ExpressionRef): i32;\nexport declare function _BinaryenConstSetValueI64High(expr: ExpressionRef, value: i32): void;\nexport declare function _BinaryenConstGetValueF32(expr: ExpressionRef): f32;\nexport declare function _BinaryenConstSetValueF32(expr: ExpressionRef, value: f32): void;\nexport declare function _BinaryenConstGetValueF64(expr: ExpressionRef): f64;\nexport declare function _BinaryenConstSetValueF64(expr: ExpressionRef, value: f64): void;\nexport declare function _BinaryenConstGetValueV128(expr: ExpressionRef, valueOut: ArrayRef): void;\nexport declare function _BinaryenConstSetValueV128(expr: ExpressionRef, value: ArrayRef): void;\n\nexport declare function _BinaryenUnary(module: ModuleRef, op: Op, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenUnaryGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenUnarySetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenUnaryGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenUnarySetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenBinary(module: ModuleRef, op: Op, leftExpr: ExpressionRef, rightExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBinaryGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenBinarySetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenBinaryGetLeft(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBinarySetLeft(expr: ExpressionRef, leftExpr: ExpressionRef): void;\nexport declare function _BinaryenBinaryGetRight(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBinarySetRight(expr: ExpressionRef, rightExpr: ExpressionRef): void;\n\nexport declare function _BinaryenSelect(module: ModuleRef, conditionExpr: ExpressionRef, ifTrueExpr: ExpressionRef, ifFalseExpr: ExpressionRef, type: TypeRef): ExpressionRef;\nexport declare function _BinaryenSelectGetIfTrue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSelectSetIfTrue(expr: ExpressionRef, ifTrueExpr: ExpressionRef): void;\nexport declare function _BinaryenSelectGetIfFalse(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSelectSetIfFalse(expr: ExpressionRef, ifFalseExpr: ExpressionRef): void;\nexport declare function _BinaryenSelectGetCondition(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSelectSetCondition(expr: ExpressionRef, conditionExpr: ExpressionRef): void;\n\nexport declare function _BinaryenDrop(module: ModuleRef, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenDropGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenDropSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenReturn(module: ModuleRef, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenReturnGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenReturnSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenNop(module: ModuleRef): ExpressionRef;\n\nexport declare function _BinaryenUnreachable(module: ModuleRef): ExpressionRef;\n\nexport declare function _BinaryenAtomicRMW(module: ModuleRef, op: Op, bytes: u32, offset: u32, ptrExpr: ExpressionRef, valueExpr: ExpressionRef, type: TypeRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenAtomicRMWGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenAtomicRMWSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenAtomicRMWGetBytes(expr: ExpressionRef): u32;\nexport declare function _BinaryenAtomicRMWSetBytes(expr: ExpressionRef, bytes: u32): void;\nexport declare function _BinaryenAtomicRMWGetOffset(expr: ExpressionRef): u32;\nexport declare function _BinaryenAtomicRMWSetOffset(expr: ExpressionRef, offset: u32): void;\nexport declare function _BinaryenAtomicRMWGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicRMWSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicRMWGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicRMWSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenAtomicCmpxchg(module: ModuleRef, bytes: u32, offset: u32, ptrExpr: ExpressionRef, expectedExpr: ExpressionRef, replacementExpr: ExpressionRef, type: TypeRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenAtomicCmpxchgGetBytes(expr: ExpressionRef): u32;\nexport declare function _BinaryenAtomicCmpxchgSetBytes(expr: ExpressionRef, bytes: u32): void;\nexport declare function _BinaryenAtomicCmpxchgGetOffset(expr: ExpressionRef): u32;\nexport declare function _BinaryenAtomicCmpxchgSetOffset(expr: ExpressionRef, offset: u32): void;\nexport declare function _BinaryenAtomicCmpxchgGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicCmpxchgSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicCmpxchgGetExpected(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicCmpxchgSetExpected(expr: ExpressionRef, expectedExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicCmpxchgGetReplacement(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicCmpxchgSetReplacement(expr: ExpressionRef, replacementExpr: ExpressionRef): void;\n\nexport declare function _BinaryenAtomicWait(module: ModuleRef, ptrExpr: ExpressionRef, expectedExpr: ExpressionRef, timeoutExpr: ExpressionRef, expectedType: TypeRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenAtomicWaitGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicWaitSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicWaitGetExpected(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicWaitSetExpected(expr: ExpressionRef, expectedExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicWaitGetTimeout(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicWaitSetTimeout(expr: ExpressionRef, timeoutExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicWaitGetExpectedType(expr: ExpressionRef): TypeRef;\nexport declare function _BinaryenAtomicWaitSetExpectedType(expr: ExpressionRef, expectedType: TypeRef): void;\n\nexport declare function _BinaryenAtomicNotify(module: ModuleRef, ptrExpr: ExpressionRef, notifyCountExpr: ExpressionRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenAtomicNotifyGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicNotifySetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenAtomicNotifyGetNotifyCount(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenAtomicNotifySetNotifyCount(expr: ExpressionRef, notifyCountExpr: ExpressionRef): void;\n\nexport declare function _BinaryenAtomicFence(module: ModuleRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenAtomicFenceGetOrder(expr: ExpressionRef): u8; // unused\nexport declare function _BinaryenAtomicFenceSetOrder(expr: ExpressionRef, order: u8): void; // unused\n\nexport declare function _BinaryenSIMDExtract(module: ModuleRef, op: Op, vecExpr: ExpressionRef, index: u8): ExpressionRef;\nexport declare function _BinaryenSIMDExtractGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenSIMDExtractSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenSIMDExtractGetVec(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDExtractSetVec(expr: ExpressionRef, vecExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDExtractGetIndex(expr: ExpressionRef): u8;\nexport declare function _BinaryenSIMDExtractSetIndex(expr: ExpressionRef, index: u8): void;\n\nexport declare function _BinaryenSIMDReplace(module: ModuleRef, op: Op, vecEpr: ExpressionRef, index: u8, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDReplaceGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenSIMDReplaceSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenSIMDReplaceGetVec(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDReplaceSetVec(expr: ExpressionRef, vecExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDReplaceGetIndex(expr: ExpressionRef): u8;\nexport declare function _BinaryenSIMDReplaceSetIndex(expr: ExpressionRef, index: u8): void;\nexport declare function _BinaryenSIMDReplaceGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDReplaceSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenSIMDShuffle(module: ModuleRef, leftExpr: ExpressionRef, rightExpr: ExpressionRef, mask: ArrayRef): ExpressionRef;\nexport declare function _BinaryenSIMDShuffleGetLeft(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDShuffleSetLeft(expr: ExpressionRef, leftExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDShuffleGetRight(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDShuffleSetRight(expr: ExpressionRef, rightExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDShuffleGetMask(expr: ExpressionRef, maskOut: ArrayRef): void;\nexport declare function _BinaryenSIMDShuffleSetMask(expr: ExpressionRef, mask: ArrayRef): void;\n\nexport declare function _BinaryenSIMDTernary(module: ModuleRef, op: Op, aExpr: ExpressionRef, bExpr: ExpressionRef, cExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDTernaryGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenSIMDTernarySetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenSIMDTernaryGetA(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDTernarySetA(expr: ExpressionRef, aExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDTernaryGetB(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDTernarySetB(expr: ExpressionRef, bExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDTernaryGetC(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDTernarySetC(expr: ExpressionRef, cExpr: ExpressionRef): void;\n\nexport declare function _BinaryenSIMDShift(module: ModuleRef, op: Op, vecExpr: ExpressionRef, shiftExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDShiftGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenSIMDShiftSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenSIMDShiftGetVec(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDShiftSetVec(expr: ExpressionRef, vecExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDShiftGetShift(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDShiftSetShift(expr: ExpressionRef, shiftExpr: ExpressionRef): void;\n\nexport declare function _BinaryenSIMDLoad(module: ModuleRef, op: Op, offset: u32, align: u32, ptrExpr: ExpressionRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenSIMDLoadGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenSIMDLoadSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenSIMDLoadGetOffset(expr: ExpressionRef): u32;\nexport declare function _BinaryenSIMDLoadSetOffset(expr: ExpressionRef, offset: u32): void;\nexport declare function _BinaryenSIMDLoadGetAlign(expr: ExpressionRef): u32;\nexport declare function _BinaryenSIMDLoadSetAlign(expr: ExpressionRef, align: u32): void;\nexport declare function _BinaryenSIMDLoadGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDLoadSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\n\nexport declare function _BinaryenSIMDLoadStoreLane(module: ModuleRef, op: Op, offset: u32, align: u32, index: u8, ptr: ExpressionRef, vec: ExpressionRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenSIMDLoadStoreLaneGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenSIMDLoadStoreLaneSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenSIMDLoadStoreLaneGetOffset(expr: ExpressionRef): u32;\nexport declare function _BinaryenSIMDLoadStoreLaneSetOffset(expr: ExpressionRef, offset: u32): void;\nexport declare function _BinaryenSIMDLoadStoreLaneGetAlign(expr: ExpressionRef): u32;\nexport declare function _BinaryenSIMDLoadStoreLaneSetAlign(expr: ExpressionRef, align: u32): void;\nexport declare function _BinaryenSIMDLoadStoreLaneGetIndex(expr: ExpressionRef): u8;\nexport declare function _BinaryenSIMDLoadStoreLaneSetIndex(expr: ExpressionRef, index: u8): void;\nexport declare function _BinaryenSIMDLoadStoreLaneGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDLoadStoreLaneSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDLoadStoreLaneGetVec(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenSIMDLoadStoreLaneSetVec(expr: ExpressionRef, vecExpr: ExpressionRef): void;\nexport declare function _BinaryenSIMDLoadStoreLaneIsStore(expr: ExpressionRef): bool;\n\nexport declare function _BinaryenMemoryInit(module: ModuleRef, segmentIndex: u32, destExpr: ExpressionRef, offsetExpr: ExpressionRef, sizeExpr: ExpressionRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenMemoryInitGetSegment(expr: ExpressionRef): u32;\nexport declare function _BinaryenMemoryInitSetSegment(expr: ExpressionRef, segmentIndex: u32): void;\nexport declare function _BinaryenMemoryInitGetDest(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryInitSetDest(expr: ExpressionRef, destExpr: ExpressionRef): void;\nexport declare function _BinaryenMemoryInitGetOffset(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryInitSetOffset(expr: ExpressionRef, offsetExpr: ExpressionRef): void;\nexport declare function _BinaryenMemoryInitGetSize(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryInitSetSize(expr: ExpressionRef, sizeExpr: ExpressionRef): void;\n\nexport declare function _BinaryenDataDrop(module: ModuleRef, segmentIndex: u32): ExpressionRef;\nexport declare function _BinaryenDataDropGetSegment(expr: ExpressionRef): u32;\nexport declare function _BinaryenDataDropSetSegment(expr: ExpressionRef, segmentIndex: u32): void;\n\nexport declare function _BinaryenMemoryCopy(module: ModuleRef, destExpr: ExpressionRef, sourceExpr: ExpressionRef, sizeExpr: ExpressionRef, destMemoryName: StringRef, sourceMemoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenMemoryCopyGetDest(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryCopySetDest(expr: ExpressionRef, destExpr: ExpressionRef): void;\nexport declare function _BinaryenMemoryCopyGetSource(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryCopySetSource(expr: ExpressionRef, sourceExpr: ExpressionRef): void;\nexport declare function _BinaryenMemoryCopyGetSize(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryCopySetSize(expr: ExpressionRef, sizeExpr: ExpressionRef): void;\n\nexport declare function _BinaryenMemoryFill(module: ModuleRef, destExpr: ExpressionRef, valueExpr: ExpressionRef, sizeExpr: ExpressionRef, memoryName: StringRef): ExpressionRef;\nexport declare function _BinaryenMemoryFillGetDest(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryFillSetDest(expr: ExpressionRef, destExpr: ExpressionRef): void;\nexport declare function _BinaryenMemoryFillGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryFillSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\nexport declare function _BinaryenMemoryFillGetSize(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenMemoryFillSetSize(expr: ExpressionRef, sizeExpr: ExpressionRef): void;\n\nexport declare function _BinaryenRefNull(module: ModuleRef, type: TypeRef): ExpressionRef;\n\nexport declare function _BinaryenRefIsNull(module: ModuleRef, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefIsNullGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefIsNullSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenRefAs(module: ModuleRef, op: Op, valueExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefAsGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenRefAsSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenRefAsGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefAsSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenRefFunc(module: ModuleRef, funcName: StringRef, type: TypeRef): ExpressionRef;\nexport declare function _BinaryenRefFuncGetFunc(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenRefFuncSetFunc(expr: ExpressionRef, funcName: StringRef): void;\n\nexport declare function _BinaryenRefEq(module: ModuleRef, leftExpr: ExpressionRef, rightExpr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefEqGetLeft(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefEqSetLeft(expr: ExpressionRef, leftExpr: ExpressionRef): void;\nexport declare function _BinaryenRefEqGetRight(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefEqSetRight(expr: ExpressionRef, rightExpr: ExpressionRef): void;\n\nexport declare function _BinaryenTableGet(module: ModuleRef, name: StringRef, index: ExpressionRef, type: TypeRef): ExpressionRef;\nexport declare function _BinaryenTableGetGetTable(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenTableGetSetTable(expr: ExpressionRef, table: StringRef): void;\nexport declare function _BinaryenTableGetGetIndex(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableGetSetIndex(expr: ExpressionRef, index: ExpressionRef): void;\n\nexport declare function _BinaryenTableSet(module: ModuleRef, name: StringRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableSetGetTable(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenTableSetSetTable(expr: ExpressionRef, table: StringRef): void;\nexport declare function _BinaryenTableSetGetIndex(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableSetSetIndex(expr: ExpressionRef, index: ExpressionRef): void;\nexport declare function _BinaryenTableSetGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableSetSetValue(expr: ExpressionRef, value: ExpressionRef): void;\n\nexport declare function _BinaryenTableSize(module: ModuleRef, name: StringRef): ExpressionRef;\nexport declare function _BinaryenTableSizeGetTable(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenTableSizeSetTable(expr: ExpressionRef, table: StringRef): void;\n\nexport declare function _BinaryenTableGrow(module: ModuleRef, name: StringRef, value: ExpressionRef, delta: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableGrowGetTable(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenTableGrowSetTable(expr: ExpressionRef, table: StringRef): void;\nexport declare function _BinaryenTableGrowGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableGrowSetValue(expr: ExpressionRef, value: ExpressionRef): void;\nexport declare function _BinaryenTableGrowGetDelta(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTableGrowSetDelta(expr: ExpressionRef, delta: ExpressionRef): void;\n\nexport declare function _BinaryenTry(module: ModuleRef, name: StringRef, bodyExpr: ExpressionRef, catchTags: ArrayRef, numCatchTags: Index, catchBodies: ArrayRef, numCatchBodies: Index, delegateTarget: StringRef): ExpressionRef;\nexport declare function _BinaryenTryGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenTrySetName(expr: ExpressionRef, name: StringRef): void;\nexport declare function _BinaryenTryGetBody(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTrySetBody(expr: ExpressionRef, bodyExpr: ExpressionRef): void;\nexport declare function _BinaryenTryGetNumCatchTags(expr: ExpressionRef): Index;\nexport declare function _BinaryenTryGetNumCatchBodies(expr: ExpressionRef): Index;\nexport declare function _BinaryenTryGetCatchTagAt(expr: ExpressionRef, index: Index): StringRef;\nexport declare function _BinaryenTrySetCatchTagAt(expr: ExpressionRef, index: Index, catchTag: StringRef): void;\nexport declare function _BinaryenTryAppendCatchTag(expr: ExpressionRef, catchTag: StringRef): Index;\nexport declare function _BinaryenTryInsertCatchTagAt(expr: ExpressionRef, index: Index, catchTag: StringRef): void;\nexport declare function _BinaryenTryRemoveCatchTagAt(expr: ExpressionRef, index: Index): StringRef;\nexport declare function _BinaryenTryGetCatchBodyAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenTrySetCatchBodyAt(expr: ExpressionRef, index: Index, catchExpr: ExpressionRef): void;\nexport declare function _BinaryenTryAppendCatchBody(expr: ExpressionRef, catchExpr: ExpressionRef): Index;\nexport declare function _BinaryenTryInsertCatchBodyAt(expr: ExpressionRef, index: Index, catchExpr: ExpressionRef): void;\nexport declare function _BinaryenTryRemoveCatchBodyAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenTryHasCatchAll(expr: ExpressionRef): bool;\nexport declare function _BinaryenTryGetDelegateTarget(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenTrySetDelegateTarget(expr: ExpressionRef, delegateTarget: StringRef): void;\nexport declare function _BinaryenTryIsDelegate(expr: ExpressionRef): bool;\n\nexport declare function _BinaryenThrow(module: ModuleRef, tagName: StringRef, operands: ArrayRef, numOperands: Index): ExpressionRef;\nexport declare function _BinaryenThrowGetTag(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenThrowSetTag(expr: ExpressionRef, tagName: StringRef): void;\nexport declare function _BinaryenThrowGetNumOperands(expr: ExpressionRef): Index;\nexport declare function _BinaryenThrowGetOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenThrowSetOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenThrowAppendOperand(expr: ExpressionRef, operandExpr: ExpressionRef): Index;\nexport declare function _BinaryenThrowInsertOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenThrowRemoveOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\n\nexport declare function _BinaryenRethrow(module: ModuleRef, target: StringRef): ExpressionRef;\nexport declare function _BinaryenRethrowGetTarget(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenRethrowSetDepth(expr: ExpressionRef, target: StringRef): void;\n\nexport declare function _BinaryenTupleMake(module: ModuleRef, operandExprs: ArrayRef, numOperands: Index): ExpressionRef;\nexport declare function _BinaryenTupleMakeGetNumOperands(expr: ExpressionRef): Index;\nexport declare function _BinaryenTupleMakeGetOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenTupleMakeSetOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenTupleMakeAppendOperand(expr: ExpressionRef, operandExpr: ExpressionRef): Index;\nexport declare function _BinaryenTupleMakeInsertOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenTupleMakeRemoveOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\n\nexport declare function _BinaryenTupleExtract(module: ModuleRef, tupleExpr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenTupleExtractGetTuple(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenTupleExtractSetTuple(expr: ExpressionRef, tupleExpr: ExpressionRef): void;\nexport declare function _BinaryenTupleExtractGetIndex(expr: ExpressionRef): Index;\nexport declare function _BinaryenTupleExtractSetIndex(expr: ExpressionRef, index: Index): void;\n\nexport declare function _BinaryenPop(module: ModuleRef, type: TypeRef): ExpressionRef;\n\nexport declare function _BinaryenI31New(module: ModuleRef, value: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenI31NewGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenI31NewSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenI31Get(module: ModuleRef, i31Expr: ExpressionRef, signed: bool): ExpressionRef;\nexport declare function _BinaryenI31GetGetI31(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenI31GetSetI31(expr: ExpressionRef, i31Expr: ExpressionRef): void;\nexport declare function _BinaryenI31GetIsSigned(expr: ExpressionRef): bool;\nexport declare function _BinaryenI31GetSetSigned(expr: ExpressionRef, signed: bool): void;\n\nexport declare function _BinaryenCallRef(module: ModuleRef, target: ExpressionRef, operands: ArrayRef, numOperands: Index, type: TypeRef, isReturn: bool): ExpressionRef;\nexport declare function _BinaryenCallRefGetNumOperands(expr: ExpressionRef): Index;\nexport declare function _BinaryenCallRefGetOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenCallRefSetOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenCallRefAppendOperand(expr: ExpressionRef, operandExpr: ExpressionRef): Index;\nexport declare function _BinaryenCallRefInsertOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenCallRefRemoveOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenCallRefGetTarget(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenCallRefSetTarget(expr: ExpressionRef, targetExpr: ExpressionRef): void;\nexport declare function _BinaryenCallRefIsReturn(expr: ExpressionRef): bool;\nexport declare function _BinaryenCallRefSetReturn(expr: ExpressionRef, isReturn: bool): void;\n\nexport declare function _BinaryenRefTest(module: ModuleRef, refExpr: ExpressionRef, castType: HeapTypeRef): ExpressionRef;\nexport declare function _BinaryenRefTestGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefTestSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenRefTestGetCastType(expr: ExpressionRef): HeapTypeRef;\nexport declare function _BinaryenRefTestSetCastType(expr: ExpressionRef, castType: HeapTypeRef): void;\n\nexport declare function _BinaryenRefCast(module: ModuleRef, refExpr: ExpressionRef, intendedType: HeapTypeRef): ExpressionRef;\nexport declare function _BinaryenRefCastGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenRefCastSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\n\nexport declare function _BinaryenBrOn(module: ModuleRef, op: Op, name: StringRef, ref: ExpressionRef, castType: HeapTypeRef): ExpressionRef;\nexport declare function _BinaryenBrOnGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenBrOnSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenBrOnGetName(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenBrOnSetName(expr: ExpressionRef, nameStr: StringRef): void;\nexport declare function _BinaryenBrOnGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenBrOnSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenBrOnGetCastType(expr: ExpressionRef): HeapTypeRef;\nexport declare function _BinaryenBrOnSetCastType(expr: ExpressionRef, castType: HeapTypeRef): void;\n\nexport declare function _BinaryenStructNew(module: ModuleRef, operands: ArrayRef, numOperands: Index, type: HeapTypeRef): ExpressionRef;\nexport declare function _BinaryenStructNewGetNumOperands(expr: ExpressionRef): Index;\nexport declare function _BinaryenStructNewGetOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenStructNewSetOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenStructNewAppendOperand(expr: ExpressionRef, operandExpr: ExpressionRef): Index;\nexport declare function _BinaryenStructNewInsertOperandAt(expr: ExpressionRef, index: Index, operandExpr: ExpressionRef): void;\nexport declare function _BinaryenStructNewRemoveOperandAt(expr: ExpressionRef, index: Index): ExpressionRef;\n\nexport declare function _BinaryenStructGet(module: ModuleRef, index: Index, ref: ExpressionRef, type: TypeRef, signed: bool): ExpressionRef;\nexport declare function _BinaryenStructGetGetIndex(expr: ExpressionRef): Index;\nexport declare function _BinaryenStructGetSetIndex(expr: ExpressionRef, index: Index): void;\nexport declare function _BinaryenStructGetGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStructGetSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStructGetIsSigned(expr: ExpressionRef): bool;\nexport declare function _BinaryenStructGetSetSigned(expr: ExpressionRef, signed: bool): void;\n\nexport declare function _BinaryenStructSet(module: ModuleRef, index: Index, ref: ExpressionRef, value: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStructSetGetIndex(expr: ExpressionRef): Index;\nexport declare function _BinaryenStructSetSetIndex(expr: ExpressionRef, index: Index): void;\nexport declare function _BinaryenStructSetGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStructSetSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStructSetGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStructSetSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenArrayNew(module: ModuleRef, type: HeapTypeRef, size: ExpressionRef, init: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayNewGetInit(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayNewSetInit(expr: ExpressionRef, initExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayNewGetSize(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayNewSetSize(expr: ExpressionRef, sizeExpr: ExpressionRef): void;\n\n// TODO: BinaryenArrayNewSeg\n\nexport declare function _BinaryenArrayInit(module: ModuleRef, type: HeapTypeRef, values: ArrayRef, numValues: Index): ExpressionRef;\nexport declare function _BinaryenArrayInitGetNumValues(expr: ExpressionRef): Index;\nexport declare function _BinaryenArrayInitGetValueAt(expr: ExpressionRef, index: Index): ExpressionRef;\nexport declare function _BinaryenArrayInitSetValueAt(expr: ExpressionRef, index: Index, valueExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayInitAppendValue(expr: ExpressionRef, valueExpr: ExpressionRef): Index;\nexport declare function _BinaryenArrayInitInsertValueAt(expr: ExpressionRef, index: Index, valueExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayInitRemoveValueAt(expr: ExpressionRef, index: Index): ExpressionRef;\n\nexport declare function _BinaryenArrayGet(module: ModuleRef, ref: ExpressionRef, index: ExpressionRef, type: TypeRef, signed: bool): ExpressionRef;\nexport declare function _BinaryenArrayGetGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayGetSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayGetGetIndex(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayGetSetIndex(expr: ExpressionRef, indexExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayGetIsSigned(expr: ExpressionRef): bool;\nexport declare function _BinaryenArrayGetSetSigned(expr: ExpressionRef, signed: bool): void;\n\nexport declare function _BinaryenArraySet(module: ModuleRef, ref: ExpressionRef, index: ExpressionRef, value: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArraySetGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArraySetSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenArraySetGetIndex(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArraySetSetIndex(expr: ExpressionRef, indexExpr: ExpressionRef): void;\nexport declare function _BinaryenArraySetGetValue(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArraySetSetValue(expr: ExpressionRef, valueExpr: ExpressionRef): void;\n\nexport declare function _BinaryenArrayLen(module: ModuleRef, ref: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayLenGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayLenSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\n\nexport declare function _BinaryenArrayCopy(module: ModuleRef, destRef: ExpressionRef, destIndex: ExpressionRef, srcRef: ExpressionRef, srcIndex: ExpressionRef, length: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayCopyGetDestRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayCopySetDestRef(expr: ExpressionRef, destRefExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayCopyGetDestIndex(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayCopySetDestIndex(expr: ExpressionRef, destIndexExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayCopyGetSrcRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayCopySetSrcRef(expr: ExpressionRef, srcRefExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayCopyGetSrcIndex(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayCopySetSrcIndex(expr: ExpressionRef, srcIndexExpr: ExpressionRef): void;\nexport declare function _BinaryenArrayCopyGetLength(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenArrayCopySetLength(expr: ExpressionRef, lengthExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringNew(module: ModuleRef, op: Op, ptr: ExpressionRef, length: ExpressionRef, start: ExpressionRef, end: ExpressionRef, isTry: bool): ExpressionRef;\nexport declare function _BinaryenStringNewGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringNewSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringNewGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringNewSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenStringNewGetLength(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringNewSetLength(expr: ExpressionRef, lengthExpr: ExpressionRef): void;\nexport declare function _BinaryenStringNewGetStart(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringNewSetStart(expr: ExpressionRef, startExpr: ExpressionRef): void;\nexport declare function _BinaryenStringNewGetEnd(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringNewSetEnd(expr: ExpressionRef, endExpr: ExpressionRef): void;\nexport declare function _BinaryenStringNewIsTry(expr: ExpressionRef): bool;\nexport declare function _BinaryenStringNewSetTry(expr: ExpressionRef, isTry: bool): void;\n\nexport declare function _BinaryenStringConst(module: ExpressionRef, name: StringRef): ExpressionRef;\nexport declare function _BinaryenStringConstGetString(expr: ExpressionRef): StringRef;\nexport declare function _BinaryenStringConstSetString(expr: ExpressionRef, string: StringRef): void;\n\nexport declare function _BinaryenStringMeasure(module: ExpressionRef, op: Op, ref: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringMeasureGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringMeasureSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringMeasureGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringMeasureSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringEncode(module: ExpressionRef, op: Op, ref: ExpressionRef, ptr: ExpressionRef, start: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEncodeGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringEncodeSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringEncodeGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEncodeSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStringEncodeGetPtr(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEncodeSetPtr(expr: ExpressionRef, ptrExpr: ExpressionRef): void;\nexport declare function _BinaryenStringEncodeGetStart(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEncodeSetStart(expr: ExpressionRef, startExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringConcat(module: ExpressionRef, left: ExpressionRef, right: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringConcatGetLeft(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringConcatSetLeft(expr: ExpressionRef, leftExpr: ExpressionRef): void;\nexport declare function _BinaryenStringConcatGetRight(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringConcatSetRight(expr: ExpressionRef, rightExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringEq(module: ExpressionRef, op: Op, left: ExpressionRef, right: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEqGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringEqSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringEqGetLeft(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEqSetLeft(expr: ExpressionRef, leftExpr: ExpressionRef): void;\nexport declare function _BinaryenStringEqGetRight(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringEqSetRight(expr: ExpressionRef, rightExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringAs(module: ExpressionRef, op: Op, ref: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringAsGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringAsSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringAsGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringAsSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringWTF8Advance(module: ExpressionRef, ref: ExpressionRef, pos: ExpressionRef, bytes: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF8AdvanceGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF8AdvanceSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStringWTF8AdvanceGetPos(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF8AdvanceSetPos(expr: ExpressionRef, posExpr: ExpressionRef): void;\nexport declare function _BinaryenStringWTF8AdvanceGetBytes(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF8AdvanceSetBytes(expr: ExpressionRef, bytesExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringWTF16Get(module: ExpressionRef, ref: ExpressionRef, pos: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF16GetGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF16GetSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStringWTF16GetGetPos(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringWTF16GetSetPos(expr: ExpressionRef, posExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringIterNext(module: ExpressionRef, ref: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringIterNextGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringIterNextSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringIterMove(module: ExpressionRef, op: Op, ref: ExpressionRef, num: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringIterMoveGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringIterMoveSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringIterMoveGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringIterMoveSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStringIterMoveGetNum(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringIterMoveSetNum(expr: ExpressionRef, numExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringSliceWTF(module: ExpressionRef, op: Op, ref: ExpressionRef, start: ExpressionRef, end: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceWTFGetOp(expr: ExpressionRef): Op;\nexport declare function _BinaryenStringSliceWTFSetOp(expr: ExpressionRef, op: Op): void;\nexport declare function _BinaryenStringSliceWTFGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceWTFSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStringSliceWTFGetStart(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceWTFSetStart(expr: ExpressionRef, startExpr: ExpressionRef): void;\nexport declare function _BinaryenStringSliceWTFGetEnd(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceWTFSetEnd(expr: ExpressionRef, endExpr: ExpressionRef): void;\n\nexport declare function _BinaryenStringSliceIter(module: ExpressionRef, ref: ExpressionRef, num: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceIterGetRef(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceIterSetRef(expr: ExpressionRef, refExpr: ExpressionRef): void;\nexport declare function _BinaryenStringSliceIterGetNum(expr: ExpressionRef): ExpressionRef;\nexport declare function _BinaryenStringSliceIterSetNum(expr: ExpressionRef, numExpr: ExpressionRef): void;\n\nexport declare function _BinaryenAddFunction(module: ModuleRef, name: StringRef, params: TypeRef, results: TypeRef, varTypes: ArrayRef, numVarTypes: Index, body: ExpressionRef): FunctionRef;\nexport declare function _BinaryenGetFunction(module: ModuleRef, name: StringRef): FunctionRef;\nexport declare function _BinaryenRemoveFunction(module: ModuleRef, name: StringRef): void;\nexport declare function _BinaryenGetNumFunctions(module: ModuleRef): Index;\nexport declare function _BinaryenGetFunctionByIndex(module: ModuleRef, index: Index): FunctionRef;\n\nexport declare function _BinaryenFunctionGetName(func: FunctionRef): StringRef;\nexport declare function _BinaryenFunctionGetParams(func: FunctionRef): TypeRef;\nexport declare function _BinaryenFunctionGetResults(func: FunctionRef): TypeRef;\nexport declare function _BinaryenFunctionGetNumVars(func: FunctionRef): Index;\nexport declare function _BinaryenFunctionGetVar(func: FunctionRef, index: Index): TypeRef;\nexport declare function _BinaryenFunctionGetNumLocals(func: FunctionRef): Index;\nexport declare function _BinaryenFunctionHasLocalName(func: FunctionRef, index: Index): bool;\nexport declare function _BinaryenFunctionGetLocalName(func: FunctionRef, index: Index): StringRef;\nexport declare function _BinaryenFunctionSetLocalName(func: FunctionRef, index: Index, name: StringRef): void;\nexport declare function _BinaryenFunctionGetBody(func: FunctionRef): ExpressionRef;\nexport declare function _BinaryenFunctionSetBody(func: FunctionRef, bodyExpr: ExpressionRef): void;\nexport declare function _BinaryenFunctionOptimize(func: FunctionRef, module: ModuleRef): void;\nexport declare function _BinaryenFunctionRunPasses(func: FunctionRef, module: ModuleRef, passes: ArrayRef, numPasses: Index): void;\nexport declare function _BinaryenFunctionSetDebugLocation(func: FunctionRef, expr: ExpressionRef, fileIndex: Index, lineNumber: Index, columnNumber: Index): void;\n\nexport declare function _BinaryenAddFunctionImport(module: ModuleRef, internalName: StringRef, externalModuleName: StringRef, externalBaseName: StringRef, params: TypeRef, results: TypeRef): void;\nexport declare function _BinaryenAddTableImport(module: ModuleRef, internalName: StringRef, externalModuleName: StringRef, externalBaseName: StringRef): void;\nexport declare function _BinaryenAddMemoryImport(module: ModuleRef, internalName: StringRef, externalModuleName: StringRef, externalBaseName: StringRef, shared:bool): void;\nexport declare function _BinaryenAddGlobalImport(module: ModuleRef, internalName: StringRef, externalModuleName: StringRef, externalBaseName: StringRef, globalType: TypeRef, mutable: bool): void;\nexport declare function _BinaryenAddTagImport(module: ModuleRef, internalName: StringRef, externalModuleName: StringRef, externalBaseName: StringRef, params: TypeRef, results: TypeRef): void;\n\nexport declare function _BinaryenAddFunctionExport(module: ModuleRef, internalName: StringRef, externalName: StringRef): ExportRef;\nexport declare function _BinaryenAddTableExport(module: ModuleRef, internalName: StringRef, externalName: StringRef): ExportRef;\nexport declare function _BinaryenAddMemoryExport(module: ModuleRef, internalName: StringRef, externalName: StringRef): ExportRef;\nexport declare function _BinaryenAddGlobalExport(module: ModuleRef, internalName: StringRef, externalName: StringRef): ExportRef;\nexport declare function _BinaryenAddTagExport(module: ModuleRef, internalName: StringRef, externalName: StringRef): ExportRef;\nexport declare function _BinaryenGetExport(module: ModuleRef, externalName: StringRef): ExportRef;\nexport declare function _BinaryenRemoveExport(module: ModuleRef, externalName: StringRef): void;\nexport declare function _BinaryenGetNumExports(module: ModuleRef): Index;\nexport declare function _BinaryenGetExportByIndex(module: ModuleRef, index: Index): ExportRef;\nexport declare function _BinaryenExportGetKind(ref: ExportRef): ExternalKind;\nexport declare function _BinaryenExportGetName(ref: ExportRef): StringRef;\nexport declare function _BinaryenExportGetValue(ref: ExportRef): StringRef;\n\nexport declare function _BinaryenAddGlobal(module: ModuleRef, name: StringRef, type: TypeRef, mutable: bool, init: ExpressionRef): GlobalRef;\nexport declare function _BinaryenGetGlobal(module: ModuleRef, name: StringRef): GlobalRef;\nexport declare function _BinaryenRemoveGlobal(module: ModuleRef, name: StringRef): void;\nexport declare function _BinaryenGetNumGlobals(module: ModuleRef): Index;\nexport declare function _BinaryenGetGlobalByIndex(module: ModuleRef, index: Index): GlobalRef;\n\nexport declare function _BinaryenGlobalGetName(global: GlobalRef): StringRef;\nexport declare function _BinaryenGlobalGetType(global: GlobalRef): TypeRef;\nexport declare function _BinaryenGlobalIsMutable(global: GlobalRef): bool;\nexport declare function _BinaryenGlobalGetInitExpr(global: GlobalRef): ExpressionRef;\n\nexport declare function _BinaryenAddTag(module: ModuleRef, name: StringRef, params: TypeRef, results: TypeRef): TagRef;\nexport declare function _BinaryenGetTag(module: ModuleRef, name: StringRef): TagRef;\nexport declare function _BinaryenRemoveTag(module: ModuleRef, name: StringRef): void;\n\nexport declare function _BinaryenTagGetName(tag: TagRef): StringRef;\nexport declare function _BinaryenTagGetParams(tag: TagRef): TypeRef;\nexport declare function _BinaryenTagGetResults(tag: TagRef): TypeRef;\n\nexport declare function _BinaryenAddTable(module: ModuleRef, name: StringRef, initial: Index, maximum: Index, type: TypeRef): TableRef;\nexport declare function _BinaryenRemoveTable(module: ModuleRef, table: StringRef): void;\nexport declare function _BinaryenGetNumTables(module: ModuleRef): Index;\nexport declare function _BinaryenGetTable(module: ModuleRef, name: StringRef): TableRef;\nexport declare function _BinaryenGetTableByIndex(module: ModuleRef, index: Index): TableRef;\n\nexport declare function _BinaryenTableGetName(table: TableRef): StringRef;\nexport declare function _BinaryenTableSetName(table: TableRef, name: StringRef): void;\nexport declare function _BinaryenTableGetInitial(table: TableRef): Index;\nexport declare function _BinaryenTableSetInitial(table: TableRef, initial: Index): void;\nexport declare function _BinaryenTableHasMax(table: TableRef): bool;\nexport declare function _BinaryenTableGetMax(table: TableRef): Index;\nexport declare function _BinaryenTableSetMax(table: TableRef, max: Index): void;\n\nexport declare function _BinaryenAddActiveElementSegment(module: ModuleRef, table: StringRef, name: StringRef, funcNames: ArrayRef, numFuncNames: Index, offset: ExpressionRef): ElementSegmentRef;\nexport declare function _BinaryenAddPassiveElementSegment(module: ModuleRef, name: StringRef, funcNames: ArrayRef, numFuncNames: Index): ElementSegmentRef;\nexport declare function _BinaryenRemoveElementSegment(module: ModuleRef, name: StringRef): void;\nexport declare function _BinaryenGetNumElementSegments(module: ModuleRef, name: StringRef): Index;\nexport declare function _BinaryenGetElementSegment(module: ModuleRef, name: StringRef): ElementSegmentRef;\nexport declare function _BinaryenGetElementSegmentByIndex(module: ModuleRef, index: Index): ElementSegmentRef;\n\nexport declare function _BinaryenSetMemory(module: ModuleRef, initial: Index, maximum: Index, exportName: StringRef, segments: ArrayRef>, segmentPassive: ArrayRef, segmentOffsets: ArrayRef, segmentSizes: ArrayRef, numSegments: Index, shared: bool, memory64: bool, name: StringRef): void;\nexport declare function _BinaryenGetNumMemorySegments(module: ModuleRef): Index;\nexport declare function _BinaryenGetMemorySegmentByteOffset(module: ModuleRef, index: Index): u32;\nexport declare function _BinaryenGetMemorySegmentByteLength(module: ModuleRef, id: Index): usize;\nexport declare function _BinaryenCopyMemorySegmentData(module: ModuleRef, id: Index, buffer: ArrayRef): void;\n\nexport declare function _BinaryenSetStart(module: ModuleRef, start: FunctionRef): void;\n\nexport declare function _BinaryenModuleParse(text: StringRef): ModuleRef;\nexport declare function _BinaryenModulePrint(module: ModuleRef): void;\nexport declare function _BinaryenModulePrintAsmjs(module: ModuleRef): void;\nexport declare function _BinaryenModuleValidate(module: ModuleRef): i32;\nexport declare function _BinaryenModuleOptimize(module: ModuleRef): void;\nexport declare function _BinaryenModuleRunPasses(module: ModuleRef, passes: ArrayRef, numPasses: Index): void;\nexport declare function _BinaryenModuleAutoDrop(module: ModuleRef): void;\nexport declare function _BinaryenSizeofAllocateAndWriteResult(): i32;\nexport declare function _BinaryenModuleAllocateAndWrite(resultOut: BinaryenModuleAllocateAndWriteResultRef, module: ModuleRef, sourceMapUrl: StringRef): void;\nexport declare function _BinaryenModuleAllocateAndWriteText(module: ModuleRef): StringRef;\nexport declare function _BinaryenModuleAllocateAndWriteStackIR(module: ModuleRef, optimize: bool): StringRef;\nexport declare function _BinaryenModuleRead(input: ArrayRef, inputSize: usize): ModuleRef;\nexport declare function _BinaryenModuleInterpret(module: ModuleRef): void;\nexport declare function _BinaryenModuleAddDebugInfoFileName(module: ModuleRef, filename: StringRef): Index;\nexport declare function _BinaryenModuleGetDebugInfoFileName(module: ModuleRef, index: Index): StringRef;\nexport declare function _BinaryenModuleGetFeatures(module: ModuleRef): FeatureFlags;\nexport declare function _BinaryenModuleSetFeatures(module: ModuleRef, featureFlags: FeatureFlags): void;\n\nexport declare function _BinaryenAddCustomSection(module: ModuleRef, name: StringRef, contents: ArrayRef, contentsSize: Index): void;\n\nexport declare function _BinaryenExpressionGetSideEffects(expr: ExpressionRef, module: ModuleRef): SideEffects;\n\nexport declare function _RelooperCreate(module: ModuleRef): RelooperRef;\nexport declare function _RelooperAddBlock(relooper: RelooperRef, code: ExpressionRef): RelooperBlockRef;\nexport declare function _RelooperAddBranch(from: RelooperBlockRef, to: RelooperBlockRef, condition: ExpressionRef, code: ExpressionRef): void;\nexport declare function _RelooperAddBlockWithSwitch(relooper: RelooperRef, code: ExpressionRef, condition: ExpressionRef): RelooperBlockRef;\nexport declare function _RelooperAddBranchForSwitch(from: RelooperBlockRef, to: RelooperBlockRef, indexes: ArrayRef, numIndexes: Index, code: ExpressionRef): void;\nexport declare function _RelooperRenderAndDispose(relooper: RelooperRef, entry: RelooperBlockRef, labelHelper: Index): ExpressionRef;\n\nexport declare function _ExpressionRunnerCreate(module: ModuleRef, flags: ExpressionRunnerFlags, maxDepth: Index, maxLoopIterations: Index): ExpressionRunnerRef;\nexport declare function _ExpressionRunnerSetLocalValue(runner: ExpressionRunnerRef, index: Index, value: ExpressionRef): bool;\nexport declare function _ExpressionRunnerSetGlobalValue(runner: ExpressionRunnerRef, name: StringRef, value: ExpressionRef): bool;\nexport declare function _ExpressionRunnerRunAndDispose(runner: ExpressionRunnerRef, expr: ExpressionRef): ExpressionRef;\n\nexport declare function _TypeBuilderCreate(size: Index): TypeBuilderRef;\nexport declare function _TypeBuilderGrow(builder: TypeBuilderRef, count: Index): void;\nexport declare function _TypeBuilderGetSize(builder: TypeBuilderRef): Index;\nexport declare function _TypeBuilderSetBasicHeapType(builder: TypeBuilderRef, index: Index, basicHeapType: HeapTypeRef): void;\nexport declare function _TypeBuilderSetSignatureType(builder: TypeBuilderRef, index: Index, paramTypes: TypeRef, resultTypes: TypeRef): void;\nexport declare function _TypeBuilderSetStructType(builder: TypeBuilderRef, index: Index, fieldTypes: ArrayRef, fieldPackedTypes: ArrayRef, fieldMutables: ArrayRef, numFields: i32): void;\nexport declare function _TypeBuilderSetArrayType(builder: TypeBuilderRef, index: Index, elementType: TypeRef, elementPackedTyype: PackedType, elementMutable: bool): void;\nexport declare function _TypeBuilderIsBasic(builder: TypeBuilderRef, index: Index): bool;\nexport declare function _TypeBuilderGetBasic(builder: TypeBuilderRef, index: Index): HeapTypeRef;\nexport declare function _TypeBuilderGetTempHeapType(builder: TypeBuilderRef, index: Index): HeapTypeRef;\nexport declare function _TypeBuilderGetTempTupleType(builder: TypeBuilderRef, types: ArrayRef, numTypes: Index): TypeRef;\nexport declare function _TypeBuilderGetTempRefType(builder: TypeBuilderRef, heapType: HeapTypeRef, nullable: bool): TypeRef;\nexport declare function _TypeBuilderSetSubType(builder: TypeBuilderRef, index: Index, superType: HeapTypeRef): void;\nexport declare function _TypeBuilderCreateRecGroup(builder: TypeBuilderRef, index: Index, length: Index): void;\nexport declare function _TypeBuilderBuildAndDispose(builder: TypeBuilderRef, heapTypes: ArrayRef, errorIndex: Pointer, errorReason: Pointer): bool;\nexport declare function _BinaryenModuleSetTypeName(module: ModuleRef, heapType: HeapTypeRef, name: StringRef): void;\nexport declare function _BinaryenModuleSetFieldName(module: ModuleRef, heapType: HeapTypeRef, index: Index, name: StringRef): void;\n\nexport declare function _BinaryenGetOptimizeLevel(): i32;\nexport declare function _BinaryenSetOptimizeLevel(level: i32): void;\nexport declare function _BinaryenGetShrinkLevel(): i32;\nexport declare function _BinaryenSetShrinkLevel(level: i32): void;\nexport declare function _BinaryenGetDebugInfo(): bool;\nexport declare function _BinaryenSetDebugInfo(on: bool): void;\nexport declare function _BinaryenGetLowMemoryUnused(): bool;\nexport declare function _BinaryenSetLowMemoryUnused(on: bool): void;\nexport declare function _BinaryenGetZeroFilledMemory(): bool;\nexport declare function _BinaryenSetZeroFilledMemory(on: bool): void;\nexport declare function _BinaryenGetFastMath(): bool;\nexport declare function _BinaryenSetFastMath(on: bool): void;\nexport declare function _BinaryenGetPassArgument(key: StringRef): StringRef;\nexport declare function _BinaryenSetPassArgument(key: StringRef, value: StringRef): void;\nexport declare function _BinaryenClearPassArguments(): void;\nexport declare function _BinaryenGetAlwaysInlineMaxSize(): Index;\nexport declare function _BinaryenSetAlwaysInlineMaxSize(size: Index): void;\nexport declare function _BinaryenGetFlexibleInlineMaxSize(): Index;\nexport declare function _BinaryenSetFlexibleInlineMaxSize(size: Index): void;\nexport declare function _BinaryenGetOneCallerInlineMaxSize(): Index;\nexport declare function _BinaryenSetOneCallerInlineMaxSize(size: Index): void;\nexport declare function _BinaryenGetAllowInliningFunctionsWithLoops(): bool;\nexport declare function _BinaryenSetAllowInliningFunctionsWithLoops(enabled: bool): void;\nexport declare function _BinaryenGetTypeSystem(): TypeSystem;\nexport declare function _BinaryenSetTypeSystem(typeSystem: TypeSystem): void;\n\n// Helpers\n\nexport declare function _malloc(size: usize): usize;\nexport declare function _free(ptr: usize): void;\nexport declare function __i32_store8(ptr: usize, value: number): void;\nexport declare function __i32_store16(ptr: usize, value: number): void;\nexport declare function __i32_store(ptr: usize, value: number): void;\nexport declare function __f32_store(ptr: usize, value: number): void;\nexport declare function __f64_store(ptr: usize, value: number): void;\nexport declare function __i32_load8_s(ptr: usize): i8;\nexport declare function __i32_load8_u(ptr: usize): u8;\nexport declare function __i32_load16_s(ptr: usize): i16;\nexport declare function __i32_load16_u(ptr: usize): u16;\nexport declare function __i32_load(ptr: usize): i32;\nexport declare function __f32_load(ptr: usize): f32;\nexport declare function __f64_load(ptr: usize): f64;\n","/**\n * @fileoverview Mappings from AssemblyScript types to WebAssembly types.\n * @license Apache-2.0\n */\n\nimport {\n CommonNames\n} from \"./common\";\n\nimport {\n Class,\n Program,\n DecoratorFlags\n} from \"./program\";\n\nimport {\n TypeRef,\n createType,\n HeapTypeRef,\n ensureType\n} from \"./module\";\n\nimport * as binaryen from \"./glue/binaryen\";\n\n/** Indicates the kind of a type. */\nexport const enum TypeKind {\n /** A 1-bit unsigned integer. */\n Bool,\n\n // signed integers\n\n /** An 8-bit signed integer. */\n I8,\n /** A 16-bit signed integer. */\n I16,\n /** A 32-bit signed integer. */\n I32,\n /** A 64-bit signed integer. */\n I64,\n /** A 32-bit/64-bit signed integer, depending on the target. */\n Isize,\n\n // unsigned integers\n\n /** An 8-bit unsigned integer. */\n U8,\n /** A 16-bit unsigned integer. */\n U16,\n /** A 32-bit unsigned integer. Also the base of function types. */\n U32,\n /** A 64-bit unsigned integer. */\n U64,\n /** A 32-bit/64-bit unsigned integer, depending on the target. Also the base of class types. */\n Usize,\n\n // floats\n\n /** A 32-bit float. */\n F32,\n /** A 64-bit double. */\n F64,\n\n // vectors\n\n /** A 128-bit vector. */\n V128,\n\n // references (keep in same order as in Binaryen)\n\n /** External reference. */\n Externref,\n /** Function reference. */\n Funcref,\n /** Any reference. */\n Anyref,\n /** Equatable reference. */\n Eqref,\n /** Struct reference. */\n Structref,\n /** Array reference. */\n Arrayref,\n /** 31-bit integer reference. */\n I31ref,\n /** String reference. */\n Stringref,\n /** WTF8 string view. */\n StringviewWTF8,\n /** WTF16 string view. */\n StringviewWTF16,\n /** String iterator. */\n StringviewIter,\n\n // other\n\n /** No return type. */\n Void\n}\n\n/** Indicates capabilities of a type. */\nexport const enum TypeFlags {\n None = 0,\n /** Is a signed type that can represent negative values. */\n Signed = 1 << 0,\n /** Is an unsigned type that cannot represent negative values. */\n Unsigned = 1 << 1,\n /** Is an integer type. */\n Integer = 1 << 2,\n /** Is a floating point type. */\n Float = 1 << 3,\n /** Is a varying (in size) type. */\n Varying = 1 << 4,\n /** Is smaller than 32-bits. */\n Short = 1 << 5,\n /** Is larger than 32-bits. */\n Long = 1 << 6,\n /** Is a value type. */\n Value = 1 << 7,\n /** Is a reference type (either a class or a function type). */\n Reference = 1 << 8,\n /** Is a nullable type. */\n Nullable = 1 << 9,\n /** Is a vector type. */\n Vector = 1 << 10,\n /** Is an external type. */\n External = 1 << 11,\n /** Is a class. */\n Class = 1 << 12,\n /** Is a function. */\n Function = 1 << 13\n}\n\n/** Represents a resolved type. */\nexport class Type {\n\n /** Type kind. */\n kind: TypeKind;\n /** Type flags. */\n flags: TypeFlags;\n /** Size in bits. */\n size: i32;\n /** Underlying class reference, if a class type. */\n classReference: Class | null = null;\n /** Underlying signature reference, if a function type. */\n signatureReference: Signature | null = null;\n /** Respective non-nullable type, if nullable. */\n private _nonNullableType: Type | null = null;\n /** Respective nullable type, if non-nullable. */\n private _nullableType: Type | null = null;\n /** Cached Binaryen type reference. */\n ref: TypeRef = 0;\n\n /** Constructs a new resolved type. */\n constructor(kind: TypeKind, flags: TypeFlags, size: u32) {\n this.kind = kind;\n this.flags = flags;\n this.size = size;\n if (!(flags & TypeFlags.Nullable)) {\n this._nonNullableType = this;\n } else {\n this._nullableType = this;\n }\n }\n\n /** Returns the closest int type representing this type. */\n get intType(): Type {\n if (this == Type.auto) return this; // keep auto as a hint\n switch (this.kind) {\n case TypeKind.Bool:\n case TypeKind.I32:\n case TypeKind.F32: return Type.i32;\n case TypeKind.I8: return Type.i8;\n case TypeKind.I16: return Type.i16;\n case TypeKind.F64:\n case TypeKind.I64: return Type.i64;\n case TypeKind.Isize: return this.size == 64 ? Type.isize64 : Type.isize32;\n case TypeKind.U8: return Type.u8;\n case TypeKind.U16: return Type.u16;\n case TypeKind.U32: return Type.u32;\n case TypeKind.U64: return Type.u64;\n case TypeKind.Usize: return this.size == 64 ? Type.usize64 : Type.usize32;\n default: return Type.i32;\n }\n }\n\n /** Substitutes this type with the auto type if this type is void. */\n get exceptVoid(): Type {\n return this.kind == TypeKind.Void ? Type.auto : this;\n }\n\n /** Size in bytes. */\n get byteSize(): i32 {\n // ceiled div by 8\n return this.size + 7 >>> 3;\n }\n\n /** Gets this type's logarithmic alignment in memory. */\n get alignLog2(): i32 {\n return 31 - clz(this.byteSize);\n }\n\n /** Tests if this type represents a basic value. */\n get isValue(): bool {\n return this.is(TypeFlags.Value);\n }\n\n /** Tests if this type represents an integer value. */\n get isIntegerValue(): bool {\n return this.is(TypeFlags.Integer | TypeFlags.Value);\n }\n\n /** Tests if this type represents a small (< 32 bits) integer value. */\n get isShortIntegerValue(): bool {\n return this.is(TypeFlags.Short | TypeFlags.Integer | TypeFlags.Value);\n }\n\n /** Tests if this type represents a long (> 32 bits) integer value. */\n get isLongIntegerValue(): bool {\n return this.is(TypeFlags.Long | TypeFlags.Integer | TypeFlags.Value);\n }\n\n /** Tests if this type represents a signed integer value. */\n get isSignedIntegerValue(): bool {\n return this.is(TypeFlags.Signed | TypeFlags.Integer | TypeFlags.Value);\n }\n\n /** Tests if this type represents an unsigned integer value. */\n get isUnsignedIntegerValue(): bool {\n return this.is(TypeFlags.Unsigned | TypeFlags.Integer | TypeFlags.Value);\n }\n\n /** Tests if this type represents a varying (in size) integer value. */\n get isVaryingIntegerValue(): bool {\n return this.is(TypeFlags.Varying | TypeFlags.Integer | TypeFlags.Value);\n }\n\n /** Tests if this type represents an integer, including references. */\n get isIntegerInclReference(): bool {\n return this.is(TypeFlags.Integer);\n }\n\n /** Tests if this type represents a floating point value. */\n get isFloatValue(): bool {\n return this.is(TypeFlags.Float | TypeFlags.Value);\n }\n\n /** Tests if this type represents a numeric (integer or floating point) value. */\n get isNumericValue(): bool {\n return this.isIntegerValue || this.isFloatValue;\n }\n\n /** Tests if this type represents a boolean value. */\n get isBooleanValue(): bool {\n return this == Type.bool;\n }\n\n /** Tests if this type represents a vector value. */\n get isVectorValue(): bool {\n return this.is(TypeFlags.Vector | TypeFlags.Value);\n }\n\n /** Tests if this type represents an internal or external reference. */\n get isReference(): bool {\n return this.is(TypeFlags.Reference);\n }\n\n /** Tests if this type represents a nullable internal or external reference. */\n get isNullableReference(): bool {\n return this.is(TypeFlags.Nullable | TypeFlags.Reference);\n }\n\n /** Tests if this type represents an internal object. */\n get isInternalReference(): bool {\n return this.is(TypeFlags.Integer | TypeFlags.Reference);\n }\n\n /** Tests if this type represents an external object. */\n get isExternalReference(): bool {\n return this.is(TypeFlags.External | TypeFlags.Reference);\n }\n\n /** Gets the underlying class of this type, if any. */\n getClass(): Class | null {\n return this.isInternalReference\n ? this.classReference\n : null;\n }\n\n /** Tests if this type represents a class. */\n get isClass(): bool {\n return this.getClass() != null;\n }\n\n /** Gets the underlying class or wrapper class of this type, if any. */\n getClassOrWrapper(program: Program): Class | null {\n let classReference = this.getClass();\n if (classReference) {\n // typical class\n return classReference;\n } else {\n let signatureReference = this.getSignature();\n if (signatureReference) {\n // function wrapper\n let type = signatureReference.type;\n let wrapper = assert(program.resolver.resolveClass(program.functionPrototype, [ type ]));\n wrapper.wrappedType = type;\n return wrapper;\n } else {\n let wrapperClasses = program.wrapperClasses;\n if (wrapperClasses.has(this)) {\n // value wrapper\n return assert(wrapperClasses.get(this));\n }\n }\n }\n return null;\n }\n\n /** Gets the underlying function signature of this type, if any. */\n getSignature(): Signature | null {\n return this.isInternalReference\n ? this.signatureReference\n : null;\n }\n\n /** Tests if this type represents a function. */\n get isFunction(): bool {\n return this.getSignature() != null;\n }\n\n /** Tests if this is a managed type that needs GC hooks. */\n get isManaged(): bool {\n if (this.isInternalReference) {\n let classReference = this.classReference;\n if (classReference) return !classReference.hasDecorator(DecoratorFlags.Unmanaged);\n return this.signatureReference != null; // function references are managed\n }\n return false;\n }\n\n /** Tests if this is a class type explicitly annotated as unmanaged. */\n get isUnmanaged(): bool {\n let classReference = this.classReference;\n return classReference != null && classReference.hasDecorator(DecoratorFlags.Unmanaged);\n }\n\n get isMemory(): bool {\n switch (this.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize:\n case TypeKind.F32:\n case TypeKind.F64:\n case TypeKind.V128: return true;\n }\n return false;\n }\n\n /** Gets the corresponding non-nullable type. */\n get nonNullableType(): Type {\n if (this.isExternalReference) {\n return this; // TODO\n }\n return assert(this._nonNullableType); // set either in ctor or asNullable\n }\n\n /** Gets the corresponding nullable type, if applicable. */\n get nullableType(): Type | null {\n return this._nullableType; // set either in ctor or asNullable\n }\n\n /** Computes the sign-extending shift in the target type. */\n computeSmallIntegerShift(targetType: Type): i32 {\n return targetType.size - this.size;\n }\n\n /** Computes the truncating mask in the target type. */\n computeSmallIntegerMask(targetType: Type): i32 {\n let size = this.size;\n if (!this.is(TypeFlags.Unsigned)) size -= 1;\n return ~0 >>> (targetType.size - size);\n }\n\n /** Tests if this type has (all of) the specified flags. */\n is(flags: TypeFlags): bool { return (this.flags & flags) == flags; }\n /** Tests if this type has any of the specified flags. */\n isAny(flags: TypeFlags): bool { return (this.flags & flags) != 0; }\n\n /** Composes the respective nullable type of this type. */\n asNullable(): Type {\n assert(this.isInternalReference);\n let nullableType = this._nullableType;\n if (!nullableType) {\n assert(!this.isNullableReference);\n this._nullableType = nullableType = new Type(this.kind, this.flags | TypeFlags.Nullable, this.size);\n nullableType.classReference = this.classReference; // either a class reference\n nullableType.signatureReference = this.signatureReference; // or a function reference\n nullableType._nonNullableType = this;\n }\n return nullableType;\n }\n\n /** Use unsigned type for according size if possible. */\n toUnsigned(): Type {\n switch (this.kind) {\n case TypeKind.I8: return Type.u8;\n case TypeKind.I16: return Type.u16;\n case TypeKind.I32: return Type.u32;\n case TypeKind.I64: return Type.u64;\n case TypeKind.Isize: return this.size == 64 ? Type.usize64 : Type.usize32;\n }\n return this;\n }\n\n /** Tests if this type equals the specified. */\n equals(other: Type): bool {\n if (this.kind != other.kind) {\n return false;\n }\n if (this.isReference) {\n let selfSignatureReference = this.signatureReference;\n let otherSignatureReference = other.signatureReference;\n\n return (\n this.classReference == other.classReference\n && selfSignatureReference == otherSignatureReference\n && this.isNullableReference == other.isNullableReference\n );\n }\n return true;\n }\n\n /** Tests if a value of this type is assignable to the target type incl. implicit conversion. */\n isAssignableTo(target: Type, signednessIsRelevant: bool = false): bool {\n let currentClass: Class | null;\n let targetClass: Class | null;\n let currentFunction: Signature | null;\n let targetFunction: Signature | null;\n if (this.isReference) {\n if (target.isReference) {\n if (!this.isNullableReference || target.isNullableReference) {\n if (currentClass = this.getClass()) {\n if (targetClass = target.getClass()) {\n return currentClass.isAssignableTo(targetClass);\n }\n } else if (currentFunction = this.getSignature()) {\n if (targetFunction = target.getSignature()) {\n return currentFunction.isAssignableTo(targetFunction);\n }\n } else if (this.isExternalReference) {\n if (\n this.kind == target.kind ||\n (target.kind == TypeKind.Anyref && this.kind != TypeKind.Externref)\n ) {\n return true;\n }\n }\n }\n }\n } else if (!target.isReference) {\n if (this.isIntegerValue) {\n if (target.isIntegerValue) {\n if (\n !signednessIsRelevant ||\n this.isBooleanValue || // a bool (0 or 1) can be safely assigned to all sorts of integers\n this.isSignedIntegerValue == target.isSignedIntegerValue\n ) {\n return this.size <= target.size;\n }\n } else if (target.kind == TypeKind.F32) {\n return this.size <= 23; // mantissa bits\n } else if (target.kind == TypeKind.F64) {\n return this.size <= 52; // ^\n }\n } else if (this.isFloatValue) {\n if (target.isFloatValue) {\n return this.size <= target.size;\n }\n } else if (this.isVectorValue) {\n if (target.isVectorValue) {\n return this.size == target.size;\n }\n }\n }\n return false;\n }\n\n /** Tests if a value of this type is assignable to the target type excl. implicit conversion. */\n isStrictlyAssignableTo(target: Type, signednessIsRelevant: bool = false): bool {\n if (this.isReference) return this.isAssignableTo(target);\n else if (target.isReference) return false;\n // not dealing with references from here on\n if (this.isIntegerValue) {\n return target.isIntegerValue && target.size == this.size && (\n !signednessIsRelevant ||\n this.isSignedIntegerValue == target.isSignedIntegerValue\n );\n }\n return this.kind == target.kind;\n }\n\n /** Tests if this type has a subtype assignable to the target type. */\n hasSubtypeAssignableTo(target: Type): bool {\n let thisClass = this.getClass();\n let targetClass = target.getClass();\n if (!thisClass || !targetClass) return false; // TODO: what about basic types?\n return thisClass.hasSubclassAssignableTo(targetClass);\n }\n\n /** Tests if a value of this type can be changed to the target type using `changetype`. */\n isChangeableTo(target: Type): bool {\n // special in that it allows integer references as well\n if (this.is(TypeFlags.Integer) && target.is(TypeFlags.Integer)) {\n let size = this.size;\n return size == target.size && (\n size >= 32 ||\n this.is(TypeFlags.Signed) == target.is(TypeFlags.Signed)\n );\n }\n return this.kind == target.kind;\n }\n\n /** Tests if this type can extend or implement the given type. */\n canExtendOrImplement(base: Type): bool {\n // Both must be class types\n let thisClass = this.getClass();\n let baseClass = base.getClass();\n if (!thisClass || !baseClass) return false;\n // Both types must be either managed or unmanaged\n if (this.isManaged != base.isManaged) return false;\n // Both types must be either internal or external references\n if (this.isInternalReference) {\n if (!base.isInternalReference) return false;\n } else if (this.isExternalReference) {\n if (!base.isExternalReference) return false;\n } else {\n return false;\n }\n return true;\n }\n\n /** Computes the common type of a binary-like expression, if any. */\n static commonType(\n /** LHS type. */\n left: Type,\n /** RHS type. */\n right: Type,\n /** Contextual type, if any. */\n contextualType: Type = Type.auto,\n /** Whether signedness is relevant. */\n signednessIsRelevant: bool = false\n ): Type | null {\n // Compute LUB of internal reference types (classes)\n if (left.isInternalReference) {\n if (!right.isInternalReference) return null;\n // Prefer contextual type if meaningful\n if (contextualType != Type.void && left.isAssignableTo(contextualType) && right.isAssignableTo(contextualType)) {\n return contextualType;\n }\n let leftClass = left.getClass();\n let rightClass = right.getClass();\n if (leftClass && rightClass) {\n let lubClass = Class.leastUpperBound(leftClass, rightClass);\n if (lubClass) {\n let ret = left.is(TypeFlags.Nullable) || right.is(TypeFlags.Nullable) ? lubClass.type.asNullable() : lubClass.type;\n return ret;\n }\n }\n } else if (right.isInternalReference) {\n return null;\n }\n // TODO: External reference types (needs nullability)\n // Otherwise do a trivial check\n if (right.isAssignableTo(left, signednessIsRelevant)) return left;\n else if (left.isAssignableTo(right, signednessIsRelevant)) return right;\n return null;\n }\n\n /** Converts this type to a string. */\n toString(validWat: bool = false): string {\n const nullablePostfix = validWat ? \"|null\" : \" | null\";\n if (this.isReference) {\n let classReference = this.getClass();\n if (classReference) {\n return this.isNullableReference\n ? classReference.internalName + nullablePostfix\n : classReference.internalName;\n } else {\n let signatureReference = this.getSignature();\n if (signatureReference) {\n return this.isNullableReference\n ? `(${signatureReference.toString(validWat)})${nullablePostfix}`\n : signatureReference.toString(validWat);\n }\n }\n }\n switch (this.kind) {\n case TypeKind.Bool: return CommonNames.bool;\n case TypeKind.I8: return CommonNames.i8;\n case TypeKind.I16: return CommonNames.i16;\n case TypeKind.I32: return CommonNames.i32;\n case TypeKind.I64: return CommonNames.i64;\n case TypeKind.Isize: return CommonNames.isize;\n case TypeKind.U8: return CommonNames.u8;\n case TypeKind.U16: return CommonNames.u16;\n case TypeKind.U32: return CommonNames.u32;\n case TypeKind.U64: return CommonNames.u64;\n case TypeKind.Usize: return CommonNames.usize;\n case TypeKind.F32: return CommonNames.f32;\n case TypeKind.F64: return CommonNames.f64;\n case TypeKind.V128: return CommonNames.v128;\n case TypeKind.Funcref: return CommonNames.funcref;\n case TypeKind.Externref: return CommonNames.externref;\n case TypeKind.Anyref: return CommonNames.anyref;\n case TypeKind.Eqref: return CommonNames.eqref;\n case TypeKind.Structref: return CommonNames.structref;\n case TypeKind.Arrayref: return CommonNames.arrayref;\n case TypeKind.I31ref: return CommonNames.i31ref;\n case TypeKind.Stringref: return CommonNames.stringref;\n case TypeKind.StringviewWTF8: return CommonNames.stringview_wtf8;\n case TypeKind.StringviewWTF16: return CommonNames.stringview_wtf16;\n case TypeKind.StringviewIter: return CommonNames.stringview_iter;\n default: assert(false);\n case TypeKind.Void: return CommonNames.void_;\n }\n }\n\n // Binaryen specific\n\n /** Converts this type to its respective type reference. */\n toRef(): TypeRef {\n switch (this.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: return TypeRef.I32;\n case TypeKind.Isize:\n case TypeKind.Usize: if (this.size != 64) return TypeRef.I32;\n case TypeKind.I64:\n case TypeKind.U64: return TypeRef.I64;\n case TypeKind.F32: return TypeRef.F32;\n case TypeKind.F64: return TypeRef.F64;\n case TypeKind.V128: return TypeRef.V128;\n case TypeKind.Funcref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Func, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Externref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Extern, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Anyref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Any, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Eqref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Eq, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Structref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Struct, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Arrayref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Array, this.is(TypeFlags.Nullable));\n }\n case TypeKind.I31ref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.I31, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Stringref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.String, this.is(TypeFlags.Nullable));\n }\n case TypeKind.StringviewWTF8: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.StringviewWTF8, this.is(TypeFlags.Nullable));\n }\n case TypeKind.StringviewWTF16: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.StringviewWTF16, this.is(TypeFlags.Nullable));\n }\n case TypeKind.StringviewIter: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.StringviewIter, this.is(TypeFlags.Nullable));\n }\n case TypeKind.Void: return TypeRef.None;\n }\n // TODO: not used yet\n assert(false);\n return ensureType(this);\n }\n\n // Types\n\n /** An 8-bit signed integer. */\n static readonly i8: Type = new Type(TypeKind.I8,\n TypeFlags.Signed |\n TypeFlags.Short |\n TypeFlags.Integer |\n TypeFlags.Value, 8\n );\n\n /** A 16-bit signed integer. */\n static readonly i16: Type = new Type(TypeKind.I16,\n TypeFlags.Signed |\n TypeFlags.Short |\n TypeFlags.Integer |\n TypeFlags.Value, 16\n );\n\n /** A 32-bit signed integer. */\n static readonly i32: Type = new Type(TypeKind.I32,\n TypeFlags.Signed |\n TypeFlags.Integer |\n TypeFlags.Value, 32\n );\n\n /** A 64-bit signed integer. */\n static readonly i64: Type = new Type(TypeKind.I64,\n TypeFlags.Signed |\n TypeFlags.Long |\n TypeFlags.Integer |\n TypeFlags.Value, 64\n );\n\n /** A 32-bit signed size. WASM32 only. */\n static readonly isize32: Type = new Type(TypeKind.Isize,\n TypeFlags.Signed |\n TypeFlags.Integer |\n TypeFlags.Varying |\n TypeFlags.Value, 32\n );\n\n /** A 64-bit signed size. WASM64 only. */\n static readonly isize64: Type = new Type(TypeKind.Isize,\n TypeFlags.Signed |\n TypeFlags.Long |\n TypeFlags.Integer |\n TypeFlags.Varying |\n TypeFlags.Value, 64\n );\n\n /** An 8-bit unsigned integer. */\n static readonly u8: Type = new Type(TypeKind.U8,\n TypeFlags.Unsigned |\n TypeFlags.Short |\n TypeFlags.Integer |\n TypeFlags.Value, 8\n );\n\n /** A 16-bit unsigned integer. */\n static readonly u16: Type = new Type(TypeKind.U16,\n TypeFlags.Unsigned |\n TypeFlags.Short |\n TypeFlags.Integer |\n TypeFlags.Value, 16\n );\n\n /** A 32-bit unsigned integer. */\n static readonly u32: Type = new Type(TypeKind.U32,\n TypeFlags.Unsigned |\n TypeFlags.Integer |\n TypeFlags.Value, 32\n );\n\n /** A 64-bit unsigned integer. */\n static readonly u64: Type = new Type(TypeKind.U64,\n TypeFlags.Unsigned |\n TypeFlags.Long |\n TypeFlags.Integer |\n TypeFlags.Value, 64\n );\n\n /** A 32-bit unsigned size. WASM32 only. */\n static readonly usize32: Type = new Type(TypeKind.Usize,\n TypeFlags.Unsigned |\n TypeFlags.Integer |\n TypeFlags.Varying |\n TypeFlags.Value, 32\n );\n\n /** A 64-bit unsigned size. WASM64 only. */\n static readonly usize64: Type = new Type(TypeKind.Usize,\n TypeFlags.Unsigned |\n TypeFlags.Long |\n TypeFlags.Integer |\n TypeFlags.Varying |\n TypeFlags.Value, 64\n );\n\n /** A 1-bit unsigned integer. */\n static readonly bool: Type = new Type(TypeKind.Bool,\n TypeFlags.Unsigned |\n TypeFlags.Short |\n TypeFlags.Integer |\n TypeFlags.Value, 1\n );\n\n /** A 32-bit float. */\n static readonly f32: Type = new Type(TypeKind.F32,\n TypeFlags.Signed |\n TypeFlags.Float |\n TypeFlags.Value, 32\n );\n\n /** A 64-bit float. */\n static readonly f64: Type = new Type(TypeKind.F64,\n TypeFlags.Signed |\n TypeFlags.Long |\n TypeFlags.Float |\n TypeFlags.Value, 64\n );\n\n /** A 128-bit vector. */\n static readonly v128: Type = new Type(TypeKind.V128,\n TypeFlags.Vector |\n TypeFlags.Value, 128\n );\n\n /** Function reference. */\n static readonly funcref: Type = new Type(TypeKind.Funcref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** External reference. */\n static readonly externref: Type = new Type(TypeKind.Externref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** Any reference. */\n static readonly anyref: Type = new Type(TypeKind.Anyref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** Equatable reference. */\n static readonly eqref: Type = new Type(TypeKind.Eqref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** Struct reference. */\n static readonly structref: Type = new Type(TypeKind.Structref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** Array reference. */\n static readonly arrayref: Type = new Type(TypeKind.Arrayref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** 31-bit integer reference. */\n static readonly i31ref: Type = new Type(TypeKind.I31ref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** String reference. */\n static readonly stringref: Type = new Type(TypeKind.Stringref,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** WTF8 string view. */\n static readonly stringview_wtf8: Type = new Type(TypeKind.StringviewWTF8,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** WTF16 string view. */\n static readonly stringview_wtf16: Type = new Type(TypeKind.StringviewWTF16,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** String iterator. */\n static readonly stringview_iter: Type = new Type(TypeKind.StringviewIter,\n TypeFlags.External |\n TypeFlags.Nullable |\n TypeFlags.Reference, 0\n );\n\n /** No return type. */\n static readonly void: Type = new Type(TypeKind.Void, TypeFlags.None, 0);\n\n /** Alias of i32 indicating type inference of locals and globals with just an initializer. */\n static readonly auto: Type = new Type(Type.i32.kind, Type.i32.flags, Type.i32.size);\n}\n\n/** Converts an array of types to an array of type references. */\nexport function typesToRefs(types: Type[]): TypeRef[] {\n let numTypes = types.length;\n let ret = new Array(numTypes);\n for (let i = 0; i < numTypes; ++i) {\n unchecked(ret[i] = types[i].toRef());\n }\n return ret;\n}\n\n/** Converts an array of types to its combined string representation. */\nexport function typesToString(types: Type[]): string {\n let numTypes = types.length;\n if (!numTypes) return \"\";\n let sb = new Array(numTypes);\n for (let i = 0; i < numTypes; ++i) {\n unchecked(sb[i] = types[i].toString(true));\n }\n return sb.join(\",\");\n}\n\n/** Represents a fully resolved function signature. */\nexport class Signature {\n /** Construct a new signature. */\n public static create(\n /** The program that created this signature. */\n program: Program,\n /** Parameter types, if any, excluding `this`. */\n parameterTypes: Type[] = [],\n /** Return type. */\n returnType: Type = Type.void,\n /** This type, if an instance signature. */\n thisType: Type | null = null,\n /** Number of required parameters excluding `this`. Other parameters are considered optional. */\n requiredParameters: i32 = parameterTypes ? parameterTypes.length : 0,\n /** Whether the last parameter is a rest parameter. */\n hasRest: bool = false,\n ): Signature {\n // get the usize type, and the type of the signature\n let usizeType = program.options.usizeType;\n let type = new Type(\n usizeType.kind,\n usizeType.flags & ~TypeFlags.Value | TypeFlags.Reference,\n usizeType.size\n );\n\n // calculate the properties\n let signatureTypes = program.uniqueSignatures;\n let nextId = program.nextSignatureId;\n \n // construct the signature and calculate it's unique key\n let signature = new Signature(program, parameterTypes, returnType, thisType, requiredParameters, hasRest, nextId, type);\n let uniqueKey = signature.toString();\n\n // check if it exists, and return it\n if (signatureTypes.has(uniqueKey)) {\n let existing = assert(signatureTypes.get(uniqueKey));\n assert(signature.equals(existing));\n return existing;\n }\n\n // otherwise increment the program's signature id, set the signature reference of the type, and memoize the signature\n program.nextSignatureId = nextId + 1;\n type.signatureReference = signature;\n signatureTypes.set(uniqueKey, signature);\n return signature;\n }\n\n /** Constructs a new signature. */\n private constructor(\n /** The program that created this signature. */\n public readonly program: Program,\n /** Parameter types, if any, excluding `this`. */\n public readonly parameterTypes: Type[],\n /** Return type. */\n public readonly returnType: Type,\n /** This type, if an instance signature. */\n public readonly thisType: Type | null,\n /** Number of required parameters excluding `this`. Other parameters are considered optional. */\n public readonly requiredParameters: i32,\n /** Whether the last parameter is a rest parameter. */\n public readonly hasRest: bool,\n /** Unique id representing this signature. */\n public readonly id: u32,\n /** Respective function type. */\n public readonly type: Type,\n ) {}\n\n get paramRefs(): TypeRef {\n let thisType = this.thisType;\n let parameterTypes = this.parameterTypes;\n let numParameterTypes = parameterTypes.length;\n if (!numParameterTypes) {\n return thisType ? thisType.toRef() : TypeRef.None;\n }\n if (thisType) {\n let typeRefs = new Array(1 + numParameterTypes);\n unchecked(typeRefs[0] = thisType.toRef());\n for (let i = 0; i < numParameterTypes; ++i) {\n unchecked(typeRefs[i + 1] = parameterTypes[i].toRef());\n }\n return createType(typeRefs);\n }\n return createType(typesToRefs(parameterTypes));\n }\n\n get resultRefs(): TypeRef {\n return this.returnType.toRef();\n }\n\n /** Tests if this signature equals the specified. */\n equals(other: Signature): bool {\n\n // check `this` type\n let thisThisType = this.thisType;\n let otherThisType = other.thisType;\n if (thisThisType) {\n if (!otherThisType || !thisThisType.equals(otherThisType)) return false;\n } else if (otherThisType) {\n return false;\n }\n\n // check rest parameter\n if (this.hasRest != other.hasRest) return false;\n\n // check return type\n if (!this.returnType.equals(other.returnType)) return false;\n\n // check parameter types\n let selfParameterTypes = this.parameterTypes;\n let otherParameterTypes = other.parameterTypes;\n let numParameters = selfParameterTypes.length;\n if (numParameters != otherParameterTypes.length) return false;\n\n for (let i = 0; i < numParameters; ++i) {\n let selfParameterType = unchecked(selfParameterTypes[i]);\n let otherParameterType = unchecked(otherParameterTypes[i]);\n if (!selfParameterType.equals(otherParameterType)) return false;\n }\n return true;\n }\n\n /** Tests if a value of this function type is assignable to a target of the specified function type. */\n isAssignableTo(target: Signature, checkCompatibleOverride: bool = false): bool {\n let thisThisType = this.thisType;\n let targetThisType = target.thisType;\n if (checkCompatibleOverride) {\n // check kind of `this` type\n if (thisThisType) {\n if (!targetThisType || !thisThisType.canExtendOrImplement(targetThisType)) {\n return false;\n }\n } else if (targetThisType) {\n return false;\n }\n } else {\n // check `this` type (invariant)\n if (thisThisType) {\n if (targetThisType != targetThisType) return false;\n } else if (targetThisType) {\n return false;\n }\n }\n\n // check rest parameter\n if (this.hasRest != target.hasRest) return false; // TODO\n\n // check return type (covariant)\n let thisReturnType = this.returnType;\n let targetReturnType = target.returnType;\n if (!(thisReturnType == targetReturnType || thisReturnType.isAssignableTo(targetReturnType))) {\n return false;\n }\n // check parameter types (invariant)\n let thisParameterTypes = this.parameterTypes;\n let targetParameterTypes = target.parameterTypes;\n let numParameters = thisParameterTypes.length;\n if (numParameters != targetParameterTypes.length) return false; // TODO\n\n for (let i = 0; i < numParameters; ++i) {\n let thisParameterType = unchecked(thisParameterTypes[i]);\n let targetParameterType = unchecked(targetParameterTypes[i]);\n if (thisParameterType != targetParameterType) return false;\n }\n return true;\n }\n\n /** Tests if this signature has at least one managed operand. */\n get hasManagedOperands(): bool {\n let thisType = this.thisType;\n if (thisType && thisType.isManaged) {\n return true;\n }\n let parameterTypes = this.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (unchecked(parameterTypes[i]).isManaged) return true;\n }\n return false;\n }\n\n /** Gets the indices of all managed operands. */\n getManagedOperandIndices(): i32[] {\n let indices = new Array();\n let index = 0;\n let thisType = this.thisType;\n if (thisType) {\n if (thisType.isManaged) indices.push(index);\n ++index;\n }\n let parameterTypes = this.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (unchecked(parameterTypes[i]).isManaged) {\n indices.push(index);\n }\n ++index;\n }\n return indices;\n }\n\n /** Tests if this signature has at least one v128 operand. */\n get hasVectorValueOperands(): bool {\n let thisType = this.thisType;\n if (thisType && thisType.isVectorValue) {\n return true;\n }\n let parameterTypes = this.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (unchecked(parameterTypes[i]).isVectorValue) return true;\n }\n return false;\n }\n\n /** Gets the indices of all v128 operands. */\n getVectorValueOperandIndices(): i32[] {\n let indices = new Array();\n let index = 0;\n let thisType = this.thisType;\n if (thisType) {\n if (thisType.isVectorValue) indices.push(index);\n ++index;\n }\n let parameterTypes = this.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (unchecked(parameterTypes[i]).isVectorValue) {\n indices.push(index);\n }\n ++index;\n }\n return indices;\n }\n\n /** Converts this signature to a string. */\n toString(validWat: bool = false): string {\n let sb = new Array();\n sb.push(validWat ? \"%28\" : \"(\");\n let index = 0;\n let thisType = this.thisType;\n if (thisType) {\n sb.push(validWat ? \"this:\" : \"this: \");\n sb.push(thisType.toString(validWat));\n index = 1;\n }\n let parameters = this.parameterTypes;\n let numParameters = parameters.length;\n if (numParameters) {\n let optionalStart = this.requiredParameters;\n let restIndex = this.hasRest ? numParameters - 1 : -1;\n for (let i = 0; i < numParameters; ++i, ++index) {\n if (index) sb.push(validWat ? \"%2C\" : \", \");\n if (i == restIndex) sb.push(\"...\");\n sb.push(parameters[i].toString(validWat));\n if (i >= optionalStart && i != restIndex) sb.push(\"?\");\n }\n }\n sb.push(validWat ? \"%29=>\" : \") => \");\n sb.push(this.returnType.toString(validWat));\n return sb.join(\"\");\n }\n\n /** Creates a clone of this signature that is safe to modify. */\n clone(requiredParameters: i32 = this.requiredParameters, hasRest: bool = this.hasRest): Signature {\n let parameterTypes = this.parameterTypes;\n let numParameterTypes = parameterTypes.length;\n let cloneParameterTypes = new Array(numParameterTypes);\n for (let i = 0; i < numParameterTypes; ++i) {\n unchecked(cloneParameterTypes[i] = parameterTypes[i]);\n }\n return Signature.create(\n this.program,\n cloneParameterTypes,\n this.returnType,\n this.thisType,\n requiredParameters,\n hasRest\n );\n }\n}\n","/**\n * @fileoverview A thin wrapper around Binaryen's C-API.\n *\n * The AssemblyScript compiler utilizes Binaryen's C-API directly. Even\n * though it currently imports binaryen.js, none of the JS APIs it\n * provides are used.\n *\n * @license Apache-2.0\n */\n\nimport { BuiltinNames } from \"./builtins\";\nimport { CommonNames, Target } from \"./common\";\nimport {\n isHighSurrogate,\n isLowSurrogate,\n combineSurrogates,\n SURROGATE_HIGH,\n SURROGATE_LOW\n} from \"./util\";\nimport {\n Type,\n TypeFlags,\n TypeKind\n} from \"./types\";\nimport {\n ElementKind,\n PropertyPrototype\n} from \"./program\";\nimport * as binaryen from \"./glue/binaryen\";\n\n/** A Binaryen-compatible index. */\nexport type Index = binaryen.Index;\n/** Reference to a Binaryen-compatible string. */\nexport type StringRef = binaryen.StringRef;\n/** Reference to a Binaryen module. */\nexport type ModuleRef = binaryen.ModuleRef;\n/** Reference to a Binaryen function. */\nexport type FunctionRef = binaryen.FunctionRef;\n/** Reference to a Binaryen expression. */\nexport type ExpressionRef = binaryen.ExpressionRef;\n/** Reference to a Binaryen global. */\nexport type GlobalRef = binaryen.GlobalRef;\n/** Reference to a Binaryen tag. */\nexport type TagRef = binaryen.TagRef;\n/** Reference to a Binaryen import. */\nexport type ImportRef = binaryen.ImportRef;\n/** Reference to a Binaryen export. */\nexport type ExportRef = binaryen.ExportRef;\n/** Reference to a Binaryen relooper. */\nexport type RelooperRef = binaryen.RelooperRef;\n/** Reference to a Binaryen relooper block. */\nexport type RelooperBlockRef = binaryen.RelooperBlockRef;\n\n// The following constants must be updated by running scripts/update-constants.\n// This is necessary because the functions are not yet callable with Binaryen\n// compiled to WebAssembly, requiring awaiting the ready promise first. Note\n// that this essentially fixes the compiler to specific versions of Binaryen\n// sometimes, because these constants can differ between Binaryen versions.\n\n/** Reference to a Binaryen type. */\nexport type TypeRef = binaryen.TypeRef;\nexport namespace TypeRef {\n // special types\n export const None: TypeRef = 0 /* _BinaryenTypeNone */;\n export const Unreachable: TypeRef = 1 /* _BinaryenTypeUnreachable */;\n // value types\n export const I32: TypeRef = 2 /* _BinaryenTypeInt32 */;\n export const I64: TypeRef = 3 /* _BinaryenTypeInt64 */;\n export const F32: TypeRef = 4 /* _BinaryenTypeFloat32 */;\n export const F64: TypeRef = 5 /* _BinaryenTypeFloat64 */;\n export const V128: TypeRef = 6 /* _BinaryenTypeVec128 */;\n // reference/gc types\n export const Funcref = binaryen._BinaryenTypeFuncref();\n export const Externref = binaryen._BinaryenTypeExternref();\n export const Anyref = binaryen._BinaryenTypeAnyref();\n export const Eqref = binaryen._BinaryenTypeEqref();\n export const Structref = binaryen._BinaryenTypeStructref();\n export const Arrayref = binaryen._BinaryenTypeArrayref();\n export const I31ref = binaryen._BinaryenTypeI31ref();\n export const Stringref = binaryen._BinaryenTypeStringref();\n export const StringviewWTF8 = binaryen._BinaryenTypeStringviewWTF8();\n export const StringviewWTF16 = binaryen._BinaryenTypeStringviewWTF16();\n export const StringviewIter = binaryen._BinaryenTypeStringviewIter();\n export const Noneref = binaryen._BinaryenTypeNullref();\n export const Nofuncref = binaryen._BinaryenTypeNullFuncref();\n export const Noexternref = binaryen._BinaryenTypeNullExternref();\n}\n\n/** Reference to a Binaryen heap type. */\nexport type HeapTypeRef = binaryen.HeapTypeRef;\nexport namespace HeapTypeRef {\n\n // any extern func\n // | | |\n // __ eq __ ? noextern (...)\n // / | \\ | |\n // i31 struct array string nofunc\n // | | | |\n // none (...) (...) ?\n // | |\n // none none\n //\n // where (...) represents the concrete subtypes\n\n export const Extern: HeapTypeRef = 0 /* _BinaryenHeapTypeExt */;\n export const Func: HeapTypeRef = 1 /* _BinaryenHeapTypeFunc */;\n export const Any: HeapTypeRef = 2 /* _BinaryenHeapTypeAny */;\n export const Eq: HeapTypeRef = 3 /* _BinaryenHeapTypeEq */;\n export const I31: HeapTypeRef = 4 /* _BinaryenHeapTypeI31 */;\n export const Struct: HeapTypeRef = 5 /* _BinaryenHeapTypeStruct */;\n export const Array: HeapTypeRef = 6 /* _BinaryenHeapTypeArray */;\n export const String: HeapTypeRef = 7 /* _BinaryenHeapTypeString */;\n export const StringviewWTF8: HeapTypeRef = 8 /* _BinaryenHeapTypeStringviewWTF8 */;\n export const StringviewWTF16: HeapTypeRef = 9 /* _BinaryenHeapTypeStringviewWTF16 */;\n export const StringviewIter: HeapTypeRef = 10 /* _BinaryenHeapTypeStringviewIter */;\n export const None: HeapTypeRef = 11 /* _BinaryenHeapTypeNone */;\n export const Noextern: HeapTypeRef = 12 /* _BinaryenHeapTypeNoext */;\n export const Nofunc: HeapTypeRef = 13 /* _BinaryenHeapTypeNofunc */;\n\n export function isBottom(ht: HeapTypeRef): bool {\n return binaryen._BinaryenHeapTypeIsBottom(ht);\n }\n\n export function getBottom(ht: HeapTypeRef): HeapTypeRef {\n return binaryen._BinaryenHeapTypeGetBottom(ht);\n }\n\n export function isSubtype(ht: HeapTypeRef, superHt: HeapTypeRef): bool {\n return binaryen._BinaryenHeapTypeIsSubType(ht, superHt);\n }\n\n export function leastUpperBound(a: HeapTypeRef, b: HeapTypeRef): HeapTypeRef {\n // see binaryen/src/wasm/wasm-type.cpp\n if (a == b) return a;\n if (getBottom(a) != getBottom(b)) return -1;\n if (isBottom(a)) return b;\n if (isBottom(b)) return a;\n if (a > b) {\n let t = a;\n a = b;\n b = t;\n }\n switch (a) {\n case HeapTypeRef.Extern:\n case HeapTypeRef.Func: return -1;\n case HeapTypeRef.Any: return a;\n case HeapTypeRef.Eq: {\n return b == HeapTypeRef.I31 || b == HeapTypeRef.Struct || b == HeapTypeRef.Array\n ? HeapTypeRef.Eq\n : HeapTypeRef.Any;\n }\n case HeapTypeRef.I31: {\n return b == HeapTypeRef.Struct || b == HeapTypeRef.Array\n ? HeapTypeRef.Eq\n : HeapTypeRef.Any;\n }\n case HeapTypeRef.Struct: {\n return b == HeapTypeRef.Array\n ? HeapTypeRef.Eq\n : HeapTypeRef.Any;\n }\n case HeapTypeRef.Array:\n case HeapTypeRef.String:\n case HeapTypeRef.StringviewWTF8:\n case HeapTypeRef.StringviewWTF16:\n case HeapTypeRef.StringviewIter: return HeapTypeRef.Any;\n }\n assert(false);\n return -1;\n }\n}\n\n/** Packed array element respectively struct field types. */\nexport type PackedType = binaryen.PackedType;\nexport namespace PackedType {\n export const NotPacked: PackedType = 0 /* _BinaryenPackedTypeNotPacked */;\n export const I8: PackedType = 1 /* _BinaryenPackedTypeInt8 */;\n export const I16: PackedType = 2 /* _BinaryenPackedTypeInt16 */;\n}\n\n/** Type builder error reasons. */\nexport type TypeBuilderErrorReason = binaryen.TypeBuilderErrorReason;\nexport namespace TypeBuilderErrorReason {\n /** Indicates a cycle in the supertype relation. */\n export const SelfSupertype: TypeBuilderErrorReason = 0 /* _TypeBuilderErrorReasonSelfSupertype */;\n /** Indicates that the declared supertype of a type is invalid. */\n export const InvalidSupertype: TypeBuilderErrorReason = 1 /* _TypeBuilderErrorReasonInvalidSupertype */;\n /** Indicates that the declared supertype is an invalid forward reference. */\n export const ForwardSupertypeReference: TypeBuilderErrorReason = 2 /* _TypeBuilderErrorReasonForwardSupertypeReference */;\n /** Indicates that a child of a type is an invalid forward reference. */\n export const ForwardChildReference: TypeBuilderErrorReason = 3 /* _TypeBuilderErrorReasonForwardChildReference */;\n /** Converts a type builder error reason to a string. */\n export function toString(reason: TypeBuilderErrorReason): string {\n switch (reason) {\n case SelfSupertype: return \"SelfSupertype\";\n case InvalidSupertype: return \"InvalidSupertype\";\n case ForwardSupertypeReference: return \"ForwardSupertypeReference\";\n case ForwardChildReference: return \"ForwardChildReference\";\n }\n assert(false);\n return \"\";\n }\n}\n\n/** Type system constants. */\nexport type TypeSystem = binaryen.TypeSystem;\nexport namespace TypeSystem {\n export const Isorecursive: TypeSystem = 0 /* _BinaryenTypeSystemIsorecursive */;\n export const Nominal: TypeSystem = 1 /* _BinaryenTypeSystemNominal */;\n}\n\n/** Binaryen feature constants. */\nexport const enum FeatureFlags {\n MVP = 0 /* _BinaryenFeatureMVP */,\n Atomics = 1 /* _BinaryenFeatureAtomics */,\n MutableGlobals = 2 /* _BinaryenFeatureMutableGlobals */,\n TruncSat = 4 /* _BinaryenFeatureNontrappingFPToInt */,\n SIMD = 8 /* _BinaryenFeatureSIMD128 */,\n BulkMemory = 16 /* _BinaryenFeatureBulkMemory */,\n SignExt = 32 /* _BinaryenFeatureSignExt */,\n ExceptionHandling = 64 /* _BinaryenFeatureExceptionHandling */,\n TailCall = 128 /* _BinaryenFeatureTailCall */,\n ReferenceTypes = 256 /* _BinaryenFeatureReferenceTypes */,\n MultiValue = 512 /* _BinaryenFeatureMultivalue */,\n GC = 1024 /* _BinaryenFeatureGC */,\n Memory64 = 2048 /* _BinaryenFeatureMemory64 */,\n RelaxedSIMD = 8192 /* _BinaryenFeatureRelaxedSIMD */,\n ExtendedConst = 16384 /* _BinaryenFeatureExtendedConst */,\n Stringref = 32768 /* _BinaryenFeatureStrings */,\n MultiMemory = 65536 /* _BinaryenFeatureMultiMemories */,\n All = 126975 /* _BinaryenFeatureAll */\n}\n\n/** Binaryen expression id constants. */\nexport const enum ExpressionId {\n Invalid = 0 /* _BinaryenInvalidId */,\n Block = 1 /* _BinaryenBlockId */,\n If = 2 /* _BinaryenIfId */,\n Loop = 3 /* _BinaryenLoopId */,\n Break = 4 /* _BinaryenBreakId */,\n Switch = 5 /* _BinaryenSwitchId */,\n Call = 6 /* _BinaryenCallId */,\n CallIndirect = 7 /* _BinaryenCallIndirectId */,\n LocalGet = 8 /* _BinaryenLocalGetId */,\n LocalSet = 9 /* _BinaryenLocalSetId */,\n GlobalGet = 10 /* _BinaryenGlobalGetId */,\n GlobalSet = 11 /* _BinaryenGlobalSetId */,\n Load = 12 /* _BinaryenLoadId */,\n Store = 13 /* _BinaryenStoreId */,\n Const = 14 /* _BinaryenConstId */,\n Unary = 15 /* _BinaryenUnaryId */,\n Binary = 16 /* _BinaryenBinaryId */,\n Select = 17 /* _BinaryenSelectId */,\n Drop = 18 /* _BinaryenDropId */,\n Return = 19 /* _BinaryenReturnId */,\n MemorySize = 20 /* _BinaryenMemorySizeId */,\n MemoryGrow = 21 /* _BinaryenMemoryGrowId */,\n Nop = 22 /* _BinaryenNopId */,\n Unreachable = 23 /* _BinaryenUnreachableId */,\n AtomicRMW = 24 /* _BinaryenAtomicRMWId */,\n AtomicCmpxchg = 25 /* _BinaryenAtomicCmpxchgId */,\n AtomicWait = 26 /* _BinaryenAtomicWaitId */,\n AtomicNotify = 27 /* _BinaryenAtomicNotifyId */,\n AtomicFence = 28 /* _BinaryenAtomicFenceId */,\n SIMDExtract = 29 /* _BinaryenSIMDExtractId */,\n SIMDReplace = 30 /* _BinaryenSIMDReplaceId */,\n SIMDShuffle = 31 /* _BinaryenSIMDShuffleId */,\n SIMDTernary = 32 /* _BinaryenSIMDTernaryId */,\n SIMDShift = 33 /* _BinaryenSIMDShiftId */,\n SIMDLoad = 34 /* _BinaryenSIMDLoadId */,\n SIMDLoadStoreLane = 35 /* _BinaryenSIMDLoadStoreLaneId */,\n MemoryInit = 36 /* _BinaryenMemoryInitId */,\n DataDrop = 37 /* _BinaryenDataDropId */,\n MemoryCopy = 38 /* _BinaryenMemoryCopyId */,\n MemoryFill = 39 /* _BinaryenMemoryFillId */,\n Pop = 40 /* _BinaryenPopId */,\n RefNull = 41 /* _BinaryenRefNullId */,\n RefIsNull = 42 /* _BinaryenRefIsNullId */,\n RefFunc = 43 /* _BinaryenRefFuncId */,\n RefEq = 44 /* _BinaryenRefEqId */,\n TableGet = 45 /* _BinaryenTableGetId */,\n TableSet = 46 /* _BinaryenTableSetId */,\n TableSize = 47 /* _BinaryenTableSizeId */,\n TableGrow = 48 /* _BinaryenTableGrowId */,\n Try = 49 /* _BinaryenTryId */,\n Throw = 50 /* _BinaryenThrowId */,\n Rethrow = 51 /* _BinaryenRethrowId */,\n TupleMake = 52 /* _BinaryenTupleMakeId */,\n TupleExtract = 53 /* _BinaryenTupleExtractId */,\n I31New = 54 /* _BinaryenI31NewId */,\n I31Get = 55 /* _BinaryenI31GetId */,\n CallRef = 56 /* _BinaryenCallRefId */,\n RefTest = 57 /* _BinaryenRefTestId */,\n RefCast = 58 /* _BinaryenRefCastId */,\n BrOn = 59 /* _BinaryenBrOnId */,\n StructNew = 60 /* _BinaryenStructNewId */,\n StructGet = 61 /* _BinaryenStructGetId */,\n StructSet = 62 /* _BinaryenStructSetId */,\n ArrayNew = 63 /* _BinaryenArrayNewId */,\n ArrayNewSeg = 64 /* TODO_BinaryenArraySegId */,\n ArrayInit = 65 /* _BinaryenArrayInitId */,\n ArrayGet = 66 /* _BinaryenArrayGetId */,\n ArraySet = 67 /* _BinaryenArraySetId */,\n ArrayLen = 68 /* _BinaryenArrayLenId */,\n ArrayCopy = 69 /* _BinaryenArrayCopyId */,\n RefAs = 70 /* _BinaryenRefAsId */,\n StringNew = 71 /* _BinaryenStringNewId */,\n StringConst = 72 /* _BinaryenStringConstId */,\n StringMeasure = 73 /* _BinaryenStringMeasureId */,\n StringEncode = 74 /* _BinaryenStringEncodeId */,\n StringConcat = 75 /* _BinaryenStringConcatId */,\n StringEq = 76 /* _BinaryenStringEqId */,\n StringAs = 77 /* _BinaryenStringAsId */,\n StringWTF8Advance = 78 /* _BinaryenStringWTF8AdvanceId */,\n StringWTF16Get = 79 /* _BinaryenStringWTF16GetId */,\n StringIterNext = 80 /* _BinaryenStringIterNextId */,\n StringIterMove = 81 /* _BinaryenStringIterMoveId */,\n StringSliceWTF = 82 /* _BinaryenStringSliceWTFId */,\n StringSliceIter = 83 /* _BinaryenStringSliceIterId */\n}\n\n/** Binaryen external kind constants. */\nexport const enum ExternalKind {\n Function = 0 /* _BinaryenExternalFunction */,\n Table = 1 /* _BinaryenExternalTable */,\n Memory = 2 /* _BinaryenExternalMemory */,\n Global = 3 /* _BinaryenExternalGlobal */,\n Tag = 4 /* _BinaryenExternalTag */\n}\n\n/** Binaryen unary operation constants. */\nexport const enum UnaryOp {\n /** i32.clz */\n ClzI32 = 0 /* _BinaryenClzInt32 */,\n /** i64.clz */\n ClzI64 = 1 /* _BinaryenClzInt64 */,\n /** i32.ctz */\n CtzI32 = 2 /* _BinaryenCtzInt32 */,\n /** i64.ctz */\n CtzI64 = 3 /* _BinaryenCtzInt64 */,\n /** i32.popcnt */\n PopcntI32 = 4 /* _BinaryenPopcntInt32 */,\n /** i64.popcnt */\n PopcntI64 = 5 /* _BinaryenPopcntInt64 */,\n /** f32.neg */\n NegF32 = 6 /* _BinaryenNegFloat32 */,\n /** f64.neg */\n NegF64 = 7 /* _BinaryenNegFloat64 */,\n /** f32.abs */\n AbsF32 = 8 /* _BinaryenAbsFloat32 */,\n /** f64.abs */\n AbsF64 = 9 /* _BinaryenAbsFloat64 */,\n /** f32.ceil */\n CeilF32 = 10 /* _BinaryenCeilFloat32 */,\n /** f64.ceil */\n CeilF64 = 11 /* _BinaryenCeilFloat64 */,\n /** f32.floor */\n FloorF32 = 12 /* _BinaryenFloorFloat32 */,\n /** f64.floor */\n FloorF64 = 13 /* _BinaryenFloorFloat64 */,\n /** f32.trunc */\n TruncF32 = 14 /* _BinaryenTruncFloat32 */,\n /** f64.trunc */\n TruncF64 = 15 /* _BinaryenTruncFloat64 */,\n /** f32.nearest */\n NearestF32 = 16 /* _BinaryenNearestFloat32 */,\n /** f64.nearest */\n NearestF64 = 17 /* _BinaryenNearestFloat64 */,\n /** f32.sqrt */\n SqrtF32 = 18 /* _BinaryenSqrtFloat32 */,\n /** f64.sqrt */\n SqrtF64 = 19 /* _BinaryenSqrtFloat64 */,\n /** i32.eqz */\n EqzI32 = 20 /* _BinaryenEqZInt32 */,\n /** i64.eqz */\n EqzI64 = 21 /* _BinaryenEqZInt64 */,\n /** i64.extend_i32_s */\n ExtendI32ToI64 = 22 /* _BinaryenExtendSInt32 */,\n /** i64.extend_i32_u */\n ExtendU32ToU64 = 23 /* _BinaryenExtendUInt32 */,\n /** i32.wrap_i64 */\n WrapI64ToI32 = 24 /* _BinaryenWrapInt64 */,\n /** i32.trunc_f32_s */\n TruncF32ToI32 = 25 /* _BinaryenTruncSFloat32ToInt32 */,\n /** i64.trunc_f32_s */\n TruncF32ToI64 = 26 /* _BinaryenTruncSFloat32ToInt64 */,\n /** i32.trunc_f32_u */\n TruncF32ToU32 = 27 /* _BinaryenTruncUFloat32ToInt32 */,\n /** i64.trunc_f32_u */\n TruncF32ToU64 = 28 /* _BinaryenTruncUFloat32ToInt64 */,\n /** i32.trunc_f64_s */\n TruncF64ToI32 = 29 /* _BinaryenTruncSFloat64ToInt32 */,\n /** i64.trunc_f64_s */\n TruncF64ToI64 = 30 /* _BinaryenTruncSFloat64ToInt64 */,\n /** i32.trunc_f64_u */\n TruncF64ToU32 = 31 /* _BinaryenTruncUFloat64ToInt32 */,\n /** i64.trunc_f64_u */\n TruncF64ToU64 = 32 /* _BinaryenTruncUFloat64ToInt64 */,\n /** i32.reinterpret_f32 */\n ReinterpretF32ToI32 = 33 /* _BinaryenReinterpretFloat32 */,\n /** i64.reinterpret_f64 */\n ReinterpretF64ToI64 = 34 /* _BinaryenReinterpretFloat64 */,\n /** f32.convert_i32_s */\n ConvertI32ToF32 = 35 /* _BinaryenConvertSInt32ToFloat32 */,\n /** f64.convert_i32_s */\n ConvertI32ToF64 = 36 /* _BinaryenConvertSInt32ToFloat64 */,\n /** f32.convert_i32_u */\n ConvertU32ToF32 = 37 /* _BinaryenConvertUInt32ToFloat32 */,\n /** f64.convert_i32_u */\n ConvertU32ToF64 = 38 /* _BinaryenConvertUInt32ToFloat64 */,\n /** f32.convert_i64_s */\n ConvertI64ToF32 = 39 /* _BinaryenConvertSInt64ToFloat32 */,\n /** f64.convert_i64_s */\n ConvertI64ToF64 = 40 /* _BinaryenConvertSInt64ToFloat64 */,\n /** f32.convert_i64_u */\n ConvertU64ToF32 = 41 /* _BinaryenConvertUInt64ToFloat32 */,\n /** f64.convert_i64_u */\n ConvertU64ToF64 = 42 /* _BinaryenConvertUInt64ToFloat64 */,\n /** f64.promote.f32 */\n PromoteF32ToF64 = 43 /* _BinaryenPromoteFloat32 */,\n /** f32.demote_f64 */\n DemoteF64ToF32 = 44 /* _BinaryenDemoteFloat64 */,\n /** f32.reinterpret_i32 */\n ReinterpretI32ToF32 = 45 /* _BinaryenReinterpretInt32 */,\n /** f64.reinterpret_i64 */\n ReinterpretI64ToF64 = 46 /* _BinaryenReinterpretInt64 */,\n\n // see: https://github.com/WebAssembly/sign-extension-ops\n\n /** i32.extend8_s */\n Extend8I32 = 47 /* _BinaryenExtendS8Int32 */,\n /** i32.extend16_s */\n Extend16I32 = 48 /* _BinaryenExtendS16Int32 */,\n /** i64.extend8_s */\n Extend8I64 = 49 /* _BinaryenExtendS8Int64 */,\n /** i64.extend16_s */\n Extend16I64 = 50 /* _BinaryenExtendS16Int64 */,\n /** i64.extend32_s (i64 in, i64 out) */\n Extend32I64 = 51 /* _BinaryenExtendS32Int64 */,\n\n // see: https://github.com/WebAssembly/nontrapping-float-to-int-conversions\n\n /** i32.trunc_sat_f32_s */\n TruncSatF32ToI32 = 52 /* _BinaryenTruncSatSFloat32ToInt32 */,\n /** i32.trunc_sat_f32_u */\n TruncSatF32ToU32 = 53 /* _BinaryenTruncSatUFloat32ToInt32 */,\n /** i32.trunc_sat_f64_s */\n TruncSatF64ToI32 = 54 /* _BinaryenTruncSatSFloat64ToInt32 */,\n /** i32.trunc_sat_f64_u */\n TruncSatF64ToU32 = 55 /* _BinaryenTruncSatUFloat64ToInt32 */,\n /** i64.trunc_sat_f32_s */\n TruncSatF32ToI64 = 56 /* _BinaryenTruncSatSFloat32ToInt64 */,\n /** i64.trunc_sat_f32_u */\n TruncSatF32ToU64 = 57 /* _BinaryenTruncSatUFloat32ToInt64 */,\n /** i64.trunc_sat_f64_s */\n TruncSatF64ToI64 = 58 /* _BinaryenTruncSatSFloat64ToInt64 */,\n /** i64.trunc_sat_f64_u */\n TruncSatF64ToU64 = 59 /* _BinaryenTruncSatUFloat64ToInt64 */,\n\n // see: https://github.com/WebAssembly/simd\n\n /** i8x16.splat */\n SplatI8x16 = 60 /* _BinaryenSplatVecI8x16 */,\n /** i16x8.splat */\n SplatI16x8 = 61 /* _BinaryenSplatVecI16x8 */,\n /** i32x4.splat */\n SplatI32x4 = 62 /* _BinaryenSplatVecI32x4 */,\n /** i64x2.splat */\n SplatI64x2 = 63 /* _BinaryenSplatVecI64x2 */,\n /** f32x4.splat */\n SplatF32x4 = 64 /* _BinaryenSplatVecF32x4 */,\n /** f64x2.splat */\n SplatF64x2 = 65 /* _BinaryenSplatVecF64x2 */,\n /** v128.not */\n NotV128 = 66 /* _BinaryenNotVec128 */,\n /** v128.any_true */\n AnyTrueV128 = 67 /* _BinaryenAnyTrueVec128 */,\n /** i8x16.abs */\n AbsI8x16 = 68 /* _BinaryenAbsVecI8x16 */,\n /** i8x16.neg */\n NegI8x16 = 69 /* _BinaryenNegVecI8x16 */,\n /** i8x16.all_true */\n AllTrueI8x16 = 70 /* _BinaryenAllTrueVecI8x16 */,\n /** i8x16.bitmask */\n BitmaskI8x16 = 71 /* _BinaryenBitmaskVecI8x16 */,\n /** i8x16.popcnt */\n PopcntI8x16 = 72 /* _BinaryenPopcntVecI8x16 */,\n /** i16x8.abs */\n AbsI16x8 = 73 /* _BinaryenAbsVecI16x8 */,\n /** i16x8.neg */\n NegI16x8 = 74 /* _BinaryenNegVecI16x8 */,\n /** i16x8.all_true */\n AllTrueI16x8 = 75 /* _BinaryenAllTrueVecI16x8 */,\n /** i16x8.bitmask */\n BitmaskI16x8 = 76 /* _BinaryenBitmaskVecI16x8 */,\n /** i32x4.abs */\n AbsI32x4 = 77 /* _BinaryenAbsVecI32x4 */,\n /** i32x4.neg */\n NegI32x4 = 78 /* _BinaryenNegVecI32x4 */,\n /** i32x4.all_true */\n AllTrueI32x4 = 79 /* _BinaryenAllTrueVecI32x4 */,\n /** i32x4.bitmask */\n BitmaskI32x4 = 80 /* _BinaryenBitmaskVecI32x4 */,\n /** i64x2.abs */\n AbsI64x2 = 81 /* _BinaryenAbsVecI64x2 */,\n /** i64x2.neg */\n NegI64x2 = 82 /* _BinaryenNegVecI64x2 */,\n /** i64x2.all_true */\n AllTrueI64x2 = 83 /* _BinaryenAllTrueVecI64x2 */,\n /** i64x2.bitmask */\n BitmaskI64x2 = 84 /* _BinaryenBitmaskVecI64x2 */,\n /** f32x4.abs */\n AbsF32x4 = 85 /* _BinaryenAbsVecF32x4 */,\n /** f32x4.neg */\n NegF32x4 = 86 /* _BinaryenNegVecF32x4 */,\n /** f32x4.sqrt */\n SqrtF32x4 = 87 /* _BinaryenSqrtVecF32x4 */,\n /** f32x4.ceil */\n CeilF32x4 = 88 /* _BinaryenCeilVecF32x4 */,\n /** f32x4.floor */\n FloorF32x4 = 89 /* _BinaryenFloorVecF32x4 */,\n /** f32x4.trunc */\n TruncF32x4 = 90 /* BinaryenTruncVecF32x4 */,\n /** f32x4.nearest */\n NearestF32x4 = 91 /* BinaryenNearestVecF32x4 */,\n /** f64x2.abs */\n AbsF64x2 = 92 /* _BinaryenAbsVecF64x2 */,\n /** f64x2.neg */\n NegF64x2 = 93 /* _BinaryenNegVecF64x2 */,\n /** f64x2.sqrt */\n SqrtF64x2 = 94 /* _BinaryenSqrtVecF64x2 */,\n /** f64x2.ceil */\n CeilF64x2 = 95 /* _BinaryenCeilVecF64x2 */,\n /** f64x2.floor */\n FloorF64x2 = 96 /* _BinaryenFloorVecF64x2 */,\n /** f64x2.trunc */\n TruncF64x2 = 97 /* _BinaryenTruncVecF64x2 */,\n /** f64x2.nearest */\n NearestF64x2 = 98 /* _BinaryenNearestVecF64x2 */,\n /** i16x8.extadd_pairwise_i8x16_s */\n ExtaddPairwiseI8x16ToI16x8 = 99 /* _BinaryenExtAddPairwiseSVecI8x16ToI16x8 */,\n /** i16x8.extadd_pairwise.i8x16_u */\n ExtaddPairwiseU8x16ToU16x8 = 100 /* _BinaryenExtAddPairwiseUVecI8x16ToI16x8 */,\n /** i32x4.extadd_pairwise.i16x8_s */\n ExtaddPairwiseI16x8ToI32x4 = 101 /* _BinaryenExtAddPairwiseSVecI16x8ToI32x4 */,\n /** i32x4.extadd_pairwise.i64x8_u */\n ExtaddPairwiseU16x8ToU32x4 = 102 /* _BinaryenExtAddPairwiseUVecI16x8ToI32x4 */,\n /** i32x4.trunc_sat_f32x4_s */\n TruncSatF32x4ToI32x4 = 103 /* _BinaryenTruncSatSVecF32x4ToVecI32x4 */,\n /** i32x4.trunc_sat_f32x4_u */\n TruncSatF32x4ToU32x4 = 104 /* _BinaryenTruncSatUVecF32x4ToVecI32x4 */,\n /** f32x4.convert_i32x4_s */\n ConvertI32x4ToF32x4 = 105 /* _BinaryenConvertSVecI32x4ToVecF32x4 */,\n /** f32x4.convert_i32x4_u */\n ConvertU32x4ToF32x4 = 106 /* _BinaryenConvertUVecI32x4ToVecF32x4 */,\n /** i16x8.extend_low_i8x16_s */\n ExtendLowI8x16ToI16x8 = 107 /* _BinaryenExtendLowSVecI8x16ToVecI16x8 */,\n /** i16x8.extend_high_i8x16_s */\n ExtendHighI8x16ToI16x8 = 108 /* _BinaryenExtendHighSVecI8x16ToVecI16x8 */,\n /** i16x8.extend_low_i8x16_u */\n ExtendLowU8x16ToU16x8 = 109 /* _BinaryenExtendLowUVecI8x16ToVecI16x8 */,\n /** i16x8.extend_high_i8x16_u */\n ExtendHighU8x16ToU16x8 = 110 /* _BinaryenExtendHighUVecI8x16ToVecI16x8 */,\n /** i32x4.extend_low_i16x8_s */\n ExtendLowI16x8ToI32x4 = 111 /* _BinaryenExtendLowSVecI16x8ToVecI32x4 */,\n /** i32x4.extend_high_i16x8_s */\n ExtendHighI16x8ToI32x4 = 112 /* _BinaryenExtendHighSVecI16x8ToVecI32x4 */,\n /** i32x4.extend_low_i16x8_u */\n ExtendLowU16x8ToU32x4 = 113 /* _BinaryenExtendLowUVecI16x8ToVecI32x4 */,\n /** i32x4.extend_high_i16x8_u */\n ExtendHighU16x8ToU32x4 = 114 /* _BinaryenExtendHighUVecI16x8ToVecI32x4 */,\n /** i64x2.extend_low_i32x4_s */\n ExtendLowI32x4ToI64x2 = 115 /* _BinaryenExtendLowSVecI32x4ToVecI64x2 */,\n /** i64x2.extend_high_i32x4_s */\n ExtendHighI32x4ToI64x2 = 116 /* _BinaryenExtendHighSVecI32x4ToVecI64x2 */,\n /** i64x2.extend_low_i32x4_u */\n ExtendLowU32x4ToU64x2 = 117 /* _BinaryenExtendLowUVecI32x4ToVecI64x2 */,\n /** i64x2.extend_high_i32x4_u */\n ExtendHighU32x4ToU64x2 = 118 /* _BinaryenExtendHighUVecI32x4ToVecI64x2 */,\n /** f32x4.convert_i32x4_s */\n ConvertLowI32x4ToF64x2 = 119 /* _BinaryenConvertLowSVecI32x4ToVecF64x2 */,\n /** f32x4.convert_i32x4_u */\n ConvertLowU32x4ToF64x2 = 120 /* _BinaryenConvertLowUVecI32x4ToVecF64x2 */,\n /** i32x4.trunc_sat_f64x2_s_zero */\n TruncSatF64x2ToI32x4Zero = 121 /* _BinaryenTruncSatZeroSVecF64x2ToVecI32x4 */,\n /** i32x4.trunc_sat_f64x2_u_zero */\n TruncSatF64x2ToU32x4Zero = 122 /* _BinaryenTruncSatZeroUVecF64x2ToVecI32x4 */,\n /** f32x4.demote_f64x2_zero */\n DemoteZeroF64x2ToF32x4 = 123 /* _BinaryenDemoteZeroVecF64x2ToVecF32x4 */,\n /** f64x2.promote_low_f32x4 */\n PromoteLowF32x4ToF64x2 = 124 /* _BinaryenPromoteLowVecF32x4ToVecF64x2 */,\n\n // see: https://github.com/WebAssembly/relaxed-simd\n\n /** i32x4.relaxed_trunc_f32x4_s */\n RelaxedTruncF32x4ToI32x4 = 125 /* TODO_BinaryenRelaxedTruncSVecF32x4ToVecI32x4 */,\n /** i32x4.relaxed_trunc_f32x4_u */\n RelaxedTruncF32x4ToU32x4 = 126 /* TODO_BinaryenRelaxedTruncUVecF32x4ToVecI32x4 */,\n /** i32x4.relaxed_trunc_f64x2_s_zero */\n RelaxedTruncF64x2ToI32x4Zero = 127 /* TODO_BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4 */,\n /** i32x4.relaxed_trunc_f64x2_u_zero */\n RelaxedTruncF64x2ToU32x4Zero = 128 /* TODO_BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4 */,\n\n _last = RelaxedTruncF64x2ToU32x4Zero,\n\n // Target dependent\n\n /** i32.clz or i64.clz, depending on target word size */\n ClzSize,\n /** i32.ctz or i64.ctz, depending on target word size */\n CtzSize,\n /** i32.popcnt or i64.popcnt, depending on target word size */\n PopcntSize,\n /** i32.eqz or i64.eqz, depending on target word size */\n EqzSize\n}\n\n/** Binaryen binary operation constants. */\nexport const enum BinaryOp {\n /** i32.add */\n AddI32 = 0 /* _BinaryenAddInt32 */,\n /** i32.sub */\n SubI32 = 1 /* _BinaryenSubInt32 */,\n /** i32.mul */\n MulI32 = 2 /* _BinaryenMulInt32 */,\n /** i32.div_s */\n DivI32 = 3 /* _BinaryenDivSInt32 */,\n /** i32.div_u */\n DivU32 = 4 /* _BinaryenDivUInt32 */,\n /** i32.rem_s */\n RemI32 = 5 /* _BinaryenRemSInt32 */,\n /** i32.rem_u */\n RemU32 = 6 /* _BinaryenRemUInt32 */,\n /** i32.and */\n AndI32 = 7 /* _BinaryenAndInt32 */,\n /** i32.or */\n OrI32 = 8 /* _BinaryenOrInt32 */,\n /** i32.xor */\n XorI32 = 9 /* _BinaryenXorInt32 */,\n /** i32.shl */\n ShlI32 = 10 /* _BinaryenShlInt32 */,\n /** i32.shr_s */\n ShrI32 = 11 /* _BinaryenShrSInt32 */,\n /** i32.shr_u */\n ShrU32 = 12 /* _BinaryenShrUInt32 */,\n /** i32.rotl */\n RotlI32 = 13 /* _BinaryenRotLInt32 */,\n /** i32.rotr */\n RotrI32 = 14 /* _BinaryenRotRInt32 */,\n /** i32.eq */\n EqI32 = 15 /* _BinaryenEqInt32 */,\n /** i32.ne */\n NeI32 = 16 /* _BinaryenNeInt32 */,\n /** i32.lt_s */\n LtI32 = 17 /* _BinaryenLtSInt32 */,\n /** i32.lt_u */\n LtU32 = 18 /* _BinaryenLtUInt32 */,\n /** i32.le_s */\n LeI32 = 19 /* _BinaryenLeSInt32 */,\n /** i32.le_u */\n LeU32 = 20 /* _BinaryenLeUInt32 */,\n /** i32.gt_s */\n GtI32 = 21 /* _BinaryenGtSInt32 */,\n /** i32.gt_u */\n GtU32 = 22 /* _BinaryenGtUInt32 */,\n /** i32.ge_s */\n GeI32 = 23 /* _BinaryenGeSInt32 */,\n /** i32.ge_u */\n GeU32 = 24 /* _BinaryenGeUInt32 */,\n /** i64.add */\n AddI64 = 25 /* _BinaryenAddInt64 */,\n /** i64.sub */\n SubI64 = 26 /* _BinaryenSubInt64 */,\n /** i64.mul */\n MulI64 = 27 /* _BinaryenMulInt64 */,\n /** i64.div_s */\n DivI64 = 28 /* _BinaryenDivSInt64 */,\n /** i64.div_u */\n DivU64 = 29 /* _BinaryenDivUInt64 */,\n /** i64.rem_s */\n RemI64 = 30 /* _BinaryenRemSInt64 */,\n /** i64.rem_u */\n RemU64 = 31 /* _BinaryenRemUInt64 */,\n /** i64.and */\n AndI64 = 32 /* _BinaryenAndInt64 */,\n /** i64.or */\n OrI64 = 33 /* _BinaryenOrInt64 */,\n /** i64.xor */\n XorI64 = 34 /* _BinaryenXorInt64 */,\n /** i64.shl */\n ShlI64 = 35 /* _BinaryenShlInt64 */,\n /** i64.shr_s */\n ShrI64 = 36 /* _BinaryenShrSInt64 */,\n /** i64.shr_u */\n ShrU64 = 37 /* _BinaryenShrUInt64 */,\n /** i64.rotl */\n RotlI64 = 38 /* _BinaryenRotLInt64 */,\n /** i64.rotr */\n RotrI64 = 39 /* _BinaryenRotRInt64 */,\n /** i64.eq */\n EqI64 = 40 /* _BinaryenEqInt64 */,\n /** i64.ne */\n NeI64 = 41 /* _BinaryenNeInt64 */,\n /** i64.lt_s */\n LtI64 = 42 /* _BinaryenLtSInt64 */,\n /** i64.lt_u */\n LtU64 = 43 /* _BinaryenLtUInt64 */,\n /** i64.le_s */\n LeI64 = 44 /* _BinaryenLeSInt64 */,\n /** i64.le_u */\n LeU64 = 45 /* _BinaryenLeUInt64 */,\n /** i64.gt_s */\n GtI64 = 46 /* _BinaryenGtSInt64 */,\n /** i64.gt_u */\n GtU64 = 47 /* _BinaryenGtUInt64 */,\n /** i64.ge_s */\n GeI64 = 48 /* _BinaryenGeSInt64 */,\n /** i64.ge_u */\n GeU64 = 49 /* _BinaryenGeUInt64 */,\n /** f32.add */\n AddF32 = 50 /* _BinaryenAddFloat32 */,\n /** f32.sub */\n SubF32 = 51 /* _BinaryenSubFloat32 */,\n /** f32.mul */\n MulF32 = 52 /* _BinaryenMulFloat32 */,\n /** f32.div */\n DivF32 = 53 /* _BinaryenDivFloat32 */,\n /** f32.copysign */\n CopysignF32 = 54 /* _BinaryenCopySignFloat32 */,\n /** f32.min */\n MinF32 = 55 /* _BinaryenMinFloat32 */,\n /** f32.max */\n MaxF32 = 56 /* _BinaryenMaxFloat32 */,\n /** f32.eq */\n EqF32 = 57 /* _BinaryenEqFloat32 */,\n /** f32.ne */\n NeF32 = 58 /* _BinaryenNeFloat32 */,\n /** f32.lt */\n LtF32 = 59 /* _BinaryenLtFloat32 */,\n /** f32.le */\n LeF32 = 60 /* _BinaryenLeFloat32 */,\n /** f32.gt */\n GtF32 = 61 /* _BinaryenGtFloat32 */,\n /** f32.ge */\n GeF32 = 62 /* _BinaryenGeFloat32 */,\n /** f64.add */\n AddF64 = 63 /* _BinaryenAddFloat64 */,\n /** f64.sub */\n SubF64 = 64 /* _BinaryenSubFloat64 */,\n /** f64.mul */\n MulF64 = 65 /* _BinaryenMulFloat64 */,\n /** f64.div */\n DivF64 = 66 /* _BinaryenDivFloat64 */,\n /** f64.copysign */\n CopysignF64 = 67 /* _BinaryenCopySignFloat64 */,\n /** f64.min */\n MinF64 = 68 /* _BinaryenMinFloat64 */,\n /** f64.max */\n MaxF64 = 69 /* _BinaryenMaxFloat64 */,\n /** f64.eq */\n EqF64 = 70 /* _BinaryenEqFloat64 */,\n /** f64.ne */\n NeF64 = 71 /* _BinaryenNeFloat64 */,\n /** f64.lt */\n LtF64 = 72 /* _BinaryenLtFloat64 */,\n /** f64.le */\n LeF64 = 73 /* _BinaryenLeFloat64 */,\n /** f64.gt */\n GtF64 = 74 /* _BinaryenGtFloat64 */,\n /** f64.ge */\n GeF64 = 75 /* _BinaryenGeFloat64 */,\n\n // see: https://github.com/WebAssembly/simd\n\n /** i8x16.eq */\n EqI8x16 = 76 /* _BinaryenEqVecI8x16 */,\n /** i8x16.he */\n NeI8x16 = 77 /* _BinaryenNeVecI8x16 */,\n /** i8x16.lt_s */\n LtI8x16 = 78 /* _BinaryenLtSVecI8x16 */,\n /** i8x16.lt_u */\n LtU8x16 = 79 /* _BinaryenLtUVecI8x16 */,\n /** i8x16.gt_s */\n GtI8x16 = 80 /* _BinaryenGtSVecI8x16 */,\n /** i8x16.gt_u */\n GtU8x16 = 81 /* _BinaryenGtUVecI8x16 */,\n /** i8x16.le_s */\n LeI8x16 = 82 /* _BinaryenLeSVecI8x16 */,\n /** i8x16.le_u */\n LeU8x16 = 83 /* _BinaryenLeUVecI8x16 */,\n /** i8x16.ge_s */\n GeI8x16 = 84 /* _BinaryenGeSVecI8x16 */,\n /** i8x16.ge_u */\n GeU8x16 = 85 /* _BinaryenGeUVecI8x16 */,\n /** i16x8.eq */\n EqI16x8 = 86 /* _BinaryenEqVecI16x8 */,\n /** i16x8.ne */\n NeI16x8 = 87 /* _BinaryenNeVecI16x8 */,\n /** i16x8.lt_s */\n LtI16x8 = 88 /* _BinaryenLtSVecI16x8 */,\n /** i16x8.lt_u */\n LtU16x8 = 89 /* _BinaryenLtUVecI16x8 */,\n /** i16x8.gt_s */\n GtI16x8 = 90 /* _BinaryenGtSVecI16x8 */,\n /** i16x8.gt_u */\n GtU16x8 = 91 /* _BinaryenGtUVecI16x8 */,\n /** i16x8.le_s */\n LeI16x8 = 92 /* _BinaryenLeSVecI16x8 */,\n /** i16x8.le_u */\n LeU16x8 = 93 /* _BinaryenLeUVecI16x8 */,\n /** i16x8.ge_s */\n GeI16x8 = 94 /* _BinaryenGeSVecI16x8 */,\n /** i16x8.ge_u */\n GeU16x8 = 95 /* _BinaryenGeUVecI16x8 */,\n /** i32x4.eq */\n EqI32x4 = 96 /* _BinaryenEqVecI32x4 */,\n /** i32x4.ne */\n NeI32x4 = 97 /* _BinaryenNeVecI32x4 */,\n /** i32x4.lt_s */\n LtI32x4 = 98 /* _BinaryenLtSVecI32x4 */,\n /** i32x4.lt_u */\n LtU32x4 = 99 /* _BinaryenLtUVecI32x4 */,\n /** i32x4.gt_s */\n GtI32x4 = 100 /* _BinaryenGtSVecI32x4 */,\n /** i32x4.gt_u */\n GtU32x4 = 101 /* _BinaryenGtUVecI32x4 */,\n /** i32x4.le_s */\n LeI32x4 = 102 /* _BinaryenLeSVecI32x4 */,\n /** i32x4.le_u */\n LeU32x4 = 103 /* _BinaryenLeUVecI32x4 */,\n /** i32x4.ge_s */\n GeI32x4 = 104 /* _BinaryenGeSVecI32x4 */,\n /** i32x4.ge_u */\n GeU32x4 = 105 /* _BinaryenGeUVecI32x4 */,\n /** i64x2.eq */\n EqI64x2 = 106 /* _BinaryenEqVecI64x2 */,\n /** i64x2.ne */\n NeI64x2 = 107 /* _BinaryenNeVecI64x2 */,\n /** i64x2.lt_s */\n LtI64x2 = 108 /* _BinaryenLtSVecI64x2 */,\n /** i64x2.gt_s */\n GtI64x2 = 109 /* _BinaryenGtSVecI64x2 */,\n /** i64x2.le_s */\n LeI64x2 = 110 /* _BinaryenLeSVecI64x2 */,\n /** i64x2.ge_s */\n GeI64x2 = 111 /* _BinaryenGeSVecI64x2 */,\n /** f32x4.eq */\n EqF32x4 = 112 /* _BinaryenEqVecF32x4 */,\n /** f32x4.ne */\n NeF32x4 = 113 /* _BinaryenNeVecF32x4 */,\n /** f32x4.lt */\n LtF32x4 = 114 /* _BinaryenLtVecF32x4 */,\n /** f32x4.gt */\n GtF32x4 = 115 /* _BinaryenGtVecF32x4 */,\n /** f32x4.le */\n LeF32x4 = 116 /* _BinaryenLeVecF32x4 */,\n /** f32x4.ge */\n GeF32x4 = 117 /* _BinaryenGeVecF32x4 */,\n /** f64x2.eq */\n EqF64x2 = 118 /* _BinaryenEqVecF64x2 */,\n /** f64x2.ne */\n NeF64x2 = 119 /* _BinaryenNeVecF64x2 */,\n /** f64x2.lt */\n LtF64x2 = 120 /* _BinaryenLtVecF64x2 */,\n /** f64x2.gt */\n GtF64x2 = 121 /* _BinaryenGtVecF64x2 */,\n /** f64x2.le */\n LeF64x2 = 122 /* _BinaryenLeVecF64x2 */,\n /** f64x2.ge */\n GeF64x2 = 123 /* _BinaryenGeVecF64x2 */,\n /** v128.and */\n AndV128 = 124 /* _BinaryenAndVec128 */,\n /** v128.or */\n OrV128 = 125 /* _BinaryenOrVec128 */,\n /** v128.xor */\n XorV128 = 126 /* _BinaryenXorVec128 */,\n /** v128.andnot */\n AndnotV128 = 127 /* _BinaryenAndNotVec128 */,\n /** i8x16.add */\n AddI8x16 = 128 /* _BinaryenAddVecI8x16 */,\n /** i8x16.add_sat_s */\n AddSatI8x16 = 129 /* _BinaryenAddSatSVecI8x16 */,\n /** i8x16.add_sat_u */\n AddSatU8x16 = 130 /* _BinaryenAddSatUVecI8x16 */,\n /** i8x16.sub */\n SubI8x16 = 131 /* _BinaryenSubVecI8x16 */,\n /** i8x16.sub_sat_s */\n SubSatI8x16 = 132 /* _BinaryenSubSatSVecI8x16 */,\n /** i8x16.sub_sat_u */\n SubSatU8x16 = 133 /* _BinaryenSubSatUVecI8x16 */,\n /** i8x16.min_s */\n MinI8x16 = 134 /* _BinaryenMinSVecI8x16 */,\n /** i8x16.min_u */\n MinU8x16 = 135 /* _BinaryenMinUVecI8x16 */,\n /** i8x16.max_s */\n MaxI8x16 = 136 /* _BinaryenMaxSVecI8x16 */,\n /** i8x16.max_u */\n MaxU8x16 = 137 /* _BinaryenMaxUVecI8x16 */,\n /** i8x16.avgr_u */\n AvgrU8x16 = 138 /* _BinaryenAvgrUVecI8x16 */,\n /** i16x8.add */\n AddI16x8 = 139 /* _BinaryenAddVecI16x8 */,\n /** i16x8.add_sat_s */\n AddSatI16x8 = 140 /* _BinaryenAddSatSVecI16x8 */,\n /** i16x8.add_sat_u */\n AddSatU16x8 = 141 /* _BinaryenAddSatUVecI16x8 */,\n /** i16x8.sub */\n SubI16x8 = 142 /* _BinaryenSubVecI16x8 */,\n /** i16x8.sub_sat_s */\n SubSatI16x8 = 143 /* _BinaryenSubSatSVecI16x8 */,\n /** i16x8.sub_sat_u */\n SubSatU16x8 = 144 /* _BinaryenSubSatUVecI16x8 */,\n /** i16x8.mul */\n MulI16x8 = 145 /* _BinaryenMulVecI16x8 */,\n /** i16x8.min_s */\n MinI16x8 = 146 /* _BinaryenMinSVecI16x8 */,\n /** i16x8.min_u */\n MinU16x8 = 147 /* _BinaryenMinUVecI16x8 */,\n /** i16x8.max_s */\n MaxI16x8 = 148 /* _BinaryenMaxSVecI16x8 */,\n /** i16x8.max_u */\n MaxU16x8 = 149 /* _BinaryenMaxUVecI16x8 */,\n /** i16x8.avgr_u */\n AvgrU16x8 = 150 /* _BinaryenAvgrUVecI16x8 */,\n /** i16x8.q15mulr_sat_s */\n Q15mulrSatI16x8 = 151 /* _BinaryenQ15MulrSatSVecI16x8 */,\n /** i16x8.extmul_low_i8x16_s */\n ExtmulLowI16x8 = 152 /* _BinaryenExtMulLowSVecI16x8 */,\n /** i16x8.extmul_high_i8x16_s */\n ExtmulHighI16x8 = 153 /* _BinaryenExtMulHighSVecI16x8 */,\n /** i16x8.extmul_low_i8x16_u */\n ExtmulLowU16x8 = 154 /* _BinaryenExtMulLowUVecI16x8 */,\n /** i16x8.extmul_high_i8x16_u */\n ExtmulHighU16x8 = 155 /* _BinaryenExtMulHighUVecI16x8 */,\n /** i32x4.add */\n AddI32x4 = 156 /* _BinaryenAddVecI32x4 */,\n /** i32x4.sub */\n SubI32x4 = 157 /* _BinaryenSubVecI32x4 */,\n /** i32x4.mul */\n MulI32x4 = 158 /* _BinaryenMulVecI32x4 */,\n /** i32x4.min_s */\n MinI32x4 = 159 /* _BinaryenMinSVecI32x4 */,\n /** i32x4.min_u */\n MinU32x4 = 160 /* _BinaryenMinUVecI32x4 */,\n /** i32x4.max_s */\n MaxI32x4 = 161 /* _BinaryenMaxSVecI32x4 */,\n /** i32x4.max_u */\n MaxU32x4 = 162 /* _BinaryenMaxUVecI32x4 */,\n /** i32x4.dot_i16x8_s */\n DotI16x8 = 163 /* _BinaryenDotSVecI16x8ToVecI32x4 */,\n /** i32x4.extmul_low_i16x8_s */\n ExtmulLowI32x4 = 164 /* _BinaryenExtMulLowSVecI32x4 */,\n /** i32x4.extmul_high_i16x8_s */\n ExtmulHighI32x4 = 165 /* _BinaryenExtMulHighSVecI32x4 */,\n /** i32x4.extmul_low_i16x8_u */\n ExtmulLowU32x4 = 166 /* _BinaryenExtMulLowUVecI32x4 */,\n /** i32x4.extmul_high_i16x8_u */\n ExtmulHighU32x4 = 167 /* _BinaryenExtMulHighUVecI32x4 */,\n /** i64x2.add */\n AddI64x2 = 168 /* _BinaryenAddVecI64x2 */,\n /** i64x2.sub */\n SubI64x2 = 169 /* _BinaryenSubVecI64x2 */,\n /** i64x2.mul */\n MulI64x2 = 170 /* _BinaryenMulVecI64x2 */,\n /** i64x2.extmul_low_i32x4_s */\n ExtmulLowI64x2 = 171 /* _BinaryenExtMulLowSVecI64x2 */,\n /** i64x2.extmul_high_i32x4_s */\n ExtmulHighI64x2 = 172 /* _BinaryenExtMulHighSVecI64x2 */,\n /** i64x2.extmul_low_i32x4_u */\n ExtmulLowU64x2 = 173 /* _BinaryenExtMulLowUVecI64x2 */,\n /** i64x2.extmul_high_i32x4_u */\n ExtmulHighU64x2 = 174 /* _BinaryenExtMulHighUVecI64x2 */,\n /** f32x4.add */\n AddF32x4 = 175 /* _BinaryenAddVecF32x4 */,\n /** f32x4.sub */\n SubF32x4 = 176 /* _BinaryenSubVecF32x4 */,\n /** f32x4.mul */\n MulF32x4 = 177 /* _BinaryenMulVecF32x4 */,\n /** f32x4.div */\n DivF32x4 = 178 /* _BinaryenDivVecF32x4 */,\n /** f32x4.min */\n MinF32x4 = 179 /* _BinaryenMinVecF32x4 */,\n /** f32x4.max */\n MaxF32x4 = 180 /* _BinaryenMaxVecF32x4 */,\n /** f32x4.pmin */\n PminF32x4 = 181 /* _BinaryenPMinVecF32x4 */,\n /** f32x4.pmax */\n PmaxF32x4 = 182 /* _BinaryenPMaxVecF32x4 */,\n /** f64x2.add */\n AddF64x2 = 183 /* _BinaryenAddVecF64x2 */,\n /** f64x2.sub */\n SubF64x2 = 184 /* _BinaryenSubVecF64x2 */,\n /** f64x2.mul */\n MulF64x2 = 185 /* _BinaryenMulVecF64x2 */,\n /** f64x2.div */\n DivF64x2 = 186 /* _BinaryenDivVecF64x2 */,\n /** f64x2.min */\n MinF64x2 = 187 /* _BinaryenMinVecF64x2 */,\n /** f64x2.max */\n MaxF64x2 = 188 /* _BinaryenMaxVecF64x2 */,\n /** f64x2.pmin */\n PminF64x2 = 189 /* _BinaryenPMinVecF64x2 */,\n /** f64x2.pmax */\n PmaxF64x2 = 190 /* _BinaryenPMaxVecF64x2 */,\n /** i8x16.narrow_i16x8_s */\n NarrowI16x8ToI8x16 = 191 /* _BinaryenNarrowSVecI16x8ToVecI8x16 */,\n /** i8x16.narrow_i16x8_u */\n NarrowU16x8ToU8x16 = 192 /* _BinaryenNarrowUVecI16x8ToVecI8x16 */,\n /** i16x8.narrow_i32x4_s */\n NarrowI32x4ToI16x8 = 193 /* _BinaryenNarrowSVecI32x4ToVecI16x8 */,\n /** i16x8.narrow_i32x4_u */\n NarrowU32x4ToU16x8 = 194 /* _BinaryenNarrowUVecI32x4ToVecI16x8 */,\n /** i8x16.swizzle */\n SwizzleI8x16 = 195 /* _BinaryenSwizzleVecI8x16 */,\n\n // see: https://github.com/WebAssembly/relaxed-simd\n\n /** i8x16.relaxed_swizzle */\n RelaxedSwizzleI8x16 = 196 /* TODO_BinaryenRelaxedSwizzleVecI8x16 */,\n /** f32x4.relaxed_min */\n RelaxedMinF32x4 = 197 /* TODO_BinaryenRelaxedMinVecF32x4 */,\n /** f32x4.relaxed_max */\n RelaxedMaxF32x4 = 198 /* TODO_BinaryenRelaxedMaxVecF32x4 */,\n /** f64x2.relaxed_min */\n RelaxedMinF64x2 = 199 /* TODO_BinaryenRelaxedMinVecF64x2 */,\n /** f64x2.relaxed_max */\n RelaxedMaxF64x2 = 200 /* TODO_BinaryenRelaxedMaxVecF64x2 */,\n /** i16x8.relaxed_q15mulr_s */\n RelaxedQ15MulrI16x8 = 201 /* TODO_BinaryenRelaxedQ15MulrSVecI16x8 */,\n /** i16x8.relaxed_dot_i8x16_i7x16_s */\n RelaxedDotI8x16I7x16ToI16x8 = 202 /* TODO_BinaryenDotI8x16I7x16SToVecI16x8 */,\n\n _last = RelaxedDotI8x16I7x16ToI16x8,\n\n // Target dependent\n\n /** i32.add or i64.add, depending on target word size */\n AddSize,\n /** i32.sub or i64.sub, depending on target word size */\n SubSize,\n /** i32.mul or i64.mul, depending on target word size */\n MulSize,\n /** i32.div_s or i64.div_s, depending on target word size */\n DivISize,\n /** i32.div_u or i64.div_u, depending on target word size */\n DivUSize,\n /** i32.rem_s or i64.rem_s, depending on target word size */\n RemISize,\n /** i32.rem_u or i64.rem_u, depending on target word size */\n RemUSize,\n /** i32.and or i64.and, depending on target word size */\n AndSize,\n /** i32.or or i64.or, depending on target word size */\n OrSize,\n /** i32.xor or i64.xor, depending on target word size */\n XorSize,\n /** i32.shl or i64.shl, depending on target word size */\n ShlSize,\n /** i32.shr_s or i64.shr_s, depending on target word size */\n ShrISize,\n /** i32.shr_u or i64.shr_u, depending on target word size */\n ShrUSize,\n /** i32.rotl or i64.rotl, depending on target word size */\n RotlSize,\n /** i32.rotr or i64.rotr, depending on target word size */\n RotrSize,\n /** i32.eq or i64.eq, depending on target word size */\n EqSize,\n /** i32.ne or i64.ne, depending on target word size */\n NeSize,\n /** i32.lt_s or i64.lt_s, depending on target word size */\n LtISize,\n /** i32.lt_u or i64.lt_u, depending on target word size */\n LtUSize,\n /** i32.le_s or i64.le_s, depending on target word size */\n LeISize,\n /** i32.le_u or i64.le_u, depending on target word size */\n LeUSize,\n /** i32.gt_s or i64.gt_s, depending on target word size */\n GtISize,\n /** i32.gt_u or i64.gt_u, depending on target word size */\n GtUSize,\n /** i32.ge_s or i64.ge_s, depending on target word size */\n GeISize,\n /** i32.ge_u or i64.ge_u, depending on target word size */\n GeUSize\n}\n\n/** Binaryen atomic read-modify-write operation constants. */\nexport const enum AtomicRMWOp {\n /** i32.atomic.rmw.add, i32.atomic.rmw8.add_u, i32.atomic.rmw16.add_u, i64.atomic.rmw.add, i64.atomic.rmw8.add_u, i64.atomic.rmw16.add_u, i64.atomic.rmw32.add_u */\n Add = 0 /* _BinaryenAtomicRMWAdd */,\n /** i32.atomic.rmw.sub, i32.atomic.rmw8.sub_u, i32.atomic.rmw16.sub_u, i64.atomic.rmw.sub, i64.atomic.rmw8.sub_u, i64.atomic.rmw16.sub_u, i64.atomic.rmw32.sub_u */\n Sub = 1 /* _BinaryenAtomicRMWSub */,\n /** i32.atomic.rmw.and, i32.atomic.rmw8.and_u, i32.atomic.rmw16.and_u, i64.atomic.rmw.and, i64.atomic.rmw8.and_u, i64.atomic.rmw16.and_u, i64.atomic.rmw32.and_u */\n And = 2 /* _BinaryenAtomicRMWAnd */,\n /** i32.atomic.rmw.or, i32.atomic.rmw8.or_u, i32.atomic.rmw16.or_u, i64.atomic.rmw.or, i64.atomic.rmw8.or_u, i64.atomic.rmw16.or_u, i64.atomic.rmw32.or_u */\n Or = 3 /* _BinaryenAtomicRMWOr */,\n /** i32.atomic.rmw.xor, i32.atomic.rmw8.xor_u, i32.atomic.rmw16.xor_u, i64.atomic.rmw.xor, i64.atomic.rmw8.xor_u, i64.atomic.rmw16.xor_u, i64.atomic.rmw32.xor_u */\n Xor = 4 /* _BinaryenAtomicRMWXor */,\n /** i32.atomic.rmw.xchg, i32.atomic.rmw8.xchg_u, i32.atomic.rmw16.xchg_u, i64.atomic.rmw.xchg, i64.atomic.rmw8.xchg_u, i64.atomic.rmw16.xchg_u, i64.atomic.rmw32.xchg_u */\n Xchg = 5 /* _BinaryenAtomicRMWXchg */\n}\n\n/** Binaryen SIMD extract operation constants. */\nexport const enum SIMDExtractOp {\n /** i8x16.extract_lane_s */\n ExtractLaneI8x16 = 0 /* _BinaryenExtractLaneSVecI8x16 */,\n /** i8x16.extract_lane_u */\n ExtractLaneU8x16 = 1 /* _BinaryenExtractLaneUVecI8x16 */,\n /** i16x8.extract_lane_s */\n ExtractLaneI16x8 = 2 /* _BinaryenExtractLaneSVecI16x8 */,\n /** i16x8.extract_lane_u */\n ExtractLaneU16x8 = 3 /* _BinaryenExtractLaneUVecI16x8 */,\n /** i32x4.extract_lane_s */\n ExtractLaneI32x4 = 4 /* _BinaryenExtractLaneVecI32x4 */,\n /** i32x4.extract_lane_u */\n ExtractLaneI64x2 = 5 /* _BinaryenExtractLaneVecI64x2 */,\n /** i64x2.extract_lane_s */\n ExtractLaneF32x4 = 6 /* _BinaryenExtractLaneVecF32x4 */,\n /** i64x2.extract_lane_u */\n ExtractLaneF64x2 = 7 /* _BinaryenExtractLaneVecF64x2 */,\n}\n\n/** Binaryen SIMD replace operation constants. */\nexport const enum SIMDReplaceOp {\n /** i8x16.replace_lane */\n ReplaceLaneI8x16 = 0 /* _BinaryenReplaceLaneVecI8x16 */,\n /** i16x8.replace_lane */\n ReplaceLaneI16x8 = 1 /* _BinaryenReplaceLaneVecI16x8 */,\n /** i32x4.replace_lane */\n ReplaceLaneI32x4 = 2 /* _BinaryenReplaceLaneVecI32x4 */,\n /** i64x2.replace_lane */\n ReplaceLaneI64x2 = 3 /* _BinaryenReplaceLaneVecI64x2 */,\n /** f32x4.replace_lane */\n ReplaceLaneF32x4 = 4 /* _BinaryenReplaceLaneVecF32x4 */,\n /** f64x2.replace_lane */\n ReplaceLaneF64x2 = 5 /* _BinaryenReplaceLaneVecF64x2 */\n}\n\n/** Binaryen SIMD shift operation constants. */\nexport const enum SIMDShiftOp {\n /** i8x16.shl */\n ShlI8x16 = 0 /* _BinaryenShlVecI8x16 */,\n /** i8x16.shr_s */\n ShrI8x16 = 1 /* _BinaryenShrSVecI8x16 */,\n /** i8x16.shr_u */\n ShrU8x16 = 2 /* _BinaryenShrUVecI8x16 */,\n /** i16x8.shl */\n ShlI16x8 = 3 /* _BinaryenShlVecI16x8 */,\n /** i16x8.shr_s */\n ShrI16x8 = 4 /* _BinaryenShrSVecI16x8 */,\n /** i16x8.shr_u */\n ShrU16x8 = 5 /* _BinaryenShrUVecI16x8 */,\n /** i16x8.shl */\n ShlI32x4 = 6 /* _BinaryenShlVecI32x4 */,\n /** i32x4.shr_s */\n ShrI32x4 = 7 /* _BinaryenShrSVecI32x4 */,\n /** i32x4.shr_u */\n ShrU32x4 = 8 /* _BinaryenShrUVecI32x4 */,\n /** i64x2.shl */\n ShlI64x2 = 9 /* _BinaryenShlVecI64x2 */,\n /** i64x2.shr_u */\n ShrI64x2 = 10 /* _BinaryenShrSVecI64x2 */,\n /** i64x2.shr_u */\n ShrU64x2 = 11 /* _BinaryenShrUVecI64x2 */\n}\n\n/** Binaryen SIMD load operation constants. */\nexport const enum SIMDLoadOp {\n /** v128.load8_splat */\n Load8Splat = 0 /* _BinaryenLoad8SplatVec128 */,\n /** v128.load16_splat */\n Load16Splat = 1 /* _BinaryenLoad16SplatVec128 */,\n /** v128.load32_splat */\n Load32Splat = 2 /* _BinaryenLoad32SplatVec128 */,\n /** v128.load64_splat */\n Load64Splat = 3 /* _BinaryenLoad64SplatVec128 */,\n /** v128.load8x8_s */\n Load8x8S = 4 /* _BinaryenLoad8x8SVec128 */,\n /** v128.load8x8_u */\n Load8x8U = 5 /* _BinaryenLoad8x8UVec128 */,\n /** v128.load16x4_s */\n Load16x4S = 6 /* _BinaryenLoad16x4SVec128 */,\n /** v128.load16x4_u */\n Load16x4U = 7 /* _BinaryenLoad16x4UVec128 */,\n /** v128.load32x2_s */\n Load32x2S = 8 /* _BinaryenLoad32x2SVec128 */,\n /** v128.load32x2_u */\n Load32x2U = 9 /* _BinaryenLoad32x2UVec128 */,\n /** v128.load32_zero */\n Load32Zero = 10 /* _BinaryenLoad32ZeroVec128 */,\n /** v128.load64_zero */\n Load64Zero = 11 /* _BinaryenLoad64ZeroVec128 */,\n}\n\n/** Binaryen SIMD load/store lane operation constants. */\nexport const enum SIMDLoadStoreLaneOp {\n /** v128.load8_lane */\n Load8Lane = 0 /* _BinaryenLoad8LaneVec128 */,\n /** v128.load16_lane */\n Load16Lane = 1 /* _BinaryenLoad16LaneVec128 */,\n /** v128.load32_lane */\n Load32Lane = 2 /* _BinaryenLoad32LaneVec128 */,\n /** v128.load64_lane */\n Load64Lane = 3 /* _BinaryenLoad64LaneVec128 */,\n /** v128.store8_lane */\n Store8Lane = 4 /* _BinaryenStore8LaneVec128 */,\n /** v128.store16_lane */\n Store16Lane = 5 /* _BinaryenStore16LaneVec128 */,\n /** v128.store32_lane */\n Store32Lane = 6 /* _BinaryenStore32LaneVec128 */,\n /** v128.store64_lane */\n Store64Lane = 7 /* _BinaryenStore64LaneVec128 */,\n}\n\n/** Binaryen SIMD ternary operation constants. */\nexport const enum SIMDTernaryOp {\n /** v128.bitselect */\n Bitselect = 0 /* _BinaryenBitselectVec128 */,\n\n // see: https://github.com/WebAssembly/relaxed-simd\n\n /** f32x4.relaxed_madd */\n RelaxedMaddF32x4 = 1 /* TODO_BinaryenRelaxedFmaVecF32x4 */,\n /** f32x4.relaxed_nmadd */\n RelaxedNmaddF32x4 = 2 /* TODO_BinaryenRelaxedFmsVecF32x4 */,\n /** f64x2.relaxed_madd */\n RelaxedMaddF64x2 = 3 /* TODO_BinaryenRelaxedFmaVecF64x2 */,\n /** f64x2.relaxed_nmadd */\n RelaxedNmaddF64x2 = 4 /* TODO_BinaryenRelaxedFmsVecF64x2 */,\n /** i8x16.relaxed_laneselect */\n RelaxedLaneselectI8x16 = 5 /* TODO_BinaryenLaneselectI8x16 */,\n /** i16x8.relaxed_laneselect */\n RelaxedLaneselectI16x8 = 6 /* TODO_BinaryenLaneselectI16x8 */,\n /** i32x4.relaxed_laneselect */\n RelaxedLaneselectI32x4 = 7 /* TODO_BinaryenLaneselectI32x4 */,\n /** i64x2.relaxed_laneselect */\n RelaxedLaneselectI64x2 = 8 /* TODO_BinaryenLaneselectI64x2 */,\n /** i32x4.relaxed_dot_i8x16_i7x16_add_s */\n RelaxedDotI8x16I7x16AddToI32x4 = 9 /* TODO_BinaryenDotI8x16I7x16AddSToVecI32x4 */,\n}\n\n/** Binaryen RefAs operation constants. */\nexport const enum RefAsOp {\n /** ref.as_non_null */\n NonNull = 0 /* _BinaryenRefAsNonNull */,\n /** extern.internalize */\n ExternInternalize = 1 /* _BinaryenRefAsExternInternalize */,\n /** extern.externalize */\n ExternExternalize = 2 /* _BinaryenRefAsExternExternalize */\n}\n\n/** Binaryen BrOn operation constants. */\nexport const enum BrOnOp {\n /** br_on_null */\n Null = 0 /* _BinaryenBrOnNull */,\n /** br_on_non_null */\n NonNull = 1 /* _BinaryenBrOnNonNull */,\n /** br_on_cast */\n Cast = 2 /* _BinaryenBrOnCast */,\n /** br_on_cast_fail */\n CastFail = 3 /* _BinaryenBrOnCastFail */\n}\n\n/** Binaryen StringNew operation constants. */\nexport const enum StringNewOp {\n /** string.new_wtf8 utf8 */\n UTF8 = 0 /* _BinaryenStringNewUTF8 */,\n /** string.new_wtf8 wtf8 */\n WTF8 = 1 /* _BinaryenStringNewWTF8 */,\n /** string.new_wtf8 replace */\n Replace = 2 /* _BinaryenStringNewReplace */,\n /** string.new_wtf16 */\n WTF16 = 3 /* _BinaryenStringNewWTF16 */,\n /** string.new_wtf8_array utf8 */\n UTF8Array = 4 /* _BinaryenStringNewUTF8Array */,\n /** string.new_wtf8_array wtf8 */\n WTF8Array = 5 /* _BinaryenStringNewWTF8Array */,\n /** string.new_wtf8_array replace */\n ReplaceArray = 6 /* _BinaryenStringNewReplaceArray */,\n /** string.new_wtf16_array */\n WTF16Array = 7 /* _BinaryenStringNewWTF16Array */,\n /** string.from_code_point */\n FromCodePoint = 8 /* _BinaryenStringNewFromCodePoint */\n}\n\n/** Binaryen StringMeasure operation constants. */\nexport const enum StringMeasureOp {\n /** string.measure_wtf8 utf8 */\n UTF8 = 0 /* _BinaryenStringMeasureUTF8 */,\n /** string.measure_wtf8 wtf8 */\n WTF8 = 1 /* _BinaryenStringMeasureWTF8 */,\n /** string.measure_wtf16 */\n WTF16 = 2 /* _BinaryenStringMeasureWTF16 */,\n /** string.is_usv_sequence */\n IsUSV = 3 /* _BinaryenStringMeasureIsUSV */,\n /** stringview_wtf16.length */\n WTF16View = 4 /* _BinaryenStringMeasureWTF16View */\n}\n\n/** Binaryen StringEncode operation constants. */\nexport const enum StringEncodeOp {\n /** string.encode_wtf8 utf8 */\n UTF8 = 0 /* _BinaryenStringEncodeUTF8 */,\n /** string.encode_wtf8 wtf8 */\n WTF8 = 1 /* _BinaryenStringEncodeWTF8 */,\n /** string.encode_wtf16 */\n WTF16 = 2 /* _BinaryenStringEncodeWTF16 */,\n /** string.encode_wtf8_array utf8 */\n UTF8Array = 3 /* _BinaryenStringEncodeUTF8Array */,\n /** string.encode_wtf8_array wtf8 */\n WTF8Array = 4 /* _BinaryenStringEncodeWTF8Array */,\n /** string.encode_wtf16_array */\n WTF16Array = 5 /* _BinaryenStringEncodeWTF16Array */\n}\n\n/** Binaryen StringEq operation constants. */\nexport const enum StringEqOp {\n /** string.eq */\n Equal = 0 /* _BinaryenStringEqEqual */,\n /** string.compare */\n Compare = 1 /* _BinaryenStringEqCompare */\n}\n\n/** Binaryen StringAs operation constants. */\nexport const enum StringAsOp {\n /** string.as_wtf8 */\n WTF8 = 0 /* _BinaryenStringAsWTF8 */,\n /** string.as_wtf16 */\n WTF16 = 1 /* _BinaryenStringAsWTF16 */,\n /** string.as_iter */\n Iter = 2 /* _BinaryenStringAsIter */\n}\n\n/** Binaryen StringIterMove operation constants. */\nexport const enum StringIterMoveOp {\n /** stringview_iter.advance */\n Advance = 0 /* _BinaryenStringIterMoveAdvance */,\n /** stringview_iter.rewind */\n Rewind = 1 /* _BinaryenStringIterMoveRewind */\n}\n\n/** Binaryen StringSlice operation constants. */\nexport const enum StringSliceWTFOp {\n /** stringview_wtf8.slice */\n WTF8 = 0 /* _BinaryenStringSliceWTF8 */,\n /** stringview_wtf16.slice */\n WTF16 = 1 /* _BinaryenStringSliceWTF16 */\n}\n\n/** Binaryen expression runner flags. */\nexport const enum ExpressionRunnerFlags {\n Default = 0 /* _ExpressionRunnerFlagsDefault */,\n PreserveSideeffects = 1 /* _ExpressionRunnerFlagsPreserveSideeffects */,\n TraverseCalls = 2 /* _ExpressionRunnerFlagsTraverseCalls */\n}\n\nexport class MemorySegment {\n constructor(\n /** Segment data. */\n public buffer: Uint8Array,\n /** Segment offset. */\n public offset: i64\n ) {}\n}\n\nexport class Module {\n constructor(\n /** Binaryen module reference. */\n public ref: ModuleRef,\n /** Whether a shadow stack is used. */\n public useShadowStack: bool,\n /** Architecture-dependent size type. */\n public sizeType: TypeRef\n ) {\n assert(sizeType == TypeRef.I32 || sizeType == TypeRef.I64);\n this.lit = binaryen._malloc(binaryen._BinaryenSizeofLiteral());\n binaryen._BinaryenSetTypeSystem(TypeSystem.Nominal);\n }\n\n private lit: usize;\n\n static create(useShadowStack: bool, sizeType: TypeRef): Module {\n return new Module(binaryen._BinaryenModuleCreate(), useShadowStack, sizeType);\n }\n\n static createFrom(buffer: Uint8Array, useShadowStack: bool, sizeType: TypeRef): Module {\n let cArr = allocU8Array(buffer);\n let module = new Module(binaryen._BinaryenModuleRead(cArr, buffer.length), useShadowStack, sizeType);\n binaryen._free(changetype(cArr));\n return module;\n }\n\n // constants\n\n i32(value: i32): ExpressionRef {\n let out = this.lit;\n binaryen._BinaryenLiteralInt32(out, value);\n return binaryen._BinaryenConst(this.ref, out);\n }\n\n i64(valueLow: i32, valueHigh: i32 = 0): ExpressionRef {\n let out = this.lit;\n binaryen._BinaryenLiteralInt64(out, valueLow, valueHigh);\n return binaryen._BinaryenConst(this.ref, out);\n }\n\n // isize(value: T): ExpressionRef {\n // if (i64_is(value)) {\n // if (this.sizeType == TypeRef.I64) {\n // return this.i64(i64_low(value), i64_high(value));\n // }\n // assert(i64_is_i32(value));\n // return this.i32(i64_low(value));\n // }\n // return this.sizeType == TypeRef.I64\n // ? this.i64(i32(value), i32(value) < 0 ? -1 : 0)\n // : this.i32(i32(value));\n // }\n\n usize(value: T): ExpressionRef {\n if (i64_is(value)) {\n if (this.sizeType == TypeRef.I64) {\n return this.i64(i64_low(value), i64_high(value));\n }\n assert(i64_is_u32(value));\n return this.i32(i64_low(value));\n }\n return this.sizeType == TypeRef.I64\n ? this.i64(i32(value))\n : this.i32(i32(value));\n }\n\n f32(value: f32): ExpressionRef {\n let out = this.lit;\n binaryen._BinaryenLiteralFloat32(out, value);\n return binaryen._BinaryenConst(this.ref, out);\n }\n\n f64(value: f64): ExpressionRef {\n let out = this.lit;\n binaryen._BinaryenLiteralFloat64(out, value);\n return binaryen._BinaryenConst(this.ref, out);\n }\n\n v128(bytes: Uint8Array): ExpressionRef {\n assert(bytes.length == 16);\n let out = this.lit;\n for (let i = 0; i < 16; ++i) {\n binaryen.__i32_store8(out + i, unchecked(bytes[i]));\n }\n binaryen._BinaryenLiteralVec128(out, out);\n return binaryen._BinaryenConst(this.ref, out);\n }\n\n ref_null(type: TypeRef): ExpressionRef {\n // TODO: Provide the desired bottom type directly? Currently, Binaryen does\n // this under the hood, but this API could change to take a heap type.\n // type = binaryen._BinaryenTypeFromHeapType(\n // binaryen._BinaryenHeapTypeGetBottom(\n // binaryen._BinaryenTypeGetHeapType(type)\n // ),\n // true\n // );\n return binaryen._BinaryenRefNull(this.ref, type);\n }\n\n ref_eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenRefEq(this.ref, left, right);\n }\n\n string_eq(left: ExpressionRef, right: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenStringEq(this.ref, StringEqOp.Equal, left, right);\n }\n\n string_compare(left: ExpressionRef, right: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenStringEq(this.ref, StringEqOp.Compare, left, right);\n }\n\n // expressions\n\n unary(\n op: UnaryOp,\n value: ExpressionRef\n ): ExpressionRef {\n if (op > UnaryOp._last) {\n let isWam64 = this.sizeType == TypeRef.I64;\n switch (op) {\n case UnaryOp.ClzSize: op = isWam64 ? UnaryOp.ClzI64 : UnaryOp.ClzI32; break;\n case UnaryOp.CtzSize: op = isWam64 ? UnaryOp.CtzI64 : UnaryOp.CtzI32; break;\n case UnaryOp.PopcntSize: op = isWam64 ? UnaryOp.PopcntI64 : UnaryOp.PopcntI32; break;\n case UnaryOp.EqzSize: op = isWam64 ? UnaryOp.EqzI64 : UnaryOp.EqzI32; break;\n default: assert(false);\n }\n }\n return binaryen._BinaryenUnary(this.ref, op, value);\n }\n\n binary(\n op: BinaryOp,\n left: ExpressionRef,\n right: ExpressionRef\n ): ExpressionRef {\n if (op > BinaryOp._last) {\n let isWasm64 = this.sizeType == TypeRef.I64;\n switch (op) {\n case BinaryOp.AddSize: op = isWasm64 ? BinaryOp.AddI64 : BinaryOp.AddI32; break;\n case BinaryOp.SubSize: op = isWasm64 ? BinaryOp.SubI64 : BinaryOp.SubI32; break;\n case BinaryOp.MulSize: op = isWasm64 ? BinaryOp.MulI64 : BinaryOp.MulI32; break;\n case BinaryOp.DivISize: op = isWasm64 ? BinaryOp.DivI64 : BinaryOp.DivI32; break;\n case BinaryOp.DivUSize: op = isWasm64 ? BinaryOp.DivU64 : BinaryOp.DivU32; break;\n case BinaryOp.RemISize: op = isWasm64 ? BinaryOp.RemI64 : BinaryOp.RemI32; break;\n case BinaryOp.RemUSize: op = isWasm64 ? BinaryOp.RemU64 : BinaryOp.RemU32; break;\n case BinaryOp.AndSize: op = isWasm64 ? BinaryOp.AndI64 : BinaryOp.AndI32; break;\n case BinaryOp.OrSize: op = isWasm64 ? BinaryOp.OrI64 : BinaryOp.OrI32; break;\n case BinaryOp.XorSize: op = isWasm64 ? BinaryOp.XorI64 : BinaryOp.XorI32; break;\n case BinaryOp.ShlSize: op = isWasm64 ? BinaryOp.ShlI64 : BinaryOp.ShlI32; break;\n case BinaryOp.ShrISize: op = isWasm64 ? BinaryOp.ShrI64 : BinaryOp.ShrI32; break;\n case BinaryOp.ShrUSize: op = isWasm64 ? BinaryOp.ShrU64 : BinaryOp.ShrU32; break;\n case BinaryOp.RotlSize: op = isWasm64 ? BinaryOp.RotlI64 : BinaryOp.RotlI32; break;\n case BinaryOp.RotrSize: op = isWasm64 ? BinaryOp.RotrI64 : BinaryOp.RotrI32; break;\n case BinaryOp.EqSize: op = isWasm64 ? BinaryOp.EqI64 : BinaryOp.EqI32; break;\n case BinaryOp.NeSize: op = isWasm64 ? BinaryOp.NeI64 : BinaryOp.NeI32; break;\n case BinaryOp.LtISize: op = isWasm64 ? BinaryOp.LtI64 : BinaryOp.LtI32; break;\n case BinaryOp.LtUSize: op = isWasm64 ? BinaryOp.LtU64 : BinaryOp.LtU32; break;\n case BinaryOp.LeISize: op = isWasm64 ? BinaryOp.LeI64 : BinaryOp.LeI32; break;\n case BinaryOp.LeUSize: op = isWasm64 ? BinaryOp.LeU64 : BinaryOp.LeU32; break;\n case BinaryOp.GtISize: op = isWasm64 ? BinaryOp.GtI64 : BinaryOp.GtI32; break;\n case BinaryOp.GtUSize: op = isWasm64 ? BinaryOp.GtU64 : BinaryOp.GtU32; break;\n case BinaryOp.GeISize: op = isWasm64 ? BinaryOp.GeI64 : BinaryOp.GeI32; break;\n case BinaryOp.GeUSize: op = isWasm64 ? BinaryOp.GeU64 : BinaryOp.GeU32; break;\n default: assert(false);\n }\n }\n return binaryen._BinaryenBinary(this.ref, op, left, right);\n }\n\n memory_size(name: string = CommonNames.DefaultMemory, is64: bool = false): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenMemorySize(this.ref, cStr, is64);\n }\n\n memory_grow(delta: ExpressionRef, name: string = CommonNames.DefaultMemory, is64: bool = false): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenMemoryGrow(this.ref, delta, cStr, is64);\n }\n\n table_size(name: string): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenTableSize(this.ref, cStr);\n }\n\n table_grow(name: string, delta: ExpressionRef, value: ExpressionRef = 0): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenTableGrow(this.ref, cStr, value, delta);\n }\n\n local_get(\n index: i32,\n type: TypeRef\n ): ExpressionRef {\n return binaryen._BinaryenLocalGet(this.ref, index, type);\n }\n\n tostack(value: ExpressionRef): ExpressionRef {\n if (this.useShadowStack) {\n let type = binaryen._BinaryenExpressionGetType(value);\n assert(type == TypeRef.I32 || type == TypeRef.Unreachable);\n return this.call(BuiltinNames.tostack, [ value ], type);\n }\n return value;\n }\n\n local_tee(\n index: i32,\n value: ExpressionRef,\n isManaged: bool,\n type: TypeRef = -1,\n ): ExpressionRef {\n if (type == -1) type = binaryen._BinaryenExpressionGetType(value);\n if (isManaged && this.useShadowStack) {\n value = this.tostack(value);\n }\n return binaryen._BinaryenLocalTee(this.ref, index, value, type);\n }\n\n global_get(\n name: string,\n type: TypeRef\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenGlobalGet(this.ref, cStr, type);\n }\n\n table_get(\n name: string,\n index: ExpressionRef,\n type: TypeRef\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenTableGet(this.ref, cStr, index, type);\n }\n\n load(\n bytes: Index,\n signed: bool,\n ptr: ExpressionRef,\n type: TypeRef,\n offset: Index = 0,\n align: Index = bytes, // naturally aligned by default\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenLoad(this.ref, bytes, signed, offset, align, type, ptr, cStr);\n }\n\n store(\n bytes: Index,\n ptr: ExpressionRef,\n value: ExpressionRef,\n type: TypeRef,\n offset: Index = 0,\n align: Index = bytes, // naturally aligned by default\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenStore(this.ref, bytes, offset, align, ptr, value, type, cStr);\n }\n\n atomic_load(\n bytes: Index,\n ptr: ExpressionRef,\n type: TypeRef,\n offset: Index = 0,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicLoad(this.ref, bytes, offset, type, ptr, cStr);\n }\n\n atomic_store(\n bytes: Index,\n ptr: ExpressionRef,\n value: ExpressionRef,\n type: TypeRef,\n offset: Index = 0,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicStore(this.ref, bytes, offset, ptr, value, type, cStr);\n }\n\n atomic_rmw(\n op: AtomicRMWOp,\n bytes: Index,\n offset: Index,\n ptr: ExpressionRef,\n value: ExpressionRef,\n type: TypeRef,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicRMW(this.ref, op, bytes, offset, ptr, value, type, cStr);\n }\n\n atomic_cmpxchg(\n bytes: Index,\n offset: Index,\n ptr: ExpressionRef,\n expected: ExpressionRef,\n replacement: ExpressionRef,\n type: TypeRef,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicCmpxchg(this.ref, bytes, offset, ptr, expected, replacement, type, cStr);\n }\n\n atomic_wait(\n ptr: ExpressionRef,\n expected: ExpressionRef,\n timeout: ExpressionRef,\n expectedType: TypeRef,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicWait(this.ref, ptr, expected, timeout, expectedType, cStr);\n }\n\n atomic_notify(\n ptr: ExpressionRef,\n notifyCount: ExpressionRef,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicNotify(this.ref, ptr, notifyCount, cStr);\n }\n\n atomic_fence(name: string | null = null): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAtomicFence(this.ref, cStr);\n }\n\n // statements\n\n local_set(\n index: Index,\n value: ExpressionRef,\n isManaged: bool\n ): ExpressionRef {\n if (isManaged && this.useShadowStack) {\n value = this.tostack(value);\n }\n return binaryen._BinaryenLocalSet(this.ref, index, value);\n }\n\n global_set(\n name: string,\n value: ExpressionRef\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenGlobalSet(this.ref, cStr, value);\n }\n\n table_set(\n name: string,\n index: ExpressionRef,\n value: ExpressionRef\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenTableSet(this.ref, cStr, index, value);\n }\n\n block(\n label: string | null,\n children: ExpressionRef[],\n type: TypeRef = TypeRef.None\n ): ExpressionRef {\n let cStr = this.allocStringCached(label);\n let cArr = allocPtrArray(children);\n let ret = binaryen._BinaryenBlock(this.ref, cStr, cArr, children.length, type);\n binaryen._free(cArr);\n return ret;\n }\n\n /** Attempts to trivially flatten a series of expressions instead of emitting a block. */\n flatten(\n stmts: ExpressionRef[],\n type: TypeRef = TypeRef.None\n ): ExpressionRef {\n let length = stmts.length;\n if (length == 0) return this.nop(); // usually filtered out again\n if (length == 1) {\n let single = stmts[0];\n switch (getExpressionId(single)) {\n case ExpressionId.Return:\n case ExpressionId.Throw:\n case ExpressionId.Unreachable: {\n // type does no matter, terminates anyway\n return single;\n }\n }\n let singleType = getExpressionType(single);\n if (singleType != TypeRef.Unreachable && singleType != type) {\n // can happen when there was a diagnostic prior\n return this.unreachable();\n }\n return single;\n }\n return this.block(null, stmts, type);\n }\n\n br(\n label: string | null,\n condition: ExpressionRef = 0,\n value: ExpressionRef = 0\n ): ExpressionRef {\n let cStr = this.allocStringCached(label);\n return binaryen._BinaryenBreak(this.ref, cStr, condition, value);\n }\n\n drop(\n expression: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenDrop(this.ref, expression);\n }\n\n /** Drops an expression if it evaluates to a value. */\n maybeDrop(\n expression: ExpressionRef\n ): ExpressionRef {\n let type = binaryen._BinaryenExpressionGetType(expression);\n if (type != TypeRef.None && type != TypeRef.Unreachable) {\n return binaryen._BinaryenDrop(this.ref, expression);\n }\n return expression;\n }\n\n maybeDropCondition(condition: ExpressionRef, result: ExpressionRef): ExpressionRef {\n // FIXME: This is necessary because Binaryen's ExpressionRunner bails early\n // when encountering a local with an unknown value. This helper only drops\n // the pre-evaluated condition if it has relevant side effects.\n // see WebAssembly/binaryen#1237\n if ((getSideEffects(condition, this.ref) & ~(SideEffects.ReadsLocal | SideEffects.ReadsGlobal)) != 0) {\n return this.block(null, [\n this.drop(condition),\n result\n ], getExpressionType(result));\n }\n return result;\n }\n\n loop(\n label: string | null,\n body: ExpressionRef\n ): ExpressionRef {\n let cStr = this.allocStringCached(label);\n return binaryen._BinaryenLoop(this.ref, cStr, body);\n }\n\n if(\n condition: ExpressionRef,\n ifTrue: ExpressionRef,\n ifFalse: ExpressionRef = 0\n ): ExpressionRef {\n return binaryen._BinaryenIf(this.ref, condition, ifTrue, ifFalse);\n }\n\n nop(): ExpressionRef {\n return binaryen._BinaryenNop(this.ref);\n }\n\n return(\n expression: ExpressionRef = 0\n ): ExpressionRef {\n return binaryen._BinaryenReturn(this.ref, expression);\n }\n\n select(\n ifTrue: ExpressionRef,\n ifFalse: ExpressionRef,\n condition: ExpressionRef,\n type: TypeRef\n ): ExpressionRef {\n return binaryen._BinaryenSelect(this.ref, condition, ifTrue, ifFalse, type);\n }\n\n switch(\n names: string[],\n defaultName: string | null,\n condition: ExpressionRef,\n value: ExpressionRef = 0\n ): ExpressionRef {\n let numNames = names.length;\n let strs = new Array(numNames);\n for (let i = 0; i < numNames; ++i) {\n unchecked(strs[i] = this.allocStringCached(names[i]));\n }\n let cArr = allocPtrArray(strs);\n let cStr = this.allocStringCached(defaultName);\n let ret = binaryen._BinaryenSwitch(this.ref, cArr, numNames, cStr, condition, value);\n binaryen._free(cArr);\n return ret;\n }\n\n call(\n target: string,\n operands: ExpressionRef[] | null,\n returnType: TypeRef,\n isReturn: bool = false\n ): ExpressionRef {\n let cStr = this.allocStringCached(target);\n let cArr = allocPtrArray(operands);\n let ret = isReturn\n ? binaryen._BinaryenReturnCall(\n this.ref, cStr, cArr, operands ? operands.length : 0, returnType\n )\n : binaryen._BinaryenCall(\n this.ref, cStr, cArr, operands ? operands.length : 0, returnType\n );\n binaryen._free(cArr);\n return ret;\n }\n\n return_call(\n target: string,\n operands: ExpressionRef[] | null,\n returnType: TypeRef\n ): ExpressionRef {\n return this.call(target, operands, returnType, true);\n }\n\n call_indirect(\n tableName: string | null,\n index: ExpressionRef,\n operands: ExpressionRef[] | null,\n params: TypeRef,\n results: TypeRef,\n isReturn: bool = false\n ): ExpressionRef {\n let cStr = this.allocStringCached(tableName != null\n ? tableName\n : CommonNames.DefaultTable\n );\n let cArr = allocPtrArray(operands);\n let ret = isReturn\n ? binaryen._BinaryenReturnCallIndirect(\n this.ref, cStr, index, cArr, operands ? operands.length : 0, params, results\n )\n : binaryen._BinaryenCallIndirect(\n this.ref, cStr, index, cArr, operands ? operands.length : 0, params, results\n );\n binaryen._free(cArr);\n return ret;\n }\n\n return_call_indirect(\n tableName: string | null,\n index: ExpressionRef,\n operands: ExpressionRef[] | null,\n params: TypeRef,\n results: TypeRef\n ): ExpressionRef {\n return this.call_indirect(tableName, index, operands, params, results, true);\n }\n\n unreachable(): ExpressionRef {\n return binaryen._BinaryenUnreachable(this.ref);\n }\n\n // bulk memory\n\n memory_copy(\n dest: ExpressionRef,\n source: ExpressionRef,\n size: ExpressionRef,\n destName: string = CommonNames.DefaultMemory,\n sourceName: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr1 = this.allocStringCached(destName);\n let cStr2 = this.allocStringCached(sourceName);\n return binaryen._BinaryenMemoryCopy(this.ref, dest, source, size, cStr1, cStr2);\n }\n\n memory_fill(\n dest: ExpressionRef,\n value: ExpressionRef,\n size: ExpressionRef,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenMemoryFill(this.ref, dest, value, size, cStr);\n }\n\n // exception handling\n\n try(\n name: string | null,\n body: ExpressionRef,\n catchTags: string[],\n catchBodies: ExpressionRef[],\n delegateTarget: string | null = null\n ): ExpressionRef {\n let numCatchTags = catchTags.length;\n let strs = new Array(numCatchTags);\n for (let i = 0; i < numCatchTags; ++i) {\n strs[i] = this.allocStringCached(catchTags[i]);\n }\n let cArr1 = allocPtrArray(strs);\n let cArr2 = allocPtrArray(catchBodies);\n let cStr1 = this.allocStringCached(name);\n let cStr2 = this.allocStringCached(delegateTarget);\n let ret = binaryen._BinaryenTry(\n this.ref, cStr1, body, cArr1, numCatchTags, cArr2, catchBodies.length, cStr2\n );\n binaryen._free(cArr2);\n binaryen._free(cArr1);\n return ret;\n }\n\n throw(\n tagName: string,\n operands: ExpressionRef[]\n ): ExpressionRef {\n let cStr = this.allocStringCached(tagName);\n let cArr = allocPtrArray(operands);\n let ret = binaryen._BinaryenThrow(this.ref, cStr, cArr, operands.length);\n binaryen._free(cArr);\n return ret;\n }\n\n rethrow(\n target: string\n ): ExpressionRef {\n let cStr = this.allocStringCached(target);\n return binaryen._BinaryenRethrow(this.ref, cStr);\n }\n\n // multi value (pseudo instructions)\n\n pop(\n type: TypeRef\n ): ExpressionRef {\n return binaryen._BinaryenPop(this.ref, type);\n }\n\n tuple_make(operands: ExpressionRef[]): ExpressionRef {\n let cArr = allocPtrArray(operands);\n let ret = binaryen._BinaryenTupleMake(this.ref, cArr, operands.length);\n binaryen._free(cArr);\n return ret;\n }\n\n tuple_extract(tuple: ExpressionRef, index: Index): ExpressionRef {\n return binaryen._BinaryenTupleExtract(this.ref, tuple, index);\n }\n\n // simd\n\n simd_extract(\n op: SIMDExtractOp,\n vec: ExpressionRef,\n idx: u8\n ): ExpressionRef {\n return binaryen._BinaryenSIMDExtract(this.ref, op, vec, idx);\n }\n\n simd_replace(\n op: SIMDReplaceOp,\n vec: ExpressionRef,\n idx: u8,\n value: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenSIMDReplace(this.ref, op, vec, idx, value);\n }\n\n simd_shuffle(\n vec1: ExpressionRef,\n vec2: ExpressionRef,\n mask: Uint8Array\n ): ExpressionRef {\n assert(mask.length == 16);\n let cArr = allocU8Array(mask);\n let ret = binaryen._BinaryenSIMDShuffle(this.ref, vec1, vec2, cArr);\n binaryen._free(cArr);\n return ret;\n }\n\n simd_ternary(\n op: SIMDTernaryOp,\n a: ExpressionRef,\n b: ExpressionRef,\n c: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenSIMDTernary(this.ref, op, a, b, c);\n }\n\n simd_shift(\n op: SIMDShiftOp,\n vec: ExpressionRef,\n shift: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenSIMDShift(this.ref, op, vec, shift);\n }\n\n simd_load(\n op: SIMDLoadOp,\n ptr: ExpressionRef,\n offset: u32,\n align: u32,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenSIMDLoad(this.ref, op, offset, align, ptr, cStr);\n }\n\n simd_loadstorelane(\n op: SIMDLoadStoreLaneOp,\n ptr: ExpressionRef,\n offset: u32,\n align: u32,\n index: u8,\n vec: ExpressionRef,\n name: string = CommonNames.DefaultMemory\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenSIMDLoadStoreLane(this.ref, op, offset, align, index, ptr, vec, cStr);\n }\n\n // reference types / gc\n\n ref_is_null(\n expr: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenRefIsNull(this.ref, expr);\n }\n\n ref_as(\n op: RefAsOp,\n expr: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenRefAs(this.ref, op, expr);\n }\n\n ref_as_nonnull(\n expr: ExpressionRef\n ): ExpressionRef {\n if (isNullableType(getExpressionType(expr))) {\n return binaryen._BinaryenRefAs(this.ref, RefAsOp.NonNull, expr);\n } else {\n return expr;\n }\n }\n\n ref_func(\n name: string,\n type: TypeRef\n ): ExpressionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenRefFunc(this.ref, cStr, type);\n }\n\n i31_new(\n value: ExpressionRef\n ): ExpressionRef {\n return binaryen._BinaryenI31New(this.ref, value);\n }\n\n i31_get(\n expr: ExpressionRef,\n signed: bool\n ): ExpressionRef {\n return binaryen._BinaryenI31Get(this.ref, expr, signed);\n }\n\n // globals\n\n addGlobal(\n name: string,\n type: TypeRef,\n mutable: bool,\n initializer: ExpressionRef\n ): GlobalRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAddGlobal(this.ref, cStr, type, mutable, initializer);\n }\n\n getGlobal(\n name: string\n ): GlobalRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenGetGlobal(this.ref, cStr);\n }\n\n removeGlobal(\n name: string\n ): bool {\n let cStr = this.allocStringCached(name);\n if (!binaryen._BinaryenGetGlobal(this.ref, cStr)) return false;\n binaryen._BinaryenRemoveGlobal(this.ref, cStr);\n return true;\n }\n\n // tags\n\n addTag(\n name: string,\n params: TypeRef,\n results: TypeRef\n ): TagRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenAddTag(this.ref, cStr, params, results);\n }\n\n getTag(\n name: string\n ): TagRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenGetTag(this.ref, cStr);\n }\n\n removeTag(\n name: string\n ): void {\n let cStr = this.allocStringCached(name);\n binaryen._BinaryenRemoveTag(this.ref, cStr);\n }\n\n // functions\n\n addFunction(\n name: string,\n params: TypeRef,\n results: TypeRef,\n varTypes: TypeRef[] | null,\n body: ExpressionRef\n ): FunctionRef {\n let cStr = this.allocStringCached(name);\n let cArr = allocPtrArray(varTypes);\n let ret = binaryen._BinaryenAddFunction(\n this.ref,\n cStr,\n params,\n results,\n cArr,\n varTypes ? varTypes.length : 0,\n body\n );\n binaryen._free(cArr);\n return ret;\n }\n\n setLocalName(funcRef: FunctionRef, index: u32, name: string): void {\n binaryen._BinaryenFunctionSetLocalName(funcRef, index, this.allocStringCached(name));\n }\n\n getFunction(\n name: string\n ): FunctionRef {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenGetFunction(this.ref, cStr);\n }\n\n removeFunction(name: string): void {\n let cStr = this.allocStringCached(name);\n binaryen._BinaryenRemoveFunction(this.ref, cStr);\n }\n\n hasFunction(name: string): bool {\n let cStr = this.allocStringCached(name);\n return binaryen._BinaryenGetFunction(this.ref, cStr) != 0;\n }\n\n private hasTemporaryFunction: bool = false;\n\n addTemporaryFunction(\n result: TypeRef,\n paramTypes: TypeRef[] | null,\n body: ExpressionRef\n ): FunctionRef {\n this.hasTemporaryFunction = assert(!this.hasTemporaryFunction);\n let tempName = this.allocStringCached(\"\");\n let cArr = allocPtrArray(paramTypes);\n let ret = binaryen._BinaryenAddFunction(this.ref,\n tempName,\n createType(paramTypes),\n result,\n 0, 0,\n body\n );\n binaryen._free(cArr);\n return ret;\n }\n\n removeTemporaryFunction(): void {\n this.hasTemporaryFunction = !assert(this.hasTemporaryFunction);\n let tempName = this.allocStringCached(\"\");\n binaryen._BinaryenRemoveFunction(this.ref, tempName);\n }\n\n setStart(func: FunctionRef): void {\n binaryen._BinaryenSetStart(this.ref, func);\n }\n\n // exports\n\n addFunctionExport(\n internalName: string,\n externalName: string\n ): ExportRef {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalName);\n return binaryen._BinaryenAddFunctionExport(this.ref, cStr1, cStr2);\n }\n\n addTableExport(\n internalName: string,\n externalName: string\n ): ExportRef {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalName);\n return binaryen._BinaryenAddTableExport(this.ref, cStr1, cStr2);\n }\n\n addMemoryExport(\n internalName: string,\n externalName: string\n ): ExportRef {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalName);\n return binaryen._BinaryenAddMemoryExport(this.ref, cStr1, cStr2);\n }\n\n addGlobalExport(\n internalName: string,\n externalName: string\n ): ExportRef {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalName);\n return binaryen._BinaryenAddGlobalExport(this.ref, cStr1, cStr2);\n }\n\n addTagExport(\n internalName: string,\n externalName: string\n ): ExportRef {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalName);\n return binaryen._BinaryenAddTagExport(this.ref, cStr1, cStr2);\n }\n\n removeExport(externalName: string): void {\n let cStr = this.allocStringCached(externalName);\n binaryen._BinaryenRemoveExport(this.ref, cStr);\n }\n\n hasExport(externalName: string): bool {\n let cStr = this.allocStringCached(externalName);\n return binaryen._BinaryenGetExport(this.ref, cStr) != 0;\n }\n\n // imports\n\n addFunctionImport(\n internalName: string,\n externalModuleName: string,\n externalBaseName: string,\n params: TypeRef,\n results: TypeRef\n ): void {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalModuleName);\n let cStr3 = this.allocStringCached(externalBaseName);\n binaryen._BinaryenAddFunctionImport(this.ref, cStr1, cStr2, cStr3, params, results);\n }\n\n addTableImport(\n internalName: string,\n externalModuleName: string,\n externalBaseName: string\n ): void {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalModuleName);\n let cStr3 = this.allocStringCached(externalBaseName);\n binaryen._BinaryenAddTableImport(this.ref, cStr1, cStr2, cStr3);\n }\n\n addMemoryImport(\n internalName: string,\n externalModuleName: string,\n externalBaseName: string,\n shared: bool = false,\n ): void {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalModuleName);\n let cStr3 = this.allocStringCached(externalBaseName);\n binaryen._BinaryenAddMemoryImport(this.ref, cStr1, cStr2, cStr3, shared);\n }\n\n addGlobalImport(\n internalName: string,\n externalModuleName: string,\n externalBaseName: string,\n globalType: TypeRef,\n mutable: bool = false\n ): void {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalModuleName);\n let cStr3 = this.allocStringCached(externalBaseName);\n binaryen._BinaryenAddGlobalImport(this.ref, cStr1, cStr2, cStr3, globalType, mutable);\n }\n\n addTagImport(\n internalName: string,\n externalModuleName: string,\n externalBaseName: string,\n params: TypeRef,\n results: TypeRef\n ): void {\n let cStr1 = this.allocStringCached(internalName);\n let cStr2 = this.allocStringCached(externalModuleName);\n let cStr3 = this.allocStringCached(externalBaseName);\n binaryen._BinaryenAddTagImport(\n this.ref, cStr1, cStr2, cStr3, params, results\n );\n }\n\n // memory\n\n /** Unlimited memory constant. */\n static readonly UNLIMITED_MEMORY: Index = -1;\n\n setMemory(\n initial: Index,\n maximum: Index,\n segments: MemorySegment[],\n target: Target,\n exportName: string | null = null,\n name: string = CommonNames.DefaultMemory,\n shared: bool = false\n ): void {\n let cStr1 = this.allocStringCached(exportName);\n let cStr2 = this.allocStringCached(name);\n let k = segments.length;\n let segs = new Array(k);\n let psvs = new Uint8Array(k);\n let offs = new Array(k);\n let sizs = new Array(k);\n for (let i = 0; i < k; ++i) {\n let segment = unchecked(segments[i]);\n let buffer = segment.buffer;\n let offset = segment.offset;\n unchecked(segs[i] = allocU8Array(buffer));\n unchecked(psvs[i] = 0); // no passive segments currently\n unchecked(offs[i] = target == Target.Wasm64\n ? this.i64(i64_low(offset), i64_high(offset))\n : this.i32(i64_low(offset))\n );\n unchecked(sizs[i] = buffer.length);\n }\n let cArr1 = allocPtrArray(segs);\n let cArr2 = allocU8Array(psvs);\n let cArr3 = allocPtrArray(offs);\n let cArr4 = allocU32Array(sizs);\n binaryen._BinaryenSetMemory(\n this.ref, initial, maximum, cStr1, cArr1, cArr2, cArr3, cArr4, k, shared, false, cStr2\n );\n binaryen._free(cArr4);\n binaryen._free(cArr3);\n binaryen._free(cArr2);\n binaryen._free(cArr1);\n for (let i = k - 1; i >= 0; --i) {\n binaryen._free(unchecked(segs[i]));\n }\n }\n\n // table\n\n /** Unlimited table constant. */\n static readonly UNLIMITED_TABLE: Index = -1;\n\n addFunctionTable(\n name: string,\n initial: Index,\n maximum: Index,\n funcs: string[],\n offset: ExpressionRef\n ): void {\n let cStr = this.allocStringCached(name);\n let numNames = funcs.length;\n let names = new Array(numNames);\n for (let i = 0; i < numNames; ++i) {\n unchecked(names[i] = this.allocStringCached(funcs[i]));\n }\n let cArr = allocPtrArray(names);\n let tableRef = binaryen._BinaryenGetTable(this.ref, cStr);\n if (!tableRef) {\n tableRef = binaryen._BinaryenAddTable(this.ref, cStr, initial, maximum, TypeRef.Funcref);\n } else {\n binaryen._BinaryenTableSetInitial(tableRef, initial);\n binaryen._BinaryenTableSetMax(tableRef, maximum);\n }\n binaryen._BinaryenAddActiveElementSegment(this.ref, cStr, cStr, cArr, numNames, offset);\n binaryen._free(cArr);\n }\n\n /* setFunctionTable(\n initial: Index,\n maximum: Index,\n funcs: string[],\n offset: ExpressionRef\n ): void {\n let numNames = funcs.length;\n let names = new Array(numNames);\n for (let i = 0; i < numNames; ++i) {\n names[i] = this.allocStringCached(funcs[i]);\n }\n let cArr = allocPtrArray(names);\n binaryen._BinaryenSetFunctionTable(\n this.ref, initial, maximum, cArr, numNames, offset\n );\n binaryen._free(cArr);\n } */\n\n // sections\n\n addCustomSection(name: string, contents: Uint8Array): void {\n let cStr = this.allocStringCached(name);\n let cArr = allocU8Array(contents);\n binaryen._BinaryenAddCustomSection(this.ref, cStr, cArr, contents.length);\n binaryen._free(cArr);\n }\n\n // meta (global)\n\n getOptimizeLevel(): i32 {\n return binaryen._BinaryenGetOptimizeLevel();\n }\n\n setOptimizeLevel(level: i32): void {\n binaryen._BinaryenSetOptimizeLevel(level);\n }\n\n getShrinkLevel(): i32 {\n return binaryen._BinaryenGetShrinkLevel();\n }\n\n setShrinkLevel(level: i32): void {\n binaryen._BinaryenSetShrinkLevel(level);\n }\n\n getDebugInfo(): boolean {\n return binaryen._BinaryenGetDebugInfo();\n }\n\n setDebugInfo(on: bool): void {\n binaryen._BinaryenSetDebugInfo(on);\n }\n\n getLowMemoryUnused(): bool {\n return binaryen._BinaryenGetLowMemoryUnused();\n }\n\n setLowMemoryUnused(on: bool): void {\n binaryen._BinaryenSetLowMemoryUnused(on);\n }\n\n getZeroFilledMemory(): bool {\n return binaryen._BinaryenGetZeroFilledMemory();\n }\n\n setZeroFilledMemory(on: bool): void {\n binaryen._BinaryenSetZeroFilledMemory(on);\n }\n\n getFastMath(): bool {\n return binaryen._BinaryenGetFastMath();\n }\n\n setFastMath(on: bool): void {\n binaryen._BinaryenSetFastMath(on);\n }\n\n getPassArgument(key: string): string | null {\n let cStr = this.allocStringCached(key);\n let ptr = binaryen._BinaryenGetPassArgument(cStr);\n return ptr ? readString(ptr) : null;\n }\n\n setPassArgument(key: string, value: string | null): void {\n let cStr1 = this.allocStringCached(key);\n let cStr2 = this.allocStringCached(value);\n binaryen._BinaryenSetPassArgument(cStr1, cStr2);\n }\n\n clearPassArguments(): void {\n binaryen._BinaryenClearPassArguments();\n }\n\n getAlwaysInlineMaxSize(): Index {\n return binaryen._BinaryenGetAlwaysInlineMaxSize();\n }\n\n setAlwaysInlineMaxSize(size: Index): void {\n binaryen._BinaryenSetAlwaysInlineMaxSize(size);\n }\n\n getFlexibleInlineMaxSize(): Index {\n return binaryen._BinaryenGetFlexibleInlineMaxSize();\n }\n\n setFlexibleInlineMaxSize(size: Index): void {\n binaryen._BinaryenSetFlexibleInlineMaxSize(size);\n }\n\n getOneCallerInlineMaxSize(): Index {\n return binaryen._BinaryenGetOneCallerInlineMaxSize();\n }\n\n setOneCallerInlineMaxSize(size: Index): void {\n binaryen._BinaryenSetOneCallerInlineMaxSize(size);\n }\n\n getAllowInliningFunctionsWithLoops(): bool {\n return binaryen._BinaryenGetAllowInliningFunctionsWithLoops();\n }\n\n setAllowInliningFunctionsWithLoops(enabled: bool): void {\n binaryen._BinaryenSetAllowInliningFunctionsWithLoops(enabled);\n }\n\n // meta (module)\n\n getFeatures(): FeatureFlags {\n return binaryen._BinaryenModuleGetFeatures(this.ref);\n }\n\n setFeatures(featureFlags: FeatureFlags): void {\n binaryen._BinaryenModuleSetFeatures(this.ref, featureFlags);\n }\n\n runPasses(passes: string[], func: FunctionRef = 0): void {\n let numNames = passes.length;\n let cStrs = new Array(numNames);\n for (let i = 0; i < numNames; ++i) {\n cStrs[i] = allocString(passes[i]);\n }\n let cArr = allocPtrArray(cStrs);\n if (func) {\n binaryen._BinaryenFunctionRunPasses(func, this.ref, cArr, numNames);\n } else {\n binaryen._BinaryenModuleRunPasses(this.ref, cArr, numNames);\n }\n binaryen._free(cArr);\n for (let i = numNames - 1; i >= 0; --i) binaryen._free(cStrs[i]);\n }\n\n optimize(\n optimizeLevel: i32,\n shrinkLevel: i32,\n debugInfo: bool = false,\n zeroFilledMemory: bool = false\n ): void {\n // Implicitly run costly non-LLVM optimizations on -O3 or -Oz\n if (optimizeLevel >= 3 || shrinkLevel >= 2) optimizeLevel = 4;\n\n this.setOptimizeLevel(optimizeLevel);\n this.setShrinkLevel(shrinkLevel);\n this.setDebugInfo(debugInfo);\n this.setZeroFilledMemory(zeroFilledMemory);\n this.setFastMath(true);\n this.clearPassArguments();\n\n // Tweak inlining limits based on optimization levels\n if (optimizeLevel >= 2 && shrinkLevel == 0) {\n this.setAlwaysInlineMaxSize(12);\n this.setFlexibleInlineMaxSize(70);\n this.setOneCallerInlineMaxSize(200);\n this.setAllowInliningFunctionsWithLoops(optimizeLevel >= 3);\n } else {\n this.setAlwaysInlineMaxSize(\n optimizeLevel <= 1 || shrinkLevel >= 2\n ? 2\n : 6\n );\n this.setFlexibleInlineMaxSize(65);\n this.setOneCallerInlineMaxSize(80);\n this.setAllowInliningFunctionsWithLoops(false);\n }\n\n // Pass order here differs substantially from Binaryen's defaults\n // see: Binaryen/src/pass.cpp\n if (optimizeLevel > 0 || shrinkLevel > 0) {\n let passes = new Array();\n\n // --- PassRunner::addDefaultGlobalOptimizationPrePasses ---\n\n passes.push(\"duplicate-function-elimination\");\n passes.push(\"remove-unused-module-elements\"); // +\n\n // --- PassRunner::addDefaultFunctionOptimizationPasses ---\n if (optimizeLevel >= 2) {\n passes.push(\"once-reduction\");\n passes.push(\"inlining\");\n passes.push(\"simplify-globals-optimizing\");\n }\n if (optimizeLevel >= 3 || shrinkLevel >= 1) {\n passes.push(\"rse\");\n passes.push(\"vacuum\");\n passes.push(\"code-folding\");\n passes.push(\"ssa-nomerge\");\n passes.push(\"local-cse\");\n passes.push(\"remove-unused-brs\");\n passes.push(\"remove-unused-names\");\n passes.push(\"merge-blocks\");\n passes.push(\"precompute-propagate\");\n passes.push(\"simplify-globals-optimizing\");\n passes.push(\"gufa-optimizing\");\n passes.push(\"dae-optimizing\");\n }\n if (optimizeLevel >= 3) {\n passes.push(\"simplify-locals-nostructure\");\n passes.push(\"flatten\");\n passes.push(\"vacuum\");\n passes.push(\"simplify-locals-notee-nostructure\");\n passes.push(\"vacuum\");\n passes.push(\"licm\");\n passes.push(\"merge-locals\");\n passes.push(\"reorder-locals\");\n }\n passes.push(\"optimize-instructions\");\n if (optimizeLevel >= 3 || shrinkLevel >= 1) {\n passes.push(\"dce\");\n }\n passes.push(\"remove-unused-brs\");\n passes.push(\"remove-unused-names\");\n if (optimizeLevel >= 3 || shrinkLevel >= 2) {\n passes.push(\"inlining\");\n passes.push(\"precompute-propagate\");\n passes.push(\"simplify-globals-optimizing\");\n } else {\n passes.push(\"precompute\");\n }\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"pick-load-signs\");\n }\n passes.push(\"simplify-locals-notee-nostructure\");\n passes.push(\"vacuum\");\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"local-cse\");\n }\n passes.push(\"reorder-locals\");\n passes.push(\"coalesce-locals\");\n passes.push(\"simplify-locals\");\n passes.push(\"coalesce-locals\");\n passes.push(\"reorder-locals\");\n passes.push(\"vacuum\");\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"rse\");\n passes.push(\"vacuum\");\n }\n if (optimizeLevel >= 3 || shrinkLevel >= 1) {\n passes.push(\"merge-locals\");\n passes.push(\"vacuum\");\n }\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"simplify-globals-optimizing\");\n passes.push(\"simplify-globals-optimizing\");\n }\n passes.push(\"remove-unused-brs\");\n passes.push(\"remove-unused-names\");\n passes.push(\"merge-blocks\");\n if (optimizeLevel >= 3) {\n passes.push(\"optimize-instructions\");\n }\n\n // --- PassRunner::addDefaultGlobalOptimizationPostPasses ---\n\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"simplify-globals-optimizing\");\n passes.push(\"dae-optimizing\");\n }\n if (optimizeLevel >= 2 || shrinkLevel >= 2) {\n passes.push(\"inlining-optimizing\");\n }\n if (this.getLowMemoryUnused()) {\n if (optimizeLevel >= 3 || shrinkLevel >= 1) {\n passes.push(\"optimize-added-constants-propagate\");\n } else {\n passes.push(\"optimize-added-constants\");\n }\n }\n passes.push(\"duplicate-import-elimination\");\n if (optimizeLevel >= 2 || shrinkLevel >= 2) {\n passes.push(\"simplify-globals-optimizing\");\n } else {\n passes.push(\"simplify-globals\");\n passes.push(\"vacuum\");\n }\n if (optimizeLevel >= 2 && (this.getFeatures() & FeatureFlags.GC) != 0) {\n passes.push(\"heap2local\");\n passes.push(\"merge-locals\");\n passes.push(\"local-subtyping\");\n }\n // precompute works best after global optimizations\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"precompute-propagate\");\n passes.push(\"simplify-globals-optimizing\");\n passes.push(\"simplify-globals-optimizing\");\n } else {\n passes.push(\"precompute\");\n }\n passes.push(\"directize\"); // replace indirect with direct calls\n passes.push(\"dae-optimizing\"); // reduce arity\n passes.push(\"inlining-optimizing\"); // and inline if possible\n if (optimizeLevel >= 2 || shrinkLevel >= 1) {\n passes.push(\"code-folding\");\n passes.push(\"ssa-nomerge\");\n passes.push(\"rse\");\n // move code on early return (after CFG cleanup)\n passes.push(\"code-pushing\");\n if (optimizeLevel >= 3) {\n // very expensive, so O3 only\n passes.push(\"simplify-globals\");\n passes.push(\"vacuum\");\n\n passes.push(\"precompute-propagate\");\n\n // replace indirect with direct calls again and inline\n passes.push(\"inlining-optimizing\");\n passes.push(\"directize\");\n passes.push(\"dae-optimizing\");\n passes.push(\"local-cse\");\n\n passes.push(\"merge-locals\");\n passes.push(\"coalesce-locals\");\n passes.push(\"simplify-locals\");\n passes.push(\"vacuum\");\n\n passes.push(\"inlining\");\n passes.push(\"precompute-propagate\");\n passes.push(\"rse\");\n passes.push(\"vacuum\");\n passes.push(\"ssa-nomerge\");\n passes.push(\"simplify-locals\");\n passes.push(\"coalesce-locals\");\n }\n passes.push(\"optimize-instructions\");\n passes.push(\"remove-unused-brs\");\n passes.push(\"remove-unused-names\");\n passes.push(\"merge-blocks\");\n passes.push(\"vacuum\");\n\n passes.push(\"simplify-globals-optimizing\");\n passes.push(\"reorder-globals\");\n passes.push(\"remove-unused-brs\");\n passes.push(\"optimize-instructions\");\n }\n // clean up\n passes.push(\"duplicate-function-elimination\");\n if (shrinkLevel >= 2) {\n passes.push(\"merge-similar-functions\");\n }\n passes.push(\"memory-packing\");\n passes.push(\"remove-unused-module-elements\");\n\n this.runPasses(passes);\n }\n }\n\n validate(): bool {\n return binaryen._BinaryenModuleValidate(this.ref) == 1;\n }\n\n interpret(): void {\n binaryen._BinaryenModuleInterpret(this.ref);\n }\n\n toBinary(sourceMapUrl: string | null = null): BinaryModule {\n assert(\n binaryen._BinaryenSizeofLiteral() >=\n binaryen._BinaryenSizeofAllocateAndWriteResult()\n );\n\n // now safely reuse lit buffer for BinaryenModuleAllocateAndWriteResult\n let resPtr = this.lit;\n let urlPtr = allocString(sourceMapUrl);\n\n binaryen._BinaryenModuleAllocateAndWrite(resPtr, this.ref, urlPtr);\n\n // read BinaryenModuleAllocateAndWriteResult struct\n let binaryPtr = binaryen.__i32_load(resPtr + 0) as usize; // non-nullabe\n let binaryLen = binaryen.__i32_load(resPtr + 4);\n let srcMapPtr = binaryen.__i32_load(resPtr + 8) as usize; // nullable\n\n let binary = new BinaryModule(\n readBuffer(assert(binaryPtr), binaryLen),\n readString(srcMapPtr)\n );\n\n if (urlPtr) binaryen._free(urlPtr);\n if (srcMapPtr) binaryen._free(srcMapPtr);\n binaryen._free(binaryPtr);\n\n return binary;\n }\n\n toText(watFormat: bool = true): string {\n let textPtr = watFormat\n ? binaryen._BinaryenModuleAllocateAndWriteStackIR(this.ref, true)\n : binaryen._BinaryenModuleAllocateAndWriteText(this.ref);\n let text = readString(textPtr);\n if (textPtr) binaryen._free(textPtr);\n return text || \"\";\n }\n\n private cachedStringsToPointers: Map = new Map();\n private cachedPointersToStrings: Map = new Map();\n\n allocStringCached(str: string | null): usize {\n if (str == null) return 0;\n let cached = this.cachedStringsToPointers;\n if (cached.has(str)) return changetype(cached.get(str));\n let ptr = allocString(str);\n cached.set(str, ptr);\n return ptr;\n }\n\n readStringCached(ptr: usize): string | null {\n // Binaryen internalizes names, so using this method where it's safe can\n // avoid quite a bit of unnecessary garbage.\n if (ptr == 0) return null;\n let cached = this.cachedPointersToStrings;\n if (cached.has(ptr)) return changetype(cached.get(ptr));\n let str = readString(ptr);\n cached.set(ptr, str);\n return str;\n }\n\n dispose(): void {\n assert(this.ref);\n // TODO: for (let ptr of this.cachedStrings.values()) {\n for (let _values = Map_values(this.cachedStringsToPointers), i = 0, k = _values.length; i < k; ++i) {\n let ptr = unchecked(_values[i]);\n binaryen._free(ptr);\n }\n this.cachedStringsToPointers.clear();\n this.cachedPointersToStrings.clear();\n binaryen._free(this.lit);\n binaryen._BinaryenModuleDispose(this.ref);\n this.ref = 0;\n }\n\n createRelooper(): Relooper {\n return Relooper.create(this);\n }\n\n /** Makes a copy of a trivial expression (doesn't contain subexpressions). Returns `0` if non-trivial. */\n tryCopyTrivialExpression(expr: ExpressionRef): ExpressionRef {\n switch (binaryen._BinaryenExpressionGetId(expr)) {\n case ExpressionId.LocalGet:\n case ExpressionId.GlobalGet:\n case ExpressionId.Const:\n case ExpressionId.MemorySize:\n case ExpressionId.Nop:\n case ExpressionId.Unreachable:\n case ExpressionId.DataDrop:\n case ExpressionId.RefNull: return this.copyExpression(expr);\n }\n return 0;\n }\n\n /** Makes a copy of any expression including all subexpressions. */\n copyExpression(expr: ExpressionRef): ExpressionRef {\n // TODO: Copy debug location as well (needs Binaryen support)\n return binaryen._BinaryenExpressionCopy(expr, this.ref);\n }\n\n runExpression(\n expr: ExpressionRef,\n flags: ExpressionRunnerFlags,\n maxDepth: i32 = 50,\n maxLoopIterations: i32 = 1\n ): ExpressionRef {\n let runner = binaryen._ExpressionRunnerCreate(this.ref, flags, maxDepth, maxLoopIterations);\n let precomp = binaryen._ExpressionRunnerRunAndDispose(runner, expr);\n if (precomp) {\n if (!this.isConstExpression(precomp)) return 0;\n assert(getExpressionType(precomp) == getExpressionType(expr));\n }\n return precomp;\n }\n\n isConstExpression(expr: ExpressionRef): bool {\n switch (getExpressionId(expr)) {\n case ExpressionId.Const:\n case ExpressionId.RefNull:\n case ExpressionId.RefFunc:\n case ExpressionId.I31New: return true;\n case ExpressionId.Binary: {\n if (this.getFeatures() & FeatureFlags.ExtendedConst) {\n switch (getBinaryOp(expr)) {\n case BinaryOp.AddI32:\n case BinaryOp.SubI32:\n case BinaryOp.MulI32:\n case BinaryOp.AddI64:\n case BinaryOp.SubI64:\n case BinaryOp.MulI64:\n return (\n this.isConstExpression(getBinaryLeft(expr)) &&\n this.isConstExpression(getBinaryRight(expr))\n );\n }\n }\n break;\n }\n }\n return false;\n }\n\n // source map generation\n\n addDebugInfoFile(name: string): Index {\n let cStr = allocString(name);\n let ret = binaryen._BinaryenModuleAddDebugInfoFileName(this.ref, cStr);\n binaryen._free(cStr);\n return ret;\n }\n\n getDebugInfoFile(index: Index): string | null {\n return readString(binaryen._BinaryenModuleGetDebugInfoFileName(this.ref, index));\n }\n\n setDebugLocation(\n func: FunctionRef,\n expr: ExpressionRef,\n fileIndex: Index,\n lineNumber: Index,\n columnNumber: Index\n ): void {\n binaryen._BinaryenFunctionSetDebugLocation(func, expr, fileIndex, lineNumber, columnNumber);\n }\n}\n\n// types\n\nexport function createType(types: TypeRef[] | null): TypeRef {\n if (!types) return TypeRef.None;\n switch (types.length) {\n case 0: return TypeRef.None;\n case 1: return types[0];\n }\n let cArr = allocPtrArray(types);\n let ret = binaryen._BinaryenTypeCreate(cArr, types.length);\n binaryen._free(cArr);\n return ret;\n}\n\nexport function expandType(type: TypeRef): TypeRef[] {\n let arity = binaryen._BinaryenTypeArity(type);\n let cArr = binaryen._malloc(arity << 2);\n binaryen._BinaryenTypeExpand(type, cArr);\n let types = new Array(arity);\n for (let i: u32 = 0; i < arity; ++i) {\n unchecked(types[i] = binaryen.__i32_load(cArr + (i << 2)));\n }\n binaryen._free(cArr);\n return types;\n}\n\nexport function isNullableType(type: TypeRef): bool {\n return binaryen._BinaryenTypeIsNullable(type);\n}\n\n// expressions\n\nexport function getExpressionId(expr: ExpressionRef): ExpressionId {\n return binaryen._BinaryenExpressionGetId(expr);\n}\n\nexport function getExpressionType(expr: ExpressionRef): TypeRef {\n return binaryen._BinaryenExpressionGetType(expr);\n}\n\nexport function getConstValueI32(expr: ExpressionRef): i32 {\n return binaryen._BinaryenConstGetValueI32(expr);\n}\n\nexport function getConstValueI64Low(expr: ExpressionRef): i32 {\n return binaryen._BinaryenConstGetValueI64Low(expr);\n}\n\nexport function getConstValueI64High(expr: ExpressionRef): i32 {\n return binaryen._BinaryenConstGetValueI64High(expr);\n}\n\nexport function getConstValueF32(expr: ExpressionRef): f32 {\n return binaryen._BinaryenConstGetValueF32(expr);\n}\n\nexport function getConstValueF64(expr: ExpressionRef): f64 {\n return binaryen._BinaryenConstGetValueF64(expr);\n}\n\nexport function getConstValueV128(expr: ExpressionRef): Uint8Array {\n let cArr = binaryen._malloc(16);\n binaryen._BinaryenConstGetValueV128(expr, cArr);\n let out = new Uint8Array(16);\n for (let i = 0; i < 16; ++i) {\n out[i] = binaryen.__i32_load8_u(cArr + i);\n }\n binaryen._free(cArr);\n return out;\n}\n\nexport function isConstZero(expr: ExpressionRef): bool {\n if (getExpressionId(expr) != ExpressionId.Const) return false;\n let type = getExpressionType(expr);\n if (type == TypeRef.I32) return getConstValueI32(expr) == 0;\n if (type == TypeRef.I64) return (getConstValueI64Low(expr) | getConstValueI64High(expr)) == 0;\n if (type == TypeRef.F32) return getConstValueF32(expr) == 0;\n if (type == TypeRef.F64) return getConstValueF64(expr) == 0;\n return false;\n}\n\nexport function isConstNonZero(expr: ExpressionRef): bool {\n if (getExpressionId(expr) != ExpressionId.Const) return false;\n let type = getExpressionType(expr);\n if (type == TypeRef.I32) return getConstValueI32(expr) != 0;\n if (type == TypeRef.I64) return (getConstValueI64Low(expr) | getConstValueI64High(expr)) != 0;\n if (type == TypeRef.F32) return getConstValueF32(expr) != 0;\n if (type == TypeRef.F64) return getConstValueF64(expr) != 0;\n return false;\n}\n\nexport function isConstNegZero(expr: ExpressionRef): bool {\n if (getExpressionId(expr) != ExpressionId.Const) return false;\n let type = getExpressionType(expr);\n if (type == TypeRef.F32) {\n let d = getConstValueF32(expr);\n return d == 0 && f32_as_i32(d) < 0;\n }\n if (type == TypeRef.F64) {\n let d = getConstValueF64(expr);\n return d == 0 && i64_signbit(f64_as_i64(d));\n }\n return false;\n}\n\nexport function isConstNaN(expr: ExpressionRef): bool {\n if (getExpressionId(expr) != ExpressionId.Const) return false;\n let type = getExpressionType(expr);\n if (type == TypeRef.F32) return isNaN(getConstValueF32(expr));\n if (type == TypeRef.F64) return isNaN(getConstValueF64(expr));\n return false;\n}\n\nexport function isConstExpressionNaN(module: Module, expr: ExpressionRef): bool {\n let id = getExpressionId(expr);\n let type = getExpressionType(expr);\n if (type == TypeRef.F32 || type == TypeRef.F64) {\n if (id == ExpressionId.Const) {\n return isNaN(\n type == TypeRef.F32\n ? getConstValueF32(expr)\n : getConstValueF64(expr)\n );\n } else if (id == ExpressionId.GlobalGet) {\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.Default, 8);\n if (precomp) {\n return isNaN(\n type == TypeRef.F32\n ? getConstValueF32(precomp)\n : getConstValueF64(precomp)\n );\n }\n }\n }\n return false;\n}\n\nexport function getLocalGetIndex(expr: ExpressionRef): Index {\n return binaryen._BinaryenLocalGetGetIndex(expr);\n}\n\nexport function getLocalSetIndex(expr: ExpressionRef): Index {\n return binaryen._BinaryenLocalSetGetIndex(expr);\n}\n\nexport function getLocalSetValue(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenLocalSetGetValue(expr);\n}\n\nexport function isLocalTee(expr: ExpressionRef): bool {\n return binaryen._BinaryenLocalSetIsTee(expr);\n}\n\nexport function getGlobalGetName(expr: ExpressionRef): string | null {\n return readString(binaryen._BinaryenGlobalGetGetName(expr));\n}\n\nexport function getBinaryOp(expr: ExpressionRef): BinaryOp {\n return binaryen._BinaryenBinaryGetOp(expr);\n}\n\nexport function getBinaryLeft(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenBinaryGetLeft(expr);\n}\n\nexport function getBinaryRight(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenBinaryGetRight(expr);\n}\n\nexport function getUnaryOp(expr: ExpressionRef): UnaryOp {\n return binaryen._BinaryenUnaryGetOp(expr);\n}\n\nexport function getUnaryValue(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenUnaryGetValue(expr);\n}\n\nexport function getLoadBytes(expr: ExpressionRef): u32 {\n return binaryen._BinaryenLoadGetBytes(expr);\n}\n\nexport function getLoadOffset(expr: ExpressionRef): u32 {\n return binaryen._BinaryenLoadGetOffset(expr);\n}\n\nexport function getLoadPtr(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenLoadGetPtr(expr);\n}\n\nexport function isLoadSigned(expr: ExpressionRef): bool {\n return binaryen._BinaryenLoadIsSigned(expr);\n}\n\nexport function getStoreBytes(expr: ExpressionRef): u32 {\n return binaryen._BinaryenStoreGetBytes(expr);\n}\n\nexport function getStoreOffset(expr: ExpressionRef): u32 {\n return binaryen._BinaryenStoreGetOffset(expr);\n}\n\nexport function getStorePtr(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenStoreGetPtr(expr);\n}\n\nexport function getStoreValue(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenStoreGetValue(expr);\n}\n\nexport function getBlockName(expr: ExpressionRef): string | null {\n return readString(binaryen._BinaryenBlockGetName(expr));\n}\n\nexport function getBlockChildCount(expr: ExpressionRef): Index {\n return binaryen._BinaryenBlockGetNumChildren(expr);\n}\n\nexport function getBlockChildAt(expr: ExpressionRef, index: Index): ExpressionRef {\n return binaryen._BinaryenBlockGetChildAt(expr, index);\n}\n\nexport function getIfCondition(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenIfGetCondition(expr);\n}\n\nexport function getIfTrue(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenIfGetIfTrue(expr);\n}\n\nexport function getIfFalse(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenIfGetIfFalse(expr);\n}\n\nexport function getLoopName(expr: ExpressionRef): string | null {\n return readString(binaryen._BinaryenLoopGetName(expr));\n}\n\nexport function getLoopBody(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenLoopGetBody(expr);\n}\n\nexport function getBreakName(expr: ExpressionRef): string | null {\n return readString(binaryen._BinaryenBreakGetName(expr));\n}\n\nexport function getBreakCondition(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenBreakGetCondition(expr);\n}\n\nexport function getSelectThen(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenSelectGetIfTrue(expr);\n}\n\nexport function getSelectElse(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenSelectGetIfFalse(expr);\n}\n\nexport function getSelectCondition(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenSelectGetCondition(expr);\n}\n\nexport function getDropValue(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenDropGetValue(expr);\n}\n\nexport function getReturnValue(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenReturnGetValue(expr);\n}\n\nexport function getCallTarget(expr: ExpressionRef): string | null {\n return readString(binaryen._BinaryenCallGetTarget(expr));\n}\n\nexport function getCallOperandCount(expr: ExpressionRef): i32 {\n return binaryen._BinaryenCallGetNumOperands(expr);\n}\n\nexport function getCallOperandAt(expr: ExpressionRef, index: Index): ExpressionRef {\n return binaryen._BinaryenCallGetOperandAt(expr, index);\n}\n\nexport function getMemoryGrowDelta(expr: ExpressionRef): ExpressionRef {\n return binaryen._BinaryenMemoryGrowGetDelta(expr);\n}\n\n// functions\n\nexport function getFunctionBody(func: FunctionRef): ExpressionRef {\n return binaryen._BinaryenFunctionGetBody(func);\n}\n\nexport function getFunctionName(func: FunctionRef): string | null {\n return readString(binaryen._BinaryenFunctionGetName(func));\n}\n\nexport function getFunctionParams(func: FunctionRef): TypeRef {\n return binaryen._BinaryenFunctionGetParams(func);\n}\n\nexport function getFunctionResults(func: FunctionRef): TypeRef {\n return binaryen._BinaryenFunctionGetResults(func);\n}\n\nexport function getFunctionVars(func: FunctionRef): TypeRef[] {\n let count = binaryen._BinaryenFunctionGetNumVars(func);\n let types = new Array(count);\n for (let i: Index = 0; i < count; ++i) {\n unchecked(types[i] = binaryen._BinaryenFunctionGetVar(func, i));\n }\n return types;\n}\n\n// globals\n\nexport function getGlobalName(global: GlobalRef): string | null {\n return readString(binaryen._BinaryenGlobalGetName(global));\n}\n\nexport function getGlobalType(global: GlobalRef): TypeRef {\n return binaryen._BinaryenGlobalGetType(global);\n}\n\nexport function isGlobalMutable(global: GlobalRef): bool {\n return binaryen._BinaryenGlobalIsMutable(global);\n}\n\nexport function getGlobalInit(global: GlobalRef): ExpressionRef {\n return binaryen._BinaryenGlobalGetInitExpr(global);\n}\n\n// tags\n\nexport function getTagName(tag: TagRef): string | null {\n return readString(binaryen._BinaryenTagGetName(tag));\n}\n\nexport function getTagParams(tag: TagRef): TypeRef {\n return binaryen._BinaryenTagGetParams(tag);\n}\n\nexport function getTagResults(tag: TagRef): TypeRef {\n return binaryen._BinaryenTagGetResults(tag);\n}\n\nexport class Relooper {\n constructor(\n /** Module this relooper belongs to. */\n public module: Module,\n /** Binaryen relooper reference. */\n public ref: RelooperRef\n ) {}\n\n static create(module: Module): Relooper {\n return new Relooper(module, binaryen._RelooperCreate(module.ref));\n }\n\n addBlock(code: ExpressionRef): RelooperBlockRef {\n return binaryen._RelooperAddBlock(this.ref, code);\n }\n\n addBranch(\n from: RelooperBlockRef,\n to: RelooperBlockRef,\n condition: ExpressionRef = 0,\n code: ExpressionRef = 0\n ): void {\n binaryen._RelooperAddBranch(from, to, condition, code);\n }\n\n addBlockWithSwitch(code: ExpressionRef, condition: ExpressionRef): RelooperBlockRef {\n return binaryen._RelooperAddBlockWithSwitch(this.ref, code, condition);\n }\n\n addBranchForSwitch(\n from: RelooperBlockRef,\n to: RelooperBlockRef,\n indexes: i32[],\n code: ExpressionRef = 0\n ): void {\n let cArr = allocI32Array(indexes);\n binaryen._RelooperAddBranchForSwitch(from, to, cArr, indexes.length, code);\n binaryen._free(cArr);\n }\n\n renderAndDispose(entry: RelooperBlockRef, labelHelper: Index): ExpressionRef {\n return binaryen._RelooperRenderAndDispose(this.ref, entry, labelHelper);\n }\n}\n\n/** Builds a switch using a sequence of `br_if`s. */\nexport class SwitchBuilder {\n // This is useful because Binaryen understands sequences of `br_if`s and\n // knows how to make a `br_table` from such a sequence if switched over\n // values are considered dense enough, respectively a size-efficient sequence\n // of `if`s if not, depending on optimization levels.\n\n private module: Module;\n private condition: ExpressionRef;\n private values: i32[] = new Array();\n private indexes: i32[] = new Array();\n private cases: ExpressionRef[][] = new Array();\n private defaultIndex: i32 = -1;\n\n /** Creates a new builder using the specified i32 condition. */\n constructor(module: Module, condition: ExpressionRef) {\n this.module = module;\n this.condition = condition;\n }\n\n /** Links a case to the specified branch. */\n addCase(value: i32, code: ExpressionRef[]): void {\n let cases = this.cases;\n let index = cases.indexOf(code);\n if (index < 0) {\n index = cases.length;\n cases.push(code);\n }\n this.values.push(value);\n this.indexes.push(index);\n }\n\n /** Links the default branch. */\n addDefault(code: ExpressionRef[]): void {\n assert(this.defaultIndex == -1);\n let cases = this.cases;\n this.defaultIndex = cases.length;\n cases.push(code);\n }\n\n /** Renders the switch to a block. */\n render(localIndex: i32, labelPostfix: string = \"\"): ExpressionRef {\n let module = this.module;\n let cases = this.cases;\n let numCases = cases.length;\n if (!numCases) {\n return module.drop(this.condition);\n }\n let values = this.values;\n let numValues = values.length;\n let indexes = this.indexes;\n let entry = new Array(1 + numValues + 1);\n let labels = new Array(numCases);\n for (let i = 0; i < numCases; ++i) {\n unchecked(labels[i] = `case${i}${labelPostfix}`);\n }\n entry[0] = module.local_set(localIndex, this.condition, false); // u32\n for (let i = 0; i < numValues; ++i) {\n let index = unchecked(indexes[i]);\n unchecked(entry[1 + i] = module.br(labels[index],\n module.binary(BinaryOp.EqI32,\n module.local_get(localIndex, TypeRef.I32),\n module.i32(values[i])\n )\n ));\n }\n let defaultIndex = this.defaultIndex;\n let defaultLabel = `default${labelPostfix}`;\n entry[1 + numValues] = module.br(\n ~defaultIndex\n ? labels[defaultIndex]\n : defaultLabel\n );\n let current = module.block(labels[0], entry);\n for (let i = 1; i < numCases; ++i) {\n let block = cases[i - 1];\n block.unshift(current);\n current = module.block(unchecked(labels[i]), block);\n }\n let lastCase = cases[numCases - 1];\n lastCase.unshift(current);\n return module.block(\n ~defaultIndex\n ? null\n : defaultLabel,\n lastCase\n );\n }\n}\n\nexport const enum SideEffects {\n None = 0 /* _BinaryenSideEffectNone */,\n Branches = 1 /* _BinaryenSideEffectBranches */,\n Calls = 2 /* _BinaryenSideEffectCalls */,\n ReadsLocal = 4 /* _BinaryenSideEffectReadsLocal */,\n WritesLocal = 8 /* _BinaryenSideEffectWritesLocal */,\n ReadsGlobal = 16 /* _BinaryenSideEffectReadsGlobal */,\n WritesGlobal = 32 /* _BinaryenSideEffectWritesGlobal */,\n ReadsMemory = 64 /* _BinaryenSideEffectReadsMemory */,\n WritesMemory = 128 /* _BinaryenSideEffectWritesMemory */,\n ReadsTable = 256 /* _BinaryenSideEffectReadsTable */,\n WritesTable = 512 /* _BinaryenSideEffectWritesTable */,\n ImplicitTrap = 1024 /* _BinaryenSideEffectImplicitTrap */,\n IsAtomic = 2048 /* _BinaryenSideEffectIsAtomic */,\n Throws = 4096 /* _BinaryenSideEffectThrows */,\n DanglingPop = 8192 /* _BinaryenSideEffectDanglingPop */,\n TrapsNeverHappen = 16384 /* _BinaryenSideEffectTrapsNeverHappen */,\n Any = 32767 /* _BinaryenSideEffectAny */\n}\n\nexport function getSideEffects(expr: ExpressionRef, module: ModuleRef): SideEffects {\n return binaryen._BinaryenExpressionGetSideEffects(expr, module);\n}\n\nexport function mustPreserveSideEffects(expr: ExpressionRef, module: ModuleRef): bool {\n return (getSideEffects(expr, module) & ~(SideEffects.ReadsLocal | SideEffects.ReadsGlobal)) != SideEffects.None;\n}\n\n// helpers\n// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js\n\nfunction allocU8Array(u8s: Uint8Array | null): usize {\n if (!u8s) return 0;\n let len = u8s.length;\n let ptr = binaryen._malloc(len);\n for (let i = 0; i < len; ++i) {\n binaryen.__i32_store8(ptr + i, unchecked(u8s[i]));\n }\n return ptr;\n}\n\nfunction allocI32Array(i32s: i32[] | null): usize {\n if (!i32s) return 0;\n let len = i32s.length;\n let ptr = binaryen._malloc(len << 2);\n let idx = ptr;\n for (let i = 0; i < len; ++i) {\n let val = unchecked(i32s[i]);\n binaryen.__i32_store(idx, val);\n idx += 4;\n }\n return ptr;\n}\n\nfunction allocU32Array(u32s: u32[] | null): usize {\n if (!u32s) return 0;\n let len = u32s.length;\n let ptr = binaryen._malloc(len << 2);\n let idx = ptr;\n for (let i = 0; i < len; ++i) {\n let val = unchecked(u32s[i]);\n binaryen.__i32_store(idx, val);\n idx += 4;\n }\n return ptr;\n}\n\nexport function allocPtrArray(ptrs: usize[] | null): usize {\n if (!ptrs) return 0;\n // TODO: WASM64\n assert(ASC_TARGET != Target.Wasm64);\n let len = ptrs.length;\n let ptr = binaryen._malloc(len << 2);\n let idx = ptr;\n for (let i = 0, k = len; i < k; ++i) {\n let val = unchecked(ptrs[i]);\n binaryen.__i32_store(idx, val);\n idx += 4;\n }\n return ptr;\n}\n\nfunction stringLengthUTF8(str: string): usize {\n let len = 0;\n for (let i = 0, k = str.length; i < k; ++i) {\n let c1 = str.charCodeAt(i) >>> 0;\n if (c1 <= 0x7F) {\n len += 1;\n } else if (c1 <= 0x7FF) {\n len += 2;\n } else if (\n isHighSurrogate(c1) && i + 1 < k &&\n isLowSurrogate(str.charCodeAt(i + 1))\n ) {\n i++;\n len += 4;\n } else {\n len += 3;\n }\n }\n return len;\n}\n\nfunction allocString(str: string | null): usize {\n if (str == null) return 0;\n let len = stringLengthUTF8(str);\n let ptr = binaryen._malloc(len + 1) >>> 0;\n let idx = ptr;\n if (len == str.length) {\n // fast path when all chars are ascii\n for (let i = 0, k = str.length; i < k; ++i) {\n let u = str.charCodeAt(i) >>> 0;\n binaryen.__i32_store8(idx++, u as u8);\n }\n } else {\n for (let i = 0, k = str.length; i < k; ++i) {\n let c1 = str.charCodeAt(i) >>> 0, c2: i32;\n if (c1 <= 0x7F) {\n binaryen.__i32_store8(idx++, c1 as u8);\n } else if (c1 <= 0x7FF) {\n binaryen.__i32_store8(idx++, (0xC0 | (c1 >>> 6) ) as u8);\n binaryen.__i32_store8(idx++, (0x80 | ( c1 & 63)) as u8);\n } else if (\n isHighSurrogate(c1) && i + 1 < k &&\n isLowSurrogate(c2 = str.charCodeAt(i + 1))\n ) {\n c1 = combineSurrogates(c1, c2);\n ++i;\n binaryen.__i32_store8(idx++, (0xF0 | (c1 >>> 18) ) as u8);\n binaryen.__i32_store8(idx++, (0x80 | ((c1 >>> 12) & 63)) as u8);\n binaryen.__i32_store8(idx++, (0x80 | ((c1 >>> 6) & 63)) as u8);\n binaryen.__i32_store8(idx++, (0x80 | ( c1 & 63)) as u8);\n } else {\n binaryen.__i32_store8(idx++, (0xE0 | (c1 >>> 12) ) as u8);\n binaryen.__i32_store8(idx++, (0x80 | ((c1 >>> 6) & 63)) as u8);\n binaryen.__i32_store8(idx++, (0x80 | ( c1 & 63)) as u8);\n }\n }\n }\n binaryen.__i32_store8(idx, 0); // \\0\n return ptr;\n}\n\nfunction readBuffer(ptr: usize, len: i32): Uint8Array {\n let ret = new Uint8Array(len);\n for (let i = 0; i < len; ++i) {\n unchecked(ret[i] = binaryen.__i32_load8_u(ptr + i));\n }\n return ret;\n}\n\nexport function readString(ptr: usize): string | null {\n if (!ptr) return null;\n let arr = new Array();\n // the following is based on Emscripten's UTF8ArrayToString\n let cp: u32;\n let u1: u32, u2: u32, u3: u32;\n while (cp = binaryen.__i32_load8_u(ptr++)) {\n if (!(cp & 0x80)) {\n arr.push(cp);\n continue;\n }\n u1 = binaryen.__i32_load8_u(ptr++) & 63;\n if ((cp & 0xE0) == 0xC0) {\n arr.push(((cp & 31) << 6) | u1);\n continue;\n }\n u2 = binaryen.__i32_load8_u(ptr++) & 63;\n if ((cp & 0xF0) == 0xE0) {\n cp = ((cp & 15) << 12) | (u1 << 6) | u2;\n } else {\n u3 = binaryen.__i32_load8_u(ptr++) & 63;\n if ((cp & 0xF8) == 0xF0) {\n cp = ((cp & 7) << 18) | (u1 << 12) | (u2 << 6) | u3;\n } else {\n assert(false, \"Invalid UTF8 sequence during readString\");\n }\n }\n if (cp < 0x10000) {\n arr.push(cp);\n } else {\n let ch = cp - 0x10000;\n arr.push(SURROGATE_HIGH | (ch >>> 10));\n arr.push(SURROGATE_LOW | (ch & 0x3FF));\n }\n }\n // TODO: implement and use String.fromCodePoints\n return String.fromCharCodes(arr);\n}\n\n/** Result structure of {@link Module#toBinary}. */\nexport class BinaryModule {\n constructor(\n /** WebAssembly binary. */\n public output: Uint8Array,\n /** Source map, if generated. */\n public sourceMap: string | null\n ) {}\n}\n\n// TypeBuilder\n\nconst DEBUG_TYPEBUILDER = false;\n\n/** Ensures that the given potentially complex type has a corresponding GC type. */\nexport function ensureType(type: Type): TypeRef {\n // Obtain basic type if applicable\n if (type == Type.void) return TypeRef.None;\n let typeRef = tryEnsureBasicType(type);\n if (typeRef) return typeRef;\n\n // From here on we are dealing with heap types independent of nullability.\n // Nullability is applied again when returning the final type.\n let originalType = type;\n type = type.nonNullableType;\n\n // Obtain cached type if already built. Guaranteed to be not a temp type.\n if (typeRef = type.ref) {\n return binaryen._BinaryenTypeFromHeapType(\n binaryen._BinaryenTypeGetHeapType(typeRef),\n originalType.is(TypeFlags.Nullable) // apply nullability\n );\n }\n\n // Otherwise use a type builder\n if (ASC_TARGET) {\n // @ts-ignore: Wasm only\n assert(sizeof() == 4); // ABI code below assumes 32-bit pointers\n }\n assert(binaryen._BinaryenGetTypeSystem() == TypeSystem.Nominal);\n let builder = binaryen._TypeBuilderCreate(0);\n let seen = new Map();\n prepareType(builder, seen, type); // drop temp return\n let size = binaryen._TypeBuilderGetSize(builder);\n let out = binaryen._malloc(max(4 * size, 8)); // either each heap type or index + reason\n if (!binaryen._TypeBuilderBuildAndDispose(builder, out, out, out + 4)) {\n let errorIndex = binaryen.__i32_load(out);\n let errorReason = binaryen.__i32_load(out + 4);\n binaryen._free(out);\n throw new Error(`type builder error at index ${errorIndex}: ${TypeBuilderErrorReason.toString(errorReason)}`);\n }\n\n // Assign all the built types to their respective non-nullable type\n for (let _keys = Map_keys(seen), i = 0, k = _keys.length; i < k; ++i) {\n let seenType = _keys[i];\n assert(!seenType.is(TypeFlags.Nullable)); // non-nullable only\n let heapType = binaryen.__i32_load(out + 4 * i);\n let fullType = binaryen._BinaryenTypeFromHeapType(heapType, false);\n assert(!seenType.ref);\n seenType.ref = fullType;\n if (DEBUG_TYPEBUILDER) {\n console.log(` set ${seenType.toString()}`);\n }\n let classInstance = seenType.getClass();\n if (classInstance) {\n let module = classInstance.program.module;\n binaryen._BinaryenModuleSetTypeName(module.ref, heapType, module.allocStringCached(classInstance.internalName));\n let members = classInstance.members;\n if (members) {\n let numFieldsInType = binaryen._BinaryenStructTypeGetNumFields(heapType);\n let numFieldsInClass = 0;\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = _values[i];\n if (member.kind != ElementKind.PropertyPrototype) continue;\n // only interested in fields (resolved during class finalization)\n let property = (member).instance;\n if (!property || !property.isField) continue;\n binaryen._BinaryenModuleSetFieldName(module.ref, heapType, numFieldsInClass++, module.allocStringCached(property.name));\n }\n assert(numFieldsInType == numFieldsInClass);\n }\n }\n }\n binaryen._free(out);\n\n // Initial type should now exist in its non-nullable variant\n if (DEBUG_TYPEBUILDER) {\n console.log(` finalize ${type.toString()}`);\n }\n typeRef = assert(type.ref);\n return binaryen._BinaryenTypeFromHeapType(\n binaryen._BinaryenTypeGetHeapType(typeRef),\n originalType.is(TypeFlags.Nullable) // apply nullability\n );\n}\n\n/** Obtains the basic type of the given type, if any. */\nfunction tryEnsureBasicType(type: Type): TypeRef {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.U8:\n case TypeKind.I16:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return TypeRef.I32;\n case TypeKind.I64:\n case TypeKind.U64: return TypeRef.I64;\n case TypeKind.Isize:\n case TypeKind.Usize: {\n if (type.isInternalReference) break; // non-basic\n return type.size == 64 ? TypeRef.I64 : TypeRef.I32;\n }\n case TypeKind.F32: return TypeRef.F32;\n case TypeKind.F64: return TypeRef.F64;\n case TypeKind.V128: return TypeRef.V128;\n case TypeKind.Funcref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Func, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Externref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Extern, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Anyref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Any, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Eqref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Eq, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Structref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Struct, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Arrayref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.Array, type.is(TypeFlags.Nullable));\n }\n case TypeKind.I31ref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.I31, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Stringref: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.String, type.is(TypeFlags.Nullable));\n }\n case TypeKind.StringviewWTF8: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.StringviewWTF8, type.is(TypeFlags.Nullable));\n }\n case TypeKind.StringviewWTF16: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.StringviewWTF16, type.is(TypeFlags.Nullable));\n }\n case TypeKind.StringviewIter: {\n return binaryen._BinaryenTypeFromHeapType(HeapTypeRef.StringviewIter, type.is(TypeFlags.Nullable));\n }\n case TypeKind.Void: assert(false); // invalid here\n }\n return 0; // non-basic\n}\n\n/** Determines the packed GC type of the given type, if applicable. */\nfunction determinePackedType(type: Type): PackedType {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.U8: return PackedType.I8;\n case TypeKind.I16:\n case TypeKind.U16: return PackedType.I16;\n }\n return PackedType.NotPacked;\n}\n\n/** Recursively prepares the given GC type, potentially returning a temporary type. */\nfunction prepareType(builder: binaryen.TypeBuilderRef, seen: Map, type: Type): TypeRef {\n // Obtain basic type if applicable\n if (type == Type.void) return TypeRef.None;\n let typeRef = tryEnsureBasicType(type);\n if (typeRef) return typeRef;\n\n assert(!type.is(TypeFlags.Nullable)); // operating on non-nullable types only\n\n // Reuse existing type\n if (typeRef = type.ref) return typeRef;\n\n // Reuse seen temporary type if it exists\n if (seen.has(type)) {\n if (DEBUG_TYPEBUILDER) {\n console.log(` prepare ${type.toString()} (seen)`);\n }\n return changetype(seen.get(type));\n }\n\n if (DEBUG_TYPEBUILDER) {\n console.log(`prepare ${type.toString()}`);\n }\n\n // Otherwise construct a new class type. Note that arrays are not supported, as these would\n // have to involve a Wasm-level `array`, either wrapped in `Array` or `Uint8Array` etc., or\n // directly representing an `ArrayBuffer` or `StaticArray`. TBD.\n let classReference = type.getClass();\n if (classReference) {\n // Make sure the base type has been built prior, at a lower index\n let base = classReference.base;\n let baseRef: HeapTypeRef = 0;\n if (base) baseRef = prepareType(builder, seen, base.type); // might be temporary, is non-nullable\n\n // Block this index with a temporary type and cache\n let index = binaryen._TypeBuilderGetSize(builder);\n binaryen._TypeBuilderGrow(builder, 1);\n if (DEBUG_TYPEBUILDER) {\n console.log(` block [${index}]: ${type.toString()}`);\n }\n let heapTypeRef = binaryen._TypeBuilderGetTempHeapType(builder, index);\n typeRef = binaryen._TypeBuilderGetTempRefType(builder, heapTypeRef, false);\n seen.set(type, typeRef);\n\n // Populate the struct type (TODO: names)\n let fieldTypes = new Array();\n let packedTypes = new Array();\n let fieldMutables = new Array();\n let members = classReference.members;\n if (members) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = _values[i];\n if (member.kind != ElementKind.PropertyPrototype) continue;\n // only interested in fields (resolved during class finalization)\n let property = (member).instance;\n if (!property || !property.isField) continue;\n let fieldType = property.type;\n if (DEBUG_TYPEBUILDER) {\n console.log(` field ${fieldType.toString()}`);\n }\n if (fieldType.is(TypeFlags.Nullable)) {\n fieldTypes.push(\n binaryen._TypeBuilderGetTempRefType(\n builder,\n binaryen._BinaryenTypeGetHeapType(\n prepareType(builder, seen, fieldType.nonNullableType)\n ),\n true\n )\n );\n } else {\n fieldTypes.push(prepareType(builder, seen, fieldType));\n }\n packedTypes.push(determinePackedType(fieldType));\n fieldMutables.push(1);\n }\n }\n let cArrFT = allocPtrArray(fieldTypes);\n let cArrPT = allocU32Array(packedTypes);\n let cArrFM = allocU32Array(fieldMutables);\n if (DEBUG_TYPEBUILDER) {\n console.log(` concretize [${index}]: ${type.toString()}`);\n }\n binaryen._TypeBuilderSetStructType(builder, index, cArrFT, cArrPT, cArrFM, fieldTypes.length);\n if (base) {\n if (DEBUG_TYPEBUILDER) {\n console.log(` set super [${index}]: ${type.toString()} <: ${base.type.toString()} ${baseRef == base.type.ref ? \" (known)\" : \"\"}`);\n }\n binaryen._TypeBuilderSetSubType(builder, index, binaryen._BinaryenTypeGetHeapType(baseRef));\n }\n binaryen._free(cArrFM);\n binaryen._free(cArrPT);\n binaryen._free(cArrFT);\n return typeRef;\n }\n\n // Respectively a new signature type\n let signatureReference = type.getSignature();\n if (signatureReference) {\n\n // Block this index with a temporary type and cache\n let index = binaryen._TypeBuilderGetSize(builder);\n binaryen._TypeBuilderGrow(builder, 1);\n let tempTypeRef = binaryen._TypeBuilderGetTempRefType(\n builder,\n binaryen._TypeBuilderGetTempHeapType(builder, index),\n false\n );\n seen.set(type, tempTypeRef);\n\n let paramTypes = new Array();\n let resultTypes = new Array();\n let parameterTypes = signatureReference.parameterTypes;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n let paramType = parameterTypes[i];\n if (paramType.is(TypeFlags.Nullable)) {\n paramTypes.push(\n binaryen._TypeBuilderGetTempRefType(\n builder,\n binaryen._BinaryenTypeGetHeapType(\n prepareType(builder, seen, paramType.nonNullableType)\n ),\n true\n )\n );\n } else {\n paramTypes.push(prepareType(builder, seen, paramType));\n }\n }\n let returnType = signatureReference.returnType;\n resultTypes.push(\n returnType == Type.void\n ? TypeRef.None\n : returnType.is(TypeFlags.Nullable)\n ? binaryen._TypeBuilderGetTempRefType(\n builder,\n binaryen._BinaryenTypeGetHeapType(\n prepareType(builder, seen, returnType.nonNullableType)\n ),\n true\n )\n : prepareType(builder, seen, returnType)\n );\n let tempParamType: TypeRef;\n if (paramTypes.length > 1) {\n let cArrPT = allocPtrArray(paramTypes);\n tempParamType = binaryen._TypeBuilderGetTempTupleType(builder, cArrPT, paramTypes.length);\n binaryen._free(cArrPT);\n } else {\n tempParamType = paramTypes.length ? paramTypes[0] : TypeRef.None;\n }\n let tempResultType: TypeRef;\n if (resultTypes.length > 1) {\n let cArrRT = allocPtrArray(resultTypes);\n tempResultType = binaryen._TypeBuilderGetTempTupleType(builder, cArrRT, resultTypes.length);\n binaryen._free(cArrRT);\n } else {\n tempResultType = resultTypes[0];\n }\n if (DEBUG_TYPEBUILDER) {\n console.log(` concretize [${index}]: ${type.toString()}`);\n }\n binaryen._TypeBuilderSetSignatureType(builder, index, tempParamType, tempResultType);\n return tempTypeRef;\n }\n\n throw new Error(`unexpected complex type: ${type.toString()}`);\n}\n","/**\n * @fileoverview Abstract syntax tree representing a source file once parsed.\n *\n * Each node in the AST is represented by an instance of a subclass of `Node`,\n * with its `Node#kind` represented by one of the `NodeKind` constants, which\n * dependent code typically switches over. The intended way to create a node\n * is to use the respective `Node.createX` method instead of its constructor.\n *\n * Note that the AST does not contain any type information except type names.\n *\n * @license Apache-2.0\n */\n\n// TODO: Make the AST more easily serializable by refactoring `Node#range` so\n// it doesn't reference the non-serializable `Source` object.\n\nimport {\n CommonFlags,\n PATH_DELIMITER,\n LIBRARY_PREFIX,\n LIBRARY_SUBST\n} from \"./common\";\n\nimport {\n Range\n} from \"./diagnostics\";\n\nimport {\n Token\n} from \"./tokenizer\";\n\nimport {\n normalizePath,\n resolvePath,\n CharCode\n} from \"./util\";\n\nimport {\n ExpressionRef\n} from \"./module\";\n\nimport {\n Type\n} from \"./types\";\n\n/** Indicates the kind of a node. */\nexport const enum NodeKind {\n\n Source,\n\n // types\n NamedType,\n FunctionType,\n TypeName,\n TypeParameter,\n Parameter,\n\n // expressions\n Identifier,\n Assertion,\n Binary,\n Call,\n Class,\n Comma,\n ElementAccess,\n False,\n Function,\n InstanceOf,\n Literal,\n New,\n Null,\n Omitted,\n Parenthesized,\n PropertyAccess,\n Ternary,\n Super,\n This,\n True,\n Constructor,\n UnaryPostfix,\n UnaryPrefix,\n Compiled,\n\n // statements\n Block,\n Break,\n Continue,\n Do,\n Empty,\n Export,\n ExportDefault,\n ExportImport,\n Expression,\n For,\n ForOf,\n If,\n Import,\n Return,\n Switch,\n Throw,\n Try,\n Variable,\n Void,\n While,\n Module,\n\n // declaration statements\n ClassDeclaration,\n EnumDeclaration,\n EnumValueDeclaration,\n FieldDeclaration,\n FunctionDeclaration,\n ImportDeclaration,\n InterfaceDeclaration,\n MethodDeclaration,\n NamespaceDeclaration,\n TypeDeclaration,\n VariableDeclaration,\n\n // special\n Decorator,\n ExportMember,\n SwitchCase,\n IndexSignature,\n Comment\n}\n\n/** Base class of all nodes. */\nexport abstract class Node {\n constructor(\n /** Kind of this node. */\n public kind: NodeKind,\n /** Source range. */\n public range: Range\n ) {}\n\n // types\n\n static createSimpleTypeName(\n name: string,\n range: Range\n ): TypeName {\n return new TypeName(Node.createIdentifierExpression(name, range), null, range);\n }\n\n static createNamedType(\n name: TypeName,\n typeArguments: TypeNode[] | null,\n isNullable: bool,\n range: Range\n ): NamedTypeNode {\n return new NamedTypeNode(name, typeArguments, isNullable, range);\n }\n\n static createFunctionType(\n parameters: ParameterNode[],\n returnType: TypeNode,\n explicitThisType: NamedTypeNode | null,\n isNullable: bool,\n range: Range\n ): FunctionTypeNode {\n return new FunctionTypeNode(parameters, returnType, explicitThisType, isNullable, range);\n }\n\n static createOmittedType(\n range: Range\n ): NamedTypeNode {\n return new NamedTypeNode(Node.createSimpleTypeName(\"\", range), null, false, range);\n }\n\n static createTypeParameter(\n name: IdentifierExpression,\n extendsType: NamedTypeNode | null,\n defaultType: NamedTypeNode | null,\n range: Range\n ): TypeParameterNode {\n return new TypeParameterNode(name, extendsType, defaultType, range);\n }\n\n static createParameter(\n parameterKind: ParameterKind,\n name: IdentifierExpression,\n type: TypeNode,\n initializer: Expression | null,\n range: Range\n ): ParameterNode {\n return new ParameterNode(parameterKind, name, type, initializer, range);\n }\n\n // special\n\n static createDecorator(\n name: Expression,\n args: Expression[] | null,\n range: Range\n ): DecoratorNode {\n return new DecoratorNode(DecoratorKind.fromNode(name), name, args, range);\n }\n\n static createComment(\n commentKind: CommentKind,\n text: string,\n range: Range\n ): CommentNode {\n return new CommentNode(commentKind, text, range);\n }\n\n // expressions\n\n static createIdentifierExpression(\n text: string,\n range: Range,\n isQuoted: bool = false\n ): IdentifierExpression {\n return new IdentifierExpression(text, isQuoted, range);\n }\n\n static createEmptyIdentifierExpression(\n range: Range\n ): IdentifierExpression {\n return new IdentifierExpression(\"\", false, range);\n }\n\n static createArrayLiteralExpression(\n elementExpressions: Expression[],\n range: Range\n ): ArrayLiteralExpression {\n return new ArrayLiteralExpression(elementExpressions, range);\n }\n\n static createAssertionExpression(\n assertionKind: AssertionKind,\n expression: Expression,\n toType: TypeNode | null,\n range: Range\n ): AssertionExpression {\n return new AssertionExpression(assertionKind, expression, toType, range);\n }\n\n static createBinaryExpression(\n operator: Token,\n left: Expression,\n right: Expression,\n range: Range\n ): BinaryExpression {\n return new BinaryExpression(operator, left, right, range);\n }\n\n static createCallExpression(\n expression: Expression,\n typeArguments: TypeNode[] | null,\n args: Expression[],\n range: Range\n ): CallExpression {\n return new CallExpression(expression, typeArguments, args, range);\n }\n\n static createClassExpression(\n declaration: ClassDeclaration\n ): ClassExpression {\n return new ClassExpression(declaration);\n }\n\n static createCommaExpression(\n expressions: Expression[],\n range: Range\n ): CommaExpression {\n return new CommaExpression(expressions, range);\n }\n\n static createConstructorExpression(\n range: Range\n ): ConstructorExpression {\n return new ConstructorExpression(range);\n }\n\n static createElementAccessExpression(\n expression: Expression,\n elementExpression: Expression,\n range: Range\n ): ElementAccessExpression {\n return new ElementAccessExpression(expression, elementExpression, range);\n }\n\n static createFalseExpression(\n range: Range\n ): FalseExpression {\n return new FalseExpression(range);\n }\n\n static createFloatLiteralExpression(\n value: f64,\n range: Range\n ): FloatLiteralExpression {\n return new FloatLiteralExpression(value, range);\n }\n\n static createFunctionExpression(\n declaration: FunctionDeclaration\n ): FunctionExpression {\n return new FunctionExpression(declaration);\n }\n\n static createInstanceOfExpression(\n expression: Expression,\n isType: TypeNode,\n range: Range\n ): InstanceOfExpression {\n return new InstanceOfExpression(expression, isType, range);\n }\n\n static createIntegerLiteralExpression(\n value: i64,\n range: Range\n ): IntegerLiteralExpression {\n return new IntegerLiteralExpression(value, range);\n }\n\n static createNewExpression(\n typeName: TypeName,\n typeArguments: TypeNode[] | null,\n args: Expression[],\n range: Range\n ): NewExpression {\n return new NewExpression(typeName, typeArguments, args, range);\n }\n\n static createNullExpression(\n range: Range\n ): NullExpression {\n return new NullExpression(range);\n }\n\n static createObjectLiteralExpression(\n names: IdentifierExpression[],\n values: Expression[],\n range: Range\n ): ObjectLiteralExpression {\n return new ObjectLiteralExpression(names, values, range);\n }\n\n static createOmittedExpression(\n range: Range\n ): OmittedExpression {\n return new OmittedExpression(range);\n }\n\n static createParenthesizedExpression(\n expression: Expression,\n range: Range\n ): ParenthesizedExpression {\n return new ParenthesizedExpression(expression, range);\n }\n\n static createPropertyAccessExpression(\n expression: Expression,\n property: IdentifierExpression,\n range: Range\n ): PropertyAccessExpression {\n return new PropertyAccessExpression(expression, property, range);\n }\n\n static createRegexpLiteralExpression(\n pattern: string,\n patternFlags: string,\n range: Range\n ): RegexpLiteralExpression {\n return new RegexpLiteralExpression(pattern, patternFlags, range);\n }\n\n static createTernaryExpression(\n condition: Expression,\n ifThen: Expression,\n ifElse: Expression,\n range: Range\n ): TernaryExpression {\n return new TernaryExpression(condition, ifThen, ifElse, range);\n }\n\n static createStringLiteralExpression(\n value: string,\n range: Range\n ): StringLiteralExpression {\n return new StringLiteralExpression(value, range);\n }\n\n static createSuperExpression(\n range: Range\n ): SuperExpression {\n return new SuperExpression(range);\n }\n\n static createTemplateLiteralExpression(\n tag: Expression | null,\n parts: string[],\n rawParts: string[],\n expressions: Expression[],\n range: Range\n ): TemplateLiteralExpression {\n return new TemplateLiteralExpression(tag, parts, rawParts, expressions, range);\n }\n\n static createThisExpression(\n range: Range\n ): ThisExpression {\n return new ThisExpression(range);\n }\n\n static createTrueExpression(\n range: Range\n ): TrueExpression {\n return new TrueExpression(range);\n }\n\n static createUnaryPostfixExpression(\n operator: Token,\n operand: Expression,\n range: Range\n ): UnaryPostfixExpression {\n return new UnaryPostfixExpression(operator, operand, range);\n }\n\n static createUnaryPrefixExpression(\n operator: Token,\n operand: Expression,\n range: Range\n ): UnaryPrefixExpression {\n return new UnaryPrefixExpression(operator, operand, range);\n }\n\n static createCompiledExpression(\n expr: ExpressionRef,\n type: Type,\n range: Range\n ): Expression {\n return new CompiledExpression(expr, type, range);\n }\n\n // statements\n\n static createBlockStatement(\n statements: Statement[],\n range: Range\n ): BlockStatement {\n return new BlockStatement(statements, range);\n }\n\n static createBreakStatement(\n label: IdentifierExpression | null,\n range: Range\n ): BreakStatement {\n return new BreakStatement(label, range);\n }\n\n static createClassDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n typeParameters: TypeParameterNode[] | null,\n extendsType: NamedTypeNode | null,\n implementsTypes: NamedTypeNode[] | null,\n members: DeclarationStatement[],\n range: Range\n ): ClassDeclaration {\n return new ClassDeclaration(name, decorators, flags, typeParameters, extendsType, implementsTypes, members, range);\n }\n\n static createContinueStatement(\n label: IdentifierExpression | null,\n range: Range\n ): ContinueStatement {\n return new ContinueStatement(label, range);\n }\n\n static createDoStatement(\n body: Statement,\n condition: Expression,\n range: Range\n ): DoStatement {\n return new DoStatement(body, condition, range);\n }\n\n static createEmptyStatement(\n range: Range\n ): EmptyStatement {\n return new EmptyStatement(range);\n }\n\n static createEnumDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n values: EnumValueDeclaration[],\n range: Range\n ): EnumDeclaration {\n return new EnumDeclaration(name, decorators, flags, values, range);\n }\n\n static createEnumValueDeclaration(\n name: IdentifierExpression,\n flags: CommonFlags,\n initializer: Expression | null,\n range: Range\n ): EnumValueDeclaration {\n return new EnumValueDeclaration(name, flags, initializer, range);\n }\n\n static createExportStatement(\n members: ExportMember[] | null,\n path: StringLiteralExpression | null,\n isDeclare: bool,\n range: Range\n ): ExportStatement {\n return new ExportStatement(members, path, isDeclare, range);\n }\n\n static createExportDefaultStatement(\n declaration: DeclarationStatement,\n range: Range\n ): ExportDefaultStatement {\n return new ExportDefaultStatement(declaration, range);\n }\n\n static createExportImportStatement(\n name: IdentifierExpression,\n externalName: IdentifierExpression,\n range: Range\n ): ExportImportStatement {\n return new ExportImportStatement(name, externalName, range);\n }\n\n static createExportMember(\n localName: IdentifierExpression,\n exportedName: IdentifierExpression | null,\n range: Range\n ): ExportMember {\n if (!exportedName) exportedName = localName;\n return new ExportMember(localName, exportedName, range);\n }\n\n static createExpressionStatement(\n expression: Expression\n ): ExpressionStatement {\n return new ExpressionStatement(expression);\n }\n\n static createIfStatement(\n condition: Expression,\n ifTrue: Statement,\n ifFalse: Statement | null,\n range: Range\n ): IfStatement {\n return new IfStatement(condition, ifTrue, ifFalse, range);\n }\n\n static createImportStatement(\n declarations: ImportDeclaration[] | null,\n path: StringLiteralExpression,\n range: Range\n ): ImportStatement {\n return new ImportStatement(declarations, null, path, range);\n }\n\n static createWildcardImportStatement(\n namespaceName: IdentifierExpression,\n path: StringLiteralExpression,\n range: Range\n ): ImportStatement {\n return new ImportStatement(null, namespaceName, path, range);\n }\n\n static createImportDeclaration(\n foreignName: IdentifierExpression,\n name: IdentifierExpression | null,\n range: Range\n ): ImportDeclaration {\n if (!name) name = foreignName;\n return new ImportDeclaration(name, foreignName, range);\n }\n\n static createInterfaceDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n typeParameters: TypeParameterNode[] | null,\n extendsType: NamedTypeNode | null,\n implementsTypes: NamedTypeNode[] | null,\n members: DeclarationStatement[],\n range: Range\n ): InterfaceDeclaration {\n return new InterfaceDeclaration(name, decorators, flags, typeParameters, extendsType, implementsTypes, members, range);\n }\n\n static createFieldDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n type: TypeNode | null,\n initializer: Expression | null,\n range: Range\n ): FieldDeclaration {\n return new FieldDeclaration(name, decorators, flags, type, initializer, -1, range);\n }\n\n static createForStatement(\n initializer: Statement | null,\n condition: Expression | null,\n incrementor: Expression | null,\n body: Statement,\n range: Range\n ): ForStatement {\n return new ForStatement(initializer, condition, incrementor, body, range);\n }\n\n static createForOfStatement(\n variable: Statement,\n iterable: Expression,\n body: Statement,\n range: Range\n ): ForOfStatement {\n return new ForOfStatement(variable, iterable, body, range);\n }\n\n static createFunctionDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n typeParameters: TypeParameterNode[] | null,\n signature: FunctionTypeNode,\n body: Statement | null,\n arrowKind: ArrowKind,\n range: Range\n ): FunctionDeclaration {\n return new FunctionDeclaration(name, decorators, flags, typeParameters, signature, body, arrowKind, range);\n }\n\n static createIndexSignature(\n keyType: NamedTypeNode,\n valueType: TypeNode,\n flags: CommonFlags,\n range: Range\n ): IndexSignatureNode {\n return new IndexSignatureNode(keyType, valueType, flags, range);\n }\n\n static createMethodDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n typeParameters: TypeParameterNode[] | null,\n signature: FunctionTypeNode,\n body: Statement | null,\n range: Range\n ): MethodDeclaration {\n return new MethodDeclaration(name, decorators, flags, typeParameters, signature, body, range);\n }\n\n static createNamespaceDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n members: Statement[],\n range: Range\n ): NamespaceDeclaration {\n return new NamespaceDeclaration(name, decorators, flags, members, range);\n }\n\n static createReturnStatement(\n value: Expression | null,\n range: Range\n ): ReturnStatement {\n return new ReturnStatement(value, range);\n }\n\n static createSwitchStatement(\n condition: Expression,\n cases: SwitchCase[],\n range: Range\n ): SwitchStatement {\n return new SwitchStatement(condition, cases, range);\n }\n\n static createSwitchCase(\n label: Expression | null,\n statements: Statement[],\n range: Range\n ): SwitchCase {\n return new SwitchCase(label, statements, range);\n }\n\n static createThrowStatement(\n value: Expression,\n range: Range\n ): ThrowStatement {\n return new ThrowStatement(value, range);\n }\n\n static createTryStatement(\n bodyStatements: Statement[],\n catchVariable: IdentifierExpression | null,\n catchStatements: Statement[] | null,\n finallyStatements: Statement[] | null,\n range: Range\n ): TryStatement {\n return new TryStatement(bodyStatements, catchVariable, catchStatements, finallyStatements, range);\n }\n\n static createTypeDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n typeParameters: TypeParameterNode[] | null,\n type: TypeNode,\n range: Range\n ): TypeDeclaration {\n return new TypeDeclaration(name, decorators, flags, typeParameters, type, range);\n }\n\n static createModuleDeclaration(\n name: string,\n flags: CommonFlags,\n range: Range\n ): ModuleDeclaration {\n return new ModuleDeclaration(name, flags, range);\n }\n\n static createVariableStatement(\n decorators: DecoratorNode[] | null,\n declarations: VariableDeclaration[],\n range: Range\n ): VariableStatement {\n return new VariableStatement(decorators, declarations, range);\n }\n\n static createVariableDeclaration(\n name: IdentifierExpression,\n decorators: DecoratorNode[] | null,\n flags: CommonFlags,\n type: TypeNode | null,\n initializer: Expression | null,\n range: Range\n ): VariableDeclaration {\n return new VariableDeclaration(name, decorators, flags, type, initializer, range);\n }\n\n static createVoidStatement(\n expression: Expression,\n range: Range\n ): VoidStatement {\n return new VoidStatement(expression, range);\n }\n\n static createWhileStatement(\n condition: Expression,\n statement: Statement,\n range: Range\n ): WhileStatement {\n return new WhileStatement(condition, statement, range);\n }\n\n /** Tests if this node is a literal of the specified kind. */\n isLiteralKind(literalKind: LiteralKind): bool {\n return this.kind == NodeKind.Literal\n && (changetype(this)).literalKind == literalKind; // TS\n }\n\n /** Tests if this node is a literal of a numeric kind (float or integer). */\n get isNumericLiteral(): bool {\n if (this.kind == NodeKind.Literal) {\n switch ((changetype(this)).literalKind) { // TS\n case LiteralKind.Float:\n case LiteralKind.Integer: return true;\n }\n }\n return false;\n }\n\n /** Tests whether this node is guaranteed to compile to a constant value. */\n get compilesToConst(): bool {\n switch (this.kind) {\n case NodeKind.Literal: {\n switch ((changetype(this)).literalKind) { // TS\n case LiteralKind.Float:\n case LiteralKind.Integer:\n case LiteralKind.String: return true;\n }\n break;\n }\n case NodeKind.Null:\n case NodeKind.True:\n case NodeKind.False: return true;\n }\n return false;\n }\n\n private isAccessOn(kind: NodeKind): bool {\n let node = changetype(this);\n if (node.kind == NodeKind.Call) {\n node = (node).expression;\n }\n if (node.kind == NodeKind.PropertyAccess) {\n let target = (node).expression;\n if (target.kind == kind) return true;\n }\n return false;\n }\n\n /** Checks if this node accesses a method or property on `this`. */\n get isAccessOnThis(): bool {\n return this.isAccessOn(NodeKind.This);\n }\n\n /** Checks if this node accesses a method or property on `super`. */\n get isAccessOnSuper(): bool {\n return this.isAccessOn(NodeKind.Super);\n }\n\n get isEmpty(): bool {\n return this.kind == NodeKind.Empty;\n }\n}\n\n// types\n\nexport abstract class TypeNode extends Node {\n constructor(\n /** Kind of the type node. */\n kind: NodeKind,\n /** Whether nullable or not. */\n public isNullable: bool,\n /** Source range. */\n range: Range\n ) {\n super(kind, range);\n }\n\n /** Whether this type node is currently in the process of being resolved. */\n currentlyResolving: bool = false;\n\n /** Tests if this type has a generic component matching one of the given type parameters. */\n hasGenericComponent(typeParameterNodes: TypeParameterNode[]): bool {\n if (this.kind == NodeKind.NamedType) {\n let namedTypeNode = changetype(this); // TS\n if (!namedTypeNode.name.next) {\n let typeArgumentNodes = namedTypeNode.typeArguments;\n if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n for (let i = 0, k = typeArgumentNodes.length; i < k; ++i) {\n if (typeArgumentNodes[i].hasGenericComponent(typeParameterNodes)) return true;\n }\n } else {\n let name = namedTypeNode.name.identifier.text;\n for (let i = 0, k = typeParameterNodes.length; i < k; ++i) {\n if (typeParameterNodes[i].name.text == name) return true;\n }\n }\n }\n } else if (this.kind == NodeKind.FunctionType) {\n let functionTypeNode = changetype(this); // TS\n let parameterNodes = functionTypeNode.parameters;\n for (let i = 0, k = parameterNodes.length; i < k; ++i) {\n if (parameterNodes[i].type.hasGenericComponent(typeParameterNodes)) return true;\n }\n if (functionTypeNode.returnType.hasGenericComponent(typeParameterNodes)) return true;\n let explicitThisType = functionTypeNode.explicitThisType;\n if (explicitThisType && explicitThisType.hasGenericComponent(typeParameterNodes)) return true;\n } else {\n assert(false);\n }\n return false;\n }\n}\n\n/** Represents a type name. */\nexport class TypeName extends Node {\n constructor(\n /** Identifier of this part. */\n public identifier: IdentifierExpression,\n /** Next part of the type name or `null` if this is the last part. */\n public next: TypeName | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.TypeName, range);\n }\n}\n\n/** Represents a named type. */\nexport class NamedTypeNode extends TypeNode {\n constructor(\n /** Type name. */\n public name: TypeName,\n /** Type argument references. */\n public typeArguments: TypeNode[] | null,\n /** Whether nullable or not. */\n isNullable: bool,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.NamedType, isNullable, range);\n }\n\n /** Checks if this type node has type arguments. */\n get hasTypeArguments(): bool {\n let typeArguments = this.typeArguments;\n return typeArguments != null && typeArguments.length > 0;\n }\n\n /** Tests if this type is \"null\". */\n get isNull(): bool {\n return this.name.identifier.text == \"null\";\n }\n}\n\n/** Represents a function type. */\nexport class FunctionTypeNode extends TypeNode {\n constructor(\n /** Function parameters. */\n public parameters: ParameterNode[],\n /** Return type. */\n public returnType: TypeNode,\n /** Explicitly provided this type, if any. */\n public explicitThisType: NamedTypeNode | null, // can't be a function\n /** Whether nullable or not. */\n isNullable: bool,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.FunctionType, isNullable, range);\n }\n}\n\n/** Represents a type parameter. */\nexport class TypeParameterNode extends Node {\n constructor(\n /** Identifier reference. */\n public name: IdentifierExpression,\n /** Extended type reference, if any. */\n public extendsType: NamedTypeNode | null, // can't be a function\n /** Default type if omitted, if any. */\n public defaultType: NamedTypeNode | null, // can't be a function\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.TypeParameter, range);\n }\n}\n\n/** Represents the kind of a parameter. */\nexport const enum ParameterKind {\n /** No specific flags. */\n Default,\n /** Is an optional parameter. */\n Optional,\n /** Is a rest parameter. */\n Rest\n}\n\n/** Represents a function parameter. */\nexport class ParameterNode extends Node {\n constructor(\n /** Parameter kind. */\n public parameterKind: ParameterKind,\n /** Parameter name. */\n public name: IdentifierExpression,\n /** Parameter type. */\n public type: TypeNode,\n /** Initializer expression, if any. */\n public initializer: Expression | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Parameter, range);\n }\n\n /** Implicit field declaration, if applicable. */\n implicitFieldDeclaration: FieldDeclaration | null = null;\n /** Common flags indicating specific traits. */\n flags: CommonFlags = CommonFlags.None;\n\n /** Tests if this node has the specified flag or flags. */\n is(flag: CommonFlags): bool { return (this.flags & flag) == flag; }\n /** Tests if this node has one of the specified flags. */\n isAny(flag: CommonFlags): bool { return (this.flags & flag) != 0; }\n /** Sets a specific flag or flags. */\n set(flag: CommonFlags): void { this.flags |= flag; }\n}\n\n// special\n\n/** Built-in decorator kinds. */\nexport enum DecoratorKind {\n Custom,\n Global,\n Operator,\n OperatorBinary,\n OperatorPrefix,\n OperatorPostfix,\n Unmanaged,\n Final,\n Inline,\n External,\n ExternalJs,\n Builtin,\n Lazy,\n Unsafe\n}\n\nexport namespace DecoratorKind {\n\n /** Returns the kind of the specified decorator name node. Defaults to {@link DecoratorKind.CUSTOM}. */\n export function fromNode(nameNode: Expression): DecoratorKind {\n if (nameNode.kind == NodeKind.Identifier) {\n let nameStr = (nameNode).text;\n assert(nameStr.length);\n switch (nameStr.charCodeAt(0)) {\n case CharCode.b: {\n if (nameStr == \"builtin\") return DecoratorKind.Builtin;\n break;\n }\n case CharCode.e: {\n if (nameStr == \"external\") return DecoratorKind.External;\n break;\n }\n case CharCode.f: {\n if (nameStr == \"final\") return DecoratorKind.Final;\n break;\n }\n case CharCode.g: {\n if (nameStr == \"global\") return DecoratorKind.Global;\n break;\n }\n case CharCode.i: {\n if (nameStr == \"inline\") return DecoratorKind.Inline;\n break;\n }\n case CharCode.l: {\n if (nameStr == \"lazy\") return DecoratorKind.Lazy;\n break;\n }\n case CharCode.o: {\n if (nameStr == \"operator\") return DecoratorKind.Operator;\n break;\n }\n case CharCode.u: {\n if (nameStr == \"unmanaged\") return DecoratorKind.Unmanaged;\n if (nameStr == \"unsafe\") return DecoratorKind.Unsafe;\n break;\n }\n }\n } else if (nameNode.kind == NodeKind.PropertyAccess) {\n let propertyAccessNode = nameNode;\n let expression = propertyAccessNode.expression;\n if (expression.kind == NodeKind.Identifier) {\n let nameStr = (expression).text;\n assert(nameStr.length);\n let propStr = propertyAccessNode.property.text;\n assert(propStr.length);\n if (nameStr == \"operator\") {\n switch (propStr.charCodeAt(0)) {\n case CharCode.b: {\n if (propStr == \"binary\") return DecoratorKind.OperatorBinary;\n break;\n }\n case CharCode.p: {\n if (propStr == \"prefix\") return DecoratorKind.OperatorPrefix;\n if (propStr == \"postfix\") return DecoratorKind.OperatorPostfix;\n break;\n }\n }\n } else if (nameStr == \"external\") {\n switch (propStr.charCodeAt(0)) {\n case CharCode.j: {\n if (propStr == \"js\") return DecoratorKind.ExternalJs;\n break;\n }\n }\n }\n }\n }\n return DecoratorKind.Custom;\n }\n}\n\n/** Represents a decorator. */\nexport class DecoratorNode extends Node {\n constructor(\n /** Built-in decorator kind, or custom. */\n public decoratorKind: DecoratorKind,\n /** Name expression. */\n public name: Expression,\n /** Argument expressions. */\n public args: Expression[] | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Decorator, range);\n }\n}\n\n/** Comment kinds. */\nexport const enum CommentKind {\n /** Line comment. */\n Line,\n /** Triple-slash line comment. */\n Triple,\n /** Block comment. */\n Block\n}\n\n/** Represents a comment. */\nexport class CommentNode extends Node {\n constructor(\n /** Comment kind. */\n public commentKind: CommentKind,\n /** Comment text. */\n public text: string,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Comment, range);\n }\n}\n\n// expressions\n\n/** Base class of all expression nodes. */\nexport abstract class Expression extends Node { }\n\n/** Represents an identifier expression. */\nexport class IdentifierExpression extends Expression {\n constructor(\n /** Textual name. */\n public text: string,\n /** Whether quoted or not. */\n public isQuoted: bool,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Identifier, range);\n }\n}\n\n/** Indicates the kind of a literal. */\nexport const enum LiteralKind {\n Float,\n Integer,\n String,\n Template,\n RegExp,\n Array,\n Object\n}\n\n/** Base class of all literal expressions. */\nexport abstract class LiteralExpression extends Expression {\n constructor(\n /** Specific literal kind. */\n public literalKind: LiteralKind,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Literal, range);\n }\n}\n\n/** Represents an `[]` literal expression. */\nexport class ArrayLiteralExpression extends LiteralExpression {\n constructor(\n /** Nested element expressions. */\n public elementExpressions: Expression[],\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.Array, range);\n }\n}\n\n/** Indicates the kind of an assertion. */\nexport const enum AssertionKind {\n /** A prefix assertion, i.e. `expr`. */\n Prefix,\n /** An as assertion, i.e. `expr as T`. */\n As,\n /** A non-null assertion, i.e. `!expr`. */\n NonNull,\n /** A const assertion, i.e. `expr as const`. */\n Const\n}\n\n/** Represents an assertion expression. */\nexport class AssertionExpression extends Expression {\n constructor(\n /** Specific kind of this assertion. */\n public assertionKind: AssertionKind,\n /** Expression being asserted. */\n public expression: Expression,\n /** Target type, if applicable. */\n public toType: TypeNode | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Assertion, range);\n }\n}\n\n/** Represents a binary expression. */\nexport class BinaryExpression extends Expression {\n constructor(\n /** Operator token. */\n public operator: Token,\n /** Left-hand side expression */\n public left: Expression,\n /** Right-hand side expression. */\n public right: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Binary, range);\n }\n}\n\n/** Represents a call expression. */\nexport class CallExpression extends Expression {\n constructor(\n /** Called expression. Usually an identifier or property access expression. */\n public expression: Expression,\n /** Provided type arguments. */\n public typeArguments: TypeNode[] | null,\n /** Provided arguments. */\n public args: Expression[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Call, range);\n }\n\n /** Gets the type arguments range for reporting. */\n get typeArgumentsRange(): Range {\n let typeArguments = this.typeArguments;\n let numTypeArguments: i32;\n if (typeArguments) {\n if (numTypeArguments = typeArguments.length) {\n return Range.join(typeArguments[0].range, typeArguments[numTypeArguments - 1].range);\n }\n }\n return this.expression.range;\n }\n\n /** Gets the arguments range for reporting. */\n get argumentsRange(): Range {\n let args = this.args;\n let numArguments = args.length;\n if (numArguments) {\n return Range.join(args[0].range, args[numArguments - 1].range);\n }\n return this.expression.range;\n }\n}\n\n/** Represents a class expression using the 'class' keyword. */\nexport class ClassExpression extends Expression {\n constructor(\n /** Inline class declaration. */\n public declaration: ClassDeclaration\n ) {\n super(NodeKind.Class, declaration.range);\n }\n}\n\n/** Represents a comma expression composed of multiple expressions. */\nexport class CommaExpression extends Expression {\n constructor(\n /** Sequential expressions. */\n public expressions: Expression[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Comma, range);\n }\n}\n\n/** Represents a `constructor` expression. */\nexport class ConstructorExpression extends IdentifierExpression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(\"constructor\", false, range);\n this.kind = NodeKind.Constructor;\n }\n}\n\n/** Represents an element access expression, e.g., array access. */\nexport class ElementAccessExpression extends Expression {\n constructor(\n /** Expression being accessed. */\n public expression: Expression,\n /** Element of the expression being accessed. */\n public elementExpression: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ElementAccess, range);\n }\n}\n\n/** Represents a float literal expression. */\nexport class FloatLiteralExpression extends LiteralExpression {\n constructor(\n /** Float value. */\n public value: f64,\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.Float, range);\n }\n}\n\n/** Represents a function expression using the 'function' keyword. */\nexport class FunctionExpression extends Expression {\n constructor(\n /** Inline function declaration. */\n public declaration: FunctionDeclaration\n ) {\n super(NodeKind.Function, declaration.range);\n }\n}\n\n/** Represents an `instanceof` expression. */\nexport class InstanceOfExpression extends Expression {\n constructor(\n /** Expression being asserted. */\n public expression: Expression,\n /** Type to test for. */\n public isType: TypeNode,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.InstanceOf, range);\n }\n}\n\n/** Represents an integer literal expression. */\nexport class IntegerLiteralExpression extends LiteralExpression {\n constructor(\n /** Integer value. */\n public value: i64,\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.Integer, range);\n }\n}\n\n/** Represents a `new` expression. Like a call but with its own kind. */\nexport class NewExpression extends Expression {\n constructor(\n /** Type being constructed. */\n public typeName: TypeName,\n /** Provided type arguments. */\n public typeArguments: TypeNode[] | null,\n /** Provided arguments. */\n public args: Expression[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.New, range);\n }\n\n /** Gets the type arguments range for reporting. */\n get typeArgumentsRange(): Range {\n let typeArguments = this.typeArguments;\n let numTypeArguments: i32;\n if (typeArguments && (numTypeArguments = typeArguments.length) > 0) {\n return Range.join(typeArguments[0].range, typeArguments[numTypeArguments - 1].range);\n }\n return this.typeName.range;\n }\n\n /** Gets the arguments range for reporting. */\n get argumentsRange(): Range {\n let args = this.args;\n let numArguments = args.length;\n if (numArguments) {\n return Range.join(args[0].range, args[numArguments - 1].range);\n }\n return this.typeName.range;\n }\n}\n\n/** Represents a `null` expression. */\nexport class NullExpression extends IdentifierExpression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(\"null\", false, range);\n this.kind = NodeKind.Null;\n }\n}\n\n/** Represents an object literal expression. */\nexport class ObjectLiteralExpression extends LiteralExpression {\n constructor(\n /** Field names. */\n public names: IdentifierExpression[],\n /** Field values. */\n public values: Expression[],\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.Object, range);\n }\n}\n\n/** Represents an omitted expression, e.g. within an array literal. */\nexport class OmittedExpression extends Expression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Omitted, range);\n }\n}\n\n/** Represents a parenthesized expression. */\nexport class ParenthesizedExpression extends Expression {\n constructor(\n /** Expression in parenthesis. */\n public expression: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Parenthesized, range);\n }\n}\n\n/** Represents a property access expression. */\nexport class PropertyAccessExpression extends Expression {\n constructor(\n /** Expression being accessed. */\n public expression: Expression,\n /** Property of the expression being accessed. */\n public property: IdentifierExpression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.PropertyAccess, range);\n }\n}\n\n/** Represents a regular expression literal expression. */\nexport class RegexpLiteralExpression extends LiteralExpression {\n constructor(\n /** Regular expression pattern. */\n public pattern: string,\n /** Regular expression flags. */\n public patternFlags: string,\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.RegExp, range);\n }\n}\n\n/** Represents a ternary expression, i.e., short if notation. */\nexport class TernaryExpression extends Expression {\n constructor(\n /** Condition expression. */\n public condition: Expression,\n /** Expression executed when condition is `true`. */\n public ifThen: Expression,\n /** Expression executed when condition is `false`. */\n public ifElse: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Ternary, range);\n }\n}\n\n/** Represents a string literal expression. */\nexport class StringLiteralExpression extends LiteralExpression {\n constructor(\n /** String value without quotes. */\n public value: string,\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.String, range);\n }\n}\n\n/** Represents a `super` expression. */\nexport class SuperExpression extends IdentifierExpression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(\"super\", false, range);\n this.kind = NodeKind.Super;\n }\n}\n\n/** Represents a template literal expression. */\nexport class TemplateLiteralExpression extends LiteralExpression {\n constructor(\n /** Tag expression, if any. */\n public tag: Expression | null,\n /** String parts. */\n public parts: string[],\n /** Raw string parts. */\n public rawParts: string[],\n /** Expression parts. */\n public expressions: Expression[],\n /** Source range. */\n range: Range\n ) {\n super(LiteralKind.Template, range);\n }\n}\n\n/** Represents a `this` expression. */\nexport class ThisExpression extends IdentifierExpression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(\"this\", false, range);\n this.kind = NodeKind.This;\n }\n}\n\n/** Represents a `true` expression. */\nexport class TrueExpression extends IdentifierExpression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(\"true\", false, range);\n this.kind = NodeKind.True;\n }\n}\n\n/** Represents a `false` expression. */\nexport class FalseExpression extends IdentifierExpression {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(\"false\", false, range);\n this.kind = NodeKind.False;\n }\n}\n\n/** Base class of all unary expressions. */\nexport abstract class UnaryExpression extends Expression {\n constructor(\n /** Unary expression kind. */\n kind: NodeKind,\n /** Operator token. */\n public operator: Token,\n /** Operand expression. */\n public operand: Expression,\n /** Source range. */\n range: Range\n ) {\n super(kind, range);\n }\n}\n\n/** Represents a unary postfix expression, e.g. a postfix increment. */\nexport class UnaryPostfixExpression extends UnaryExpression {\n constructor(\n /** Operator token. */\n operator: Token,\n /** Operand expression. */\n operand: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.UnaryPostfix, operator, operand, range);\n }\n}\n\n/** Represents a unary prefix expression, e.g. a negation. */\nexport class UnaryPrefixExpression extends UnaryExpression {\n constructor(\n /** Operator token. */\n operator: Token,\n /** Operand expression. */\n operand: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.UnaryPrefix, operator, operand, range);\n }\n}\n\n/** Represents a special pre-compiled expression. If the expression has side-effects, special care has to be taken. */\nexport class CompiledExpression extends Expression {\n constructor(\n /** Compiled expression. */\n public expr: ExpressionRef,\n /** Type of the compiled expression. */\n public type: Type,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Compiled, range);\n }\n}\n\n// statements\n\n/** Base class of all statement nodes. */\nexport abstract class Statement extends Node { }\n\n/** Indicates the specific kind of a source. */\nexport const enum SourceKind {\n /** User-provided file. */\n User = 0,\n /** User-provided entry file. */\n UserEntry = 1,\n /** Library-provided file. */\n Library = 2,\n /** Library-provided entry file. */\n LibraryEntry = 3\n}\n\n/** A top-level source node. */\nexport class Source extends Node {\n\n /** Gets the special native source. */\n static get native(): Source {\n let source = Source._native;\n if (!source) Source._native = source = new Source(SourceKind.LibraryEntry, LIBRARY_PREFIX + \"native.ts\", \"[native code]\");\n return source;\n }\n private static _native: Source | null = null;\n\n constructor(\n /** Source kind. */\n public sourceKind: SourceKind,\n /** Normalized path with file extension. */\n public normalizedPath: string,\n /** Full source text. */\n public text: string\n ) {\n super(NodeKind.Source, new Range(0, text.length));\n let internalPath = mangleInternalPath(normalizedPath);\n this.internalPath = internalPath;\n let pos = internalPath.lastIndexOf(PATH_DELIMITER);\n this.simplePath = pos >= 0 ? internalPath.substring(pos + 1) : internalPath;\n this.range.source = this;\n }\n\n /** Path used internally. */\n internalPath: string;\n /** Simple path (last part without extension). */\n simplePath: string;\n /** Contained statements. */\n statements: Statement[] = new Array();\n /** Source map index. */\n debugInfoIndex: i32 = -1;\n /** Re-exported sources. */\n exportPaths: string[] | null = null;\n\n /** Checks if this source represents native code. */\n get isNative(): bool {\n return this.internalPath == LIBRARY_SUBST;\n }\n\n /** Checks if this source is part of the (standard) library. */\n get isLibrary(): bool {\n let kind = this.sourceKind;\n return kind == SourceKind.Library || kind == SourceKind.LibraryEntry;\n }\n\n /** Cached line starts. */\n private lineCache: i32[] | null = null;\n\n /** Remembered column number. */\n private lineColumn: i32 = 1;\n\n /** Determines the line number at the specified position. Starts at `1`. */\n lineAt(pos: i32): i32 {\n assert(pos >= 0 && pos < 0x7fffffff);\n let lineCache = this.lineCache;\n if (!lineCache) {\n this.lineCache = lineCache = [0];\n let text = this.text;\n let off = 0;\n let end = text.length;\n while (off < end) {\n if (text.charCodeAt(off++) == CharCode.LineFeed) lineCache.push(off);\n }\n lineCache.push(0x7fffffff);\n }\n let l = 0;\n let r = lineCache.length - 1;\n while (l < r) {\n let m = l + ((r - l) >> 1);\n let s = unchecked(lineCache[m]);\n if (pos < s) r = m;\n else if (pos < unchecked(lineCache[m + 1])) {\n this.lineColumn = pos - s + 1;\n return m + 1;\n }\n else l = m + 1;\n }\n return assert(0);\n }\n\n /** Gets the column number at the last position queried with `lineAt`. Starts at `1`. */\n columnAt(): i32 {\n return this.lineColumn;\n }\n}\n\n/** Base class of all declaration statements. */\nexport abstract class DeclarationStatement extends Statement {\n constructor(\n /** Declaration node kind. */\n kind: NodeKind,\n /** Simple name being declared. */\n public name: IdentifierExpression,\n /** Array of decorators, if any. */\n public decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n public flags: CommonFlags,\n /** Source range. */\n range: Range\n ) {\n super(kind, range);\n }\n /** Overridden module name from preceeding `module` statement. */\n public overriddenModuleName: string | null = null;\n\n /** Tests if this node has the specified flag or flags. */\n is(flag: CommonFlags): bool { return (this.flags & flag) == flag; }\n /** Tests if this node has one of the specified flags. */\n isAny(flag: CommonFlags): bool { return (this.flags & flag) != 0; }\n /** Sets a specific flag or flags. */\n set(flag: CommonFlags): void { this.flags |= flag; }\n}\n\n/** Represents an index signature. */\nexport class IndexSignatureNode extends Node {\n constructor(\n /** Key type. */\n public keyType: NamedTypeNode,\n /** Value type. */\n public valueType: TypeNode,\n /** Common flags indicating specific traits. */\n public flags: CommonFlags,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.IndexSignature, range);\n }\n}\n\n/** Base class of all variable-like declaration statements. */\nexport abstract class VariableLikeDeclarationStatement extends DeclarationStatement {\n constructor(\n /** Variable-like declaration node kind. */\n kind: NodeKind,\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Annotated type node, if any. */\n public type: TypeNode | null,\n /** Initializer expression, if any. */\n public initializer: Expression | null,\n /** Source range. */\n range: Range\n ) {\n super(kind, name, decorators, flags, range);\n }\n}\n\n/** Represents a block statement. */\nexport class BlockStatement extends Statement {\n constructor(\n /** Contained statements. */\n public statements: Statement[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Block, range);\n }\n}\n\n/** Represents a `break` statement. */\nexport class BreakStatement extends Statement {\n constructor(\n /** Target label, if any. */\n public label: IdentifierExpression | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Break, range);\n }\n}\n\n/** Represents a `class` declaration. */\nexport class ClassDeclaration extends DeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Accepted type parameters. */\n public typeParameters: TypeParameterNode[] | null,\n /** Base class type being extended, if any. */\n public extendsType: NamedTypeNode | null, // can't be a function\n /** Interface types being implemented, if any. */\n public implementsTypes: NamedTypeNode[] | null, // can't be functions\n /** Class member declarations. */\n public members: DeclarationStatement[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ClassDeclaration, name, decorators, flags, range);\n }\n\n /** Index signature, if present. */\n indexSignature: IndexSignatureNode | null = null;\n\n get isGeneric(): bool {\n let typeParameters = this.typeParameters;\n return typeParameters != null && typeParameters.length > 0;\n }\n}\n\n/** Represents a `continue` statement. */\nexport class ContinueStatement extends Statement {\n constructor(\n /** Target label, if applicable. */\n public label: IdentifierExpression | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Continue, range);\n }\n}\n\n/** Represents a `do` statement. */\nexport class DoStatement extends Statement {\n constructor(\n /** Body statement being looped over. */\n public body: Statement,\n /** Condition when to repeat. */\n public condition: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Do, range);\n }\n}\n\n/** Represents an empty statement, i.e., a semicolon terminating nothing. */\nexport class EmptyStatement extends Statement {\n constructor(\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Empty, range);\n }\n}\n\n/** Represents an `enum` declaration. */\nexport class EnumDeclaration extends DeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Enum value declarations. */\n public values: EnumValueDeclaration[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.EnumDeclaration, name, decorators, flags, range);\n }\n}\n\n/** Represents a value of an `enum` declaration. */\nexport class EnumValueDeclaration extends VariableLikeDeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Initializer expression, if any. */\n initializer: Expression | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.EnumValueDeclaration, name, null, flags, null, initializer, range);\n }\n}\n\n/** Represents an `export import` statement of an interface. */\nexport class ExportImportStatement extends Statement {\n constructor(\n /** Identifier being imported. */\n public name: IdentifierExpression,\n /** Identifier being exported. */\n public externalName: IdentifierExpression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ExportImport, range);\n }\n}\n\n/** Represents a member of an `export` statement. */\nexport class ExportMember extends Node {\n constructor(\n /** Local identifier. */\n public localName: IdentifierExpression,\n /** Exported identifier. */\n public exportedName: IdentifierExpression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ExportMember, range);\n }\n}\n\n/** Represents an `export` statement. */\nexport class ExportStatement extends Statement {\n constructor(\n /** Array of members if a set of named exports, or `null` if a file export. */\n public members: ExportMember[] | null,\n /** Path being exported from, if applicable. */\n public path: StringLiteralExpression | null,\n /** Whether this is a declared export. */\n public isDeclare: bool,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Export, range);\n if (path) {\n let normalizedPath = normalizePath(path.value);\n if (path.value.startsWith(\".\")) { // relative\n normalizedPath = resolvePath(normalizedPath, range.source.internalPath);\n } else { // absolute\n if (!normalizedPath.startsWith(LIBRARY_PREFIX)) normalizedPath = LIBRARY_PREFIX + normalizedPath;\n }\n this.internalPath = normalizedPath;\n } else {\n this.internalPath = null;\n }\n }\n\n /** Internal path being referenced, if `path` is set. */\n internalPath: string | null;\n}\n\n/** Represents an `export default` statement. */\nexport class ExportDefaultStatement extends Statement {\n constructor(\n /** Declaration being exported as default. */\n public declaration: DeclarationStatement,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ExportDefault, range);\n }\n}\n\n/** Represents an expression that is used as a statement. */\nexport class ExpressionStatement extends Statement {\n constructor(\n /** Expression being used as a statement.*/\n public expression: Expression\n ) {\n super(NodeKind.Expression, expression.range);\n }\n}\n\n/** Represents a field declaration within a `class`. */\nexport class FieldDeclaration extends VariableLikeDeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Annotated type node, if any. */\n type: TypeNode | null,\n /** Initializer expression, if any. */\n initializer: Expression | null,\n /** Parameter index if declared as a constructor parameter, otherwise `-1`. */\n public parameterIndex: i32,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.FieldDeclaration, name, decorators, flags, type, initializer, range);\n }\n}\n\n/** Represents a `for` statement. */\nexport class ForStatement extends Statement {\n constructor(\n /** Initializer statement, if present. Either a `VariableStatement` or `ExpressionStatement`. */\n public initializer: Statement | null,\n /** Condition expression, if present. */\n public condition: Expression | null,\n /** Incrementor expression, if present. */\n public incrementor: Expression | null,\n /** Body statement being looped over. */\n public body: Statement,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.For, range);\n }\n}\n\n/** Represents a `for..of` statement. */\nexport class ForOfStatement extends Statement {\n constructor(\n /** Variable statement. Either a `VariableStatement` or `ExpressionStatement` of `IdentifierExpression`. */\n public variable: Statement,\n /** Iterable expression being iterated. */\n public iterable: Expression,\n /** Body statement being looped over. */\n public body: Statement,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ForOf, range);\n }\n}\n\n/** Indicates the kind of an array function. */\nexport const enum ArrowKind {\n /** Not an arrow function. */\n None,\n /** Parenthesized parameter list. */\n Parenthesized,\n /** Single parameter without parenthesis. */\n Single\n}\n\n/** Represents a `function` declaration. */\nexport class FunctionDeclaration extends DeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Type parameters, if any. */\n public typeParameters: TypeParameterNode[] | null,\n /** Function signature. */\n public signature: FunctionTypeNode,\n /** Body statement. Usually a block. */\n public body: Statement | null,\n /** Arrow function kind, if applicable. */\n public arrowKind: ArrowKind,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.FunctionDeclaration, name, decorators, flags, range);\n }\n\n /** Gets if this function is generic. */\n get isGeneric(): bool {\n let typeParameters = this.typeParameters;\n return typeParameters != null && typeParameters.length > 0;\n }\n\n /** Clones this function declaration. */\n clone(): FunctionDeclaration {\n return new FunctionDeclaration(\n this.name,\n this.decorators,\n this.flags,\n this.typeParameters,\n this.signature,\n this.body,\n this.arrowKind,\n this.range\n );\n }\n}\n\n/** Represents an `if` statement. */\nexport class IfStatement extends Statement {\n constructor(\n /** Condition. */\n public condition: Expression,\n /** Statement executed when condition is `true`. */\n public ifTrue: Statement,\n /** Statement executed when condition is `false`. */\n public ifFalse: Statement | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.If, range);\n }\n}\n\n/** Represents an `import` declaration part of an {@link ImportStatement}. */\nexport class ImportDeclaration extends DeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Identifier being imported. */\n public foreignName: IdentifierExpression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.ImportDeclaration, name, null, CommonFlags.None, range);\n }\n}\n\n/** Represents an `import` statement. */\nexport class ImportStatement extends Statement {\n constructor(\n /** Array of member declarations or `null` if an asterisk import. */\n public declarations: ImportDeclaration[] | null,\n /** Name of the local namespace, if an asterisk import. */\n public namespaceName: IdentifierExpression | null,\n /** Path being imported from. */\n public path: StringLiteralExpression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Import, range);\n let normalizedPath = normalizePath(path.value);\n if (path.value.startsWith(\".\")) { // relative in project\n normalizedPath = resolvePath(normalizedPath, range.source.internalPath);\n } else { // absolute in library\n if (!normalizedPath.startsWith(LIBRARY_PREFIX)) normalizedPath = LIBRARY_PREFIX + normalizedPath;\n }\n this.internalPath = mangleInternalPath(normalizedPath);\n }\n\n /** Internal path being referenced. */\n internalPath: string;\n}\n\n/** Represents an `interfarce` declaration. */\nexport class InterfaceDeclaration extends ClassDeclaration {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Accepted type parameters. */\n typeParameters: TypeParameterNode[] | null,\n /** Base class type being extended, if any. */\n extendsType: NamedTypeNode | null, // can't be a function\n /** Interface types being implemented, if any. */\n implementsTypes: NamedTypeNode[] | null, // can't be functions\n /** Class member declarations. */\n members: DeclarationStatement[],\n /** Source range. */\n range: Range\n ) {\n super(name, decorators, flags, typeParameters, extendsType, implementsTypes, members, range);\n this.kind = NodeKind.InterfaceDeclaration;\n }\n}\n\n/** Represents a method declaration within a `class`. */\nexport class MethodDeclaration extends FunctionDeclaration {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Type parameters, if any. */\n typeParameters: TypeParameterNode[] | null,\n /** Function signature. */\n signature: FunctionTypeNode,\n /** Body statement. Usually a block. */\n body: Statement | null,\n /** Source range. */\n range: Range\n ) {\n super(name, decorators, flags, typeParameters, signature, body, ArrowKind.None, range);\n this.kind = NodeKind.MethodDeclaration;\n }\n}\n\n/** Represents a `namespace` declaration. */\nexport class NamespaceDeclaration extends DeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Array of namespace members. */\n public members: Statement[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.NamespaceDeclaration, name, decorators, flags, range);\n }\n}\n\n/** Represents a `return` statement. */\nexport class ReturnStatement extends Statement {\n constructor(\n /** Value expression being returned, if present. */\n public value: Expression | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Return, range);\n }\n}\n\n/** Represents a single `case` within a `switch` statement. */\nexport class SwitchCase extends Node {\n constructor(\n /** Label expression. `null` indicates the default case. */\n public label: Expression | null,\n /** Contained statements. */\n public statements: Statement[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.SwitchCase, range);\n }\n\n get isDefault(): bool {\n return this.label == null;\n }\n}\n\n/** Represents a `switch` statement. */\nexport class SwitchStatement extends Statement {\n constructor(\n /** Condition expression. */\n public condition: Expression,\n /** Contained cases. */\n public cases: SwitchCase[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Switch, range);\n }\n}\n\n/** Represents a `throw` statement. */\nexport class ThrowStatement extends Statement {\n constructor(\n /** Value expression being thrown. */\n public value: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Throw, range);\n }\n}\n\n/** Represents a `try` statement. */\nexport class TryStatement extends Statement {\n constructor(\n /** Contained statements. */\n public bodyStatements: Statement[],\n /** Exception variable name, if a `catch` clause is present. */\n public catchVariable: IdentifierExpression | null,\n /** Statements being executed on catch, if a `catch` clause is present. */\n public catchStatements: Statement[] | null,\n /** Statements being executed afterwards, if a `finally` clause is present. */\n public finallyStatements: Statement[] | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Try, range);\n }\n}\n\n/** Represents a `module` statement. */\nexport class ModuleDeclaration extends Statement {\n constructor(\n /** Module name. */\n public moduleName: string,\n /** Common flags indicating specific traits. */\n public flags: CommonFlags,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Module, range);\n }\n}\n\n/** Represents a `type` declaration. */\nexport class TypeDeclaration extends DeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Type parameters, if any. */\n public typeParameters: TypeParameterNode[] | null,\n /** Type being aliased. */\n public type: TypeNode,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.TypeDeclaration, name, decorators, flags, range);\n }\n}\n\n/** Represents a variable declaration part of a {@link VariableStatement}. */\nexport class VariableDeclaration extends VariableLikeDeclarationStatement {\n constructor(\n /** Simple name being declared. */\n name: IdentifierExpression,\n /** Array of decorators, if any. */\n decorators: DecoratorNode[] | null,\n /** Common flags indicating specific traits. */\n flags: CommonFlags,\n /** Annotated type node, if any. */\n type: TypeNode | null,\n /** Initializer expression, if any. */\n initializer: Expression | null,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.VariableDeclaration, name, decorators, flags, type, initializer, range);\n }\n}\n\n/** Represents a variable statement wrapping {@link VariableDeclaration}s. */\nexport class VariableStatement extends Statement {\n constructor(\n /** Array of decorators. */\n public decorators: DecoratorNode[] | null,\n /** Array of member declarations. */\n public declarations: VariableDeclaration[],\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Variable, range);\n }\n}\n\n/** Represents a void statement dropping an expression's value. */\nexport class VoidStatement extends Statement {\n constructor(\n /** Expression being dropped. */\n public expression: Expression,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.Void, range);\n }\n}\n\n/** Represents a `while` statement. */\nexport class WhileStatement extends Statement {\n constructor(\n /** Condition expression. */\n public condition: Expression,\n /** Body statement being looped over. */\n public body: Statement,\n /** Source range. */\n range: Range\n ) {\n super(NodeKind.While, range);\n }\n}\n\n/** Finds the first decorator matching the specified kind. */\nexport function findDecorator(kind: DecoratorKind, decorators: DecoratorNode[] | null): DecoratorNode | null {\n if (decorators) {\n for (let i = 0, k = decorators.length; i < k; ++i) {\n let decorator = decorators[i];\n if (decorator.decoratorKind == kind) return decorator;\n }\n }\n return null;\n}\n\n/** Mangles an external to an internal path. */\nexport function mangleInternalPath(path: string): string {\n if (path.endsWith(\"/\")) {\n path += \"index\";\n } else if (path.endsWith(\".ts\")) {\n path = path.substring(0, path.length - 3);\n }\n return path;\n}\n\n/** Tests if the specified type node represents an omitted type. */\nexport function isTypeOmitted(type: TypeNode): bool {\n if (type.kind == NodeKind.NamedType) {\n let name = (type).name;\n return !(name.next || name.identifier.text.length > 0);\n }\n return false;\n}\n","// GENERATED FILE. DO NOT EDIT.\n\n/** Enum of available diagnostic codes. */\nexport enum DiagnosticCode {\n Not_implemented_0 = 100,\n Operation_is_unsafe = 101,\n User_defined_0 = 102,\n Feature_0_is_not_enabled = 103,\n Low_memory_limit_exceeded_by_static_data_0_1 = 104,\n Module_requires_at_least_0_pages_of_initial_memory = 105,\n Module_requires_at_least_0_pages_of_maximum_memory = 106,\n Shared_memory_requires_maximum_memory_to_be_defined = 107,\n Shared_memory_requires_feature_threads_to_be_enabled = 108,\n Transform_0_1 = 109,\n Start_function_name_0_is_invalid_or_conflicts_with_another_export = 110,\n Element_0_not_found = 111,\n Exchange_of_0_values_is_not_supported_by_all_embeddings = 112,\n Conversion_from_type_0_to_1_requires_an_explicit_cast = 200,\n Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit = 201,\n Type_0_cannot_be_changed_to_type_1 = 202,\n Operation_0_cannot_be_applied_to_type_1 = 203,\n Type_0_cannot_be_nullable = 204,\n Mutable_value_cannot_be_inlined = 206,\n Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,\n Unmanaged_classes_cannot_implement_interfaces = 208,\n Invalid_regular_expression_flags = 209,\n Expression_is_never_null = 210,\n Class_0_is_final_and_cannot_be_extended = 211,\n Decorator_0_is_not_valid_here = 212,\n Duplicate_decorator = 213,\n Type_0_is_illegal_in_this_context = 214,\n Optional_parameter_must_have_an_initializer = 215,\n Class_0_cannot_declare_a_constructor_when_instantiated_from_an_object_literal = 216,\n Function_0_cannot_be_inlined_into_itself = 217,\n Cannot_access_method_0_without_calling_it_as_it_requires_this_to_be_set = 218,\n Optional_properties_are_not_supported = 219,\n Expression_must_be_a_compile_time_constant = 220,\n Type_0_is_not_a_function_index_or_function_reference = 221,\n _0_must_be_a_value_between_1_and_2_inclusive = 222,\n _0_must_be_a_power_of_two = 223,\n _0_is_not_a_valid_operator = 224,\n Expression_cannot_be_represented_by_a_type = 225,\n Expression_resolves_to_unusual_type_0 = 226,\n Array_literal_expected = 227,\n Function_0_is_virtual_and_will_not_be_inlined = 228,\n Property_0_only_has_a_setter_and_is_missing_a_getter = 229,\n _0_keyword_cannot_be_used_here = 230,\n A_class_with_a_constructor_explicitly_returning_something_else_than_this_must_be_final = 231,\n Property_0_is_always_assigned_before_being_used = 233,\n Expression_does_not_compile_to_a_value_at_runtime = 234,\n Only_variables_functions_and_enums_become_WebAssembly_module_exports = 235,\n Literal_0_does_not_fit_into_i64_or_u64_types = 236,\n Index_signature_accessors_in_type_0_differ_in_types = 237,\n Initializer_definitive_assignment_or_nullable_type_expected = 238,\n Definitive_assignment_has_no_effect_on_local_variables = 239,\n Importing_the_table_disables_some_indirect_call_optimizations = 901,\n Exporting_the_table_disables_some_indirect_call_optimizations = 902,\n Expression_compiles_to_a_dynamic_check_at_runtime = 903,\n Indexed_access_may_involve_bounds_checking = 904,\n Explicitly_returning_constructor_drops_this_allocation = 905,\n Unnecessary_definite_assignment = 906,\n _NaN_does_not_compare_equal_to_any_other_value_including_itself_Use_isNaN_x_instead = 907,\n Comparison_with_0_0_is_sign_insensitive_Use_Object_is_x_0_0_if_the_sign_matters = 908,\n Unterminated_string_literal = 1002,\n Identifier_expected = 1003,\n _0_expected = 1005,\n A_file_cannot_have_a_reference_to_itself = 1006,\n Trailing_comma_not_allowed = 1009,\n Unexpected_token = 1012,\n A_rest_parameter_must_be_last_in_a_parameter_list = 1014,\n Parameter_cannot_have_question_mark_and_initializer = 1015,\n A_required_parameter_cannot_follow_an_optional_parameter = 1016,\n _0_modifier_cannot_appear_on_class_elements_of_this_kind = 1031,\n Statements_are_not_allowed_in_ambient_contexts = 1036,\n Initializers_are_not_allowed_in_ambient_contexts = 1039,\n _0_modifier_cannot_be_used_here = 1042,\n A_rest_parameter_cannot_be_optional = 1047,\n A_rest_parameter_cannot_have_an_initializer = 1048,\n A_set_accessor_must_have_exactly_one_parameter = 1049,\n A_set_accessor_parameter_cannot_have_an_initializer = 1052,\n A_get_accessor_cannot_have_parameters = 1054,\n Enum_member_must_have_initializer = 1061,\n Type_parameters_cannot_appear_on_a_constructor_declaration = 1092,\n Type_annotation_cannot_appear_on_a_constructor_declaration = 1093,\n An_accessor_cannot_have_type_parameters = 1094,\n A_set_accessor_cannot_have_a_return_type_annotation = 1095,\n Type_parameter_list_cannot_be_empty = 1098,\n Type_argument_list_cannot_be_empty = 1099,\n A_continue_statement_can_only_be_used_within_an_enclosing_iteration_statement = 1104,\n A_break_statement_can_only_be_used_within_an_enclosing_iteration_or_switch_statement = 1105,\n A_return_statement_can_only_be_used_within_a_function_body = 1108,\n Expression_expected = 1109,\n Type_expected = 1110,\n A_default_clause_cannot_appear_more_than_once_in_a_switch_statement = 1113,\n Duplicate_label_0 = 1114,\n An_export_assignment_cannot_have_modifiers = 1120,\n Octal_literals_are_not_allowed_in_strict_mode = 1121,\n Digit_expected = 1124,\n Hexadecimal_digit_expected = 1125,\n Unexpected_end_of_text = 1126,\n Invalid_character = 1127,\n _case_or_default_expected = 1130,\n _super_must_be_followed_by_an_argument_list_or_member_access = 1034,\n A_declare_modifier_cannot_be_used_in_an_already_ambient_context = 1038,\n Type_argument_expected = 1140,\n String_literal_expected = 1141,\n Line_break_not_permitted_here = 1142,\n Declaration_expected = 1146,\n _const_declarations_must_be_initialized = 1155,\n Unterminated_regular_expression_literal = 1161,\n Declarations_with_initializers_cannot_also_have_definite_assignment_assertions = 1263,\n Interface_declaration_cannot_have_implements_clause = 1176,\n Binary_digit_expected = 1177,\n Octal_digit_expected = 1178,\n An_implementation_cannot_be_declared_in_ambient_contexts = 1183,\n The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer = 1190,\n An_extended_Unicode_escape_value_must_be_between_0x0_and_0x10FFFF_inclusive = 1198,\n Unterminated_Unicode_escape_sequence = 1199,\n Decorators_are_not_valid_here = 1206,\n _abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration = 1242,\n Method_0_cannot_have_an_implementation_because_it_is_marked_abstract = 1245,\n A_definite_assignment_assertion_is_not_permitted_in_this_context = 1255,\n A_class_may_only_extend_another_class = 1311,\n A_parameter_property_cannot_be_declared_using_a_rest_parameter = 1317,\n A_default_export_can_only_be_used_in_a_module = 1319,\n An_expression_of_type_0_cannot_be_tested_for_truthiness = 1345,\n An_identifier_or_keyword_cannot_immediately_follow_a_numeric_literal = 1351,\n Duplicate_identifier_0 = 2300,\n Cannot_find_name_0 = 2304,\n Module_0_has_no_exported_member_1 = 2305,\n An_interface_can_only_extend_an_interface = 2312,\n Generic_type_0_requires_1_type_argument_s = 2314,\n Type_0_is_not_generic = 2315,\n Type_0_is_not_assignable_to_type_1 = 2322,\n Property_0_is_private_in_type_1_but_not_in_type_2 = 2325,\n Index_signature_is_missing_in_type_0 = 2329,\n _this_cannot_be_referenced_in_current_location = 2332,\n _this_cannot_be_referenced_in_constructor_arguments = 2333,\n _super_can_only_be_referenced_in_a_derived_class = 2335,\n _super_cannot_be_referenced_in_constructor_arguments = 2336,\n Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors = 2337,\n Property_0_does_not_exist_on_type_1 = 2339,\n Property_0_is_private_and_only_accessible_within_class_1 = 2341,\n Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures = 2349,\n This_expression_is_not_constructable = 2351,\n A_function_whose_declared_type_is_not_void_must_return_a_value = 2355,\n The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access = 2357,\n The_left_hand_side_of_an_assignment_expression_must_be_a_variable_or_a_property_access = 2364,\n Operator_0_cannot_be_applied_to_types_1_and_2 = 2365,\n A_super_call_must_be_the_first_statement_in_the_constructor = 2376,\n Constructors_for_derived_classes_must_contain_a_super_call = 2377,\n Getter_and_setter_accessors_do_not_agree_in_visibility = 2379,\n _get_and_set_accessor_must_have_the_same_type = 2380,\n Overload_signatures_must_all_be_public_private_or_protected = 2385,\n Constructor_implementation_is_missing = 2390,\n Function_implementation_is_missing_or_not_immediately_following_the_declaration = 2391,\n Multiple_constructor_implementations_are_not_allowed = 2392,\n Duplicate_function_implementation = 2393,\n This_overload_signature_is_not_compatible_with_its_implementation_signature = 2394,\n Individual_declarations_in_merged_declaration_0_must_be_all_exported_or_all_local = 2395,\n Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2 = 2416,\n A_class_can_only_implement_an_interface = 2422,\n A_namespace_declaration_cannot_be_located_prior_to_a_class_or_function_with_which_it_is_merged = 2434,\n Types_have_separate_declarations_of_a_private_property_0 = 2442,\n Property_0_is_protected_in_type_1_but_public_in_type_2 = 2444,\n Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses = 2445,\n Variable_0_used_before_its_declaration = 2448,\n Cannot_redeclare_block_scoped_variable_0 = 2451,\n The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly = 2453,\n Variable_0_is_used_before_being_assigned = 2454,\n Type_alias_0_circularly_references_itself = 2456,\n Type_0_has_no_property_1 = 2460,\n The_0_operator_cannot_be_applied_to_type_1 = 2469,\n In_const_enum_declarations_member_initializer_must_be_constant_expression = 2474,\n Export_declaration_conflicts_with_exported_declaration_of_0 = 2484,\n _0_is_referenced_directly_or_indirectly_in_its_own_base_expression = 2506,\n Cannot_create_an_instance_of_an_abstract_class = 2511,\n Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_2 = 2515,\n Object_is_possibly_null = 2531,\n Cannot_assign_to_0_because_it_is_a_constant_or_a_read_only_property = 2540,\n The_target_of_an_assignment_must_be_a_variable_or_a_property_access = 2541,\n Index_signature_in_type_0_only_permits_reading = 2542,\n Expected_0_arguments_but_got_1 = 2554,\n Expected_at_least_0_arguments_but_got_1 = 2555,\n Expected_0_type_arguments_but_got_1 = 2558,\n Property_0_has_no_initializer_and_is_not_assigned_in_the_constructor_before_this_is_used_or_returned = 2564,\n Property_0_is_used_before_being_assigned = 2565,\n _0_is_defined_as_an_accessor_in_class_1_but_is_overridden_here_in_2_as_an_instance_property = 2610,\n _0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor = 2611,\n A_member_initializer_in_a_enum_declaration_cannot_reference_members_declared_after_it_including_members_defined_in_other_enums = 2651,\n Constructor_of_class_0_is_private_and_only_accessible_within_the_class_declaration = 2673,\n Constructor_of_class_0_is_protected_and_only_accessible_within_the_class_declaration = 2674,\n Cannot_extend_a_class_0_Class_constructor_is_marked_as_private = 2675,\n The_this_types_of_each_signature_are_incompatible = 2685,\n Namespace_0_has_no_exported_member_1 = 2694,\n Required_type_parameters_may_not_follow_optional_type_parameters = 2706,\n Duplicate_property_0 = 2718,\n Property_0_is_missing_in_type_1_but_required_in_type_2 = 2741,\n Type_0_has_no_call_signatures = 2757,\n This_member_cannot_have_an_override_modifier_because_it_is_not_declared_in_the_base_class_0 = 4117,\n File_0_not_found = 6054,\n Numeric_separators_are_not_allowed_here = 6188,\n Multiple_consecutive_numeric_separators_are_not_permitted = 6189,\n This_expression_is_not_callable_because_it_is_a_get_accessor_Did_you_mean_to_use_it_without = 6234,\n _super_must_be_called_before_accessing_this_in_the_constructor_of_a_derived_class = 17009,\n _super_must_be_called_before_accessing_a_property_of_super_in_the_constructor_of_a_derived_class = 17011\n}\n\n/** Translates a diagnostic code to its respective string. */\nexport function diagnosticCodeToString(code: DiagnosticCode): string {\n switch (code) {\n case 100: return \"Not implemented: {0}\";\n case 101: return \"Operation is unsafe.\";\n case 102: return \"User-defined: {0}\";\n case 103: return \"Feature '{0}' is not enabled.\";\n case 104: return \"Low memory limit exceeded by static data: {0} > {1}\";\n case 105: return \"Module requires at least '{0}' pages of initial memory.\";\n case 106: return \"Module requires at least '{0}' pages of maximum memory.\";\n case 107: return \"Shared memory requires maximum memory to be defined.\";\n case 108: return \"Shared memory requires feature 'threads' to be enabled.\";\n case 109: return \"Transform '{0}': {1}\";\n case 110: return \"Start function name '{0}' is invalid or conflicts with another export.\";\n case 111: return \"Element '{0}' not found.\";\n case 112: return \"Exchange of '{0}' values is not supported by all embeddings\";\n case 200: return \"Conversion from type '{0}' to '{1}' requires an explicit cast.\";\n case 201: return \"Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.\";\n case 202: return \"Type '{0}' cannot be changed to type '{1}'.\";\n case 203: return \"Operation '{0}' cannot be applied to type '{1}'.\";\n case 204: return \"Type '{0}' cannot be nullable.\";\n case 206: return \"Mutable value cannot be inlined.\";\n case 207: return \"Unmanaged classes cannot extend managed classes and vice-versa.\";\n case 208: return \"Unmanaged classes cannot implement interfaces.\";\n case 209: return \"Invalid regular expression flags.\";\n case 210: return \"Expression is never 'null'.\";\n case 211: return \"Class '{0}' is final and cannot be extended.\";\n case 212: return \"Decorator '{0}' is not valid here.\";\n case 213: return \"Duplicate decorator.\";\n case 214: return \"Type '{0}' is illegal in this context.\";\n case 215: return \"Optional parameter must have an initializer.\";\n case 216: return \"Class '{0}' cannot declare a constructor when instantiated from an object literal.\";\n case 217: return \"Function '{0}' cannot be inlined into itself.\";\n case 218: return \"Cannot access method '{0}' without calling it as it requires 'this' to be set.\";\n case 219: return \"Optional properties are not supported.\";\n case 220: return \"Expression must be a compile-time constant.\";\n case 221: return \"Type '{0}' is not a function index or function reference.\";\n case 222: return \"'{0}' must be a value between '{1}' and '{2}' inclusive.\";\n case 223: return \"'{0}' must be a power of two.\";\n case 224: return \"'{0}' is not a valid operator.\";\n case 225: return \"Expression cannot be represented by a type.\";\n case 226: return \"Expression resolves to unusual type '{0}'.\";\n case 227: return \"Array literal expected.\";\n case 228: return \"Function '{0}' is virtual and will not be inlined.\";\n case 229: return \"Property '{0}' only has a setter and is missing a getter.\";\n case 230: return \"'{0}' keyword cannot be used here.\";\n case 231: return \"A class with a constructor explicitly returning something else than 'this' must be '@final'.\";\n case 233: return \"Property '{0}' is always assigned before being used.\";\n case 234: return \"Expression does not compile to a value at runtime.\";\n case 235: return \"Only variables, functions and enums become WebAssembly module exports.\";\n case 236: return \"Literal '{0}' does not fit into 'i64' or 'u64' types.\";\n case 237: return \"Index signature accessors in type '{0}' differ in types.\";\n case 238: return \"Initializer, definitive assignment or nullable type expected.\";\n case 239: return \"Definitive assignment has no effect on local variables.\";\n case 901: return \"Importing the table disables some indirect call optimizations.\";\n case 902: return \"Exporting the table disables some indirect call optimizations.\";\n case 903: return \"Expression compiles to a dynamic check at runtime.\";\n case 904: return \"Indexed access may involve bounds checking.\";\n case 905: return \"Explicitly returning constructor drops 'this' allocation.\";\n case 906: return \"Unnecessary definite assignment.\";\n case 907: return \"'NaN' does not compare equal to any other value including itself. Use isNaN(x) instead.\";\n case 908: return \"Comparison with -0.0 is sign insensitive. Use Object.is(x, -0.0) if the sign matters.\";\n case 1002: return \"Unterminated string literal.\";\n case 1003: return \"Identifier expected.\";\n case 1005: return \"'{0}' expected.\";\n case 1006: return \"A file cannot have a reference to itself.\";\n case 1009: return \"Trailing comma not allowed.\";\n case 1012: return \"Unexpected token.\";\n case 1014: return \"A rest parameter must be last in a parameter list.\";\n case 1015: return \"Parameter cannot have question mark and initializer.\";\n case 1016: return \"A required parameter cannot follow an optional parameter.\";\n case 1031: return \"'{0}' modifier cannot appear on class elements of this kind.\";\n case 1036: return \"Statements are not allowed in ambient contexts.\";\n case 1039: return \"Initializers are not allowed in ambient contexts.\";\n case 1042: return \"'{0}' modifier cannot be used here.\";\n case 1047: return \"A rest parameter cannot be optional.\";\n case 1048: return \"A rest parameter cannot have an initializer.\";\n case 1049: return \"A 'set' accessor must have exactly one parameter.\";\n case 1052: return \"A 'set' accessor parameter cannot have an initializer.\";\n case 1054: return \"A 'get' accessor cannot have parameters.\";\n case 1061: return \"Enum member must have initializer.\";\n case 1092: return \"Type parameters cannot appear on a constructor declaration.\";\n case 1093: return \"Type annotation cannot appear on a constructor declaration.\";\n case 1094: return \"An accessor cannot have type parameters.\";\n case 1095: return \"A 'set' accessor cannot have a return type annotation.\";\n case 1098: return \"Type parameter list cannot be empty.\";\n case 1099: return \"Type argument list cannot be empty.\";\n case 1104: return \"A 'continue' statement can only be used within an enclosing iteration statement.\";\n case 1105: return \"A 'break' statement can only be used within an enclosing iteration or switch statement.\";\n case 1108: return \"A 'return' statement can only be used within a function body.\";\n case 1109: return \"Expression expected.\";\n case 1110: return \"Type expected.\";\n case 1113: return \"A 'default' clause cannot appear more than once in a 'switch' statement.\";\n case 1114: return \"Duplicate label '{0}'.\";\n case 1120: return \"An export assignment cannot have modifiers.\";\n case 1121: return \"Octal literals are not allowed in strict mode.\";\n case 1124: return \"Digit expected.\";\n case 1125: return \"Hexadecimal digit expected.\";\n case 1126: return \"Unexpected end of text.\";\n case 1127: return \"Invalid character.\";\n case 1130: return \"'case' or 'default' expected.\";\n case 1034: return \"'super' must be followed by an argument list or member access.\";\n case 1038: return \"A 'declare' modifier cannot be used in an already ambient context.\";\n case 1140: return \"Type argument expected.\";\n case 1141: return \"String literal expected.\";\n case 1142: return \"Line break not permitted here.\";\n case 1146: return \"Declaration expected.\";\n case 1155: return \"'const' declarations must be initialized.\";\n case 1161: return \"Unterminated regular expression literal.\";\n case 1263: return \"Declarations with initializers cannot also have definite assignment assertions.\";\n case 1176: return \"Interface declaration cannot have 'implements' clause.\";\n case 1177: return \"Binary digit expected.\";\n case 1178: return \"Octal digit expected.\";\n case 1183: return \"An implementation cannot be declared in ambient contexts.\";\n case 1190: return \"The variable declaration of a 'for...of' statement cannot have an initializer.\";\n case 1198: return \"An extended Unicode escape value must be between 0x0 and 0x10FFFF inclusive.\";\n case 1199: return \"Unterminated Unicode escape sequence.\";\n case 1206: return \"Decorators are not valid here.\";\n case 1242: return \"'abstract' modifier can only appear on a class, method, or property declaration.\";\n case 1245: return \"Method '{0}' cannot have an implementation because it is marked abstract.\";\n case 1255: return \"A definite assignment assertion '!' is not permitted in this context.\";\n case 1311: return \"A class may only extend another class.\";\n case 1317: return \"A parameter property cannot be declared using a rest parameter.\";\n case 1319: return \"A default export can only be used in a module.\";\n case 1345: return \"An expression of type '{0}' cannot be tested for truthiness.\";\n case 1351: return \"An identifier or keyword cannot immediately follow a numeric literal.\";\n case 2300: return \"Duplicate identifier '{0}'.\";\n case 2304: return \"Cannot find name '{0}'.\";\n case 2305: return \"Module '{0}' has no exported member '{1}'.\";\n case 2312: return \"An interface can only extend an interface.\";\n case 2314: return \"Generic type '{0}' requires {1} type argument(s).\";\n case 2315: return \"Type '{0}' is not generic.\";\n case 2322: return \"Type '{0}' is not assignable to type '{1}'.\";\n case 2325: return \"Property '{0}' is private in type '{1}' but not in type '{2}'.\";\n case 2329: return \"Index signature is missing in type '{0}'.\";\n case 2332: return \"'this' cannot be referenced in current location.\";\n case 2333: return \"'this' cannot be referenced in constructor arguments.\";\n case 2335: return \"'super' can only be referenced in a derived class.\";\n case 2336: return \"'super' cannot be referenced in constructor arguments.\";\n case 2337: return \"Super calls are not permitted outside constructors or in nested functions inside constructors.\";\n case 2339: return \"Property '{0}' does not exist on type '{1}'.\";\n case 2341: return \"Property '{0}' is private and only accessible within class '{1}'.\";\n case 2349: return \"Cannot invoke an expression whose type lacks a call signature. Type '{0}' has no compatible call signatures.\";\n case 2351: return \"This expression is not constructable.\";\n case 2355: return \"A function whose declared type is not 'void' must return a value.\";\n case 2357: return \"The operand of an increment or decrement operator must be a variable or a property access.\";\n case 2364: return \"The left-hand side of an assignment expression must be a variable or a property access.\";\n case 2365: return \"Operator '{0}' cannot be applied to types '{1}' and '{2}'.\";\n case 2376: return \"A 'super' call must be the first statement in the constructor.\";\n case 2377: return \"Constructors for derived classes must contain a 'super' call.\";\n case 2379: return \"Getter and setter accessors do not agree in visibility.\";\n case 2380: return \"'get' and 'set' accessor must have the same type.\";\n case 2385: return \"Overload signatures must all be public, private or protected.\";\n case 2390: return \"Constructor implementation is missing.\";\n case 2391: return \"Function implementation is missing or not immediately following the declaration.\";\n case 2392: return \"Multiple constructor implementations are not allowed.\";\n case 2393: return \"Duplicate function implementation.\";\n case 2394: return \"This overload signature is not compatible with its implementation signature.\";\n case 2395: return \"Individual declarations in merged declaration '{0}' must be all exported or all local.\";\n case 2416: return \"Property '{0}' in type '{1}' is not assignable to the same property in base type '{2}'.\";\n case 2422: return \"A class can only implement an interface.\";\n case 2434: return \"A namespace declaration cannot be located prior to a class or function with which it is merged.\";\n case 2442: return \"Types have separate declarations of a private property '{0}'.\";\n case 2444: return \"Property '{0}' is protected in type '{1}' but public in type '{2}'.\";\n case 2445: return \"Property '{0}' is protected and only accessible within class '{1}' and its subclasses.\";\n case 2448: return \"Variable '{0}' used before its declaration.\";\n case 2451: return \"Cannot redeclare block-scoped variable '{0}'\";\n case 2453: return \"The type argument for type parameter '{0}' cannot be inferred from the usage. Consider specifying the type arguments explicitly.\";\n case 2454: return \"Variable '{0}' is used before being assigned.\";\n case 2456: return \"Type alias '{0}' circularly references itself.\";\n case 2460: return \"Type '{0}' has no property '{1}'.\";\n case 2469: return \"The '{0}' operator cannot be applied to type '{1}'.\";\n case 2474: return \"In 'const' enum declarations member initializer must be constant expression.\";\n case 2484: return \"Export declaration conflicts with exported declaration of '{0}'.\";\n case 2506: return \"'{0}' is referenced directly or indirectly in its own base expression.\";\n case 2511: return \"Cannot create an instance of an abstract class.\";\n case 2515: return \"Non-abstract class '{0}' does not implement inherited abstract member '{1}' from '{2}'.\";\n case 2531: return \"Object is possibly 'null'.\";\n case 2540: return \"Cannot assign to '{0}' because it is a constant or a read-only property.\";\n case 2541: return \"The target of an assignment must be a variable or a property access.\";\n case 2542: return \"Index signature in type '{0}' only permits reading.\";\n case 2554: return \"Expected {0} arguments, but got {1}.\";\n case 2555: return \"Expected at least {0} arguments, but got {1}.\";\n case 2558: return \"Expected {0} type arguments, but got {1}.\";\n case 2564: return \"Property '{0}' has no initializer and is not assigned in the constructor before 'this' is used or returned.\";\n case 2565: return \"Property '{0}' is used before being assigned.\";\n case 2610: return \"'{0}' is defined as an accessor in class '{1}', but is overridden here in '{2}' as an instance property.\";\n case 2611: return \"'{0}' is defined as a property in class '{1}', but is overridden here in '{2}' as an accessor.\";\n case 2651: return \"A member initializer in a enum declaration cannot reference members declared after it, including members defined in other enums.\";\n case 2673: return \"Constructor of class '{0}' is private and only accessible within the class declaration.\";\n case 2674: return \"Constructor of class '{0}' is protected and only accessible within the class declaration.\";\n case 2675: return \"Cannot extend a class '{0}'. Class constructor is marked as private.\";\n case 2685: return \"The 'this' types of each signature are incompatible.\";\n case 2694: return \"Namespace '{0}' has no exported member '{1}'.\";\n case 2706: return \"Required type parameters may not follow optional type parameters.\";\n case 2718: return \"Duplicate property '{0}'.\";\n case 2741: return \"Property '{0}' is missing in type '{1}' but required in type '{2}'.\";\n case 2757: return \"Type '{0}' has no call signatures.\";\n case 4117: return \"This member cannot have an 'override' modifier because it is not declared in the base class '{0}'.\";\n case 6054: return \"File '{0}' not found.\";\n case 6188: return \"Numeric separators are not allowed here.\";\n case 6189: return \"Multiple consecutive numeric separators are not permitted.\";\n case 6234: return \"This expression is not callable because it is a 'get' accessor. Did you mean to use it without '()'?\";\n case 17009: return \"'super' must be called before accessing 'this' in the constructor of a derived class.\";\n case 17011: return \"'super' must be called before accessing a property of 'super' in the constructor of a derived class.\";\n default: return \"\";\n }\n}\n","/**\n * @fileoverview Built-in elements providing core WebAssembly functionality.\n *\n * Each builtin is linked to its definition in std/assembly/builtins.ts.\n * When its prototype is called, the compiler recognizes the `@builtin`\n * decorator, looks up the respective handler in the global builtins map\n * and executes it, with the handler directly emitting WebAssembly code\n * according to context.\n *\n * Builtins can be categorized into core builtins that typically are generic\n * and emit code directly and aliases calling core builtins with overridden\n * contexts. The latter is used by inline assembler aliases of WebAssembly\n * instructions, like `i64.load8_u` deferring to `load`.\n *\n * The `contextIsExact` modifier is used to force a specific instruction\n * family. A `i32.store8` deferring to `store` for example is\n * ambiguous in that the input can still be an i32 or an i64, leading to\n * either an `i32.store8` or an `i64.store8`, so `i32` is forced there.\n * This behavior is indicated by `from i32/i64` in the comments below.\n *\n * @license Apache-2.0\n */\n\n// TODO: Add builtins for `i32.add` etc. that do not have a core builtin.\n\nimport {\n Compiler,\n Constraints,\n RuntimeFeatures,\n UncheckedBehavior\n} from \"./compiler\";\n\nimport {\n DiagnosticCode,\n DiagnosticCategory\n} from \"./diagnostics\";\n\nimport {\n Expression,\n LiteralKind,\n StringLiteralExpression,\n CallExpression,\n NodeKind,\n LiteralExpression,\n ArrayLiteralExpression,\n IdentifierExpression\n} from \"./ast\";\n\nimport {\n Type,\n TypeKind,\n TypeFlags\n} from \"./types\";\n\nimport {\n BinaryOp,\n UnaryOp,\n AtomicRMWOp,\n SIMDExtractOp,\n SIMDReplaceOp,\n SIMDShiftOp,\n SIMDTernaryOp,\n SIMDLoadOp,\n SIMDLoadStoreLaneOp,\n TypeRef,\n ExpressionRef,\n ExpressionId,\n getExpressionId,\n getExpressionType,\n getConstValueI64High,\n getConstValueI64Low,\n getConstValueI32,\n getConstValueF32,\n getConstValueF64,\n getLocalGetIndex,\n createType,\n ExpressionRunnerFlags,\n mustPreserveSideEffects\n} from \"./module\";\n\nimport {\n ElementKind,\n FunctionPrototype,\n Global,\n DecoratorFlags,\n Class,\n PropertyPrototype,\n VariableLikeElement\n} from \"./program\";\n\nimport {\n FlowFlags,\n LocalFlags\n} from \"./flow\";\n\nimport {\n ReportMode\n} from \"./resolver\";\n\nimport {\n CommonFlags,\n Feature,\n featureToString,\n TypeinfoFlags\n} from \"./common\";\n\nimport {\n writeI8,\n writeI16,\n writeI32,\n writeF32,\n writeF64,\n isPowerOf2\n} from \"./util\";\n\n/** Internal names of various compiler built-ins. */\nexport namespace BuiltinNames {\n\n // compiler-generated\n export const start = \"~start\";\n export const started = \"~started\";\n export const argumentsLength = \"~argumentsLength\";\n export const setArgumentsLength = \"~setArgumentsLength\";\n\n // std/builtins.ts\n export const abort = \"~lib/builtins/abort\";\n export const trace = \"~lib/builtins/trace\";\n export const seed = \"~lib/builtins/seed\";\n\n export const isBoolean = \"~lib/builtins/isBoolean\";\n export const isInteger = \"~lib/builtins/isInteger\";\n export const isSigned = \"~lib/builtins/isSigned\";\n export const isFloat = \"~lib/builtins/isFloat\";\n export const isVector = \"~lib/builtins/isVector\";\n export const isReference = \"~lib/builtins/isReference\";\n export const isString = \"~lib/builtins/isString\";\n export const isArray = \"~lib/builtins/isArray\";\n export const isArrayLike = \"~lib/builtins/isArrayLike\";\n export const isFunction = \"~lib/builtins/isFunction\";\n export const isNullable = \"~lib/builtins/isNullable\";\n export const isDefined = \"~lib/builtins/isDefined\";\n export const isConstant = \"~lib/builtins/isConstant\";\n export const isManaged = \"~lib/builtins/isManaged\";\n export const isVoid = \"~lib/builtins/isVoid\";\n\n export const bswap = \"~lib/builtins/bswap\";\n\n export const add = \"~lib/builtins/add\";\n export const sub = \"~lib/builtins/sub\";\n export const mul = \"~lib/builtins/mul\";\n export const div = \"~lib/builtins/div\";\n export const clz = \"~lib/builtins/clz\";\n export const ctz = \"~lib/builtins/ctz\";\n export const popcnt = \"~lib/builtins/popcnt\";\n export const rotl = \"~lib/builtins/rotl\";\n export const rotr = \"~lib/builtins/rotr\";\n export const abs = \"~lib/builtins/abs\";\n export const max = \"~lib/builtins/max\";\n export const min = \"~lib/builtins/min\";\n export const ceil = \"~lib/builtins/ceil\";\n export const floor = \"~lib/builtins/floor\";\n export const copysign = \"~lib/builtins/copysign\";\n export const nearest = \"~lib/builtins/nearest\";\n export const reinterpret = \"~lib/builtins/reinterpret\";\n export const sqrt = \"~lib/builtins/sqrt\";\n export const trunc = \"~lib/builtins/trunc\";\n export const eq = \"~lib/builtins/eq\";\n export const ne = \"~lib/builtins/ne\";\n export const rem = \"~lib/builtins/rem\";\n export const load = \"~lib/builtins/load\";\n export const store = \"~lib/builtins/store\";\n export const atomic_load = \"~lib/builtins/atomic.load\";\n export const atomic_store = \"~lib/builtins/atomic.store\";\n export const atomic_add = \"~lib/builtins/atomic.add\";\n export const atomic_sub = \"~lib/builtins/atomic.sub\";\n export const atomic_and = \"~lib/builtins/atomic.and\";\n export const atomic_or = \"~lib/builtins/atomic.or\";\n export const atomic_xor = \"~lib/builtins/atomic.xor\";\n export const atomic_xchg = \"~lib/builtins/atomic.xchg\";\n export const atomic_cmpxchg = \"~lib/builtins/atomic.cmpxchg\";\n export const atomic_wait = \"~lib/builtins/atomic.wait\";\n export const atomic_notify = \"~lib/builtins/atomic.notify\";\n export const atomic_fence = \"~lib/builtins/atomic.fence\";\n\n export const sizeof = \"~lib/builtins/sizeof\";\n export const alignof = \"~lib/builtins/alignof\";\n export const offsetof = \"~lib/builtins/offsetof\";\n export const nameof = \"~lib/builtins/nameof\";\n export const lengthof = \"~lib/builtins/lengthof\";\n export const select = \"~lib/builtins/select\";\n export const unreachable = \"~lib/builtins/unreachable\";\n export const changetype = \"~lib/builtins/changetype\";\n export const assert = \"~lib/builtins/assert\";\n export const call_indirect = \"~lib/builtins/call_indirect\";\n export const unchecked = \"~lib/builtins/unchecked\";\n export const instantiate = \"~lib/builtins/instantiate\";\n export const idof = \"~lib/builtins/idof\";\n\n export const i8 = \"~lib/builtins/i8\";\n export const i16 = \"~lib/builtins/i16\";\n export const i32 = \"~lib/builtins/i32\";\n export const i64 = \"~lib/builtins/i64\";\n export const isize = \"~lib/builtins/isize\";\n export const u8 = \"~lib/builtins/u8\";\n export const u16 = \"~lib/builtins/u16\";\n export const u32 = \"~lib/builtins/u32\";\n export const u64 = \"~lib/builtins/u64\";\n export const usize = \"~lib/builtins/usize\";\n export const bool = \"~lib/builtins/bool\";\n export const f32 = \"~lib/builtins/f32\";\n export const f64 = \"~lib/builtins/f64\";\n export const v128 = \"~lib/builtins/v128\";\n\n export const i32_clz = \"~lib/builtins/i32.clz\";\n export const i64_clz = \"~lib/builtins/i64.clz\";\n export const i32_ctz = \"~lib/builtins/i32.ctz\";\n export const i64_ctz = \"~lib/builtins/i64.ctz\";\n export const i32_popcnt = \"~lib/builtins/i32.popcnt\";\n export const i64_popcnt = \"~lib/builtins/i64.popcnt\";\n export const i32_rotl = \"~lib/builtins/i32.rotl\";\n export const i64_rotl = \"~lib/builtins/i64.rotl\";\n export const i32_rotr = \"~lib/builtins/i32.rotr\";\n export const i64_rotr = \"~lib/builtins/i64.rotr\";\n\n export const f32_abs = \"~lib/builtins/f32.abs\";\n export const f64_abs = \"~lib/builtins/f64.abs\";\n export const f32_max = \"~lib/builtins/f32.max\";\n export const f64_max = \"~lib/builtins/f64.max\";\n export const f32_min = \"~lib/builtins/f32.min\";\n export const f64_min = \"~lib/builtins/f64.min\";\n export const f32_ceil = \"~lib/builtins/f32.ceil\";\n export const f64_ceil = \"~lib/builtins/f64.ceil\";\n export const f32_floor = \"~lib/builtins/f32.floor\";\n export const f64_floor = \"~lib/builtins/f64.floor\";\n export const f32_copysign = \"~lib/builtins/f32.copysign\";\n export const f64_copysign = \"~lib/builtins/f64.copysign\";\n export const f32_nearest = \"~lib/builtins/f32.nearest\";\n export const f64_nearest = \"~lib/builtins/f64.nearest\";\n export const i32_reinterpret_f32 = \"~lib/builtins/i32.reinterpret_f32\";\n export const i64_reinterpret_f64 = \"~lib/builtins/i64.reinterpret_f64\";\n export const f32_reinterpret_i32 = \"~lib/builtins/f32.reinterpret_i32\";\n export const f64_reinterpret_i64 = \"~lib/builtins/f64.reinterpret_i64\";\n export const f32_sqrt = \"~lib/builtins/f32.sqrt\";\n export const f64_sqrt = \"~lib/builtins/f64.sqrt\";\n export const f32_trunc = \"~lib/builtins/f32.trunc\";\n export const f64_trunc = \"~lib/builtins/f64.trunc\";\n\n export const i32_add = \"~lib/builtins/i32.add\";\n export const i64_add = \"~lib/builtins/i64.add\";\n export const f32_add = \"~lib/builtins/f32.add\";\n export const f64_add = \"~lib/builtins/f64.add\";\n export const i32_sub = \"~lib/builtins/i32.sub\";\n export const i64_sub = \"~lib/builtins/i64.sub\";\n export const f32_sub = \"~lib/builtins/f32.sub\";\n export const f64_sub = \"~lib/builtins/f64.sub\";\n export const i32_mul = \"~lib/builtins/i32.mul\";\n export const i64_mul = \"~lib/builtins/i64.mul\";\n export const f32_mul = \"~lib/builtins/f32.mul\";\n export const f64_mul = \"~lib/builtins/f64.mul\";\n export const i32_div_s = \"~lib/builtins/i32.div_s\";\n export const i32_div_u = \"~lib/builtins/i32.div_u\";\n export const i64_div_s = \"~lib/builtins/i64.div_s\";\n export const i64_div_u = \"~lib/builtins/i64.div_u\";\n export const f32_div = \"~lib/builtins/f32.div\";\n export const f64_div = \"~lib/builtins/f64.div\";\n\n export const i32_eq = \"~lib/builtins/i32.eq\";\n export const i64_eq = \"~lib/builtins/i64.eq\";\n export const f32_eq = \"~lib/builtins/f32.eq\";\n export const f64_eq = \"~lib/builtins/f64.eq\";\n export const i32_ne = \"~lib/builtins/i32.ne\";\n export const i64_ne = \"~lib/builtins/i64.ne\";\n export const f32_ne = \"~lib/builtins/f32.ne\";\n export const f64_ne = \"~lib/builtins/f64.ne\";\n\n export const i32_rem_s = \"~lib/builtins/i32.rem_s\";\n export const i32_rem_u = \"~lib/builtins/i32.rem_u\";\n export const i64_rem_s = \"~lib/builtins/i64.rem_s\";\n export const i64_rem_u = \"~lib/builtins/i64.rem_u\";\n\n export const i32_load8_s = \"~lib/builtins/i32.load8_s\";\n export const i32_load8_u = \"~lib/builtins/i32.load8_u\";\n export const i32_load16_s = \"~lib/builtins/i32.load16_s\";\n export const i32_load16_u = \"~lib/builtins/i32.load16_u\";\n export const i32_load = \"~lib/builtins/i32.load\";\n export const i64_load8_s = \"~lib/builtins/i64.load8_s\";\n export const i64_load8_u = \"~lib/builtins/i64.load8_u\";\n export const i64_load16_s = \"~lib/builtins/i64.load16_s\";\n export const i64_load16_u = \"~lib/builtins/i64.load16_u\";\n export const i64_load32_s = \"~lib/builtins/i64.load32_s\";\n export const i64_load32_u = \"~lib/builtins/i64.load32_u\";\n export const i64_load = \"~lib/builtins/i64.load\";\n export const f32_load = \"~lib/builtins/f32.load\";\n export const f64_load = \"~lib/builtins/f64.load\";\n export const i32_store8 = \"~lib/builtins/i32.store8\";\n export const i32_store16 = \"~lib/builtins/i32.store16\";\n export const i32_store = \"~lib/builtins/i32.store\";\n export const i64_store8 = \"~lib/builtins/i64.store8\";\n export const i64_store16 = \"~lib/builtins/i64.store16\";\n export const i64_store32 = \"~lib/builtins/i64.store32\";\n export const i64_store = \"~lib/builtins/i64.store\";\n export const f32_store = \"~lib/builtins/f32.store\";\n export const f64_store = \"~lib/builtins/f64.store\";\n\n export const i32_atomic_load8_u = \"~lib/builtins/i32.atomic.load8_u\";\n export const i32_atomic_load16_u = \"~lib/builtins/i32.atomic.load16_u\";\n export const i32_atomic_load = \"~lib/builtins/i32.atomic.load\";\n export const i64_atomic_load8_u = \"~lib/builtins/i64.atomic.load8_u\";\n export const i64_atomic_load16_u = \"~lib/builtins/i64.atomic.load16_u\";\n export const i64_atomic_load32_u = \"~lib/builtins/i64.atomic.load32_u\";\n export const i64_atomic_load = \"~lib/builtins/i64.atomic.load\";\n export const i32_atomic_store8 = \"~lib/builtins/i32.atomic.store8\";\n export const i32_atomic_store16 = \"~lib/builtins/i32.atomic.store16\";\n export const i32_atomic_store = \"~lib/builtins/i32.atomic.store\";\n export const i64_atomic_store8 = \"~lib/builtins/i64.atomic.store8\";\n export const i64_atomic_store16 = \"~lib/builtins/i64.atomic.store16\";\n export const i64_atomic_store32 = \"~lib/builtins/i64.atomic.store32\";\n export const i64_atomic_store = \"~lib/builtins/i64.atomic.store\";\n export const i32_atomic_rmw8_add_u = \"~lib/builtins/i32.atomic.rmw8.add_u\";\n export const i32_atomic_rmw16_add_u = \"~lib/builtins/i32.atomic.rmw16.add_u\";\n export const i32_atomic_rmw_add = \"~lib/builtins/i32.atomic.rmw.add\";\n export const i64_atomic_rmw8_add_u = \"~lib/builtins/i64.atomic.rmw8.add_u\";\n export const i64_atomic_rmw16_add_u = \"~lib/builtins/i64.atomic.rmw16.add_u\";\n export const i64_atomic_rmw32_add_u = \"~lib/builtins/i64.atomic.rmw32.add_u\";\n export const i64_atomic_rmw_add = \"~lib/builtins/i64.atomic.rmw.add\";\n export const i32_atomic_rmw8_sub_u = \"~lib/builtins/i32.atomic.rmw8.sub_u\";\n export const i32_atomic_rmw16_sub_u = \"~lib/builtins/i32.atomic.rmw16.sub_u\";\n export const i32_atomic_rmw_sub = \"~lib/builtins/i32.atomic.rmw.sub\";\n export const i64_atomic_rmw8_sub_u = \"~lib/builtins/i64.atomic.rmw8.sub_u\";\n export const i64_atomic_rmw16_sub_u = \"~lib/builtins/i64.atomic.rmw16.sub_u\";\n export const i64_atomic_rmw32_sub_u = \"~lib/builtins/i64.atomic.rmw32.sub_u\";\n export const i64_atomic_rmw_sub = \"~lib/builtins/i64.atomic.rmw.sub\";\n export const i32_atomic_rmw8_and_u = \"~lib/builtins/i32.atomic.rmw8.and_u\";\n export const i32_atomic_rmw16_and_u = \"~lib/builtins/i32.atomic.rmw16.and_u\";\n export const i32_atomic_rmw_and = \"~lib/builtins/i32.atomic.rmw.and\";\n export const i64_atomic_rmw8_and_u = \"~lib/builtins/i64.atomic.rmw8.and_u\";\n export const i64_atomic_rmw16_and_u = \"~lib/builtins/i64.atomic.rmw16.and_u\";\n export const i64_atomic_rmw32_and_u = \"~lib/builtins/i64.atomic.rmw32.and_u\";\n export const i64_atomic_rmw_and = \"~lib/builtins/i64.atomic.rmw.and\";\n export const i32_atomic_rmw8_or_u = \"~lib/builtins/i32.atomic.rmw8.or_u\";\n export const i32_atomic_rmw16_or_u = \"~lib/builtins/i32.atomic.rmw16.or_u\";\n export const i32_atomic_rmw_or = \"~lib/builtins/i32.atomic.rmw.or\";\n export const i64_atomic_rmw8_or_u = \"~lib/builtins/i64.atomic.rmw8.or_u\";\n export const i64_atomic_rmw16_or_u = \"~lib/builtins/i64.atomic.rmw16.or_u\";\n export const i64_atomic_rmw32_or_u = \"~lib/builtins/i64.atomic.rmw32.or_u\";\n export const i64_atomic_rmw_or = \"~lib/builtins/i64.atomic.rmw.or\";\n export const i32_atomic_rmw8_xor_u = \"~lib/builtins/i32.atomic.rmw8.xor_u\";\n export const i32_atomic_rmw16_xor_u = \"~lib/builtins/i32.atomic.rmw16.xor_u\";\n export const i32_atomic_rmw_xor = \"~lib/builtins/i32.atomic.rmw.xor\";\n export const i64_atomic_rmw8_xor_u = \"~lib/builtins/i64.atomic.rmw8.xor_u\";\n export const i64_atomic_rmw16_xor_u = \"~lib/builtins/i64.atomic.rmw16.xor_u\";\n export const i64_atomic_rmw32_xor_u = \"~lib/builtins/i64.atomic.rmw32.xor_u\";\n export const i64_atomic_rmw_xor = \"~lib/builtins/i64.atomic.rmw.xor\";\n export const i32_atomic_rmw8_xchg_u = \"~lib/builtins/i32.atomic.rmw8.xchg_u\";\n export const i32_atomic_rmw16_xchg_u = \"~lib/builtins/i32.atomic.rmw16.xchg_u\";\n export const i32_atomic_rmw_xchg = \"~lib/builtins/i32.atomic.rmw.xchg\";\n export const i64_atomic_rmw8_xchg_u = \"~lib/builtins/i64.atomic.rmw8.xchg_u\";\n export const i64_atomic_rmw16_xchg_u = \"~lib/builtins/i64.atomic.rmw16.xchg_u\";\n export const i64_atomic_rmw32_xchg_u = \"~lib/builtins/i64.atomic.rmw32.xchg_u\";\n export const i64_atomic_rmw_xchg = \"~lib/builtins/i64.atomic.rmw.xchg\";\n export const i32_atomic_rmw8_cmpxchg_u = \"~lib/builtins/i32.atomic.rmw8.cmpxchg_u\";\n export const i32_atomic_rmw16_cmpxchg_u = \"~lib/builtins/i32.atomic.rmw16.cmpxchg_u\";\n export const i32_atomic_rmw_cmpxchg = \"~lib/builtins/i32.atomic.rmw.cmpxchg\";\n export const i64_atomic_rmw8_cmpxchg_u = \"~lib/builtins/i64.atomic.rmw8.cmpxchg_u\";\n export const i64_atomic_rmw16_cmpxchg_u = \"~lib/builtins/i64.atomic.rmw16.cmpxchg_u\";\n export const i64_atomic_rmw32_cmpxchg_u = \"~lib/builtins/i64.atomic.rmw32.cmpxchg_u\";\n export const i64_atomic_rmw_cmpxchg = \"~lib/builtins/i64.atomic.rmw.cmpxchg\";\n export const memory_atomic_wait32 = \"~lib/memory/memory.atomic.wait32\";\n export const memory_atomic_wait64 = \"~lib/memory/memory.atomic.wait64\";\n\n export const v128_splat = \"~lib/builtins/v128.splat\";\n export const v128_extract_lane = \"~lib/builtins/v128.extract_lane\";\n export const v128_replace_lane = \"~lib/builtins/v128.replace_lane\";\n export const v128_shuffle = \"~lib/builtins/v128.shuffle\";\n export const v128_swizzle = \"~lib/builtins/v128.swizzle\";\n export const v128_load_splat = \"~lib/builtins/v128.load_splat\";\n export const v128_load_ext = \"~lib/builtins/v128.load_ext\";\n export const v128_load_zero = \"~lib/builtins/v128.load_zero\";\n export const v128_load_lane = \"~lib/builtins/v128.load_lane\";\n export const v128_store_lane = \"~lib/builtins/v128.store_lane\";\n export const v128_load = \"~lib/builtins/v128.load\";\n export const v128_load8x8_s = \"~lib/builtins/v128.load8x8_s\";\n export const v128_load8x8_u = \"~lib/builtins/v128.load8x8_u\";\n export const v128_load16x4_s = \"~lib/builtins/v128.load16x4_s\";\n export const v128_load16x4_u = \"~lib/builtins/v128.load16x4_u\";\n export const v128_load32x2_s = \"~lib/builtins/v128.load32x2_s\";\n export const v128_load32x2_u = \"~lib/builtins/v128.load32x2_u\";\n export const v128_load8_splat = \"~lib/builtins/v128.load8_splat\";\n export const v128_load16_splat = \"~lib/builtins/v128.load16_splat\";\n export const v128_load32_splat = \"~lib/builtins/v128.load32_splat\";\n export const v128_load64_splat = \"~lib/builtins/v128.load64_splat\";\n export const v128_load32_zero = \"~lib/builtins/v128.load32_zero\";\n export const v128_load64_zero = \"~lib/builtins/v128.load64_zero\";\n export const v128_load8_lane = \"~lib/builtins/v128.load8_lane\";\n export const v128_load16_lane = \"~lib/builtins/v128.load16_lane\";\n export const v128_load32_lane = \"~lib/builtins/v128.load32_lane\";\n export const v128_load64_lane = \"~lib/builtins/v128.load64_lane\";\n export const v128_store8_lane = \"~lib/builtins/v128.store8_lane\";\n export const v128_store16_lane = \"~lib/builtins/v128.store16_lane\";\n export const v128_store32_lane = \"~lib/builtins/v128.store32_lane\";\n export const v128_store64_lane = \"~lib/builtins/v128.store64_lane\";\n export const v128_store = \"~lib/builtins/v128.store\";\n export const v128_add = \"~lib/builtins/v128.add\";\n export const v128_sub = \"~lib/builtins/v128.sub\";\n export const v128_mul = \"~lib/builtins/v128.mul\";\n export const v128_div = \"~lib/builtins/v128.div\";\n export const v128_neg = \"~lib/builtins/v128.neg\";\n export const v128_add_sat = \"~lib/builtins/v128.add_sat\";\n export const v128_sub_sat = \"~lib/builtins/v128.sub_sat\";\n export const v128_shl = \"~lib/builtins/v128.shl\";\n export const v128_shr = \"~lib/builtins/v128.shr\";\n export const v128_and = \"~lib/builtins/v128.and\";\n export const v128_or = \"~lib/builtins/v128.or\";\n export const v128_xor = \"~lib/builtins/v128.xor\";\n export const v128_andnot = \"~lib/builtins/v128.andnot\";\n export const v128_not = \"~lib/builtins/v128.not\";\n export const v128_bitselect = \"~lib/builtins/v128.bitselect\";\n export const v128_any_true = \"~lib/builtins/v128.any_true\";\n export const v128_all_true = \"~lib/builtins/v128.all_true\";\n export const v128_bitmask = \"~lib/builtins/v128.bitmask\";\n export const v128_popcnt = \"~lib/builtins/v128.popcnt\";\n export const v128_min = \"~lib/builtins/v128.min\";\n export const v128_max = \"~lib/builtins/v128.max\";\n export const v128_pmin = \"~lib/builtins/v128.pmin\";\n export const v128_pmax = \"~lib/builtins/v128.pmax\";\n export const v128_dot = \"~lib/builtins/v128.dot\";\n export const v128_avgr = \"~lib/builtins/v128.avgr\";\n export const v128_abs = \"~lib/builtins/v128.abs\";\n export const v128_sqrt = \"~lib/builtins/v128.sqrt\";\n export const v128_ceil = \"~lib/builtins/v128.ceil\";\n export const v128_floor = \"~lib/builtins/v128.floor\";\n export const v128_trunc = \"~lib/builtins/v128.trunc\";\n export const v128_nearest = \"~lib/builtins/v128.nearest\";\n export const v128_eq = \"~lib/builtins/v128.eq\";\n export const v128_ne = \"~lib/builtins/v128.ne\";\n export const v128_lt = \"~lib/builtins/v128.lt\";\n export const v128_le = \"~lib/builtins/v128.le\";\n export const v128_gt = \"~lib/builtins/v128.gt\";\n export const v128_ge = \"~lib/builtins/v128.ge\";\n export const v128_convert = \"~lib/builtins/v128.convert\";\n export const v128_convert_low = \"~lib/builtins/v128.convert_low\";\n export const v128_trunc_sat = \"~lib/builtins/v128.trunc_sat\";\n export const v128_trunc_sat_zero = \"~lib/builtins/v128.trunc_sat_zero\";\n export const v128_narrow = \"~lib/builtins/v128.narrow\";\n export const v128_extend_low = \"~lib/builtins/v128.extend_low\";\n export const v128_extend_high = \"~lib/builtins/v128.extend_high\";\n export const v128_extadd_pairwise = \"~lib/builtins/v128.extadd_pairwise\";\n export const v128_demote_zero = \"~lib/builtins/v128.demote_zero\";\n export const v128_promote_low = \"~lib/builtins/v128.promote_low\";\n export const v128_q15mulr_sat = \"~lib/builtins/v128.q15mulr_sat\";\n export const v128_extmul_low = \"~lib/builtins/v128.extmul_low\";\n export const v128_extmul_high = \"~lib/builtins/v128.extmul_high\";\n\n export const i8x16 = \"~lib/builtins/i8x16\";\n export const i16x8 = \"~lib/builtins/i16x8\";\n export const i32x4 = \"~lib/builtins/i32x4\";\n export const i64x2 = \"~lib/builtins/i64x2\";\n export const f32x4 = \"~lib/builtins/f32x4\";\n export const f64x2 = \"~lib/builtins/f64x2\";\n\n export const i8x16_splat = \"~lib/builtins/i8x16.splat\";\n export const i8x16_extract_lane_s = \"~lib/builtins/i8x16.extract_lane_s\";\n export const i8x16_extract_lane_u = \"~lib/builtins/i8x16.extract_lane_u\";\n export const i8x16_replace_lane = \"~lib/builtins/i8x16.replace_lane\";\n export const i8x16_add = \"~lib/builtins/i8x16.add\";\n export const i8x16_sub = \"~lib/builtins/i8x16.sub\";\n export const i8x16_mul = \"~lib/builtins/i8x16.mul\";\n export const i8x16_min_s = \"~lib/builtins/i8x16.min_s\";\n export const i8x16_min_u = \"~lib/builtins/i8x16.min_u\";\n export const i8x16_max_s = \"~lib/builtins/i8x16.max_s\";\n export const i8x16_max_u = \"~lib/builtins/i8x16.max_u\";\n export const i8x16_avgr_u = \"~lib/builtins/i8x16.avgr_u\";\n export const i8x16_abs = \"~lib/builtins/i8x16.abs\";\n export const i8x16_neg = \"~lib/builtins/i8x16.neg\";\n export const i8x16_add_sat_s = \"~lib/builtins/i8x16.add_sat_s\";\n export const i8x16_add_sat_u = \"~lib/builtins/i8x16.add_sat_u\";\n export const i8x16_sub_sat_s = \"~lib/builtins/i8x16.sub_sat_s\";\n export const i8x16_sub_sat_u = \"~lib/builtins/i8x16.sub_sat_u\";\n export const i8x16_shl = \"~lib/builtins/i8x16.shl\";\n export const i8x16_shr_s = \"~lib/builtins/i8x16.shr_s\";\n export const i8x16_shr_u = \"~lib/builtins/i8x16.shr_u\";\n export const i8x16_all_true = \"~lib/builtins/i8x16.all_true\";\n export const i8x16_bitmask = \"~lib/builtins/i8x16.bitmask\";\n export const i8x16_popcnt = \"~lib/builtins/i8x16.popcnt\";\n export const i8x16_eq = \"~lib/builtins/i8x16.eq\";\n export const i8x16_ne = \"~lib/builtins/i8x16.ne\";\n export const i8x16_lt_s = \"~lib/builtins/i8x16.lt_s\";\n export const i8x16_lt_u = \"~lib/builtins/i8x16.lt_u\";\n export const i8x16_le_s = \"~lib/builtins/i8x16.le_s\";\n export const i8x16_le_u = \"~lib/builtins/i8x16.le_u\";\n export const i8x16_gt_s = \"~lib/builtins/i8x16.gt_s\";\n export const i8x16_gt_u = \"~lib/builtins/i8x16.gt_u\";\n export const i8x16_ge_s = \"~lib/builtins/i8x16.ge_s\";\n export const i8x16_ge_u = \"~lib/builtins/i8x16.ge_u\";\n export const i8x16_narrow_i16x8_s = \"~lib/builtins/i8x16.narrow_i16x8_s\";\n export const i8x16_narrow_i16x8_u = \"~lib/builtins/i8x16.narrow_i16x8_u\";\n export const i8x16_shuffle = \"~lib/builtins/i8x16.shuffle\";\n export const i8x16_swizzle = \"~lib/builtins/i8x16.swizzle\";\n\n export const i16x8_splat = \"~lib/builtins/i16x8.splat\";\n export const i16x8_extract_lane_s = \"~lib/builtins/i16x8.extract_lane_s\";\n export const i16x8_extract_lane_u = \"~lib/builtins/i16x8.extract_lane_u\";\n export const i16x8_replace_lane = \"~lib/builtins/i16x8.replace_lane\";\n export const i16x8_add = \"~lib/builtins/i16x8.add\";\n export const i16x8_sub = \"~lib/builtins/i16x8.sub\";\n export const i16x8_mul = \"~lib/builtins/i16x8.mul\";\n export const i16x8_min_s = \"~lib/builtins/i16x8.min_s\";\n export const i16x8_min_u = \"~lib/builtins/i16x8.min_u\";\n export const i16x8_max_s = \"~lib/builtins/i16x8.max_s\";\n export const i16x8_max_u = \"~lib/builtins/i16x8.max_u\";\n export const i16x8_avgr_u = \"~lib/builtins/i16x8.avgr_u\";\n export const i16x8_abs = \"~lib/builtins/i16x8.abs\";\n export const i16x8_neg = \"~lib/builtins/i16x8.neg\";\n export const i16x8_add_sat_s = \"~lib/builtins/i16x8.add_sat_s\";\n export const i16x8_add_sat_u = \"~lib/builtins/i16x8.add_sat_u\";\n export const i16x8_sub_sat_s = \"~lib/builtins/i16x8.sub_sat_s\";\n export const i16x8_sub_sat_u = \"~lib/builtins/i16x8.sub_sat_u\";\n export const i16x8_shl = \"~lib/builtins/i16x8.shl\";\n export const i16x8_shr_s = \"~lib/builtins/i16x8.shr_s\";\n export const i16x8_shr_u = \"~lib/builtins/i16x8.shr_u\";\n export const i16x8_all_true = \"~lib/builtins/i16x8.all_true\";\n export const i16x8_bitmask = \"~lib/builtins/i16x8.bitmask\";\n export const i16x8_eq = \"~lib/builtins/i16x8.eq\";\n export const i16x8_ne = \"~lib/builtins/i16x8.ne\";\n export const i16x8_lt_s = \"~lib/builtins/i16x8.lt_s\";\n export const i16x8_lt_u = \"~lib/builtins/i16x8.lt_u\";\n export const i16x8_le_s = \"~lib/builtins/i16x8.le_s\";\n export const i16x8_le_u = \"~lib/builtins/i16x8.le_u\";\n export const i16x8_gt_s = \"~lib/builtins/i16x8.gt_s\";\n export const i16x8_gt_u = \"~lib/builtins/i16x8.gt_u\";\n export const i16x8_ge_s = \"~lib/builtins/i16x8.ge_s\";\n export const i16x8_ge_u = \"~lib/builtins/i16x8.ge_u\";\n export const i16x8_narrow_i32x4_s = \"~lib/builtins/i16x8.narrow_i32x4_s\";\n export const i16x8_narrow_i32x4_u = \"~lib/builtins/i16x8.narrow_i32x4_u\";\n export const i16x8_extend_low_i8x16_s = \"~lib/builtins/i16x8.extend_low_i8x16_s\";\n export const i16x8_extend_low_i8x16_u = \"~lib/builtins/i16x8.extend_low_i8x16_u\";\n export const i16x8_extend_high_i8x16_s = \"~lib/builtins/i16x8.extend_high_i8x16_s\";\n export const i16x8_extend_high_i8x16_u = \"~lib/builtins/i16x8.extend_high_i8x16_u\";\n export const i16x8_extadd_pairwise_i8x16_s = \"~lib/builtins/i16x8.extadd_pairwise_i8x16_s\";\n export const i16x8_extadd_pairwise_i8x16_u = \"~lib/builtins/i16x8.extadd_pairwise_i8x16_u\";\n export const i16x8_q15mulr_sat_s = \"~lib/builtins/i16x8.q15mulr_sat_s\";\n export const i16x8_extmul_low_i8x16_s = \"~lib/builtins/i16x8.extmul_low_i8x16_s\";\n export const i16x8_extmul_low_i8x16_u = \"~lib/builtins/i16x8.extmul_low_i8x16_u\";\n export const i16x8_extmul_high_i8x16_s = \"~lib/builtins/i16x8.extmul_high_i8x16_s\";\n export const i16x8_extmul_high_i8x16_u = \"~lib/builtins/i16x8.extmul_high_i8x16_u\";\n export const i16x8_shuffle = \"~lib/builtins/i16x8.shuffle\";\n export const i16x8_swizzle = \"~lib/builtins/i16x8.swizzle\";\n\n export const i32x4_splat = \"~lib/builtins/i32x4.splat\";\n export const i32x4_extract_lane = \"~lib/builtins/i32x4.extract_lane\";\n export const i32x4_replace_lane = \"~lib/builtins/i32x4.replace_lane\";\n export const i32x4_add = \"~lib/builtins/i32x4.add\";\n export const i32x4_sub = \"~lib/builtins/i32x4.sub\";\n export const i32x4_mul = \"~lib/builtins/i32x4.mul\";\n export const i32x4_min_s = \"~lib/builtins/i32x4.min_s\";\n export const i32x4_min_u = \"~lib/builtins/i32x4.min_u\";\n export const i32x4_max_s = \"~lib/builtins/i32x4.max_s\";\n export const i32x4_max_u = \"~lib/builtins/i32x4.max_u\";\n export const i32x4_dot_i16x8_s = \"~lib/builtins/i32x4.dot_i16x8_s\";\n export const i32x4_abs = \"~lib/builtins/i32x4.abs\";\n export const i32x4_neg = \"~lib/builtins/i32x4.neg\";\n export const i32x4_shl = \"~lib/builtins/i32x4.shl\";\n export const i32x4_shr_s = \"~lib/builtins/i32x4.shr_s\";\n export const i32x4_shr_u = \"~lib/builtins/i32x4.shr_u\";\n export const i32x4_all_true = \"~lib/builtins/i32x4.all_true\";\n export const i32x4_bitmask = \"~lib/builtins/i32x4.bitmask\";\n export const i32x4_eq = \"~lib/builtins/i32x4.eq\";\n export const i32x4_ne = \"~lib/builtins/i32x4.ne\";\n export const i32x4_lt_s = \"~lib/builtins/i32x4.lt_s\";\n export const i32x4_lt_u = \"~lib/builtins/i32x4.lt_u\";\n export const i32x4_le_s = \"~lib/builtins/i32x4.le_s\";\n export const i32x4_le_u = \"~lib/builtins/i32x4.le_u\";\n export const i32x4_gt_s = \"~lib/builtins/i32x4.gt_s\";\n export const i32x4_gt_u = \"~lib/builtins/i32x4.gt_u\";\n export const i32x4_ge_s = \"~lib/builtins/i32x4.ge_s\";\n export const i32x4_ge_u = \"~lib/builtins/i32x4.ge_u\";\n export const i32x4_trunc_sat_f32x4_s = \"~lib/builtins/i32x4.trunc_sat_f32x4_s\";\n export const i32x4_trunc_sat_f32x4_u = \"~lib/builtins/i32x4.trunc_sat_f32x4_u\";\n export const i32x4_trunc_sat_f64x2_s_zero = \"~lib/builtins/i32x4.trunc_sat_f64x2_s_zero\";\n export const i32x4_trunc_sat_f64x2_u_zero = \"~lib/builtins/i32x4.trunc_sat_f64x2_u_zero\";\n export const i32x4_extend_low_i16x8_s = \"~lib/builtins/i32x4.extend_low_i16x8_s\";\n export const i32x4_extend_low_i16x8_u = \"~lib/builtins/i32x4.extend_low_i16x8_u\";\n export const i32x4_extend_high_i16x8_s = \"~lib/builtins/i32x4.extend_high_i16x8_s\";\n export const i32x4_extend_high_i16x8_u = \"~lib/builtins/i32x4.extend_high_i16x8_u\";\n export const i32x4_extadd_pairwise_i16x8_s = \"~lib/builtins/i32x4.extadd_pairwise_i16x8_s\";\n export const i32x4_extadd_pairwise_i16x8_u = \"~lib/builtins/i32x4.extadd_pairwise_i16x8_u\";\n export const i32x4_extmul_low_i16x8_s = \"~lib/builtins/i32x4.extmul_low_i16x8_s\";\n export const i32x4_extmul_low_i16x8_u = \"~lib/builtins/i32x4.extmul_low_i16x8_u\";\n export const i32x4_extmul_high_i16x8_s = \"~lib/builtins/i32x4.extmul_high_i16x8_s\";\n export const i32x4_extmul_high_i16x8_u = \"~lib/builtins/i32x4.extmul_high_i16x8_u\";\n export const i32x4_shuffle = \"~lib/builtins/i32x4.shuffle\";\n export const i32x4_swizzle = \"~lib/builtins/i32x4.swizzle\";\n\n export const i64x2_splat = \"~lib/builtins/i64x2.splat\";\n export const i64x2_extract_lane = \"~lib/builtins/i64x2.extract_lane\";\n export const i64x2_replace_lane = \"~lib/builtins/i64x2.replace_lane\";\n export const i64x2_add = \"~lib/builtins/i64x2.add\";\n export const i64x2_sub = \"~lib/builtins/i64x2.sub\";\n export const i64x2_mul = \"~lib/builtins/i64x2.mul\";\n export const i64x2_abs = \"~lib/builtins/i64x2.abs\";\n export const i64x2_neg = \"~lib/builtins/i64x2.neg\";\n export const i64x2_shl = \"~lib/builtins/i64x2.shl\";\n export const i64x2_shr_s = \"~lib/builtins/i64x2.shr_s\";\n export const i64x2_shr_u = \"~lib/builtins/i64x2.shr_u\";\n export const i64x2_all_true = \"~lib/builtins/i64x2.all_true\";\n export const i64x2_bitmask = \"~lib/builtins/i64x2.bitmask\";\n export const i64x2_eq = \"~lib/builtins/i64x2.eq\";\n export const i64x2_ne = \"~lib/builtins/i64x2.ne\";\n export const i64x2_lt_s = \"~lib/builtins/i64x2.lt_s\";\n export const i64x2_lt_u = \"~lib/builtins/i64x2.lt_u\";\n export const i64x2_le_s = \"~lib/builtins/i64x2.le_s\";\n export const i64x2_le_u = \"~lib/builtins/i64x2.le_u\";\n export const i64x2_gt_s = \"~lib/builtins/i64x2.gt_s\";\n export const i64x2_gt_u = \"~lib/builtins/i64x2.gt_u\";\n export const i64x2_ge_s = \"~lib/builtins/i64x2.ge_s\";\n export const i64x2_ge_u = \"~lib/builtins/i64x2.ge_u\";\n export const i64x2_extend_low_i32x4_s = \"~lib/builtins/i64x2.extend_low_i32x4_s\";\n export const i64x2_extend_low_i32x4_u = \"~lib/builtins/i64x2.extend_low_i32x4_u\";\n export const i64x2_extend_high_i32x4_s = \"~lib/builtins/i64x2.extend_high_i32x4_s\";\n export const i64x2_extend_high_i32x4_u = \"~lib/builtins/i64x2.extend_high_i32x4_u\";\n export const i64x2_extmul_low_i32x4_s = \"~lib/builtins/i64x2.extmul_low_i32x4_s\";\n export const i64x2_extmul_low_i32x4_u = \"~lib/builtins/i64x2.extmul_low_i32x4_u\";\n export const i64x2_extmul_high_i32x4_s = \"~lib/builtins/i64x2.extmul_high_i32x4_s\";\n export const i64x2_extmul_high_i32x4_u = \"~lib/builtins/i64x2.extmul_high_i32x4_u\";\n export const i64x2_shuffle = \"~lib/builtins/i64x2.shuffle\";\n export const i64x2_swizzle = \"~lib/builtins/i64x2.swizzle\";\n\n export const f32x4_splat = \"~lib/builtins/f32x4.splat\";\n export const f32x4_extract_lane = \"~lib/builtins/f32x4.extract_lane\";\n export const f32x4_replace_lane = \"~lib/builtins/f32x4.replace_lane\";\n export const f32x4_add = \"~lib/builtins/f32x4.add\";\n export const f32x4_sub = \"~lib/builtins/f32x4.sub\";\n export const f32x4_mul = \"~lib/builtins/f32x4.mul\";\n export const f32x4_div = \"~lib/builtins/f32x4.div\";\n export const f32x4_neg = \"~lib/builtins/f32x4.neg\";\n export const f32x4_min = \"~lib/builtins/f32x4.min\";\n export const f32x4_max = \"~lib/builtins/f32x4.max\";\n export const f32x4_pmin = \"~lib/builtins/f32x4.pmin\";\n export const f32x4_pmax = \"~lib/builtins/f32x4.pmax\";\n export const f32x4_abs = \"~lib/builtins/f32x4.abs\";\n export const f32x4_sqrt = \"~lib/builtins/f32x4.sqrt\";\n export const f32x4_ceil = \"~lib/builtins/f32x4.ceil\";\n export const f32x4_floor = \"~lib/builtins/f32x4.floor\";\n export const f32x4_trunc = \"~lib/builtins/f32x4.trunc\";\n export const f32x4_nearest = \"~lib/builtins/f32x4.nearest\";\n export const f32x4_eq = \"~lib/builtins/f32x4.eq\";\n export const f32x4_ne = \"~lib/builtins/f32x4.ne\";\n export const f32x4_lt = \"~lib/builtins/f32x4.lt\";\n export const f32x4_le = \"~lib/builtins/f32x4.le\";\n export const f32x4_gt = \"~lib/builtins/f32x4.gt\";\n export const f32x4_ge = \"~lib/builtins/f32x4.ge\";\n export const f32x4_convert_i32x4_s = \"~lib/builtins/f32x4.convert_i32x4_s\";\n export const f32x4_convert_i32x4_u = \"~lib/builtins/f32x4.convert_i32x4_u\";\n export const f32x4_demote_f64x2_zero = \"~lib/builtins/f32x4.demote_f64x2_zero\";\n export const f32x4_shuffle = \"~lib/builtins/f32x4.shuffle\";\n export const f32x4_swizzle = \"~lib/builtins/f32x4.swizzle\";\n\n export const f64x2_splat = \"~lib/builtins/f64x2.splat\";\n export const f64x2_extract_lane = \"~lib/builtins/f64x2.extract_lane\";\n export const f64x2_replace_lane = \"~lib/builtins/f64x2.replace_lane\";\n export const f64x2_add = \"~lib/builtins/f64x2.add\";\n export const f64x2_sub = \"~lib/builtins/f64x2.sub\";\n export const f64x2_mul = \"~lib/builtins/f64x2.mul\";\n export const f64x2_div = \"~lib/builtins/f64x2.div\";\n export const f64x2_neg = \"~lib/builtins/f64x2.neg\";\n export const f64x2_min = \"~lib/builtins/f64x2.min\";\n export const f64x2_max = \"~lib/builtins/f64x2.max\";\n export const f64x2_pmin = \"~lib/builtins/f64x2.pmin\";\n export const f64x2_pmax = \"~lib/builtins/f64x2.pmax\";\n export const f64x2_abs = \"~lib/builtins/f64x2.abs\";\n export const f64x2_sqrt = \"~lib/builtins/f64x2.sqrt\";\n export const f64x2_ceil = \"~lib/builtins/f64x2.ceil\";\n export const f64x2_floor = \"~lib/builtins/f64x2.floor\";\n export const f64x2_trunc = \"~lib/builtins/f64x2.trunc\";\n export const f64x2_nearest = \"~lib/builtins/f64x2.nearest\";\n export const f64x2_eq = \"~lib/builtins/f64x2.eq\";\n export const f64x2_ne = \"~lib/builtins/f64x2.ne\";\n export const f64x2_lt = \"~lib/builtins/f64x2.lt\";\n export const f64x2_le = \"~lib/builtins/f64x2.le\";\n export const f64x2_gt = \"~lib/builtins/f64x2.gt\";\n export const f64x2_ge = \"~lib/builtins/f64x2.ge\";\n export const f64x2_convert_low_i32x4_s = \"~lib/builtins/f64x2.convert_low_i32x4_s\";\n export const f64x2_convert_low_i32x4_u = \"~lib/builtins/f64x2.convert_low_i32x4_u\";\n export const f64x2_promote_low_f32x4 = \"~lib/builtins/f64x2.promote_low_f32x4\";\n export const f64x2_shuffle = \"~lib/builtins/f64x2.shuffle\";\n export const f64x2_swizzle = \"~lib/builtins/f64x2.swizzle\";\n\n export const i31_new = \"~lib/builtins/i31.new\";\n export const i31_get = \"~lib/builtins/i31.get\";\n\n // internals\n export const data_end = \"~lib/memory/__data_end\";\n export const stack_pointer = \"~lib/memory/__stack_pointer\";\n export const heap_base = \"~lib/memory/__heap_base\";\n export const rtti_base = \"~lib/rt/__rtti_base\";\n export const visit_globals = \"~lib/rt/__visit_globals\";\n export const visit_members = \"~lib/rt/__visit_members\";\n export const tostack = \"~lib/rt/__tostack\";\n\n // std/number.ts\n export const NaN = \"~lib/number/NaN\";\n export const Infinity = \"~lib/number/Infinity\";\n export const isNaN = \"~lib/number/isNaN\";\n export const isFinite = \"~lib/number/isFinite\";\n\n // std/diagnostics.ts\n export const ERROR = \"~lib/diagnostics/ERROR\";\n export const WARNING = \"~lib/diagnostics/WARNING\";\n export const INFO = \"~lib/diagnostics/INFO\";\n\n // std/function.ts\n export const Function = \"~lib/function/Function\";\n export const Function_call = \"~lib/function/Function#call\";\n\n // std/memory.ts\n export const memory_size = \"~lib/memory/memory.size\";\n export const memory_grow = \"~lib/memory/memory.grow\";\n export const memory_copy = \"~lib/memory/memory.copy\";\n export const memory_fill = \"~lib/memory/memory.fill\";\n export const memory_data = \"~lib/memory/memory.data\";\n\n // std/typedarray.ts\n export const Int8Array = \"~lib/typedarray/Int8Array\";\n export const Uint8Array = \"~lib/typedarray/Uint8Array\";\n export const Uint8ClampedArray = \"~lib/typedarray/Uint8ClampedArray\";\n export const Int16Array = \"~lib/typedarray/Int16Array\";\n export const Uint16Array = \"~lib/typedarray/Uint16Array\";\n export const Int32Array = \"~lib/typedarray/Int32Array\";\n export const Uint32Array = \"~lib/typedarray/Uint32Array\";\n export const Int64Array = \"~lib/typedarray/Int64Array\";\n export const Uint64Array = \"~lib/typedarray/Uint64Array\";\n export const Float32Array = \"~lib/typedarray/Float32Array\";\n export const Float64Array = \"~lib/typedarray/Float64Array\";\n\n // std/string.ts\n export const String_raw = \"~lib/string/String.raw\";\n export const String_eq = \"~lib/string/String.__eq\";\n export const String_ne = \"~lib/string/String.__ne\";\n export const String_not = \"~lib/string/String.__not\";\n\n // std/object.ts\n export const Object = \"~lib/object/Object\";\n}\n\n/** Builtin variable compilation context. */\nexport class BuiltinVariableContext {\n constructor(\n /** Compiler reference. */\n public compiler: Compiler,\n /** Variable being accessed. */\n public element: VariableLikeElement,\n /** Contextual type. */\n public contextualType: Type = element.type,\n /** Respective report expression. */\n public reportNode: IdentifierExpression = element.identifierNode\n ) {}\n}\n\n/** Builtin function compilation context. */\nexport class BuiltinFunctionContext {\n constructor(\n /** Compiler reference. */\n public compiler: Compiler,\n /** Prototype being called. */\n public prototype: FunctionPrototype,\n /** Provided type arguments. */\n public typeArguments: Type[] | null,\n /** Provided operands. */\n public operands: Expression[],\n /** Provided this operand, if any. */\n public thisOperand: Expression | null,\n /** Contextual type. */\n public contextualType: Type,\n /** Respective call expression. */\n public reportNode: CallExpression,\n /** Whether originating from inline assembly. */\n public contextIsExact: bool\n ) {}\n}\n\n/** Builtin functions map. */\nexport const builtinFunctions = new Map ExpressionRef>();\n\n/** Builtin variables map. */\nexport const builtinVariables_onCompile = new Map void>();\nexport const builtinVariables_onAccess = new Map ExpressionRef>();\n\n// === Static type evaluation =================================================================\n\n// helper global used by checkConstantType\nlet checkConstantType_expr: ExpressionRef = 0;\n\n// isBoolean() / isBoolean(value: T) -> bool\nfunction builtin_isBoolean(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isBooleanValue ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isBoolean, builtin_isBoolean);\n\n// isInteger() / isInteger(value: T) -> bool\nfunction builtin_isInteger(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isIntegerValue ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isInteger, builtin_isInteger);\n\n// isSigned() / isSigned(value: T) -> bool\nfunction builtin_isSigned(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isSignedIntegerValue ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isSigned, builtin_isSigned);\n\n// isFloat() / isFloat(value: T) -> bool\nfunction builtin_isFloat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isFloatValue ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isFloat, builtin_isFloat);\n\n// isVector() / isVector(value: T) -> bool\nfunction builtin_isVector(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isVectorValue ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isVector, builtin_isVector);\n\n// isReference() / isReference(value: T) -> bool\nfunction builtin_isReference(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isReference ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isReference, builtin_isReference);\n\n// isString() / isString(value: T) -> bool\nfunction builtin_isString(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n let classReference = type.getClass();\n return reifyConstantType(ctx,\n module.i32(\n classReference && classReference.isAssignableTo(compiler.program.stringInstance)\n ? 1\n : 0\n )\n );\n}\nbuiltinFunctions.set(BuiltinNames.isString, builtin_isString);\n\n// isArray() / isArray(value: T) -> bool\nfunction builtin_isArray(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n let classReference = type.getClass();\n return reifyConstantType(ctx,\n module.i32(\n classReference && classReference.extendsPrototype(compiler.program.arrayPrototype)\n ? 1\n : 0\n )\n );\n}\nbuiltinFunctions.set(BuiltinNames.isArray, builtin_isArray);\n\n// isArrayLike() / isArrayLike(value: T) -> bool\nfunction builtin_isArrayLike(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n let classReference = type.getClass();\n return reifyConstantType(ctx,\n module.i32(\n classReference && classReference.isArrayLike\n ? 1\n : 0\n )\n );\n}\nbuiltinFunctions.set(BuiltinNames.isArrayLike, builtin_isArrayLike);\n\n// isFunction / isFunction(value: T) -> bool\nfunction builtin_isFunction(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isFunction ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isFunction, builtin_isFunction);\n\n// isNullable / isNullable(value: T) -> bool\nfunction builtin_isNullable(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isNullableReference ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isNullable, builtin_isNullable);\n\n// isDefined(expression) -> bool\nfunction builtin_isDefined(ctx: BuiltinFunctionContext): ExpressionRef {\n // Note that `isDefined` neither compiles nor evaluates the given expression\n // but exclusively performs a check whether it can be compiled in theory.\n // This is not exactly unsafe due to only seemingly having side effects which\n // actually never happen, but may confuse tooling unaware of its semantics.\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.bool;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let element = compiler.resolver.lookupExpression(\n ctx.operands[0],\n compiler.currentFlow,\n Type.auto,\n ReportMode.Swallow\n );\n return module.i32(element ? 1 : 0);\n}\nbuiltinFunctions.set(BuiltinNames.isDefined, builtin_isDefined);\n\n// isConstant(expression) -> bool\nfunction builtin_isConstant(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.bool;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let expr = compiler.compileExpression(ctx.operands[0], Type.auto);\n compiler.currentType = Type.bool;\n if (!mustPreserveSideEffects(expr, module.ref)) {\n return module.i32(module.isConstExpression(expr) ? 1 : 0);\n }\n return module.block(null, [\n module.maybeDrop(expr),\n module.i32(0)\n ], getExpressionType(expr));\n}\nbuiltinFunctions.set(BuiltinNames.isConstant, builtin_isConstant);\n\n// isManaged() -> bool\nfunction builtin_isManaged(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.isManaged ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isManaged, builtin_isManaged);\n\n// isVoid() -> bool\nfunction builtin_isVoid(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.bool;\n if (!type) return module.unreachable();\n return reifyConstantType(ctx, module.i32(type.kind == TypeKind.Void ? 1 : 0));\n}\nbuiltinFunctions.set(BuiltinNames.isVoid, builtin_isVoid);\n\n// lengthof() -> i32\nfunction builtin_lengthof(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.i32;\n if (!type) return module.unreachable();\n let signatureReference = type.signatureReference;\n if (!signatureReference) {\n compiler.error(\n DiagnosticCode.Type_0_has_no_call_signatures,\n ctx.reportNode.range, type.toString()\n );\n return module.unreachable();\n }\n return reifyConstantType(ctx, module.i32(signatureReference.parameterTypes.length));\n}\nbuiltinFunctions.set(BuiltinNames.lengthof, builtin_lengthof);\n\n// sizeof() -> usize*\nfunction builtin_sizeof(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = compiler.options.usizeType;\n if (\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 0)\n ) return module.unreachable();\n let type = ctx.typeArguments![0];\n let byteSize = type.byteSize;\n if (!byteSize) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"sizeof\", type.toString()\n );\n return module.unreachable();\n }\n return contextualUsize(compiler, i64_new(byteSize), ctx.contextualType);\n}\nbuiltinFunctions.set(BuiltinNames.sizeof, builtin_sizeof);\n\n// alignof() -> usize*\nfunction builtin_alignof(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = compiler.options.usizeType;\n if (\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 0)\n ) return module.unreachable();\n let type = ctx.typeArguments![0];\n let byteSize = type.byteSize;\n if (!isPowerOf2(byteSize)) { // implies == 0\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"alignof\", type.toString()\n );\n return module.unreachable();\n }\n return contextualUsize(compiler, i64_new(ctz(byteSize)), ctx.contextualType);\n}\nbuiltinFunctions.set(BuiltinNames.alignof, builtin_alignof);\n\n// offsetof(fieldName?: string) -> usize*\nfunction builtin_offsetof(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = compiler.options.usizeType;\n if (\n checkTypeRequired(ctx) |\n checkArgsOptional(ctx, 0, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let contextualType = ctx.contextualType;\n let type = ctx.typeArguments![0];\n let classReference = type.getClassOrWrapper(compiler.program);\n if (!classReference) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"offsetof\", type.toString()\n );\n if (compiler.options.isWasm64) {\n if (contextualType.isIntegerValue && contextualType.size <= 32) {\n compiler.currentType = Type.u32;\n }\n } else {\n if (contextualType.isIntegerValue && contextualType.size == 64) {\n compiler.currentType = Type.u64;\n }\n }\n return module.unreachable();\n }\n if (operands.length) {\n let firstOperand = operands[0];\n if (!firstOperand.isLiteralKind(LiteralKind.String)) {\n compiler.error(\n DiagnosticCode.String_literal_expected,\n operands[0].range\n );\n return module.unreachable();\n }\n let fieldName = (firstOperand).value;\n let fieldMember = classReference.getMember(fieldName);\n if (fieldMember && fieldMember.kind == ElementKind.PropertyPrototype) {\n let property = (fieldMember).instance;\n if (property && property.isField) {\n assert(property.memoryOffset >= 0);\n return contextualUsize(compiler, i64_new(property.memoryOffset), contextualType);\n }\n }\n compiler.error(\n DiagnosticCode.Type_0_has_no_property_1,\n firstOperand.range, classReference.internalName, fieldName\n );\n return module.unreachable();\n }\n return contextualUsize(compiler, i64_new(classReference.nextMemoryOffset), contextualType);\n}\nbuiltinFunctions.set(BuiltinNames.offsetof, builtin_offsetof);\n\n// nameof -> string\nfunction builtin_nameof(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let resultType = checkConstantType(ctx);\n if (!resultType) {\n compiler.currentType = compiler.program.stringInstance.type;\n return module.unreachable();\n }\n let value: string;\n if (resultType.isInternalReference) {\n let classReference = resultType.getClass();\n if (classReference) {\n value = classReference.name;\n } else {\n assert(resultType.getSignature());\n value = \"Function\";\n }\n } else {\n value = resultType.toString();\n }\n return reifyConstantType(ctx, compiler.ensureStaticString(value));\n}\nbuiltinFunctions.set(BuiltinNames.nameof, builtin_nameof);\n\n// idof -> u32\nfunction builtin_idof(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let type = checkConstantType(ctx);\n compiler.currentType = Type.u32;\n if (!type) return module.unreachable();\n let signatureReference = type.getSignature();\n if (signatureReference) {\n return reifyConstantType(ctx, module.i32(signatureReference.id));\n }\n let classReference = type.getClassOrWrapper(compiler.program);\n if (classReference && !classReference.hasDecorator(DecoratorFlags.Unmanaged)) {\n return reifyConstantType(ctx, module.i32(classReference.id));\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"idof\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.idof, builtin_idof);\n\n// bswap(value: T) -> T\nfunction builtin_bswap(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(\n ctx.operands[0],\n typeArguments[0].toUnsigned(),\n Constraints.ConvImplicit | Constraints.MustWrap\n )\n : compiler.compileExpression(\n ctx.operands[0],\n Type.u32,\n Constraints.MustWrap\n );\n\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.U8: return arg0;\n case TypeKind.I16:\n case TypeKind.U16: {\n // (x << 8 | x >> 8)\n let flow = compiler.currentFlow;\n let temp = flow.getTempLocal(type);\n flow.setLocalFlag(temp.index, LocalFlags.Wrapped);\n\n let res = module.binary(\n BinaryOp.OrI32,\n module.binary(\n BinaryOp.ShlI32,\n module.local_tee(temp.index, arg0, false),\n module.i32(8)\n ),\n module.binary(\n BinaryOp.ShrU32,\n module.local_get(temp.index, TypeRef.I32),\n module.i32(8)\n )\n );\n // avoid wrapping for u16 due to it's already done for input arg\n if (type.kind == TypeKind.I16) {\n res = compiler.ensureSmallIntegerWrap(res, Type.i16);\n }\n return res;\n }\n case TypeKind.I32:\n case TypeKind.U32:\n case TypeKind.Isize:\n case TypeKind.Usize: {\n if (type.size == 32) {\n // rotl(x & 0xFF00FF00, 8) | rotr(x & 0x00FF00FF, 8)\n let flow = compiler.currentFlow;\n let temp = flow.getTempLocal(type);\n flow.setLocalFlag(temp.index, LocalFlags.Wrapped);\n\n let res = module.binary(\n BinaryOp.OrI32,\n module.binary(\n BinaryOp.RotlI32,\n module.binary(\n BinaryOp.AndI32,\n module.local_tee(temp.index, arg0, false),\n module.i32(0xFF00FF00)\n ),\n module.i32(8)\n ),\n module.binary(\n BinaryOp.RotrI32,\n module.binary(\n BinaryOp.AndI32,\n module.local_get(temp.index, TypeRef.I32),\n module.i32(0x00FF00FF)\n ),\n module.i32(8)\n ),\n );\n return res;\n }\n // fall-through\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n // let t =\n // ((x >>> 8) & 0x00FF00FF00FF00FF) |\n // ((x & 0x00FF00FF00FF00FF) << 8)\n //\n // let res =\n // ((t >>> 16) & 0x0000FFFF0000FFFF) |\n // ((t & 0x0000FFFF0000FFFF) << 16)\n //\n // rotr(res, 32)\n\n let flow = compiler.currentFlow;\n let temp1 = flow.getTempLocal(type);\n flow.setLocalFlag(temp1.index, LocalFlags.Wrapped);\n let temp2 = flow.getTempLocal(type);\n flow.setLocalFlag(temp2.index, LocalFlags.Wrapped);\n\n // t = ((x >>> 8) & 0x00FF00FF00FF00FF) | ((x & 0x00FF00FF00FF00FF) << 8)\n let expr = module.local_tee(\n temp2.index,\n module.binary(\n BinaryOp.OrI64,\n module.binary(\n BinaryOp.AndI64,\n module.binary(\n BinaryOp.ShrU64,\n module.local_tee(temp1.index, arg0, false),\n module.i64(8)\n ),\n module.i64(0x00FF00FF, 0x00FF00FF)\n ),\n module.binary(\n BinaryOp.ShlI64,\n module.binary(\n BinaryOp.AndI64,\n module.local_get(temp1.index, TypeRef.I64),\n module.i64(0x00FF00FF, 0x00FF00FF)\n ),\n module.i64(8)\n ),\n ),\n false\n );\n\n // ((t >>> 16) & 0x0000FFFF0000FFFF) | ((t & 0x0000FFFF0000FFFF) << 16)\n let res = module.binary(\n BinaryOp.OrI64,\n module.binary(\n BinaryOp.AndI64,\n module.binary(\n BinaryOp.ShrU64,\n expr,\n module.i64(16)\n ),\n module.i64(0x0000FFFF, 0x0000FFFF)\n ),\n module.binary(\n BinaryOp.ShlI64,\n module.binary(\n BinaryOp.AndI64,\n module.local_get(temp2.index, TypeRef.I64),\n module.i64(0x0000FFFF, 0x0000FFFF)\n ),\n module.i64(16)\n ),\n );\n\n // rotr(res, 32)\n res = module.binary(\n BinaryOp.RotrI64,\n res,\n module.i64(32)\n );\n return res;\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"bswap\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.bswap, builtin_bswap);\n\n// === Math ===================================================================================\n\n// NaN\nfunction builtin_NaN_compile(ctx: BuiltinVariableContext): void {\n let element = ctx.element;\n if (element.is(CommonFlags.ModuleExport)) {\n let module = ctx.compiler.module;\n module.addGlobal(element.internalName, TypeRef.F64, false, module.f64(NaN));\n }\n}\nbuiltinVariables_onCompile.set(BuiltinNames.NaN, builtin_NaN_compile);\n\n// NaN -> f32 | f64\nfunction builtin_NaN_access(ctx: BuiltinVariableContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (ctx.contextualType == Type.f32) {\n compiler.currentType = Type.f32;\n return module.f32(NaN);\n }\n compiler.currentType = Type.f64;\n return module.f64(NaN);\n}\nbuiltinVariables_onAccess.set(BuiltinNames.NaN, builtin_NaN_access);\n\n// Infinity\nfunction builtin_Infinity_compile(ctx: BuiltinVariableContext): void {\n let element = ctx.element;\n if (element.is(CommonFlags.ModuleExport)) {\n let module = ctx.compiler.module;\n module.addGlobal(element.internalName, TypeRef.F64, false, module.f64(Infinity));\n }\n}\nbuiltinVariables_onCompile.set(BuiltinNames.Infinity, builtin_Infinity_compile);\n\n// Infinity -> f32 | f64\nfunction builtin_Infinity_access(ctx: BuiltinVariableContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (ctx.contextualType == Type.f32) {\n compiler.currentType = Type.f32;\n return module.f32(Infinity);\n }\n compiler.currentType = Type.f64;\n return module.f64(Infinity);\n}\nbuiltinVariables_onAccess.set(BuiltinNames.Infinity, builtin_Infinity_access);\n\n// clz(value: T) -> T\nfunction builtin_clz(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(ctx.operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(ctx.operands[0], Type.i32, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool: // not wrapped\n case TypeKind.I8:\n case TypeKind.U8:\n case TypeKind.I16:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.ClzI32, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.unary(UnaryOp.ClzSize, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.ClzI64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"clz\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.clz, builtin_clz);\n\n// ctz(value: T) -> T\nfunction builtin_ctz(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.i32, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool: // not wrapped\n case TypeKind.I8:\n case TypeKind.U8:\n case TypeKind.I16:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.CtzI32, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.unary(UnaryOp.CtzSize, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.CtzI64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"ctz\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.ctz, builtin_ctz);\n\n// popcnt(value: T) -> T\nfunction builtin_popcnt(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.i32, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (compiler.currentType.kind) {\n case TypeKind.Bool: return arg0;\n case TypeKind.I8: // not wrapped\n case TypeKind.U8:\n case TypeKind.I16:\n case TypeKind.U16:\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.PopcntI32, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.PopcntI64, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.unary(UnaryOp.PopcntSize, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"popcnt\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.popcnt, builtin_popcnt);\n\n// rotl(value: T, shift: T) -> T\nfunction builtin_rotl(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.i32, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit);\n switch (type.kind) {\n case TypeKind.Bool: return arg0;\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n // (value << (shift & mask)) | (value >>> ((0 - shift) & mask))\n let flow = compiler.currentFlow;\n let temp1 = flow.getTempLocal(type);\n flow.setLocalFlag(temp1.index, LocalFlags.Wrapped);\n let temp2 = flow.getTempLocal(type);\n flow.setLocalFlag(temp2.index, LocalFlags.Wrapped);\n\n let ret = module.binary(BinaryOp.OrI32,\n module.binary(\n BinaryOp.ShlI32,\n module.local_tee(temp1.index, arg0, false), // i32\n module.binary(\n BinaryOp.AndI32,\n module.local_tee(temp2.index, arg1, false), // i32\n module.i32(type.size - 1)\n )\n ),\n module.binary(\n BinaryOp.ShrU32,\n module.local_get(temp1.index, TypeRef.I32),\n module.binary(\n BinaryOp.AndI32,\n module.binary(\n BinaryOp.SubI32,\n module.i32(0),\n module.local_get(temp2.index, TypeRef.I32)\n ),\n module.i32(type.size - 1)\n )\n )\n );\n\n return ret;\n }\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.RotlI32, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.RotlI64, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.RotlSize, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"rotl\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.rotl, builtin_rotl);\n\n// rotr(value: T, shift: T) -> T\nfunction builtin_rotr(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.i32, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit);\n switch (type.kind) {\n case TypeKind.Bool: return arg0;\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.U8:\n case TypeKind.U16: {\n // (value >>> (shift & mask)) | (value << ((0 - shift) & mask))\n let flow = compiler.currentFlow;\n let temp1 = flow.getTempLocal(type);\n flow.setLocalFlag(temp1.index, LocalFlags.Wrapped);\n let temp2 = flow.getTempLocal(type);\n flow.setLocalFlag(temp2.index, LocalFlags.Wrapped);\n\n let ret = module.binary(BinaryOp.OrI32,\n module.binary(\n BinaryOp.ShrU32,\n module.local_tee(temp1.index, arg0, false), // i32\n module.binary(\n BinaryOp.AndI32,\n module.local_tee(temp2.index, arg1, false), // i32\n module.i32(type.size - 1)\n )\n ),\n module.binary(\n BinaryOp.ShlI32,\n module.local_get(temp1.index, TypeRef.I32),\n module.binary(\n BinaryOp.AndI32,\n module.binary(\n BinaryOp.SubI32,\n module.i32(0),\n module.local_get(temp2.index, TypeRef.I32)\n ),\n module.i32(type.size - 1)\n )\n )\n );\n\n return ret;\n }\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.RotrI32, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.RotrI64, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(BinaryOp.RotrSize, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"rotr\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.rotr, builtin_rotr);\n\n// abs(value: T) -> T\nfunction builtin_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return arg0;\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32: {\n let flow = compiler.currentFlow;\n\n // possibly overflows, e.g. abs(-128) == 128\n let temp1 = flow.getTempLocal(Type.i32);\n let temp2 = flow.getTempLocal(Type.i32);\n // (x + (x >> 31)) ^ (x >> 31)\n let ret = module.binary(BinaryOp.XorI32,\n module.binary(BinaryOp.AddI32,\n module.local_tee(\n temp2.index,\n module.binary(BinaryOp.ShrI32,\n module.local_tee(temp1.index, arg0, false), // i32\n module.i32(31)\n ),\n false // i32\n ),\n module.local_get(temp1.index, TypeRef.I32)\n ),\n module.local_get(temp2.index, TypeRef.I32)\n );\n return ret;\n }\n case TypeKind.Isize: {\n let options = compiler.options;\n let flow = compiler.currentFlow;\n\n let temp1 = flow.getTempLocal(options.usizeType);\n let temp2 = flow.getTempLocal(options.usizeType);\n let ret = module.binary(BinaryOp.XorSize,\n module.binary(BinaryOp.AddSize,\n module.local_tee(\n temp2.index,\n module.binary(BinaryOp.ShrISize,\n module.local_tee(temp1.index, arg0, false), // i32/i64\n compiler.options.isWasm64\n ? module.i64(63)\n : module.i32(31)\n ),\n false // i32/i64\n ),\n module.local_get(temp1.index, options.sizeTypeRef)\n ),\n module.local_get(temp2.index, options.sizeTypeRef)\n );\n return ret;\n }\n case TypeKind.I64: {\n let flow = compiler.currentFlow;\n\n let temp1 = flow.getTempLocal(Type.i64);\n let temp2 = flow.getTempLocal(Type.i64);\n // (x + (x >> 63)) ^ (x >> 63)\n let ret = module.binary(BinaryOp.XorI64,\n module.binary(BinaryOp.AddI64,\n module.local_tee(\n temp2.index,\n module.binary(BinaryOp.ShrI64,\n module.local_tee(temp1.index, arg0, false), // i64\n module.i64(63)\n ),\n false // i64\n ),\n module.local_get(temp1.index, TypeRef.I64)\n ),\n module.local_get(temp2.index, TypeRef.I64)\n );\n return ret;\n }\n case TypeKind.F32: return module.unary(UnaryOp.AbsF32, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.AbsF64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"abs\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.abs, builtin_abs);\n\n// max(left: T, right: T) -> T\nfunction builtin_max(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(left, typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) { // prefer right type\n arg1 = compiler.compileExpression(operands[1], type, Constraints.MustWrap);\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(left, type = compiler.currentType, Constraints.ConvImplicit | Constraints.MustWrap);\n }\n } else {\n arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit | Constraints.MustWrap);\n }\n let op: BinaryOp = -1;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32: { op = BinaryOp.GtI32; break; }\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: { op = BinaryOp.GtU32; break; }\n case TypeKind.I64: { op = BinaryOp.GtI64; break; }\n case TypeKind.U64: { op = BinaryOp.GtU64; break; }\n case TypeKind.Isize: { op = BinaryOp.GtISize; break; }\n case TypeKind.Usize: { op = BinaryOp.GtUSize; break; }\n case TypeKind.F32: return module.binary(BinaryOp.MaxF32, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.MaxF64, arg0, arg1);\n }\n if (op as i32 != -1) {\n let flow = compiler.currentFlow;\n let typeRef = type.toRef();\n let temp1 = flow.getTempLocal(type);\n flow.setLocalFlag(temp1.index, LocalFlags.Wrapped);\n let temp2 = flow.getTempLocal(type);\n flow.setLocalFlag(temp2.index, LocalFlags.Wrapped);\n let ret = module.select(\n module.local_tee(temp1.index, arg0, false), // numeric\n module.local_tee(temp2.index, arg1, false), // numeric\n module.binary(op,\n module.local_get(temp1.index, typeRef),\n module.local_get(temp2.index, typeRef)\n ),\n typeRef\n );\n return ret;\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"max\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.max, builtin_max);\n\n// min(left: T, right: T) -> T\nfunction builtin_min(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(left, typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.MustWrap);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) { // prefer right type\n arg1 = compiler.compileExpression(operands[1], type, Constraints.MustWrap);\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(left, type = compiler.currentType, Constraints.ConvImplicit | Constraints.MustWrap);\n }\n } else {\n arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit | Constraints.MustWrap);\n }\n let op: BinaryOp = -1;\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32: { op = BinaryOp.LtI32; break; }\n case TypeKind.Bool:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: { op = BinaryOp.LtU32; break; }\n case TypeKind.I64: { op = BinaryOp.LtI64; break; }\n case TypeKind.U64: { op = BinaryOp.LtU64; break; }\n case TypeKind.Isize: { op = BinaryOp.LtISize; break; }\n case TypeKind.Usize: { op = BinaryOp.LtUSize; break; }\n case TypeKind.F32: return module.binary(BinaryOp.MinF32, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.MinF64, arg0, arg1);\n }\n if (op as i32 != -1) {\n let flow = compiler.currentFlow;\n let typeRef = type.toRef();\n let temp1 = flow.getTempLocal(type);\n flow.setLocalFlag(temp1.index, LocalFlags.Wrapped);\n let temp2 = flow.getTempLocal(type);\n flow.setLocalFlag(temp2.index, LocalFlags.Wrapped);\n let ret = module.select(\n module.local_tee(temp1.index, arg0, false), // numeric\n module.local_tee(temp2.index, arg1, false), // numeric\n module.binary(op,\n module.local_get(temp1.index, typeRef),\n module.local_get(temp2.index, typeRef)\n ),\n typeRef\n );\n return ret;\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"min\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.min, builtin_min);\n\n// ceil(value: T) -> T\nfunction builtin_ceil(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.None);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return arg0; // considered rounded\n case TypeKind.F32: return module.unary(UnaryOp.CeilF32, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.CeilF64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"ceil\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.ceil, builtin_ceil);\n\n// floor(value: T) -> T\nfunction builtin_floor(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.None);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return arg0; // considered rounded\n case TypeKind.F32: return module.unary(UnaryOp.FloorF32, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.FloorF64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"floor\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.floor, builtin_floor);\n\n// copysign(left: T, right: T) -> T\nfunction builtin_copysign(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.f64, Constraints.None);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit);\n switch (type.kind) {\n // TODO: does an integer version make sense?\n case TypeKind.F32: return module.binary(BinaryOp.CopysignF32, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.CopysignF64, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"copysign\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.copysign, builtin_copysign);\n\n// nearest(value: T) -> T\nfunction builtin_nearest(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.None);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return arg0;\n case TypeKind.F32: return module.unary(UnaryOp.NearestF32, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.NearestF64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"nearest\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.nearest, builtin_nearest);\n\n// reinterpret(value: *) -> T\nfunction builtin_reinterpret(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeRequired(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let type = typeArguments![0];\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I32:\n case TypeKind.U32: {\n let arg0 = compiler.compileExpression(operands[0], Type.f32, Constraints.ConvImplicit);\n compiler.currentType = type;\n return module.unary(UnaryOp.ReinterpretF32ToI32, arg0);\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n let arg0 = compiler.compileExpression(operands[0], Type.f64, Constraints.ConvImplicit);\n compiler.currentType = type;\n return module.unary(UnaryOp.ReinterpretF64ToI64, arg0);\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n let isWasm64 = compiler.options.isWasm64;\n let arg0 = compiler.compileExpression(operands[0],\n isWasm64 ? Type.f64 : Type.f32,\n Constraints.ConvImplicit\n );\n compiler.currentType = type;\n return module.unary(\n isWasm64\n ? UnaryOp.ReinterpretF64ToI64\n : UnaryOp.ReinterpretF32ToI32,\n arg0\n );\n }\n case TypeKind.F32: {\n let arg0 = compiler.compileExpression(operands[0], Type.i32, Constraints.ConvImplicit);\n compiler.currentType = Type.f32;\n return module.unary(UnaryOp.ReinterpretI32ToF32, arg0);\n }\n case TypeKind.F64: {\n let arg0 = compiler.compileExpression(operands[0], Type.i64, Constraints.ConvImplicit);\n compiler.currentType = Type.f64;\n return module.unary(UnaryOp.ReinterpretI64ToF64, arg0);\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"reinterpret\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.reinterpret, builtin_reinterpret);\n\n// sqrt(value: T) -> T\nfunction builtin_sqrt(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.f64, Constraints.None);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n // TODO: integer versions (that return f64 or convert)?\n case TypeKind.F32: return module.unary(UnaryOp.SqrtF32, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.SqrtF64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"sqrt\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.sqrt, builtin_sqrt);\n\n// trunc(value: T) -> T\nfunction builtin_trunc(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto, Constraints.None);\n let type = compiler.currentType;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return arg0; // considered truncated\n case TypeKind.F32: return module.unary(UnaryOp.TruncF32, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.TruncF64, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"trunc\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.trunc, builtin_trunc);\n\n// isNaN(value: T) -> bool\nfunction builtin_isNaN(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.bool;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n compiler.currentType = Type.bool;\n if (type.isValue) {\n switch (type.kind) {\n // never NaN\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: {\n return module.maybeDropCondition(arg0, module.i32(0));\n }\n // (t = arg0) != t\n case TypeKind.F32: {\n if (getExpressionId(arg0) == ExpressionId.LocalGet) {\n return module.binary(BinaryOp.NeF32,\n arg0,\n module.local_get(getLocalGetIndex(arg0), TypeRef.F32)\n );\n }\n let flow = compiler.currentFlow;\n let temp = flow.getTempLocal(Type.f32);\n let ret = module.binary(BinaryOp.NeF32,\n module.local_tee(temp.index, arg0, false), // f32\n module.local_get(temp.index, TypeRef.F32)\n );\n return ret;\n }\n case TypeKind.F64: {\n if (getExpressionId(arg0) == ExpressionId.LocalGet) {\n return module.binary(BinaryOp.NeF64,\n arg0,\n module.local_get(getLocalGetIndex(arg0), TypeRef.F64)\n );\n }\n let flow = compiler.currentFlow;\n let temp = flow.getTempLocal(Type.f64);\n let ret = module.binary(BinaryOp.NeF64,\n module.local_tee(temp.index, arg0, false), // f64\n module.local_get(temp.index, TypeRef.F64)\n );\n return ret;\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"isNaN\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.isNaN, builtin_isNaN);\n\n// isFinite(value: T) -> bool\nfunction builtin_isFinite(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.bool;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n compiler.currentType = Type.bool;\n if (type.isValue) {\n switch (type.kind) {\n // always finite\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: {\n return module.maybeDropCondition(arg0, module.i32(1));\n }\n // (t = arg0) - t == 0\n case TypeKind.F32: {\n if (getExpressionId(arg0) == ExpressionId.LocalGet) {\n return module.binary(BinaryOp.EqF32,\n module.binary(BinaryOp.SubF32,\n arg0,\n module.local_get(getLocalGetIndex(arg0), TypeRef.F32)\n ),\n module.f32(0)\n );\n }\n let flow = compiler.currentFlow;\n let temp = flow.getTempLocal(Type.f32);\n let ret = module.binary(BinaryOp.EqF32,\n module.binary(BinaryOp.SubF32,\n module.local_tee(temp.index, arg0, false), // f32\n module.local_get(temp.index, TypeRef.F32)\n ),\n module.f32(0)\n );\n return ret;\n }\n case TypeKind.F64: {\n if (getExpressionId(arg0) == ExpressionId.LocalGet) {\n return module.binary(BinaryOp.EqF64,\n module.binary(BinaryOp.SubF64,\n arg0,\n module.local_get(getLocalGetIndex(arg0), TypeRef.F64)\n ),\n module.f64(0)\n );\n }\n let flow = compiler.currentFlow;\n let temp = flow.getTempLocal(Type.f64);\n let ret = module.binary(BinaryOp.EqF64,\n module.binary(BinaryOp.SubF64,\n module.local_tee(temp.index, arg0, false), // f64\n module.local_get(temp.index, TypeRef.F64)\n ),\n module.f64(0)\n );\n return ret;\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"isFinite\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.isFinite, builtin_isFinite);\n\n// === Memory access ==========================================================================\n\n// __heap_base\nfunction builtin_heap_base_compile(ctx: BuiltinVariableContext): void {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Heap;\n module.addGlobal(element.internalName, type.toRef(), true, compiler.makeZero(type)); // dummy\n}\nbuiltinVariables_onCompile.set(BuiltinNames.heap_base, builtin_heap_base_compile);\n\n// __heap_base -> usize\nfunction builtin_heap_base_access(ctx: BuiltinVariableContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Heap;\n compiler.currentType = type;\n return module.global_get(element.internalName, type.toRef());\n}\nbuiltinVariables_onAccess.set(BuiltinNames.heap_base, builtin_heap_base_access);\n\n// __data_end\nfunction builtin_data_end_compile(ctx: BuiltinVariableContext): void {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Data;\n module.addGlobal(element.internalName, type.toRef(), true, compiler.makeZero(type)); // dummy\n}\nbuiltinVariables_onCompile.set(BuiltinNames.data_end, builtin_data_end_compile);\n\n// __data_end -> usize\nfunction builtin_data_end_access(ctx: BuiltinVariableContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Data;\n compiler.currentType = type;\n return module.global_get(element.internalName, type.toRef());\n}\nbuiltinVariables_onAccess.set(BuiltinNames.data_end, builtin_data_end_access);\n\n// __stack_pointer\nfunction builtin_stack_pointer_compile(ctx: BuiltinVariableContext): void {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Stack;\n module.addGlobal(element.internalName, type.toRef(), true, compiler.makeZero(type)); // dummy\n}\nbuiltinVariables_onCompile.set(BuiltinNames.stack_pointer, builtin_stack_pointer_compile);\n\n// __stack_pointer -> usize\nfunction builtin_stack_pointer_access(ctx: BuiltinVariableContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Stack;\n compiler.currentType = type;\n return module.global_get(element.internalName, type.toRef());\n}\nbuiltinVariables_onAccess.set(BuiltinNames.stack_pointer, builtin_stack_pointer_access);\n\n// __rtti_base\nfunction builtin_rtti_base_compile(ctx: BuiltinVariableContext): void {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Rtti;\n module.addGlobal(element.internalName, type.toRef(), true, compiler.makeZero(type)); // dummy\n}\nbuiltinVariables_onCompile.set(BuiltinNames.rtti_base, builtin_rtti_base_compile);\n\n// __rtti_base -> usize\nfunction builtin_rtti_base_access(ctx: BuiltinVariableContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let element = ctx.element;\n let type = element.type;\n compiler.runtimeFeatures |= RuntimeFeatures.Rtti;\n compiler.currentType = type;\n return module.global_get(element.internalName, type.toRef());\n}\nbuiltinVariables_onAccess.set(BuiltinNames.rtti_base, builtin_rtti_base_access);\n\n// load(offset: usize, immOffset?: usize, immAlign?: usize) -> T*\nfunction builtin_load(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 1, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let contextualType = ctx.contextualType;\n let type = typeArguments![0];\n\n let outType = (\n contextualType != Type.auto &&\n type.isIntegerValue &&\n contextualType.isIntegerValue &&\n contextualType.size > type.size\n ) ? contextualType : type;\n\n if (!outType.isMemory) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"load\", outType.toString()\n );\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let numOperands = operands.length;\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 2) {\n immOffset = evaluateImmediateOffset(operands[1], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = outType;\n return module.unreachable();\n }\n if (numOperands == 3) {\n immAlign = evaluateImmediateAlign(operands[2], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = outType;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = outType;\n return module.load(\n type.byteSize,\n type.isSignedIntegerValue,\n arg0,\n outType.toRef(),\n immOffset,\n immAlign\n );\n}\nbuiltinFunctions.set(BuiltinNames.load, builtin_load);\n\n// store(ptr: usize, value: T*, immOffset?: usize, immAlign?: usize) -> void\nfunction builtin_store(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.void;\n if (\n checkTypeRequired(ctx) |\n checkArgsOptional(ctx, 2, 4)\n ) return module.unreachable();\n let operands = ctx.operands;\n let numOperands = operands.length;\n let typeArguments = ctx.typeArguments;\n let contextualType = ctx.contextualType;\n let type = typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = ctx.contextIsExact\n ? compiler.compileExpression(operands[1],\n contextualType,\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(\n operands[1],\n type,\n type.isIntegerValue\n ? Constraints.None // no need to convert to small int (but now might result in a float)\n : Constraints.ConvImplicit\n );\n let inType = compiler.currentType;\n if (!inType.isMemory) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"store\", inType.toString()\n );\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n if (\n type.isIntegerValue &&\n (\n !inType.isIntegerValue || // float to int\n inType.size < type.size // int to larger int (clear garbage bits)\n )\n ) {\n // either conversion or memory operation clears garbage bits\n arg1 = compiler.convertExpression(arg1, inType, type, false, operands[1]);\n inType = type;\n }\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 3) {\n immOffset = evaluateImmediateOffset(operands[2], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n if (numOperands == 4) {\n immAlign = evaluateImmediateAlign(operands[3], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = Type.void;\n return module.store(type.byteSize, arg0, arg1, inType.toRef(), immOffset, immAlign);\n}\nbuiltinFunctions.set(BuiltinNames.store, builtin_store);\n\n// rem(left: T, right: T) -> T\nfunction builtin_rem(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isIntegerValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isIntegerValue) {\n return compiler.makeRem(arg0, arg1, type, ctx.reportNode);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"rem\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.rem, builtin_rem);\n\n// add(left: T, right: T) -> T\nfunction builtin_add(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isNumericValue) {\n return compiler.makeAdd(arg0, arg1, type);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"add\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.add, builtin_add);\n\n// sub(left: T, right: T) -> T\nfunction builtin_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isNumericValue) {\n return compiler.makeSub(arg0, arg1, type);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"sub\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.sub, builtin_sub);\n\n// mul(left: T, right: T) -> T\nfunction builtin_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isNumericValue) {\n return compiler.makeMul(arg0, arg1, type);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"mul\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.mul, builtin_mul);\n\n// div(left: T, right: T) -> T\nfunction builtin_div(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isNumericValue) {\n return compiler.makeDiv(arg0, arg1, type);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"div\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.div, builtin_div);\n\n// eq(left: T, right: T) -> i32\nfunction builtin_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isNumericValue) {\n compiler.currentType = Type.i32;\n return compiler.makeEq(arg0, arg1, type, ctx.reportNode);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"eq\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.eq, builtin_eq);\n\n// ne(left: T, right: T) -> i32\nfunction builtin_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (checkTypeOptional(ctx, true) | checkArgsRequired(ctx, 2)) {\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let left = operands[0];\n let arg0 = typeArguments\n ? compiler.compileExpression(\n left,\n typeArguments[0],\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (type.isValue) {\n let arg1: ExpressionRef;\n if (!typeArguments && left.isNumericLiteral) {\n // prefer right type\n arg1 = compiler.compileExpression(\n operands[1],\n type\n );\n if (compiler.currentType != type) {\n arg0 = compiler.compileExpression(\n left,\n (type = compiler.currentType),\n Constraints.ConvImplicit\n );\n }\n } else {\n arg1 = compiler.compileExpression(\n operands[1],\n type,\n Constraints.ConvImplicit\n );\n }\n if (type.isNumericValue) {\n compiler.currentType = Type.i32;\n return compiler.makeNe(arg0, arg1, type, ctx.reportNode);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"ne\",\n type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.ne, builtin_ne);\n\n// === Atomics ================================================================================\n\n// atomic.load(offset: usize, immOffset?: usize) -> T*\nfunction builtin_atomic_load(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 1, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let contextualType = ctx.contextualType;\n let type = typeArguments![0];\n let outType = (\n type.isIntegerValue &&\n contextualType.isIntegerValue &&\n contextualType.size > type.size\n ) ? contextualType : type;\n if (!type.isIntegerValue) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"atomic.load\", type.toString()\n );\n compiler.currentType = outType;\n return module.unreachable();\n }\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let immOffset = operands.length == 2 ? evaluateImmediateOffset(operands[1], compiler) : 0; // reports\n if (immOffset < 0) {\n compiler.currentType = outType;\n return module.unreachable();\n }\n compiler.currentType = outType;\n return module.atomic_load(\n type.byteSize,\n arg0,\n outType.toRef(),\n immOffset\n );\n}\nbuiltinFunctions.set(BuiltinNames.atomic_load, builtin_atomic_load);\n\n// atomic.store(offset: usize, value: T*, immOffset?: usize) -> void\nfunction builtin_atomic_store(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeRequired(ctx) |\n checkArgsOptional(ctx, 2, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let contextualType = ctx.contextualType;\n let type = typeArguments![0];\n if (!type.isIntegerValue) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"atomic.store\", type.toString()\n );\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = ctx.contextIsExact\n ? compiler.compileExpression(\n operands[1],\n contextualType,\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(\n operands[1],\n type,\n type.isIntegerValue\n ? Constraints.None // no need to convert to small int (but now might result in a float)\n : Constraints.ConvImplicit\n );\n let inType = compiler.currentType;\n if (\n type.isIntegerValue &&\n (\n !inType.isIntegerValue|| // float to int\n inType.size < type.size // int to larger int (clear garbage bits)\n )\n ) {\n // either conversion or memory operation clears garbage bits\n arg1 = compiler.convertExpression(arg1, inType, type, false, operands[1]);\n inType = type;\n }\n let immOffset = operands.length == 3 ? evaluateImmediateOffset(operands[2], compiler) : 0; // reports\n if (immOffset < 0) {\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n compiler.currentType = Type.void;\n return module.atomic_store(type.byteSize, arg0, arg1, inType.toRef(), immOffset);\n}\nbuiltinFunctions.set(BuiltinNames.atomic_store, builtin_atomic_store);\n\n// any_atomic_binary(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_binary(ctx: BuiltinFunctionContext, op: AtomicRMWOp, opName: string): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 2, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let contextualType = ctx.contextualType;\n let type = typeArguments![0];\n if (!type.isIntegerValue || type.size < 8) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, opName, type.toString()\n );\n return module.unreachable();\n }\n let arg0 = compiler.compileExpression(operands[0],\n compiler.options.usizeType,\n Constraints.ConvImplicit\n );\n let arg1 = ctx.contextIsExact\n ? compiler.compileExpression(operands[1],\n contextualType,\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(\n operands[1],\n type,\n type.isIntegerValue\n ? Constraints.None // no need to convert to small int (but now might result in a float)\n : Constraints.ConvImplicit\n );\n let inType = compiler.currentType;\n if (\n type.isIntegerValue &&\n (\n !inType.isIntegerValue || // float to int\n inType.size < type.size // int to larger int (clear garbage bits)\n )\n ) {\n // either conversion or memory operation clears garbage bits\n arg1 = compiler.convertExpression(arg1, inType, type, false, operands[1]);\n inType = type;\n }\n let immOffset = operands.length == 3 ? evaluateImmediateOffset(operands[2], compiler) : 0; // reports\n if (immOffset < 0) {\n compiler.currentType = inType;\n return module.unreachable();\n }\n compiler.currentType = inType;\n return module.atomic_rmw(op, type.byteSize, immOffset, arg0, arg1, inType.toRef());\n}\n\n// atomic.add(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_add(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_atomic_binary(ctx, AtomicRMWOp.Add, \"atomic.add\");\n}\nbuiltinFunctions.set(BuiltinNames.atomic_add, builtin_atomic_add);\n\n// atomic.sub(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_atomic_binary(ctx, AtomicRMWOp.Sub, \"atomic.sub\");\n}\nbuiltinFunctions.set(BuiltinNames.atomic_sub, builtin_atomic_sub);\n\n// atomic.and(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_and(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_atomic_binary(ctx, AtomicRMWOp.And, \"atomic.and\");\n}\nbuiltinFunctions.set(BuiltinNames.atomic_and, builtin_atomic_and);\n\n// atomic.or(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_or(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_atomic_binary(ctx, AtomicRMWOp.Or, \"atomic.or\");\n}\nbuiltinFunctions.set(BuiltinNames.atomic_or, builtin_atomic_or);\n\n// atomic.xor(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_xor(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_atomic_binary(ctx, AtomicRMWOp.Xor, \"atomic.xor\");\n}\nbuiltinFunctions.set(BuiltinNames.atomic_xor, builtin_atomic_xor);\n\n// atomic.xchg(ptr, value: T, immOffset?: usize) -> T\nfunction builtin_atomic_xchg(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_atomic_binary(ctx, AtomicRMWOp.Xchg, \"atomic.xchg\");\n}\nbuiltinFunctions.set(BuiltinNames.atomic_xchg, builtin_atomic_xchg);\n\n// atomic.cmpxchg(ptr: usize, expected: T, replacement: T, off?: usize) -> T\nfunction builtin_atomic_cmpxchg(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 3, 4)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let contextualType = ctx.contextualType;\n let type = typeArguments![0];\n if (!type.isIntegerValue || type.size < 8) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"atomic.cmpxchg\", type.toString()\n );\n return module.unreachable();\n }\n let arg0 = compiler.compileExpression(operands[0],\n compiler.options.usizeType,\n Constraints.ConvImplicit\n );\n let arg1 = ctx.contextIsExact\n ? compiler.compileExpression(operands[1],\n contextualType,\n Constraints.ConvImplicit\n )\n : compiler.compileExpression(\n operands[1],\n type,\n type.isIntegerValue\n ? Constraints.None // no need to convert to small int (but now might result in a float)\n : Constraints.ConvImplicit\n );\n let inType = compiler.currentType;\n let arg2 = compiler.compileExpression(operands[2],\n inType,\n Constraints.ConvImplicit\n );\n if (\n type.isIntegerValue &&\n (\n !inType.isIntegerValue || // float to int\n inType.size < type.size // int to larger int (clear garbage bits)\n )\n ) {\n // either conversion or memory operation clears garbage bits\n arg1 = compiler.convertExpression(arg1, inType, type, false, operands[1]);\n arg2 = compiler.convertExpression(arg2, inType, type, false, operands[2]);\n inType = type;\n }\n let immOffset = operands.length == 4 ? evaluateImmediateOffset(operands[3], compiler) : 0; // reports\n if (immOffset < 0) {\n compiler.currentType = inType;\n return module.unreachable();\n }\n compiler.currentType = inType;\n return module.atomic_cmpxchg(type.byteSize, immOffset, arg0, arg1, arg2, inType.toRef());\n}\nbuiltinFunctions.set(BuiltinNames.atomic_cmpxchg, builtin_atomic_cmpxchg);\n\n// atomic.wait(ptr: usize, expected: T, timeout?: i64) -> i32\nfunction builtin_atomic_wait(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeRequired(ctx) |\n checkArgsOptional(ctx, 2, 3)\n ) {\n compiler.currentType = Type.i32;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let type = typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit);\n let arg2 = operands.length == 3\n ? compiler.compileExpression(operands[2], Type.i64, Constraints.ConvImplicit)\n : module.i64(-1, -1); // Infinite timeout\n compiler.currentType = Type.i32;\n switch (type.kind) {\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return module.atomic_wait(arg0, arg1, arg2, type.toRef());\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"atomic.wait\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.atomic_wait, builtin_atomic_wait);\n\n// atomic.notify(ptr: usize, count?: i32) -> i32\nfunction builtin_atomic_notify(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeAbsent(ctx) |\n checkArgsOptional(ctx, 1, 2)\n ) {\n compiler.currentType = Type.i32;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = operands.length == 2\n ? compiler.compileExpression(operands[1], Type.i32, Constraints.ConvImplicit)\n : module.i32(-1); // Inifinity count of waiters\n compiler.currentType = Type.i32;\n return module.atomic_notify(arg0, arg1);\n}\nbuiltinFunctions.set(BuiltinNames.atomic_notify, builtin_atomic_notify);\n\n// atomic.fence() -> void\nfunction builtin_atomic_fence(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.void;\n if (\n checkFeatureEnabled(ctx, Feature.Threads) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 0)\n ) return module.unreachable();\n return module.atomic_fence();\n}\nbuiltinFunctions.set(BuiltinNames.atomic_fence, builtin_atomic_fence);\n\n// === Control flow ===========================================================================\n\n// select(ifTrue: T, ifFalse: T, condition: bool) -> T\nfunction builtin_select(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsRequired(ctx, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit)\n : compiler.compileExpression(operands[0], Type.auto);\n let type = compiler.currentType;\n if (!type.isAny(TypeFlags.Value | TypeFlags.Reference)) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"select\", type.toString()\n );\n return module.unreachable();\n }\n let arg1 = compiler.compileExpression(operands[1], type, Constraints.ConvImplicit);\n let arg2 = compiler.makeIsTrueish(\n compiler.compileExpression(operands[2], Type.bool),\n compiler.currentType, // ^\n operands[2]\n );\n compiler.currentType = type;\n return module.select(arg0, arg1, arg2, type.toRef());\n}\nbuiltinFunctions.set(BuiltinNames.select, builtin_select);\n\n// unreachable() -> *\nfunction builtin_unreachable(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n checkArgsRequired(ctx, 0);\n return ctx.compiler.module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.unreachable, builtin_unreachable);\n\n// === Memory =================================================================================\n\n// memory.size() -> i32\nfunction builtin_memory_size(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.i32;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 0)\n ) return module.unreachable();\n return module.memory_size();\n}\nbuiltinFunctions.set(BuiltinNames.memory_size, builtin_memory_size);\n\n// memory.grow(pages: i32) -> i32\nfunction builtin_memory_grow(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.i32;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n return module.memory_grow(compiler.compileExpression(ctx.operands[0], Type.i32, Constraints.ConvImplicit));\n}\nbuiltinFunctions.set(BuiltinNames.memory_grow, builtin_memory_grow);\n\n// memory.copy(dest: usize, src: usize: n: usize) -> void\nfunction builtin_memory_copy(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.void;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n if (!compiler.options.hasFeature(Feature.BulkMemory)) {\n // use stdlib alternative if not supported\n let instance = compiler.resolver.resolveFunction(ctx.prototype, null); // reports\n compiler.currentType = Type.void;\n if (!instance || !compiler.compileFunction(instance, true)) return module.unreachable();\n return compiler.compileCallDirect(instance, operands, ctx.reportNode);\n }\n let usizeType = compiler.options.usizeType;\n let arg0 = compiler.compileExpression(operands[0], usizeType, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], usizeType, Constraints.ConvImplicit);\n let arg2 = compiler.compileExpression(operands[2], usizeType, Constraints.ConvImplicit);\n compiler.currentType = Type.void;\n return module.memory_copy(arg0, arg1, arg2);\n}\nbuiltinFunctions.set(BuiltinNames.memory_copy, builtin_memory_copy);\n\n// memory.fill(dest: usize, value: u8, n: usize) -> void\nfunction builtin_memory_fill(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.void;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n if (!compiler.options.hasFeature(Feature.BulkMemory)) {\n // use stdlib alternative if not supported\n let instance = compiler.resolver.resolveFunction(ctx.prototype, null); // reports\n compiler.currentType = Type.void;\n if (!instance || !compiler.compileFunction(instance, true)) return module.unreachable();\n return compiler.compileCallDirect(instance, operands, ctx.reportNode);\n }\n let usizeType = compiler.options.usizeType;\n let arg0 = compiler.compileExpression(operands[0], usizeType, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.u8, Constraints.ConvImplicit);\n let arg2 = compiler.compileExpression(operands[2], usizeType, Constraints.ConvImplicit);\n compiler.currentType = Type.void;\n return module.memory_fill(arg0, arg1, arg2);\n}\nbuiltinFunctions.set(BuiltinNames.memory_fill, builtin_memory_fill);\n\n// memory.data(size[, align]) -> usize\n// memory.data(values[, align]) -> usize\nfunction builtin_memory_data(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = Type.i32;\n if (\n checkTypeOptional(ctx) |\n checkArgsOptional(ctx, 1, 2)\n ) return module.unreachable();\n let typeArguments = ctx.typeArguments;\n let operands = ctx.operands;\n let numOperands = operands.length;\n let usizeType = compiler.options.usizeType;\n let offset: i64;\n if (typeArguments && typeArguments.length > 0) { // data(values[, align])\n let elementType = typeArguments[0];\n if (!elementType.isValue) {\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"memory.data\", elementType.toString()\n );\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n let valuesOperand = operands[0];\n if (valuesOperand.kind != NodeKind.Literal || (valuesOperand).literalKind != LiteralKind.Array) {\n compiler.error(\n DiagnosticCode.Array_literal_expected,\n operands[0].range\n );\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n let expressions = (valuesOperand).elementExpressions;\n let numElements = expressions.length;\n let exprs = new Array(numElements);\n let isStatic = true;\n for (let i = 0; i < numElements; ++i) {\n let elementExpression = expressions[i];\n if (elementExpression.kind != NodeKind.Omitted) {\n let expr = compiler.compileExpression(elementExpression, elementType, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n expr = precomp;\n } else {\n isStatic = false;\n }\n exprs[i] = expr;\n } else {\n exprs[i] = compiler.makeZero(elementType);\n }\n }\n if (!isStatic) {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n valuesOperand.range\n );\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n let align = elementType.byteSize;\n if (numOperands == 2) {\n align = evaluateImmediateAlign(operands[1], align, compiler); // reports\n if (align < 0) {\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n }\n let buf = new Uint8Array(numElements * elementType.byteSize);\n assert(compiler.writeStaticBuffer(buf, 0, elementType, exprs) == buf.byteLength);\n offset = compiler.addAlignedMemorySegment(buf, align).offset;\n } else { // data(size[, align])\n let arg0 = compiler.compileExpression(operands[0], Type.i32, Constraints.ConvImplicit);\n let precomp = module.runExpression(arg0, ExpressionRunnerFlags.PreserveSideeffects);\n if (!precomp) {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n operands[0].range\n );\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n let size = getConstValueI32(precomp);\n if (size < 1) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n operands[0].range, \"1\", i32.MAX_VALUE.toString()\n );\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n let align = 16;\n if (numOperands == 2) {\n align = evaluateImmediateAlign(operands[1], align, compiler); // reports\n if (align < 0) {\n compiler.currentType = usizeType;\n return module.unreachable();\n }\n }\n offset = compiler.addAlignedMemorySegment(new Uint8Array(size), align).offset;\n }\n // FIXME: what if recompiles happen? recompiles are bad.\n compiler.currentType = usizeType;\n if (usizeType == Type.usize32) {\n assert(!i64_high(offset));\n return module.i32(i64_low(offset));\n } else {\n return module.i64(i64_low(offset), i64_high(offset));\n }\n}\nbuiltinFunctions.set(BuiltinNames.memory_data, builtin_memory_data);\n\n// === GC =====================================================================================\n\nfunction builtin_i31_new(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.i32, Constraints.ConvImplicit);\n compiler.currentType = Type.i31ref;\n return module.i31_new(arg0);\n}\nbuiltinFunctions.set(BuiltinNames.i31_new, builtin_i31_new);\n\nfunction builtin_i31_get(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.i31ref, Constraints.ConvImplicit);\n if (ctx.contextualType.is(TypeFlags.Unsigned)) {\n compiler.currentType = Type.u32;\n return module.i31_get(arg0, false);\n } else {\n compiler.currentType = Type.i32;\n return module.i31_get(arg0, true);\n }\n}\nbuiltinFunctions.set(BuiltinNames.i31_get, builtin_i31_get);\n\n// === Helpers ================================================================================\n\n// changetype(value: *) -> T\nfunction builtin_changetype(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeRequired(ctx, true) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let toType = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.auto);\n let fromType = compiler.currentType;\n compiler.currentType = toType;\n if (!fromType.isChangeableTo(toType)) {\n compiler.error(\n DiagnosticCode.Type_0_cannot_be_changed_to_type_1,\n ctx.reportNode.range, fromType.toString(), toType.toString()\n );\n return module.unreachable();\n }\n return arg0;\n}\nbuiltinFunctions.set(BuiltinNames.changetype, builtin_changetype);\n\n// assert(isTrueish: T, message?: string) -> T{!= null}\nfunction builtin_assert(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n let typeArguments = ctx.typeArguments;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsOptional(ctx, 1, 2)\n ) {\n if (typeArguments) {\n assert(typeArguments.length); // otherwise invalid, should not been set at all\n compiler.currentType = typeArguments[0].nonNullableType;\n }\n return module.unreachable();\n }\n let operands = ctx.operands;\n let contextualType = ctx.contextualType;\n let arg0 = typeArguments\n ? compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit | Constraints.MustWrap)\n : compiler.compileExpression(operands[0], Type.bool, Constraints.MustWrap);\n let type = compiler.currentType;\n compiler.currentType = type.nonNullableType;\n\n // omit if assertions are disabled\n if (compiler.options.noAssert) {\n return arg0;\n }\n\n // omit if the assertion can be proven statically\n let evaled = module.runExpression(arg0, ExpressionRunnerFlags.Default);\n if (evaled) {\n switch (getExpressionType(evaled)) {\n case TypeRef.I32: {\n if (getConstValueI32(evaled)) {\n return arg0;\n }\n break;\n }\n case TypeRef.I64: {\n if (getConstValueI64Low(evaled) | getConstValueI64High(evaled)) {\n return arg0;\n }\n break;\n }\n case TypeRef.F32: {\n if (getConstValueF32(evaled)) {\n return arg0;\n }\n break;\n }\n case TypeRef.F64: {\n if (getConstValueF64(evaled)) {\n return arg0;\n }\n break;\n }\n }\n }\n\n // otherwise call abort if the assertion is false-ish\n let abort = compiler.makeAbort(operands.length == 2 ? operands[1] : null, ctx.reportNode);\n compiler.currentType = type.nonNullableType;\n if (contextualType == Type.void) { // simplify if dropped anyway\n compiler.currentType = Type.void;\n switch (type.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: return module.if(module.unary(UnaryOp.EqzI32, arg0), abort);\n case TypeKind.I64:\n case TypeKind.U64: return module.if(module.unary(UnaryOp.EqzI64, arg0), abort);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.if(module.unary(UnaryOp.EqzSize, arg0), abort);\n // TODO: also check for NaN in float assertions, as in `Boolean(NaN) -> false`?\n case TypeKind.F32: return module.if(module.binary(BinaryOp.EqF32, arg0, module.f32(0)), abort);\n case TypeKind.F64: return module.if(module.binary(BinaryOp.EqF64, arg0, module.f64(0)), abort);\n case TypeKind.Funcref:\n case TypeKind.Externref:\n case TypeKind.Anyref:\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.I31ref:\n case TypeKind.Stringref:\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter: return module.if(module.ref_is_null(arg0), abort);\n }\n } else {\n compiler.currentType = type.nonNullableType;\n let flow = compiler.currentFlow;\n switch (compiler.currentType.kind) {\n case TypeKind.Bool:\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32: {\n let temp = flow.getTempLocal(type);\n flow.setLocalFlag(temp.index, LocalFlags.Wrapped); // arg0 is wrapped\n let ret = module.if(\n module.local_tee(temp.index, arg0, false), // numeric\n module.local_get(temp.index, TypeRef.I32),\n abort\n );\n return ret;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n let temp = flow.getTempLocal(Type.i64);\n let ret = module.if(\n module.unary(UnaryOp.EqzI64,\n module.local_tee(temp.index, arg0, false) // i64\n ),\n abort,\n module.local_get(temp.index, TypeRef.I64)\n );\n return ret;\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n let temp = flow.getTempLocal(compiler.options.usizeType);\n let ret = module.if(\n module.unary(\n UnaryOp.EqzSize,\n module.local_tee(temp.index, arg0, type.isManaged)\n ),\n abort,\n module.local_get(temp.index, compiler.options.sizeTypeRef)\n );\n return ret;\n }\n case TypeKind.F32: {\n let temp = flow.getTempLocal(Type.f32);\n let ret = module.if(\n module.binary(BinaryOp.EqF32,\n module.local_tee(temp.index, arg0, false), // f32\n module.f32(0)\n ),\n abort,\n module.local_get(temp.index, TypeRef.F32)\n );\n return ret;\n }\n case TypeKind.F64: {\n let temp = flow.getTempLocal(Type.f64);\n let ret = module.if(\n module.binary(BinaryOp.EqF64,\n module.local_tee(temp.index, arg0, false), // f64\n module.f64(0)\n ),\n abort,\n module.local_get(temp.index, TypeRef.F64)\n );\n return ret;\n }\n case TypeKind.Funcref:\n case TypeKind.Externref:\n case TypeKind.Anyref:\n case TypeKind.Eqref:\n case TypeKind.Structref:\n case TypeKind.Arrayref:\n case TypeKind.I31ref:\n case TypeKind.Stringref:\n case TypeKind.StringviewWTF8:\n case TypeKind.StringviewWTF16:\n case TypeKind.StringviewIter: {\n let temp = flow.getTempLocal(type);\n let ret = module.if(\n module.ref_is_null(\n module.local_tee(temp.index, arg0, false) // ref\n ),\n abort,\n module.local_get(temp.index, type.toRef())\n );\n return ret;\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange,\n \"assert\", compiler.currentType.toString()\n );\n return abort;\n}\nbuiltinFunctions.set(BuiltinNames.assert, builtin_assert);\n\n// unchecked(expr: *) -> *\nfunction builtin_unchecked(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) return module.unreachable();\n let flow = compiler.currentFlow;\n let ignoreUnchecked = compiler.options.uncheckedBehavior === UncheckedBehavior.Never;\n let alreadyUnchecked = flow.is(FlowFlags.UncheckedContext);\n if (ignoreUnchecked) assert(!alreadyUnchecked);\n else flow.set(FlowFlags.UncheckedContext);\n // eliminate unnecessary tees by preferring contextualType(=void)\n let expr = compiler.compileExpression(ctx.operands[0], ctx.contextualType);\n if (!alreadyUnchecked) flow.unset(FlowFlags.UncheckedContext);\n return expr;\n}\nbuiltinFunctions.set(BuiltinNames.unchecked, builtin_unchecked);\n\n// call_indirect(index: u32, ...args: *[]) -> T\nfunction builtin_call_indirect(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeOptional(ctx, true) |\n checkArgsOptional(ctx, 1, i32.MAX_VALUE)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let returnType: Type;\n if (typeArguments) {\n assert(typeArguments.length);\n returnType = typeArguments[0];\n } else {\n returnType = ctx.contextualType;\n }\n let indexArg = compiler.compileExpression(operands[0], Type.u32, Constraints.ConvImplicit);\n let numOperands = operands.length - 1;\n let operandExprs = new Array(numOperands);\n let paramTypeRefs = new Array(numOperands);\n for (let i = 0; i < numOperands; ++i) {\n operandExprs[i] = compiler.compileExpression(operands[1 + i], Type.auto);\n paramTypeRefs[i] = compiler.currentType.toRef();\n }\n compiler.currentType = returnType;\n return module.call_indirect(null /* TODO */, indexArg, operandExprs, createType(paramTypeRefs), returnType.toRef());\n}\nbuiltinFunctions.set(BuiltinNames.call_indirect, builtin_call_indirect);\n\n// instantiate(...args: *[]) -> T\nfunction builtin_instantiate(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeRequired(ctx, true)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let typeArgument = typeArguments[0];\n let classInstance = typeArgument.getClass();\n if (!classInstance) {\n compiler.error(\n DiagnosticCode.This_expression_is_not_constructable,\n ctx.reportNode.expression.range\n );\n return module.unreachable();\n }\n compiler.currentType = classInstance.type;\n let ctor = compiler.ensureConstructor(classInstance, ctx.reportNode);\n compiler.checkFieldInitialization(classInstance, ctx.reportNode);\n return compiler.compileInstantiate(ctor, operands, Constraints.None, ctx.reportNode);\n}\nbuiltinFunctions.set(BuiltinNames.instantiate, builtin_instantiate);\n\n// === User-defined diagnostics ===============================================================\n\nfunction builtin_diagnostic(ctx: BuiltinFunctionContext, category: DiagnosticCategory): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n checkTypeAbsent(ctx);\n let operands = ctx.operands;\n let reportNode = ctx.reportNode;\n compiler.emitDiagnostic(\n DiagnosticCode.User_defined_0,\n category,\n reportNode.range,\n null,\n operands.length\n ? operands[0].range.toString()\n : reportNode.range.toString()\n );\n return category == DiagnosticCategory.Error\n ? module.unreachable()\n : module.nop();\n}\n\n// ERROR(message?)\nfunction builtin_error(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_diagnostic(ctx, DiagnosticCategory.Error);\n}\nbuiltinFunctions.set(BuiltinNames.ERROR, builtin_error);\n\n// WARNING(message?)\nfunction builtin_warning(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_diagnostic(ctx, DiagnosticCategory.Warning);\n}\nbuiltinFunctions.set(BuiltinNames.WARNING, builtin_warning);\n\n// INFO(message?)\nfunction builtin_info(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_diagnostic(ctx, DiagnosticCategory.Info);\n}\nbuiltinFunctions.set(BuiltinNames.INFO, builtin_info);\n\n// === Function builtins ======================================================================\n\n// Function#call(thisArg: thisof | null, ...args: *[]) -> returnof\nfunction builtin_function_call(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let parent = ctx.prototype.parent;\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n assert(classInstance.prototype == compiler.program.functionPrototype);\n let typeArguments = assert(classInstance.typeArguments);\n assert(typeArguments.length == 1);\n let ftype = typeArguments[0];\n let signature = assert(ftype.getSignature());\n let returnType = signature.returnType;\n if (\n checkTypeAbsent(ctx) |\n checkArgsOptional(ctx, 1 + signature.requiredParameters, 1 + signature.parameterTypes.length)\n ) {\n compiler.currentType = returnType;\n return compiler.module.unreachable();\n }\n let functionArg = compiler.compileExpression(assert(ctx.thisOperand), ftype, Constraints.ConvImplicit);\n let thisOperand = assert(ctx.operands.shift());\n let thisType = signature.thisType;\n let thisArg: usize = 0;\n if (thisType) {\n thisArg = compiler.compileExpression(thisOperand, thisType, Constraints.ConvImplicit);\n } else if (thisOperand.kind != NodeKind.Null) {\n compiler.error(\n DiagnosticCode._this_cannot_be_referenced_in_current_location,\n thisOperand.range\n );\n return compiler.module.unreachable();\n }\n return compiler.compileCallIndirect(signature, functionArg, ctx.operands, ctx.reportNode, thisArg, ctx.contextualType == Type.void);\n}\nbuiltinFunctions.set(BuiltinNames.Function_call, builtin_function_call);\n\n// String.raw(parts: TemplateStringsArray, ...values: unknown[]): string\nfunction builtin_string_raw(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n compiler.currentType = ctx.compiler.program.stringInstance.type;\n compiler.error(\n DiagnosticCode.Not_implemented_0,\n ctx.reportNode.range, \"String.raw\"\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.String_raw, builtin_string_raw);\n\n// === Portable type conversions ==============================================================\n\nfunction builtin_conversion(ctx: BuiltinFunctionContext, toType: Type): ExpressionRef {\n let compiler = ctx.compiler;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = toType;\n return compiler.module.unreachable();\n }\n return compiler.compileExpression(ctx.operands[0], toType, Constraints.ConvExplicit);\n}\n\n// i8(*) -> i8\nfunction builtin_i8(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.i8);\n}\nbuiltinFunctions.set(BuiltinNames.i8, builtin_i8);\n\n// i16(*) -> i16\nfunction builtin_i16(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.i16);\n}\nbuiltinFunctions.set(BuiltinNames.i16, builtin_i16);\n\n// i32(*) -> i32\nfunction builtin_i32(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.i32);\n}\nbuiltinFunctions.set(BuiltinNames.i32, builtin_i32);\n\n// i64(*) -> i64\nfunction builtin_i64(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.i64);\n}\nbuiltinFunctions.set(BuiltinNames.i64, builtin_i64);\n\n// isize(*) -> isize\nfunction builtin_isize(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, ctx.compiler.options.isizeType);\n}\nbuiltinFunctions.set(BuiltinNames.isize, builtin_isize);\n\n// u8(*) -> u8\nfunction builtin_u8(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.u8);\n}\nbuiltinFunctions.set(BuiltinNames.u8, builtin_u8);\n\n// u16(*) -> u16\nfunction builtin_u16(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.u16);\n}\nbuiltinFunctions.set(BuiltinNames.u16, builtin_u16);\n\n// u32(*) -> u32\nfunction builtin_u32(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.u32);\n}\nbuiltinFunctions.set(BuiltinNames.u32, builtin_u32);\n\n// u64(*) -> u64\nfunction builtin_u64(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.u64);\n}\nbuiltinFunctions.set(BuiltinNames.u64, builtin_u64);\n\n// usize(*) -> usize\nfunction builtin_usize(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, ctx.compiler.options.usizeType);\n}\nbuiltinFunctions.set(BuiltinNames.usize, builtin_usize);\n\n// bool(*) -> bool\nfunction builtin_bool(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.bool);\n}\nbuiltinFunctions.set(BuiltinNames.bool, builtin_bool);\n\n// f32(*) -> f32\nfunction builtin_f32(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.f32);\n}\nbuiltinFunctions.set(BuiltinNames.f32, builtin_f32);\n\n// f64(*) -> f64\nfunction builtin_f64(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_conversion(ctx, Type.f64);\n}\nbuiltinFunctions.set(BuiltinNames.f64, builtin_f64);\n\n// TODO: alias for now, splat input integer perhaps?\nfunction builtin_v128(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_i8x16(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128, builtin_v128);\n\n// === SIMD ===================================================================================\n\n// i8x16(...values: i8[16]) -> v128\nfunction builtin_i8x16(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 16)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let bytes = new Uint8Array(16);\n let vars = new Array(16);\n let numVars = 0;\n\n for (let i = 0; i < 16; ++i) {\n let expr = compiler.compileExpression(operands[i], Type.i8, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n writeI8(getConstValueI32(precomp), bytes, i);\n } else {\n vars[i] = expr;\n numVars++;\n }\n }\n compiler.currentType = Type.v128;\n if (numVars == 0) {\n // all constants\n return module.v128(bytes);\n } else {\n let vec: ExpressionRef;\n let fullVars = numVars == 16;\n if (fullVars) {\n // all variants\n vec = module.unary(UnaryOp.SplatI8x16, vars[0]);\n } else {\n // mixed constants / variants\n vec = module.v128(bytes);\n }\n for (let i = i32(fullVars); i < 16; i++) {\n let expr = vars[i];\n if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI8x16, vec, i, expr);\n }\n return vec;\n }\n}\nbuiltinFunctions.set(BuiltinNames.i8x16, builtin_i8x16);\n\n// i16x8(...values: i16[8]) -> v128\nfunction builtin_i16x8(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 8)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let bytes = new Uint8Array(16);\n let vars = new Array(8);\n let numVars = 0;\n\n for (let i = 0; i < 8; ++i) {\n let expr = compiler.compileExpression(operands[i], Type.i16, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n writeI16(getConstValueI32(precomp), bytes, i << 1);\n } else {\n vars[i] = expr;\n numVars++;\n }\n }\n compiler.currentType = Type.v128;\n if (numVars == 0) {\n // all constants\n return module.v128(bytes);\n } else {\n let vec: ExpressionRef;\n let fullVars = numVars == 8;\n if (fullVars) {\n // all variants\n vec = module.unary(UnaryOp.SplatI16x8, vars[0]);\n } else {\n // mixed constants / variants\n vec = module.v128(bytes);\n }\n for (let i = i32(fullVars); i < 8; i++) {\n let expr = vars[i];\n if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI16x8, vec, i, expr);\n }\n return vec;\n }\n}\nbuiltinFunctions.set(BuiltinNames.i16x8, builtin_i16x8);\n\n// i32x4(...values: i32[4]) -> v128\nfunction builtin_i32x4(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 4)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let bytes = new Uint8Array(16);\n let vars = new Array(4);\n let numVars = 0;\n\n for (let i = 0; i < 4; ++i) {\n let expr = compiler.compileExpression(operands[i], Type.i32, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n writeI32(getConstValueI32(precomp), bytes, i << 2);\n } else {\n vars[i] = expr;\n numVars++;\n }\n }\n compiler.currentType = Type.v128;\n if (numVars == 0) {\n // all constants\n return module.v128(bytes);\n } else {\n let vec: ExpressionRef;\n let fullVars = numVars == 4;\n if (fullVars) {\n // all variants\n vec = module.unary(UnaryOp.SplatI32x4, vars[0]);\n } else {\n // mixed constants / variants\n vec = module.v128(bytes);\n }\n for (let i = i32(fullVars); i < 4; i++) {\n let expr = vars[i];\n if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI32x4, vec, i, expr);\n }\n return vec;\n }\n}\nbuiltinFunctions.set(BuiltinNames.i32x4, builtin_i32x4);\n\n// i64x2(...values: i64[2]) -> v128\nfunction builtin_i64x2(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let bytes = new Uint8Array(16);\n let vars = new Array(2);\n let numVars = 0;\n\n for (let i = 0; i < 2; ++i) {\n let expr = compiler.compileExpression(operands[i], Type.i64, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n let off = i << 3;\n writeI32(getConstValueI64Low(precomp), bytes, off + 0);\n writeI32(getConstValueI64High(precomp), bytes, off + 4);\n } else {\n vars[i] = expr;\n numVars++;\n }\n }\n compiler.currentType = Type.v128;\n if (numVars == 0) {\n // all constants\n return module.v128(bytes);\n } else {\n let vec: ExpressionRef;\n let fullVars = numVars == 2;\n if (fullVars) {\n // all variants\n vec = module.unary(UnaryOp.SplatI64x2, vars[0]);\n } else {\n // mixed constants / variants\n vec = module.v128(bytes);\n }\n for (let i = i32(fullVars); i < 2; i++) {\n let expr = vars[i];\n if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneI64x2, vec, i, expr);\n }\n return vec;\n }\n}\nbuiltinFunctions.set(BuiltinNames.i64x2, builtin_i64x2);\n\n// f32x4(...values: f32[4]) -> v128\nfunction builtin_f32x4(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 4)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let bytes = new Uint8Array(16);\n let vars = new Array(4);\n let numVars = 0;\n\n for (let i = 0; i < 4; ++i) {\n let expr = compiler.compileExpression(operands[i], Type.f32, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n writeF32(getConstValueF32(precomp), bytes, i << 2);\n } else {\n vars[i] = expr;\n numVars++;\n }\n }\n compiler.currentType = Type.v128;\n if (numVars == 0) {\n // all constants\n return module.v128(bytes);\n } else {\n let vec: ExpressionRef;\n let fullVars = numVars == 4;\n if (fullVars) {\n // all variants\n vec = module.unary(UnaryOp.SplatF32x4, vars[0]);\n } else {\n // mixed constants / variants\n vec = module.v128(bytes);\n }\n for (let i = i32(fullVars); i < 4; i++) {\n let expr = vars[i];\n if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneF32x4, vec, i, expr);\n }\n return vec;\n }\n}\nbuiltinFunctions.set(BuiltinNames.f32x4, builtin_f32x4);\n\n// f64x2(...values: f64[2]) -> v128\nfunction builtin_f64x2(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let bytes = new Uint8Array(16);\n let vars = new Array(2);\n let numVars = 0;\n\n for (let i = 0; i < 2; ++i) {\n let expr = compiler.compileExpression(operands[i], Type.f64, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n writeF64(getConstValueF64(precomp), bytes, i << 3);\n } else {\n vars[i] = expr;\n numVars++;\n }\n }\n compiler.currentType = Type.v128;\n if (numVars == 0) {\n // all constants\n return module.v128(bytes);\n } else {\n let vec: ExpressionRef;\n let fullVars = numVars == 2;\n if (fullVars) {\n // all variants\n vec = module.unary(UnaryOp.SplatF64x2, vars[0]);\n } else {\n // mixed constants / variants\n vec = module.v128(bytes);\n }\n for (let i = i32(fullVars); i < 2; i++) {\n let expr = vars[i];\n if (expr) vec = module.simd_replace(SIMDReplaceOp.ReplaceLaneF64x2, vec, i, expr);\n }\n return vec;\n }\n}\nbuiltinFunctions.set(BuiltinNames.f64x2, builtin_f64x2);\n\n// v128.splat(x: T) -> v128\nfunction builtin_v128_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], type, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.unary(UnaryOp.SplatI8x16, arg0);\n case TypeKind.I16:\n case TypeKind.U16: return module.unary(UnaryOp.SplatI16x8, arg0);\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.SplatI32x4, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.SplatI64x2, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.unary(\n compiler.options.isWasm64\n ? UnaryOp.SplatI64x2\n : UnaryOp.SplatI32x4,\n arg0\n );\n }\n case TypeKind.F32: return module.unary(UnaryOp.SplatF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.SplatF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.splat\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_splat, builtin_v128_splat);\n\n// v128.extract_lane(x: v128, idx: u8) -> T\nfunction builtin_v128_extract_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx, true) |\n checkArgsRequired(ctx, 2)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.u8, Constraints.ConvImplicit);\n compiler.currentType = type;\n let idx = 0;\n let precomp = module.runExpression(arg1, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n idx = getConstValueI32(precomp);\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n operands[1].range\n );\n }\n if (type.isValue) {\n let maxIdx = (16 / assert(type.byteSize)) - 1;\n if (idx < 0 || idx > maxIdx) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n operands[1].range, \"Lane index\", \"0\", maxIdx.toString()\n );\n idx = 0;\n }\n switch (type.kind) {\n case TypeKind.I8: return module.simd_extract(SIMDExtractOp.ExtractLaneI8x16, arg0, idx);\n case TypeKind.U8: return module.simd_extract(SIMDExtractOp.ExtractLaneU8x16, arg0, idx);\n case TypeKind.I16: return module.simd_extract(SIMDExtractOp.ExtractLaneI16x8, arg0, idx);\n case TypeKind.U16: return module.simd_extract(SIMDExtractOp.ExtractLaneU16x8, arg0, idx);\n case TypeKind.I32:\n case TypeKind.U32: return module.simd_extract(SIMDExtractOp.ExtractLaneI32x4, arg0, idx);\n case TypeKind.I64:\n case TypeKind.U64: return module.simd_extract(SIMDExtractOp.ExtractLaneI64x2, arg0, idx);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.simd_extract(\n compiler.options.isWasm64\n ? SIMDExtractOp.ExtractLaneI64x2\n : SIMDExtractOp.ExtractLaneI32x4,\n arg0, idx\n );\n }\n case TypeKind.F32: return module.simd_extract(SIMDExtractOp.ExtractLaneF32x4, arg0, idx);\n case TypeKind.F64: return module.simd_extract(SIMDExtractOp.ExtractLaneF64x2, arg0, idx);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.extract_lane\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_extract_lane, builtin_v128_extract_lane);\n\n// v128.replace_lane(x: v128, idx: u8, value: T) -> v128\nfunction builtin_v128_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 3)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.u8, Constraints.ConvImplicit);\n let arg2 = compiler.compileExpression(operands[2], type, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n let idx = 0;\n let precomp = module.runExpression(arg1, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n idx = getConstValueI32(precomp);\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n operands[1].range\n );\n }\n if (type.isValue) {\n let maxIdx = (16 / assert(type.byteSize)) - 1;\n if (idx < 0 || idx > maxIdx) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n operands[1].range, \"Lane index\", \"0\", maxIdx.toString()\n );\n idx = 0;\n }\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.simd_replace(SIMDReplaceOp.ReplaceLaneI8x16, arg0, idx, arg2);\n case TypeKind.I16:\n case TypeKind.U16: return module.simd_replace(SIMDReplaceOp.ReplaceLaneI16x8, arg0, idx, arg2);\n case TypeKind.I32:\n case TypeKind.U32: return module.simd_replace(SIMDReplaceOp.ReplaceLaneI32x4, arg0, idx, arg2);\n case TypeKind.I64:\n case TypeKind.U64: return module.simd_replace(SIMDReplaceOp.ReplaceLaneI64x2, arg0, idx, arg2);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.simd_replace(\n compiler.options.isWasm64\n ? SIMDReplaceOp.ReplaceLaneI64x2\n : SIMDReplaceOp.ReplaceLaneI32x4,\n arg0, idx, arg2\n );\n }\n case TypeKind.F32: return module.simd_replace(SIMDReplaceOp.ReplaceLaneF32x4, arg0, idx, arg2);\n case TypeKind.F64: return module.simd_replace(SIMDReplaceOp.ReplaceLaneF64x2, arg0, idx, arg2);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.replace_lane\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_replace_lane, builtin_v128_replace_lane);\n\n// v128.shuffle(a: v128, b: v128, ...lanes: u8[]) -> v128\nfunction builtin_v128_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n if (type.isValue) {\n let laneWidth = type.byteSize;\n let laneCount = 16 / laneWidth;\n assert(Number.isInteger(laneCount) && isPowerOf2(laneCount));\n if (\n checkArgsRequired(ctx, 2 + laneCount)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32:\n case TypeKind.I64:\n case TypeKind.Isize:\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize:\n case TypeKind.F32:\n case TypeKind.F64: {\n let mask = new Uint8Array(16);\n let maxIdx = (laneCount << 1) - 1;\n for (let i = 0; i < laneCount; ++i) {\n let operand = operands[2 + i];\n let argN = compiler.compileExpression(operand, Type.u8, Constraints.ConvImplicit);\n let precomp = module.runExpression(argN, ExpressionRunnerFlags.PreserveSideeffects);\n let idx = 0;\n if (precomp) {\n idx = getConstValueI32(precomp);\n if (idx < 0 || idx > maxIdx) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n operand.range, \"Lane index\", \"0\", maxIdx.toString()\n );\n idx = 0;\n }\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n operand.range\n );\n }\n switch (laneWidth) {\n case 1: {\n writeI8(idx, mask, i);\n break;\n }\n case 2: {\n let off8 = i << 1;\n let idx8 = idx << 1;\n writeI8(idx8 , mask, off8);\n writeI8(idx8 + 1, mask, off8 + 1);\n break;\n }\n case 4: {\n let off8 = i << 2;\n let idx8 = idx << 2;\n writeI8(idx8 , mask, off8);\n writeI8(idx8 + 1, mask, off8 + 1);\n writeI8(idx8 + 2, mask, off8 + 2);\n writeI8(idx8 + 3, mask, off8 + 3);\n break;\n }\n case 8: {\n let off8 = i << 3;\n let idx8 = idx << 3;\n writeI8(idx8 , mask, off8);\n writeI8(idx8 + 1, mask, off8 + 1);\n writeI8(idx8 + 2, mask, off8 + 2);\n writeI8(idx8 + 3, mask, off8 + 3);\n writeI8(idx8 + 4, mask, off8 + 4);\n writeI8(idx8 + 5, mask, off8 + 5);\n writeI8(idx8 + 6, mask, off8 + 6);\n writeI8(idx8 + 7, mask, off8 + 7);\n break;\n }\n default: assert(false);\n }\n }\n compiler.currentType = Type.v128;\n return module.simd_shuffle(arg0, arg1, mask);\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.shuffle\", type.toString()\n );\n compiler.currentType = Type.v128;\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_shuffle, builtin_v128_shuffle);\n\n// v128.swizzle(a: v128, b: v128) -> v128\nfunction builtin_v128_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n return module.binary(BinaryOp.SwizzleI8x16, arg0, arg1);\n}\nbuiltinFunctions.set(BuiltinNames.v128_swizzle, builtin_v128_swizzle);\n\n// v128.load_splat(ptr: usize, immOffset?: usize, immAlign?: usize) -> v128\nfunction builtin_v128_load_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 1, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let numOperands = operands.length;\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 2) {\n immOffset = evaluateImmediateOffset(operands[1], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n if (numOperands == 3) {\n immAlign = evaluateImmediateAlign(operands[2], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: {\n return module.simd_load(SIMDLoadOp.Load8Splat, arg0, immOffset, immAlign);\n }\n case TypeKind.I16:\n case TypeKind.U16: {\n return module.simd_load(SIMDLoadOp.Load16Splat, arg0, immOffset, immAlign);\n }\n case TypeKind.I32:\n case TypeKind.U32:\n case TypeKind.F32: {\n return module.simd_load(SIMDLoadOp.Load32Splat, arg0, immOffset, immAlign);\n }\n case TypeKind.Isize:\n case TypeKind.Usize: {\n if (!compiler.options.isWasm64) {\n return module.simd_load(SIMDLoadOp.Load32Splat, arg0, immOffset, immAlign);\n }\n // fall-through\n }\n case TypeKind.I64:\n case TypeKind.U64:\n case TypeKind.F64: {\n return module.simd_load(SIMDLoadOp.Load64Splat, arg0, immOffset, immAlign);\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.load_splat\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_load_splat, builtin_v128_load_splat);\n\n// v128.load_ext(ptr: usize, immOffset?: usize, immAlign?: usize) -> v128\nfunction builtin_v128_load_ext(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 1, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let numOperands = operands.length;\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 2) {\n immOffset = evaluateImmediateOffset(operands[1], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n if (numOperands == 3) {\n immAlign = evaluateImmediateAlign(operands[2], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.simd_load(SIMDLoadOp.Load8x8S, arg0, immOffset, immAlign);\n case TypeKind.U8: return module.simd_load(SIMDLoadOp.Load8x8U, arg0, immOffset, immAlign);\n case TypeKind.I16: return module.simd_load(SIMDLoadOp.Load16x4S, arg0, immOffset, immAlign);\n case TypeKind.U16: return module.simd_load(SIMDLoadOp.Load16x4U, arg0, immOffset, immAlign);\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.simd_load(SIMDLoadOp.Load32x2S, arg0, immOffset, immAlign);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.simd_load(SIMDLoadOp.Load32x2U, arg0, immOffset, immAlign);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.load_ext\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_load_ext, builtin_v128_load_ext);\n\n// v128.load_zero(ptr: usize, immOffset?: usize, immAlign?: usize) -> v128\nfunction builtin_v128_load_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 1, 3)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let numOperands = operands.length;\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 2) {\n immOffset = evaluateImmediateOffset(operands[1], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n if (numOperands == 3) {\n immAlign = evaluateImmediateAlign(operands[2], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I32:\n case TypeKind.U32:\n case TypeKind.F32: return module.simd_load(SIMDLoadOp.Load32Zero, arg0, immOffset, immAlign);\n case TypeKind.I64:\n case TypeKind.U64:\n case TypeKind.F64: return module.simd_load(SIMDLoadOp.Load64Zero, arg0, immOffset, immAlign);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.simd_load(\n compiler.options.isWasm64\n ? SIMDLoadOp.Load64Zero\n : SIMDLoadOp.Load32Zero,\n arg0,\n immOffset,\n immAlign\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.load_zero\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_load_zero, builtin_v128_load_zero);\n\n// v128.load_lane(ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize) -> v128\nfunction builtin_v128_load_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 3, 5)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n let arg2 = compiler.compileExpression(operands[2], Type.u8, Constraints.ConvImplicit);\n let idx = 0;\n let precomp = module.runExpression(arg2, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n idx = getConstValueI32(precomp);\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n operands[2].range\n );\n }\n let numOperands = operands.length;\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 4) {\n immOffset = evaluateImmediateOffset(operands[3], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n if (numOperands == 5) {\n immAlign = evaluateImmediateAlign(operands[4], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = Type.v128;\n if (type.isValue) {\n let maxIdx = (16 / assert(type.byteSize)) - 1;\n if (idx < 0 || idx > maxIdx) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n operands[1].range, \"Lane index\", \"0\", maxIdx.toString()\n );\n idx = 0;\n }\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Load8Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Load16Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.I32:\n case TypeKind.U32:\n case TypeKind.F32: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Load32Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.I64:\n case TypeKind.U64:\n case TypeKind.F64: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Load64Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.simd_loadstorelane(\n compiler.options.isWasm64\n ? SIMDLoadStoreLaneOp.Load64Lane\n : SIMDLoadStoreLaneOp.Load32Lane,\n arg0,\n immOffset,\n immAlign,\n idx,\n arg1\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.load_lane\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_load_lane, builtin_v128_load_lane);\n\n// v128.store_lane(ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize) -> v128\nfunction builtin_v128_store_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx, true) |\n checkArgsOptional(ctx, 3, 5)\n ) return module.unreachable();\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n let arg2 = compiler.compileExpression(operands[2], Type.u8, Constraints.ConvImplicit);\n let idx = 0;\n let precomp = module.runExpression(arg2, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n idx = getConstValueI32(precomp);\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n operands[2].range\n );\n }\n let numOperands = operands.length;\n let immOffset = 0;\n let immAlign = type.byteSize;\n if (numOperands >= 4) {\n immOffset = evaluateImmediateOffset(operands[3], compiler); // reports\n if (immOffset < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n if (numOperands == 5) {\n immAlign = evaluateImmediateAlign(operands[4], immAlign, compiler); // reports\n if (immAlign < 0) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n }\n }\n compiler.currentType = Type.v128;\n if (type.isValue) {\n let maxIdx = (16 / assert(type.byteSize)) - 1;\n if (idx < 0 || idx > maxIdx) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n operands[1].range, \"Lane index\", \"0\", maxIdx.toString()\n );\n idx = 0;\n }\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Store8Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Store16Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.I32:\n case TypeKind.U32:\n case TypeKind.F32: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Store32Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.I64:\n case TypeKind.U64:\n case TypeKind.F64: return module.simd_loadstorelane(SIMDLoadStoreLaneOp.Store64Lane, arg0, immOffset, immAlign, idx, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.simd_loadstorelane(\n compiler.options.isWasm64\n ? SIMDLoadStoreLaneOp.Store64Lane\n : SIMDLoadStoreLaneOp.Store32Lane,\n arg0,\n immOffset,\n immAlign,\n idx,\n arg1\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.store_lane\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_store_lane, builtin_v128_store_lane);\n\n// v128.add(a: v128, b: v128) -> v128\nfunction builtin_v128_add(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.binary(BinaryOp.AddI8x16, arg0, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.binary(BinaryOp.AddI16x8, arg0, arg1);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.AddI32x4, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.AddI64x2, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.binary(\n compiler.options.isWasm64\n ? BinaryOp.AddI64x2\n : BinaryOp.AddI32x4,\n arg0, arg1\n );\n }\n case TypeKind.F32: return module.binary(BinaryOp.AddF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.AddF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.add\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_add, builtin_v128_add);\n\n// v128.sub(a: v128, b: v128) -> v128\nfunction builtin_v128_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.binary(BinaryOp.SubI8x16, arg0, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.binary(BinaryOp.SubI16x8, arg0, arg1);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.SubI32x4, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.SubI64x2, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.binary(\n compiler.options.isWasm64\n ? BinaryOp.SubI64x2\n : BinaryOp.SubI32x4,\n arg0, arg1\n );\n }\n case TypeKind.F32: return module.binary(BinaryOp.SubF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.SubF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.sub\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_sub, builtin_v128_sub);\n\n// v128.mul(a: v128, b: v128) -> v128\nfunction builtin_v128_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I16:\n case TypeKind.U16: return module.binary(BinaryOp.MulI16x8, arg0, arg1);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.MulI32x4, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.MulI64x2, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(compiler.options.isWasm64 ? BinaryOp.MulI64x2 : BinaryOp.MulI32x4, arg0, arg1);\n case TypeKind.F32: return module.binary(BinaryOp.MulF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.MulF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.mul\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_mul, builtin_v128_mul);\n\n// v128.div(a: v128, b: v128) -> v128\nfunction builtin_v128_div(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.binary(BinaryOp.DivF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.DivF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.div\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_div, builtin_v128_div);\n\n// v128.add_sat(a: v128, b: v128) -> v128\nfunction builtin_v128_add_sat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.AddSatI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.AddSatU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.AddSatI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.AddSatU16x8, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.add_sat\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_add_sat, builtin_v128_add_sat);\n\n// v128.sub_sat(a: v128, b: v128) -> v128\nfunction builtin_v128_sub_sat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.SubSatI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.SubSatU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.SubSatI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.SubSatU16x8, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.sub_sat\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_sub_sat, builtin_v128_sub_sat);\n\n// v128.min(a: v128, b: v128) -> v128\nfunction builtin_v128_min(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.MinI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.MinU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.MinI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.MinU16x8, arg0, arg1);\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.binary(BinaryOp.MinI32x4, arg0, arg1);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.binary(BinaryOp.MinU32x4, arg0, arg1);\n case TypeKind.F32: return module.binary(BinaryOp.MinF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.MinF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.min\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_min, builtin_v128_min);\n\n// v128.max(a: v128, b: v128) -> v128\nfunction builtin_v128_max(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.MaxI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.MaxU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.MaxI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.MaxU16x8, arg0, arg1);\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.binary(BinaryOp.MaxI32x4, arg0, arg1);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.binary(BinaryOp.MaxU32x4, arg0, arg1);\n case TypeKind.F32: return module.binary(BinaryOp.MaxF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.MaxF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.max\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_max, builtin_v128_max);\n\n// v128.pmin(a: v128, b: v128) -> v128\nfunction builtin_v128_pmin(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.binary(BinaryOp.PminF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.PminF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.pmin\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_pmin, builtin_v128_pmin);\n\n// v128.pmax(a: v128, b: v128) -> v128\nfunction builtin_v128_pmax(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.binary(BinaryOp.PmaxF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.PmaxF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.pmax\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_pmax, builtin_v128_pmax);\n\n// v128.dot(a: v128, b: v128) -> v128\nfunction builtin_v128_dot(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I16: return module.binary(BinaryOp.DotI16x8, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.dot\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_dot, builtin_v128_dot);\n\n// v128.avgr(a: v128, b: v128) -> v128\nfunction builtin_v128_avgr(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.U8: return module.binary(BinaryOp.AvgrU8x16, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.AvgrU16x8, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.avgr\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_avgr, builtin_v128_avgr);\n\n// v128.eq(a: v128, b: v128) -> v128\nfunction builtin_v128_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.binary(BinaryOp.EqI8x16, arg0, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.binary(BinaryOp.EqI16x8, arg0, arg1);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.EqI32x4, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.EqI64x2, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(compiler.options.isWasm64 ? BinaryOp.EqI64x2 : BinaryOp.EqI32x4, arg0, arg1);\n case TypeKind.F32: return module.binary(BinaryOp.EqF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.EqF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.eq\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_eq, builtin_v128_eq);\n\n// v128.ne(a: v128, b: v128) -> v128\nfunction builtin_v128_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.binary(BinaryOp.NeI8x16, arg0, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.binary(BinaryOp.NeI16x8, arg0, arg1);\n case TypeKind.I32:\n case TypeKind.U32: return module.binary(BinaryOp.NeI32x4, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.binary(BinaryOp.NeI64x2, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: return module.binary(compiler.options.isWasm64 ? BinaryOp.NeI64x2 : BinaryOp.NeI32x4, arg0, arg1);\n case TypeKind.F32: return module.binary(BinaryOp.NeF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.NeF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.ne\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_ne, builtin_v128_ne);\n\n// v128.lt(a: v128, b: v128) -> v128\nfunction builtin_v128_lt(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.LtI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.LtU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.LtI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.LtU16x8, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.LtI32x4, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.LtU32x4, arg0, arg1);\n case TypeKind.I64: return module.binary(BinaryOp.LtI64x2, arg0, arg1);\n // no LtU64x2\n case TypeKind.Isize: return module.binary(compiler.options.isWasm64 ? BinaryOp.LtI64x2 : BinaryOp.LtI32x4, arg0, arg1);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n return module.binary(BinaryOp.LtU32x4, arg0, arg1);\n }\n case TypeKind.F32: return module.binary(BinaryOp.LtF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.LtF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.lt\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_lt, builtin_v128_lt);\n\n// v128.le(a: v128, b: v128) -> v128\nfunction builtin_v128_le(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.LeI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.LeU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.LeI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.LeU16x8, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.LeI32x4, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.LeU32x4, arg0, arg1);\n case TypeKind.I64: return module.binary(BinaryOp.LeI64x2, arg0, arg1);\n // no LeU64x2\n case TypeKind.Isize: return module.binary(compiler.options.isWasm64 ? BinaryOp.LeI64x2 : BinaryOp.LeI32x4, arg0, arg1);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n return module.binary(BinaryOp.LeU32x4, arg0, arg1);\n }\n case TypeKind.F32: return module.binary(BinaryOp.LeF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.LeF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.le\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_le, builtin_v128_le);\n\n// v128.gt(a: v128, b: v128) -> v128\nfunction builtin_v128_gt(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.GtI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.GtU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.GtI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.GtU16x8, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.GtI32x4, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.GtU32x4, arg0, arg1);\n case TypeKind.I64: return module.binary(BinaryOp.GtI64x2, arg0, arg1);\n // no GtU64x2\n case TypeKind.Isize: return module.binary(compiler.options.isWasm64 ? BinaryOp.GtI64x2 : BinaryOp.GtI32x4, arg0, arg1);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n return module.binary(BinaryOp.GtU32x4, arg0, arg1);\n }\n case TypeKind.F32: return module.binary(BinaryOp.GtF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.GtF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.gt\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_gt, builtin_v128_gt);\n\n// v128.ge(a: v128, b: v128) -> v128\nfunction builtin_v128_ge(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.GeI8x16, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.GeU8x16, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.GeI16x8, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.GeU16x8, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.GeI32x4, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.GeU32x4, arg0, arg1);\n case TypeKind.I64: return module.binary(BinaryOp.GeI64x2, arg0, arg1);\n // no GeU64x2\n case TypeKind.Isize: return module.binary(compiler.options.isWasm64 ? BinaryOp.GeI64x2 : BinaryOp.GeI32x4, arg0, arg1);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n return module.binary(BinaryOp.GeU32x4, arg0, arg1);\n }\n case TypeKind.F32: return module.binary(BinaryOp.GeF32x4, arg0, arg1);\n case TypeKind.F64: return module.binary(BinaryOp.GeF64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.ge\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_ge, builtin_v128_ge);\n\n// v128.narrow(a: v128, b: v128) -> v128\nfunction builtin_v128_narrow(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I16: return module.binary(BinaryOp.NarrowI16x8ToI8x16, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.NarrowU16x8ToU8x16, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.NarrowI32x4ToI16x8, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.NarrowU32x4ToU16x8, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.narrow\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_narrow, builtin_v128_narrow);\n\n// v128.neg(a: v128) -> v128\nfunction builtin_v128_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.unary(UnaryOp.NegI8x16, arg0);\n case TypeKind.I16:\n case TypeKind.U16: return module.unary(UnaryOp.NegI16x8, arg0);\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.NegI32x4, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.NegI64x2, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.unary(\n compiler.options.isWasm64\n ? UnaryOp.NegI64x2\n : UnaryOp.NegI32x4,\n arg0\n );\n }\n case TypeKind.F32: return module.unary(UnaryOp.NegF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.NegF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.neg\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_neg, builtin_v128_neg);\n\n// v128.abs(a: v128) -> v128\nfunction builtin_v128_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.unary(UnaryOp.AbsI8x16, arg0);\n case TypeKind.I16: return module.unary(UnaryOp.AbsI16x8, arg0);\n case TypeKind.I32: return module.unary(UnaryOp.AbsI32x4, arg0);\n case TypeKind.I64: return module.unary(UnaryOp.AbsI64x2, arg0);\n case TypeKind.Isize: return module.unary(compiler.options.isWasm64 ? UnaryOp.AbsI64x2 : UnaryOp.AbsI32x4, arg0);\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.U64:\n case TypeKind.Usize: return arg0;\n case TypeKind.F32: return module.unary(UnaryOp.AbsF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.AbsF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.abs\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_abs, builtin_v128_abs);\n\n// v128.sqrt(a: v128) -> v128\nfunction builtin_v128_sqrt(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.unary(UnaryOp.SqrtF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.SqrtF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.sqrt\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_sqrt, builtin_v128_sqrt);\n\n// v128.ceil(a: v128) -> v128\nfunction builtin_v128_ceil(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.unary(UnaryOp.CeilF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.CeilF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.ceil\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_ceil, builtin_v128_ceil);\n\n// v128.floor(a: v128) -> v128\nfunction builtin_v128_floor(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.unary(UnaryOp.FloorF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.FloorF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.floor\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_floor, builtin_v128_floor);\n\n// v128.trunc(a: v128) -> v128\nfunction builtin_v128_trunc(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.unary(UnaryOp.TruncF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.TruncF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.trunc\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_trunc, builtin_v128_trunc);\n\n// v128.nearest(a: v128) -> v128\nfunction builtin_v128_nearest(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.unary(UnaryOp.NearestF32x4, arg0);\n case TypeKind.F64: return module.unary(UnaryOp.NearestF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.nearest\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_nearest, builtin_v128_nearest);\n\n// v128.convert(a: v128) -> v128\nfunction builtin_v128_convert(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.unary(UnaryOp.ConvertI32x4ToF32x4, arg0);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.unary(UnaryOp.ConvertU32x4ToF32x4, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.convert\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_convert, builtin_v128_convert);\n\n// v128.convert_low(a: v128) -> v128\nfunction builtin_v128_convert_low(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.unary(UnaryOp.ConvertLowI32x4ToF64x2, arg0);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.unary(UnaryOp.ConvertLowU32x4ToF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.convert_low\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_convert_low, builtin_v128_convert_low);\n\n// v128.trunc_sat(a: v128) -> v128\nfunction builtin_v128_trunc_sat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.unary(UnaryOp.TruncSatF32x4ToI32x4, arg0);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.unary(UnaryOp.TruncSatF32x4ToU32x4, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.trunc_sat\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_trunc_sat, builtin_v128_trunc_sat);\n\n// v128.trunc_sat_zero(a: v128) -> v128\nfunction builtin_v128_trunc_sat_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.unary(UnaryOp.TruncSatF64x2ToI32x4Zero, arg0);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.unary(UnaryOp.TruncSatF64x2ToU32x4Zero, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.trunc_sat_zero\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_trunc_sat_zero, builtin_v128_trunc_sat_zero);\n\n// v128.extend_low(a: v128) -> v128\nfunction builtin_v128_extend_low(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.unary(UnaryOp.ExtendLowI8x16ToI16x8, arg0);\n case TypeKind.U8: return module.unary(UnaryOp.ExtendLowU8x16ToU16x8, arg0);\n case TypeKind.I16: return module.unary(UnaryOp.ExtendLowI16x8ToI32x4, arg0);\n case TypeKind.U16: return module.unary(UnaryOp.ExtendLowU16x8ToU32x4, arg0);\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.unary(UnaryOp.ExtendLowI32x4ToI64x2, arg0);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.unary(UnaryOp.ExtendLowU32x4ToU64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.extend_low\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_extend_low, builtin_v128_extend_low);\n\n// v128.extend_high(a: v128) -> v128\nfunction builtin_v128_extend_high(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.unary(UnaryOp.ExtendHighI8x16ToI16x8, arg0);\n case TypeKind.U8: return module.unary(UnaryOp.ExtendHighU8x16ToU16x8, arg0);\n case TypeKind.I16: return module.unary(UnaryOp.ExtendHighI16x8ToI32x4, arg0);\n case TypeKind.U16: return module.unary(UnaryOp.ExtendHighU16x8ToU32x4, arg0);\n case TypeKind.Isize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.I32: return module.unary(UnaryOp.ExtendHighI32x4ToI64x2, arg0);\n case TypeKind.Usize: {\n if (compiler.options.isWasm64) break;\n // fall-through\n }\n case TypeKind.U32: return module.unary(UnaryOp.ExtendHighU32x4ToU64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.extend_high\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_extend_high, builtin_v128_extend_high);\n\n// v128.shl(a: v128, b: i32) -> v128\nfunction builtin_v128_shl(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let type = ctx.typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.i32, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.simd_shift(SIMDShiftOp.ShlI8x16, arg0, arg1);\n case TypeKind.I16:\n case TypeKind.U16: return module.simd_shift(SIMDShiftOp.ShlI16x8, arg0, arg1);\n case TypeKind.I32:\n case TypeKind.U32: return module.simd_shift(SIMDShiftOp.ShlI32x4, arg0, arg1);\n case TypeKind.I64:\n case TypeKind.U64: return module.simd_shift(SIMDShiftOp.ShlI64x2, arg0, arg1);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.simd_shift(\n compiler.options.isWasm64\n ? SIMDShiftOp.ShlI64x2\n : SIMDShiftOp.ShlI32x4,\n arg0, arg1\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.shl\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_shl, builtin_v128_shl);\n\n// v128.shr(a: v128, b: i32) -> v128\nfunction builtin_v128_shr(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let type = ctx.typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.i32, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.simd_shift(SIMDShiftOp.ShrI8x16, arg0, arg1);\n case TypeKind.U8: return module.simd_shift(SIMDShiftOp.ShrU8x16, arg0, arg1);\n case TypeKind.I16: return module.simd_shift(SIMDShiftOp.ShrI16x8, arg0, arg1);\n case TypeKind.U16: return module.simd_shift(SIMDShiftOp.ShrU16x8, arg0, arg1);\n case TypeKind.I32: return module.simd_shift(SIMDShiftOp.ShrI32x4, arg0, arg1);\n case TypeKind.U32: return module.simd_shift(SIMDShiftOp.ShrU32x4, arg0, arg1);\n case TypeKind.I64: return module.simd_shift(SIMDShiftOp.ShrI64x2, arg0, arg1);\n case TypeKind.U64: return module.simd_shift(SIMDShiftOp.ShrU64x2, arg0, arg1);\n case TypeKind.Isize: {\n return module.simd_shift(\n compiler.options.isWasm64\n ? SIMDShiftOp.ShrI64x2\n : SIMDShiftOp.ShrI32x4,\n arg0, arg1\n );\n }\n case TypeKind.Usize: {\n return module.simd_shift(\n compiler.options.isWasm64\n ? SIMDShiftOp.ShrU64x2\n : SIMDShiftOp.ShrU32x4,\n arg0, arg1\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.shr\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_shr, builtin_v128_shr);\n\nfunction builtin_v128_bitwise_binary(ctx: BuiltinFunctionContext, op: BinaryOp): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n return module.binary(op, arg0, arg1);\n}\n\n// v128.and(a: v128, b: v128) -> v128\nfunction builtin_v128_and(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_v128_bitwise_binary(ctx, BinaryOp.AndV128);\n}\nbuiltinFunctions.set(BuiltinNames.v128_and, builtin_v128_and);\n\n// v128.or(a: v128, b: v128) -> v128\nfunction builtin_v128_or(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_v128_bitwise_binary(ctx, BinaryOp.OrV128);\n}\nbuiltinFunctions.set(BuiltinNames.v128_or, builtin_v128_or);\n\n// v128.xor(a: v128, b: v128) -> v128\nfunction builtin_v128_xor(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_v128_bitwise_binary(ctx, BinaryOp.XorV128);\n}\nbuiltinFunctions.set(BuiltinNames.v128_xor, builtin_v128_xor);\n\n// v128.andnot(a: v128, b: v128) -> v128\nfunction builtin_v128_andnot(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_v128_bitwise_binary(ctx, BinaryOp.AndnotV128);\n}\nbuiltinFunctions.set(BuiltinNames.v128_andnot, builtin_v128_andnot);\n\nfunction builtin_v128_bitwise_unary(ctx: BuiltinFunctionContext, op: UnaryOp): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n return module.unary(op, arg0);\n}\n\n// v128.not(a: v128) -> v128\nfunction builtin_v128_not(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_v128_bitwise_unary(ctx, UnaryOp.NotV128);\n}\nbuiltinFunctions.set(BuiltinNames.v128_not, builtin_v128_not);\n\nfunction builtin_v128_bitwise_ternary(ctx: BuiltinFunctionContext, op: SIMDTernaryOp): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 3)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n let arg2 = compiler.compileExpression(operands[2], Type.v128, Constraints.ConvImplicit);\n return module.simd_ternary(op, arg0, arg1, arg2);\n}\n\n// v128.bitselect(v1: v128, v2: v128, c: v128) -> v128\nfunction builtin_v128_bitselect(ctx: BuiltinFunctionContext): ExpressionRef {\n return builtin_v128_bitwise_ternary(ctx, SIMDTernaryOp.Bitselect);\n}\nbuiltinFunctions.set(BuiltinNames.v128_bitselect, builtin_v128_bitselect);\n\n// v128.any_true(a: v128) -> bool\nfunction builtin_v128_any_true(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.bool;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.bool;\n return module.unary(UnaryOp.AnyTrueV128, arg0);\n}\nbuiltinFunctions.set(BuiltinNames.v128_any_true, builtin_v128_any_true);\n\n// v128.all_true(a: v128) -> bool\nfunction builtin_v128_all_true(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.bool;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let type = ctx.typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.bool;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.unary(UnaryOp.AllTrueI8x16, arg0);\n case TypeKind.I16:\n case TypeKind.U16: return module.unary(UnaryOp.AllTrueI16x8, arg0);\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.AllTrueI32x4, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.AllTrueI64x2, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.unary(\n compiler.options.isWasm64\n ? UnaryOp.AllTrueI64x2\n : UnaryOp.AllTrueI32x4,\n arg0\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.all_true\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_all_true, builtin_v128_all_true);\n\n// v128.bitmask(a: v128) -> i32\nfunction builtin_v128_bitmask(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.i32;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let type = ctx.typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.i32;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.unary(UnaryOp.BitmaskI8x16, arg0);\n case TypeKind.I16:\n case TypeKind.U16: return module.unary(UnaryOp.BitmaskI16x8, arg0);\n case TypeKind.I32:\n case TypeKind.U32: return module.unary(UnaryOp.BitmaskI32x4, arg0);\n case TypeKind.I64:\n case TypeKind.U64: return module.unary(UnaryOp.BitmaskI64x2, arg0);\n case TypeKind.Isize:\n case TypeKind.Usize: {\n return module.unary(\n compiler.options.isWasm64\n ? UnaryOp.BitmaskI64x2\n : UnaryOp.BitmaskI32x4,\n arg0\n );\n }\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.bitmask\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_bitmask, builtin_v128_bitmask);\n\n// v128.popcnt(a: v128) -> v128\nfunction builtin_v128_popcnt(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let type = ctx.typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8:\n case TypeKind.U8: return module.unary(UnaryOp.PopcntI8x16, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.popcnt\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_popcnt, builtin_v128_popcnt);\n\n// v128.extadd_pairwise(a: v128) -> v128\nfunction builtin_v128_extadd_pairwise(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let type = ctx.typeArguments![0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.unary(UnaryOp.ExtaddPairwiseI8x16ToI16x8, arg0);\n case TypeKind.U8: return module.unary(UnaryOp.ExtaddPairwiseU8x16ToU16x8, arg0);\n case TypeKind.I16: return module.unary(UnaryOp.ExtaddPairwiseI16x8ToI32x4, arg0);\n case TypeKind.U16: return module.unary(UnaryOp.ExtaddPairwiseU16x8ToU32x4, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.extadd_pairwise\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_extadd_pairwise, builtin_v128_extadd_pairwise);\n\n// v128.demote_zero(a: v128) -> v128\nfunction builtin_v128_demote_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeOptional(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let type = typeArguments ? typeArguments[0] : Type.f64;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F64: return module.unary(UnaryOp.DemoteZeroF64x2ToF32x4, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.demote_zero\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_demote_zero, builtin_v128_demote_zero);\n\n// v128.promote_low(a: v128) -> v128\nfunction builtin_v128_promote_low(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeOptional(ctx) |\n checkArgsRequired(ctx, 1)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n let type = typeArguments ? typeArguments[0] : Type.f32;\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n compiler.currentType = Type.v128;\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.F32: return module.unary(UnaryOp.PromoteLowF32x4ToF64x2, arg0);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.promote_low\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_promote_low, builtin_v128_promote_low);\n\n// v128.q15mulr_sat(a: v128, b: v128) -> v128\nfunction builtin_v128_q15mulr_sat(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I16: return module.binary(BinaryOp.Q15mulrSatI16x8, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.q15mulr_sat\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_q15mulr_sat, builtin_v128_q15mulr_sat);\n\n// v128.extmul_low(a: v128, b: v128) -> v128\nfunction builtin_v128_extmul_low(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.ExtmulLowI16x8, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.ExtmulLowU16x8, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.ExtmulLowI32x4, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.ExtmulLowU32x4, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.ExtmulLowI64x2, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.ExtmulLowU64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.extmul_low\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_extmul_low, builtin_v128_extmul_low);\n\n// v128.extmul_high(a: v128, b: v128) -> v128\nfunction builtin_v128_extmul_high(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkFeatureEnabled(ctx, Feature.Simd) |\n checkTypeRequired(ctx) |\n checkArgsRequired(ctx, 2)\n ) {\n compiler.currentType = Type.v128;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments!;\n let type = typeArguments[0];\n let arg0 = compiler.compileExpression(operands[0], Type.v128, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.v128, Constraints.ConvImplicit);\n if (type.isValue) {\n switch (type.kind) {\n case TypeKind.I8: return module.binary(BinaryOp.ExtmulHighI16x8, arg0, arg1);\n case TypeKind.U8: return module.binary(BinaryOp.ExtmulHighU16x8, arg0, arg1);\n case TypeKind.I16: return module.binary(BinaryOp.ExtmulHighI32x4, arg0, arg1);\n case TypeKind.U16: return module.binary(BinaryOp.ExtmulHighU32x4, arg0, arg1);\n case TypeKind.I32: return module.binary(BinaryOp.ExtmulHighI64x2, arg0, arg1);\n case TypeKind.U32: return module.binary(BinaryOp.ExtmulHighU64x2, arg0, arg1);\n }\n }\n compiler.error(\n DiagnosticCode.Operation_0_cannot_be_applied_to_type_1,\n ctx.reportNode.typeArgumentsRange, \"v128.extmul_high\", type.toString()\n );\n return module.unreachable();\n}\nbuiltinFunctions.set(BuiltinNames.v128_extmul_high, builtin_v128_extmul_high);\n\n// === Internal runtime =======================================================================\n\n// __visit_globals(cookie: u32) -> void\nfunction builtin_visit_globals(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 1) // cookie\n ) {\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], Type.u32, Constraints.ConvImplicit);\n compiler.runtimeFeatures |= RuntimeFeatures.visitGlobals;\n compiler.currentType = Type.void;\n return module.call(BuiltinNames.visit_globals, [ arg0 ], TypeRef.None);\n}\nbuiltinFunctions.set(BuiltinNames.visit_globals, builtin_visit_globals);\n\n// __visit_members(ref: usize, cookie: u32) -> void\nfunction builtin_visit_members(ctx: BuiltinFunctionContext): ExpressionRef {\n let compiler = ctx.compiler;\n let module = compiler.module;\n if (\n checkTypeAbsent(ctx) |\n checkArgsRequired(ctx, 2) // ref, cookie\n ) {\n compiler.currentType = Type.void;\n return module.unreachable();\n }\n let operands = ctx.operands;\n let arg0 = compiler.compileExpression(operands[0], compiler.options.usizeType, Constraints.ConvImplicit);\n let arg1 = compiler.compileExpression(operands[1], Type.u32, Constraints.ConvImplicit);\n compiler.runtimeFeatures |= RuntimeFeatures.visitMembers;\n compiler.currentType = Type.void;\n return module.call(BuiltinNames.visit_members, [ arg0, arg1 ], TypeRef.None);\n}\nbuiltinFunctions.set(BuiltinNames.visit_members, builtin_visit_members);\n\n// === Inline assembler =======================================================================\n\n// TODO: Operators can't be just deferred (don't have a corresponding generic built-in)\n// add, sub, mul, div_s, div_u, rem_s, rem_u\n// and, or, xor, shl, shr_u, shr_s\n// eq, eqz, ne, lt_s, lt_u, le_s, le_u, gt_s, gt_u, ge_s, ge_u\n\n// i32.clz -> clz\nfunction builtin_i32_clz(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_clz(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_clz, builtin_i32_clz);\n\n// i64.clz -> clz\nfunction builtin_i64_clz(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_clz(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_clz, builtin_i64_clz);\n\n// i32.ctz -> ctz\nfunction builtin_i32_ctz(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_ctz(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_ctz, builtin_i32_ctz);\n\n// i64.ctz -> ctz\nfunction builtin_i64_ctz(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_ctz(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_ctz, builtin_i64_ctz);\n\n// i32.popcnt -> popcnt\nfunction builtin_i32_popcnt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_popcnt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_popcnt, builtin_i32_popcnt);\n\n// i64.popcnt -> popcnt\nfunction builtin_i64_popcnt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_popcnt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_popcnt, builtin_i64_popcnt);\n\n// i32.rotl -> rotl\nfunction builtin_i32_rotl(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_rotl(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_rotl, builtin_i32_rotl);\n\n// i64.rotl -> rotl\nfunction builtin_i64_rotl(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_rotl(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_rotl, builtin_i64_rotl);\n\n// i32.rotr -> rotr\nfunction builtin_i32_rotr(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_rotr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_rotr, builtin_i32_rotr);\n\n// i64.rotr -> rotr\nfunction builtin_i64_rotr(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_rotr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_rotr, builtin_i64_rotr);\n\n// f32.abs -> abs\nfunction builtin_f32_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_abs, builtin_f32_abs);\n\n// f64.abs -> abs\nfunction builtin_f64_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_abs, builtin_f64_abs);\n\n// f32.max -> max\nfunction builtin_f32_max(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_max, builtin_f32_max);\n\n// f64.max -> max\nfunction builtin_f64_max(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_max, builtin_f64_max);\n\n// f32.min -> min\nfunction builtin_f32_min(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_min, builtin_f32_min);\n\n// f64.min -> min\nfunction builtin_f64_min(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_min, builtin_f64_min);\n\n// f32.ceil -> ceil\nfunction builtin_f32_ceil(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_ceil(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_ceil, builtin_f32_ceil);\n\n// f64.ceil -> ceil\nfunction builtin_f64_ceil(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_ceil(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_ceil, builtin_f64_ceil);\n\n// f32.floor -> floor\nfunction builtin_f32_floor(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_floor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_floor, builtin_f32_floor);\n\n// f64.floor -> floor\nfunction builtin_f64_floor(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_floor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_floor, builtin_f64_floor);\n\n// f32.copysign -> copysign\nfunction builtin_f32_copysign(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_copysign(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_copysign, builtin_f32_copysign);\n\n// f64.copysign -> copysign\nfunction builtin_f64_copysign(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_copysign(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_copysign, builtin_f64_copysign);\n\n// f32.nearest -> nearest\nfunction builtin_f32_nearest(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_nearest(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_nearest, builtin_f32_nearest);\n\n// f64.nearest -> nearest\nfunction builtin_f64_nearest(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_nearest(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_nearest, builtin_f64_nearest);\n\n// i32.reinterpret_f32 -> reinterpret\nfunction builtin_i32_reinterpret_f32(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.f32;\n return builtin_reinterpret(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_reinterpret_f32, builtin_i32_reinterpret_f32);\n\n// i64.reinterpret_f64 -> reinterpret\nfunction builtin_i64_reinterpret_f64(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.f64;\n return builtin_reinterpret(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_reinterpret_f64, builtin_i64_reinterpret_f64);\n\n// f32.reinterpret_i32 -> reinterpret\nfunction builtin_f32_reinterpret_i32(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.i32;\n return builtin_reinterpret(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_reinterpret_i32, builtin_f32_reinterpret_i32);\n\n// f64.reinterpret_i64 -> reinterpret\nfunction builtin_f64_reinterpret_i64(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.i64;\n return builtin_reinterpret(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_reinterpret_i64, builtin_f64_reinterpret_i64);\n\n// f32.sqrt -> sqrt\nfunction builtin_f32_sqrt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_sqrt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_sqrt, builtin_f32_sqrt);\n\n// f64.sqrt -> sqrt\nfunction builtin_f64_sqrt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_sqrt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_sqrt, builtin_f64_sqrt);\n\n// f32.trunc -> trunc\nfunction builtin_f32_trunc(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_trunc(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_trunc, builtin_f32_trunc);\n\n// f64.trunc -> trunc\nfunction builtin_f64_trunc(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_trunc(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_trunc, builtin_f64_trunc);\n\n// i32.rem_s -> rem\nfunction builtin_i32_rem_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_rem(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_rem_s, builtin_i32_rem_s);\n\n// i32.rem_u -> rem\nfunction builtin_i32_rem_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.u32;\n return builtin_rem(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_rem_u, builtin_i32_rem_u);\n\n// i64.rem_s -> rem\nfunction builtin_i64_rem_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_rem(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_rem_s, builtin_i64_rem_s);\n\n// i64.rem_u -> rem\nfunction builtin_i64_rem_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.u64;\n return builtin_rem(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_rem_u, builtin_i64_rem_u);\n\n// i32.add -> add\nfunction builtin_i32_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_add, builtin_i32_add);\n\n// i64.add -> add\nfunction builtin_i64_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_add, builtin_i64_add);\n\n// f32.add -> add\nfunction builtin_f32_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_add, builtin_f32_add);\n\n// f64.add -> add\nfunction builtin_f64_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_add, builtin_f64_add);\n\n// i32.sub -> sub\nfunction builtin_i32_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_sub, builtin_i32_sub);\n\n// i64.sub -> sub\nfunction builtin_i64_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_sub, builtin_i64_sub);\n\n// f32.sub -> sub\nfunction builtin_f32_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_sub, builtin_f32_sub);\n\n// f64.sub -> sub\nfunction builtin_f64_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_sub, builtin_f64_sub);\n\n// i32.mul -> mul\nfunction builtin_i32_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_mul, builtin_i32_mul);\n\n// i64.mul -> mul\nfunction builtin_i64_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_mul, builtin_i64_mul);\n\n// f32.mul -> mul\nfunction builtin_f32_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_mul, builtin_f32_mul);\n\n// f64.mul -> mul\nfunction builtin_f64_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_mul, builtin_f64_mul);\n\n// i32.div_s -> div\nfunction builtin_i32_div_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_div_s, builtin_i32_div_s);\n\n// i32.div_u -> div\nfunction builtin_i32_div_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.u32;\n return builtin_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_div_u, builtin_i32_div_u);\n\n// i64.div_s -> div_s\nfunction builtin_i64_div_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_div_s, builtin_i64_div_s);\n\n// i64.div_u -> div_u\nfunction builtin_i64_div_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.u64;\n return builtin_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_div_u, builtin_i64_div_u);\n\n// f32.div -> div\nfunction builtin_f32_div(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_div, builtin_f32_div);\n\n// f64.div -> div\nfunction builtin_f64_div(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_div, builtin_f64_div);\n\n// i32.eq -> eq\nfunction builtin_i32_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_eq, builtin_i32_eq);\n\n// i64.eq -> eq\nfunction builtin_i64_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i32;\n return builtin_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_eq, builtin_i64_eq);\n\n// f32.eq -> eq\nfunction builtin_f32_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.i32;\n return builtin_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_eq, builtin_f32_eq);\n\n// f64.eq -> eq\nfunction builtin_f64_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.i32;\n return builtin_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_eq, builtin_f64_eq);\n\n// i32.ne -> ne\nfunction builtin_i32_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_ne, builtin_i32_ne);\n\n// i64.ne -> ne\nfunction builtin_i64_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i32;\n return builtin_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_ne, builtin_i64_ne);\n\n// f32.ne -> ne\nfunction builtin_f32_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.i32;\n return builtin_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_ne, builtin_f32_ne);\n\n// f64.ne-> ne\nfunction builtin_f64_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.i32;\n return builtin_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_ne, builtin_f64_ne);\n\n// i32.load8_s -> load\nfunction builtin_i32_load8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i32;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_load8_s, builtin_i32_load8_s);\n\n// i32.load8_u -> load\nfunction builtin_i32_load8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_load8_u, builtin_i32_load8_u);\n\n// i32.load16_s -> load\nfunction builtin_i32_load16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i32;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_load16_s, builtin_i32_load16_s);\n\n// i32.load16_u -> load\nfunction builtin_i32_load16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_load16_u, builtin_i32_load16_u);\n\n// i32.load -> load\nfunction builtin_i32_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_load, builtin_i32_load);\n\n// i64.load8_s -> load\nfunction builtin_i64_load8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load8_s, builtin_i64_load8_s);\n\n// i64.load8_u -> load\nfunction builtin_i64_load8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load8_u, builtin_i64_load8_u);\n\n// i64.load16_s -> load\nfunction builtin_i64_load16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load16_s, builtin_i64_load16_s);\n\n// i64.load16_u -> load\nfunction builtin_i64_load16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load16_u, builtin_i64_load16_u);\n\n// i64.load32_s -> load\nfunction builtin_i64_load32_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load32_s, builtin_i64_load32_s);\n\n// i64.load32_u -> load\nfunction builtin_i64_load32_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load32_u, builtin_i64_load32_u);\n\n// i64.load -> load\nfunction builtin_i64_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_load, builtin_i64_load);\n\n// f32.load -> load\nfunction builtin_f32_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_load, builtin_f32_load);\n\n// f64.load -> load\nfunction builtin_f64_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_load, builtin_f64_load);\n\n// i32.store8 -> store\nfunction builtin_i32_store8(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_store8, builtin_i32_store8);\n\n// i32.store16 -> store\nfunction builtin_i32_store16(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_store16, builtin_i32_store16);\n\n// i32.store -> store\nfunction builtin_i32_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_store, builtin_i32_store);\n\n// i64.store8 -> store\nfunction builtin_i64_store8(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_store8, builtin_i64_store8);\n\n// i64.store16 -> store\nfunction builtin_i64_store16(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_store16, builtin_i64_store16);\n\n// i64.store32 -> store\nfunction builtin_i64_store32(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_store32, builtin_i64_store32);\n\n// i64.store -> store\nfunction builtin_i64_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_store, builtin_i64_store);\n\n// f32.store -> store\nfunction builtin_f32_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32_store, builtin_f32_store);\n\n// f64.store -> store\nfunction builtin_f64_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64_store, builtin_f64_store);\n\n// i32.atomic.load8_u -> atomic.load\nfunction builtin_i32_atomic_load8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_load8_u, builtin_i32_atomic_load8_u);\n\n// i32.atomic.load16_u -> atomic.load\nfunction builtin_i32_atomic_load16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_load16_u, builtin_i32_atomic_load16_u);\n\n// i32.atomic.load -> atomic.load\nfunction builtin_i32_atomic_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_load, builtin_i32_atomic_load);\n\n// i64.atomic.load8_u -> atomic.load\nfunction builtin_i64_atomic_load8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_load8_u, builtin_i64_atomic_load8_u);\n\n// i64.atomic.load16_u -> atomic.load\nfunction builtin_i64_atomic_load16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_load16_u, builtin_i64_atomic_load16_u);\n\n// i64.atomic.load32_u -> atomic.load\nfunction builtin_i64_atomic_load32_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_load32_u, builtin_i64_atomic_load32_u);\n\n// i64.atomic.load -> atomic.load\nfunction builtin_i64_atomic_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_atomic_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_load, builtin_i64_atomic_load);\n\n// i32.atomic.store8 -> atomic.store\nfunction builtin_i32_atomic_store8(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_store8, builtin_i32_atomic_store8);\n\n// i32.atomic.store16 -> atomic.store\nfunction builtin_i32_atomic_store16(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_store16, builtin_i32_atomic_store16);\n\n// i32.atomic.store -> atomic.store\nfunction builtin_i32_atomic_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_store, builtin_i32_atomic_store);\n\n// i64.atomic.store8 -> atomic.store\nfunction builtin_i64_atomic_store8(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_store8, builtin_i64_atomic_store8);\n\n// i64.atomic.store16 -> atomic.store\nfunction builtin_i64_atomic_store16(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_store16, builtin_i64_atomic_store16);\n\n// i64.atomic.store32 -> atomic.store\nfunction builtin_i64_atomic_store32(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_store32, builtin_i64_atomic_store32);\n\n// i64.atomic.store -> atomic.store\nfunction builtin_i64_atomic_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_store, builtin_i64_atomic_store);\n\n// i32.atomic.rmw8.add_u -> atomic.add\nfunction builtin_i32_atomic_rmw8_add_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_add_u, builtin_i32_atomic_rmw8_add_u);\n\n// i32.atomic.rmw16.add_u -> atomic.add\nfunction builtin_i32_atomic_rmw16_add_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_add_u, builtin_i32_atomic_rmw16_add_u);\n\n// i32.atomic.rmw.add -> atomic.add\nfunction builtin_i32_atomic_rmw_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_add, builtin_i32_atomic_rmw_add);\n\n// i64.atomic.rmw8.add_u -> atomic.add\nfunction builtin_i64_atomic_rmw8_add_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_add_u, builtin_i64_atomic_rmw8_add_u);\n\n// i64.atomic.rmw16.add_u -> atomic.add\nfunction builtin_i64_atomic_rmw16_add_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_add_u, builtin_i64_atomic_rmw16_add_u);\n\n// i64.atomic.rmw32.add_u -> atomic.add\nfunction builtin_i64_atomic_rmw32_add_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_add_u, builtin_i64_atomic_rmw32_add_u);\n\n// i64.atomic.rmw.add -> atomic.add\nfunction builtin_i64_atomic_rmw_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_add, builtin_i64_atomic_rmw_add);\n\n// i32.atomic.rmw8.sub_u -> atomic.sub\nfunction builtin_i32_atomic_rmw8_sub_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_sub_u, builtin_i32_atomic_rmw8_sub_u);\n\n// i32.atomic.rmw16.sub_u -> atomic.sub\nfunction builtin_i32_atomic_rmw16_sub_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_sub_u, builtin_i32_atomic_rmw16_sub_u);\n\n// i32.atomic.rmw.sub -> atomic.sub\nfunction builtin_i32_atomic_rmw_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_sub, builtin_i32_atomic_rmw_sub);\n\n// i64.atomic.rmw8.sub_u -> atomic.sub\nfunction builtin_i64_atomic_rmw8_sub_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_sub_u, builtin_i64_atomic_rmw8_sub_u);\n\n// i64.atomic.rmw16.sub_u -> atomic.sub\nfunction builtin_i64_atomic_rmw16_sub_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_sub_u, builtin_i64_atomic_rmw16_sub_u);\n\n// i64.atomic.rmw32.sub_u -> atomic.sub\nfunction builtin_i64_atomic_rmw32_sub_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_sub_u, builtin_i64_atomic_rmw32_sub_u);\n\n// i64.atomic.rmw.sub -> atomic.sub\nfunction builtin_i64_atomic_rmw_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_sub, builtin_i64_atomic_rmw_sub);\n\n// i32.atomic.rmw8.and_u -> atomic.and\nfunction builtin_i32_atomic_rmw8_and_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_and_u, builtin_i32_atomic_rmw8_and_u);\n\n// i32.atomic.rmw16.and_u -> atomic.and\nfunction builtin_i32_atomic_rmw16_and_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_and_u, builtin_i32_atomic_rmw16_and_u);\n\n// i32.atomic.rmw.and -> atomic.and\nfunction builtin_i32_atomic_rmw_and(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_and, builtin_i32_atomic_rmw_and);\n\n// i64.atomic.rmw8.and_u -> atomic.and\nfunction builtin_i64_atomic_rmw8_and_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_and_u, builtin_i64_atomic_rmw8_and_u);\n\n// i64.atomic.rmw16.and_u -> atomic.and\nfunction builtin_i64_atomic_rmw16_and_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_and_u, builtin_i64_atomic_rmw16_and_u);\n\n// i64.atomic.rmw32.and_u -> atomic.and\nfunction builtin_i64_atomic_rmw32_and_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_and_u, builtin_i64_atomic_rmw32_and_u);\n\n// i64.atomic.rmw.and -> atomic.and\nfunction builtin_i64_atomic_rmw_and(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_and(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_and, builtin_i64_atomic_rmw_and);\n\n// i32.atomic.rmw8.or_u -> atomic.or\nfunction builtin_i32_atomic_rmw8_or_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_or_u, builtin_i32_atomic_rmw8_or_u);\n\n// i32.atomic.rmw16.or_u -> \nfunction builtin_i32_atomic_rmw16_or_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_or_u, builtin_i32_atomic_rmw16_or_u);\n\n// i32.atomic.rmw.or -> atomic.or\nfunction builtin_i32_atomic_rmw_or(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_or, builtin_i32_atomic_rmw_or);\n\n// i64.atomic.rmw8.or_u -> atomic.or\nfunction builtin_i64_atomic_rmw8_or_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_or_u, builtin_i64_atomic_rmw8_or_u);\n\n// i64.atomic.rmw16.or_u -> atomic.or\nfunction builtin_i64_atomic_rmw16_or_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_or_u, builtin_i64_atomic_rmw16_or_u);\n\n// i64.atomic.rmw32.or_u -> atomic.or\nfunction builtin_i64_atomic_rmw32_or_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_or_u, builtin_i64_atomic_rmw32_or_u);\n\n// i64.atomic.rmw.or -> atomic.or\nfunction builtin_i64_atomic_rmw_or(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_or(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_or, builtin_i64_atomic_rmw_or);\n\n// i32.atomic.rmw8.xor_u -> atomic.xor\nfunction builtin_i32_atomic_rmw8_xor_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_xor_u, builtin_i32_atomic_rmw8_xor_u);\n\n// i32.atomic.rmw16.xor_u -> atomic.xor\nfunction builtin_i32_atomic_rmw16_xor_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_xor_u, builtin_i32_atomic_rmw16_xor_u);\n\n// i32.atomic.rmw.xor -> atomic.xor\nfunction builtin_i32_atomic_rmw_xor(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_xor, builtin_i32_atomic_rmw_xor);\n\n// i64.atomic.rmw8.xor_u -> atomic.xor\nfunction builtin_i64_atomic_rmw8_xor_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_xor_u, builtin_i64_atomic_rmw8_xor_u);\n\n// i64.atomic.rmw16.xor_u -> atomic.xor\nfunction builtin_i64_atomic_rmw16_xor_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_xor_u, builtin_i64_atomic_rmw16_xor_u);\n\n// i64.atomic.rmw32.xor_u -> atomic.xor\nfunction builtin_i64_atomic_rmw32_xor_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_xor_u, builtin_i64_atomic_rmw32_xor_u);\n\n// i64.atomic.rmw.xor -> atomic.xor\nfunction builtin_i64_atomic_rmw_xor(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_xor, builtin_i64_atomic_rmw_xor);\n\n// i32.atomic.rmw8.xchg_u -> atomic.xchg\nfunction builtin_i32_atomic_rmw8_xchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_xchg_u, builtin_i32_atomic_rmw8_xchg_u);\n\n// i32.atomic.rmw16.xchg_u -> atomic.xchg\nfunction builtin_i32_atomic_rmw16_xchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_xchg_u, builtin_i32_atomic_rmw16_xchg_u);\n\n// i32.atomic.rmw.xchg -> atomic.xchg\nfunction builtin_i32_atomic_rmw_xchg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_xchg, builtin_i32_atomic_rmw_xchg);\n\n// i64.atomic.rmw8.xchg_u -> atomic.xchg\nfunction builtin_i64_atomic_rmw8_xchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_xchg_u, builtin_i64_atomic_rmw8_xchg_u);\n\n// i64.atomic.rmw16.xchg_u -> atomic.xchg\nfunction builtin_i64_atomic_rmw16_xchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_xchg_u, builtin_i64_atomic_rmw16_xchg_u);\n\n// i64.atomic.rmw32.xchg_u -> atomic.xchg\nfunction builtin_i64_atomic_rmw32_xchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_xchg_u, builtin_i64_atomic_rmw32_xchg_u);\n\n// i64.atomic.rmw.xchg -> atomic.xchg\nfunction builtin_i64_atomic_rmw_xchg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_xchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_xchg, builtin_i64_atomic_rmw_xchg);\n\n// i32.atomic.rmw8.cmpxchg_u -> atomic.cmpxchg\nfunction builtin_i32_atomic_rmw8_cmpxchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw8_cmpxchg_u, builtin_i32_atomic_rmw8_cmpxchg_u);\n\n// i32.atomic.rmw16.cmpxchg_u -> atomic.cmpxchg\nfunction builtin_i32_atomic_rmw16_cmpxchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw16_cmpxchg_u, builtin_i32_atomic_rmw16_cmpxchg_u);\n\n// i32.atomic.rmw.cmpxchg -> atomic.cmpxchg\nfunction builtin_i32_atomic_rmw_cmpxchg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32_atomic_rmw_cmpxchg, builtin_i32_atomic_rmw_cmpxchg);\n\n// i64.atomic.rmw8.cmpxchg_u -> atomic.cmpxchg\nfunction builtin_i64_atomic_rmw8_cmpxchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw8_cmpxchg_u, builtin_i64_atomic_rmw8_cmpxchg_u);\n\n// i64.atomic.rmw16.cmpxchg_u -> atomic.cmpxchg\nfunction builtin_i64_atomic_rmw16_cmpxchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw16_cmpxchg_u, builtin_i64_atomic_rmw16_cmpxchg_u);\n\n// i64.atomic.rmw32.cmpxchg_u -> atomic.cmpxchg\nfunction builtin_i64_atomic_rmw32_cmpxchg_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw32_cmpxchg_u, builtin_i64_atomic_rmw32_cmpxchg_u);\n\n// i64.atomic.rmw.cmpxchg -> atomic.cmpxchg\nfunction builtin_i64_atomic_rmw_cmpxchg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n ctx.contextIsExact = true;\n return builtin_atomic_cmpxchg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64_atomic_rmw_cmpxchg, builtin_i64_atomic_rmw_cmpxchg);\n\n// memory.atomic.wait32 -> atomic.wait\nfunction builtin_memory_atomic_wait32(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n return builtin_atomic_wait(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.memory_atomic_wait32, builtin_memory_atomic_wait32);\n\n// memory.atomic.wait64 -> atomic.wait\nfunction builtin_memory_atomic_wait64(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i32;\n return builtin_atomic_wait(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.memory_atomic_wait64, builtin_memory_atomic_wait64);\n\n// v128.load -> load\nfunction builtin_v128_load(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.v128 ];\n ctx.contextualType = Type.v128;\n return builtin_load(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load, builtin_v128_load);\n\n// v128.load8x8_s -> v128.load_ext\nfunction builtin_v128_load8x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_ext(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load8x8_s, builtin_v128_load8x8_s);\n\n// v128.load8x8_u -> v128.load_ext\nfunction builtin_v128_load8x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_ext(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load8x8_u, builtin_v128_load8x8_u);\n\n// v128.load16x4_s -> v128.load_ext\nfunction builtin_v128_load16x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_ext(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load16x4_s, builtin_v128_load16x4_s);\n\n// v128.load16x4_u -> v128.load_ext\nfunction builtin_v128_load16x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_ext(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load16x4_u, builtin_v128_load16x4_u);\n\n// v128.load32x2_s -> v128.load_ext\nfunction builtin_v128_load32x2_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_ext(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load32x2_s, builtin_v128_load32x2_s);\n\n// v128.load32x2_u -> v128.load_ext\nfunction builtin_v128_load32x2_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_ext(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load32x2_u, builtin_v128_load32x2_u);\n\n// v128.load8_splat -> v128.load_splat\nfunction builtin_v128_load8_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load8_splat, builtin_v128_load8_splat);\n\n// v128.load16_splat -> v128.load_splat\nfunction builtin_v128_load16_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load16_splat, builtin_v128_load16_splat);\n\n// v128.load32_splat -> v128.load_splat\nfunction builtin_v128_load32_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load32_splat, builtin_v128_load32_splat);\n\n// v128.load64_splat -> v128.load_splat\nfunction builtin_v128_load64_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load64_splat, builtin_v128_load64_splat);\n\n// v128.load32_zero -> v128.load_zero\nfunction builtin_v128_load32_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_zero(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load32_zero, builtin_v128_load32_zero);\n\n// v128.load64_zero -> v128.load_zero\nfunction builtin_v128_load64_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_zero(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load64_zero, builtin_v128_load64_zero);\n\n// v128.load8_lane -> v128.load_lane\nfunction builtin_v128_load8_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load8_lane, builtin_v128_load8_lane);\n\n// v128.load16_lane -> v128.load_lane\nfunction builtin_v128_load16_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load16_lane, builtin_v128_load16_lane);\n\n// v128.load32_lane -> v128.load_lane\nfunction builtin_v128_load32_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load32_lane, builtin_v128_load32_lane);\n\n// v128.load64_lane -> v128.load_lane\nfunction builtin_v128_load64_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_load_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_load64_lane, builtin_v128_load64_lane);\n\n// v128.store8_lane -> v128.store_lane\nfunction builtin_v128_store8_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_store_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_store8_lane, builtin_v128_store8_lane);\n\n// v128.store16_lane -> v128.store_lane\nfunction builtin_v128_store16_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_store_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_store16_lane, builtin_v128_store16_lane);\n\n// v128.store32_lane -> v128.store_lane\nfunction builtin_v128_store32_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_store_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_store32_lane, builtin_v128_store32_lane);\n\n// v128.store64_lane -> v128.store_lane\nfunction builtin_v128_store64_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_store_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_store64_lane, builtin_v128_store64_lane);\n\n// v128.store -> store\nfunction builtin_v128_store(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.v128 ];\n ctx.contextualType = Type.v128;\n ctx.contextIsExact = true;\n return builtin_store(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.v128_store, builtin_v128_store);\n\n// i8x16_splat -> v128.splat\nfunction builtin_i8x16_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_splat, builtin_i8x16_splat);\n\n// i8x16.extract_lane_s -> v128.extract_lane\nfunction builtin_i8x16_extract_lane_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_extract_lane_s, builtin_i8x16_extract_lane_s);\n\n// i8x16.extract_lane_u -> v128.extract_lane\nfunction builtin_i8x16_extract_lane_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_extract_lane_u, builtin_i8x16_extract_lane_u);\n\n// i8x16.replace_lane -> v128.replace_lane\nfunction builtin_i8x16_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_replace_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_replace_lane, builtin_i8x16_replace_lane);\n\n// i8x16.add -> v128.add\nfunction builtin_i8x16_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_add, builtin_i8x16_add);\n\n// i8x16.sub -> v128.sub\nfunction builtin_i8x16_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_sub, builtin_i8x16_sub);\n\n// i8x16.min_s -> v128.min\nfunction builtin_i8x16_min_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_min_s, builtin_i8x16_min_s);\n\n// i8x16.min_u -> v128.min\nfunction builtin_i8x16_min_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_min_u, builtin_i8x16_min_u);\n\n// i8x16.max_s -> v128.max\nfunction builtin_i8x16_max_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_max_s, builtin_i8x16_max_s);\n\n// i8x16.max_u -> v128.max\nfunction builtin_i8x16_max_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_max_u, builtin_i8x16_max_u);\n\n// i8x16.avgr_u -> v128.avgr\nfunction builtin_i8x16_avgr_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_avgr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_avgr_u, builtin_i8x16_avgr_u);\n\n// i8x16.abs -> v128.abs\nfunction builtin_i8x16_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_abs, builtin_i8x16_abs);\n\n// i8x16.neg -> v128.neg\nfunction builtin_i8x16_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_neg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_neg, builtin_i8x16_neg);\n\n// i8x16.add_sat_s -> v128.add_sat\nfunction builtin_i8x16_add_sat_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_add_sat_s, builtin_i8x16_add_sat_s);\n\n// i8x16.add_sat_u -> v128.add_sat\nfunction builtin_i8x16_add_sat_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_add_sat_u, builtin_i8x16_add_sat_u);\n\n// i8x16.sub_sat_s -> v128.sub_sat\nfunction builtin_i8x16_sub_sat_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_sub_sat_s, builtin_i8x16_sub_sat_s);\n\n// i8x16.sub_sat_u -> v128.sub_sat\nfunction builtin_i8x16_sub_sat_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_sub_sat_u, builtin_i8x16_sub_sat_u);\n\n// i8x16.shl -> v128.shl\nfunction builtin_i8x16_shl(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shl(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_shl, builtin_i8x16_shl);\n\n// i8x16.shr_s -> v128.shr\nfunction builtin_i8x16_shr_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_shr_s, builtin_i8x16_shr_s);\n\n// i8x16.shr_u -> v128.shr\nfunction builtin_i8x16_shr_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_shr_u, builtin_i8x16_shr_u);\n\n// i8x16.all_true -> v128.all_true\nfunction builtin_i8x16_all_true(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_all_true(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_all_true, builtin_i8x16_all_true);\n\n// i8x16.bitmask -> v128.bitmask\nfunction builtin_i8x16_bitmask(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_bitmask(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_bitmask, builtin_i8x16_bitmask);\n\n// i8x16.popcnt -> v128.popcnt\nfunction builtin_i8x16_popcnt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_popcnt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_popcnt, builtin_i8x16_popcnt);\n\n// i8x16.eq -> v128.eq\nfunction builtin_i8x16_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_eq, builtin_i8x16_eq);\n\n// i8x16.ne -> v128.ne\nfunction builtin_i8x16_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_ne, builtin_i8x16_ne);\n\n// i8x16.lt_s -> v128.lt\nfunction builtin_i8x16_lt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_lt_s, builtin_i8x16_lt_s);\n\n// i8x16.lt_u -> v128.lt\nfunction builtin_i8x16_lt_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_lt_u, builtin_i8x16_lt_u);\n\n// i8x16.le_s -> v128.le\nfunction builtin_i8x16_le_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_le_s, builtin_i8x16_le_s);\n\n// i8x16.le_u -> v128.le\nfunction builtin_i8x16_le_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_le_u, builtin_i8x16_le_u);\n\n// i8x16.gt_s -> v128.gt\nfunction builtin_i8x16_gt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_gt_s, builtin_i8x16_gt_s);\n\n// i8x16.gt_u -> v128.gt\nfunction builtin_i8x16_gt_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_gt_u, builtin_i8x16_gt_u);\n\n// i8x16.ge_s -> v128.ge\nfunction builtin_i8x16_ge_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_ge_s, builtin_i8x16_ge_s);\n\n// i8x16.ge_u -> v128.ge\nfunction builtin_i8x16_ge_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_ge_u, builtin_i8x16_ge_u);\n\n// i8x16.narrow_i16x8_s -> v128.narrow\nfunction builtin_i8x16_narrow_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_narrow(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_narrow_i16x8_s, builtin_i8x16_narrow_i16x8_s);\n\n// i8x16.narrow_i16x8_u -> v128.narrow\nfunction builtin_i8x16_narrow_i16x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_narrow(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_narrow_i16x8_u, builtin_i8x16_narrow_i16x8_u);\n\n// i8x16.shuffle -> v128.shuffle\nfunction builtin_i8x16_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shuffle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_shuffle, builtin_i8x16_shuffle);\n\n// i8x16.swizzle -> v128.swizzle\nfunction builtin_i8x16_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n ctx.typeArguments = null;\n ctx.contextualType = Type.v128;\n return builtin_v128_swizzle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i8x16_swizzle, builtin_i8x16_swizzle);\n\n// i16x8.splat -> v128.splat\nfunction builtin_i16x8_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_splat, builtin_i16x8_splat);\n\n// i16x8.extract_lane_s -> v128.extract_lane\nfunction builtin_i16x8_extract_lane_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extract_lane_s, builtin_i16x8_extract_lane_s);\n\n// i16x8..extract_lane_u -> v128.extract_lane\nfunction builtin_i16x8_extract_lane_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extract_lane_u, builtin_i16x8_extract_lane_u);\n\n// i16x8.replace_lane -> v128.replace_lane\nfunction builtin_i16x8_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_replace_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_replace_lane, builtin_i16x8_replace_lane);\n\n// i16x8.add -> v128.add\nfunction builtin_i16x8_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_add, builtin_i16x8_add);\n\n// i16x8.sub -> v128.sub\nfunction builtin_i16x8_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_sub, builtin_i16x8_sub);\n\n// i16x8.mul -> v128.mul\nfunction builtin_i16x8_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_mul, builtin_i16x8_mul);\n\n// i16x8.min_s -> v128.min\nfunction builtin_i16x8_min_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_min_s, builtin_i16x8_min_s);\n\n// i16x8.min_u -> v128.min\nfunction builtin_i16x8_min_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_min_u, builtin_i16x8_min_u);\n\n// i16x8.max_s -> v128.max\nfunction builtin_i16x8_max_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_max_s, builtin_i16x8_max_s);\n\n// i16x8.max_u -> v128.max\nfunction builtin_i16x8_max_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_max_u, builtin_i16x8_max_u);\n\n// i16x8.avgr_u -> v128.avgr\nfunction builtin_i16x8_avgr_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_avgr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_avgr_u, builtin_i16x8_avgr_u);\n\n// i16x8.abs -> v128.abs\nfunction builtin_i16x8_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_abs, builtin_i16x8_abs);\n\n// i16x8.neg -> v128.neg\nfunction builtin_i16x8_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_neg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_neg, builtin_i16x8_neg);\n\n// i16x8.add_sat_s -> v128.add_sat\nfunction builtin_i16x8_add_sat_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_add_sat_s, builtin_i16x8_add_sat_s);\n\n// i16x8.add_sat_u -> v128.add_sat\nfunction builtin_i16x8_add_sat_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_add_sat_u, builtin_i16x8_add_sat_u);\n\n// i16x8.sub_sat_s -> v128.sub_sat\nfunction builtin_i16x8_sub_sat_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_sub_sat_s, builtin_i16x8_sub_sat_s);\n\n// i16x8.sub_sat_u -> v128.sub_sat\nfunction builtin_i16x8_sub_sat_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_sub_sat_u, builtin_i16x8_sub_sat_u);\n\n// i16x8.shl -> v128.shl\nfunction builtin_i16x8_shl(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shl(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_shl, builtin_i16x8_shl);\n\n// i16x8.shr_s -> v128.shr\nfunction builtin_i16x8_shr_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_shr_s, builtin_i16x8_shr_s);\n\n// i16x8.shr_u -> v128.shr\nfunction builtin_i16x8_shr_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_shr_u, builtin_i16x8_shr_u);\n\n// i16x8.all_true -> v128.all_true\nfunction builtin_i16x8_all_true(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_all_true(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_all_true, builtin_i16x8_all_true);\n\n// i16x8.bitmask -> v128.bitmask\nfunction builtin_i16x8_bitmask(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_bitmask(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_bitmask, builtin_i16x8_bitmask);\n\n// i16x8.eq -> v128.eq\nfunction builtin_i16x8_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_eq, builtin_i16x8_eq);\n\n// i16x8.ne -> v128.ne\nfunction builtin_i16x8_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_ne, builtin_i16x8_ne);\n\n// i16x8.lt_s -> v128.lt\nfunction builtin_i16x8_lt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_lt_s, builtin_i16x8_lt_s);\n\n// i16x8.lt_u -> v128.lt\nfunction builtin_i16x8_lt_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_lt_u, builtin_i16x8_lt_u);\n\n// i16x8.le_s -> v128.le\nfunction builtin_i16x8_le_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_le_s, builtin_i16x8_le_s);\n\n// i16x8.le_u -> v128.le\nfunction builtin_i16x8_le_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_le_u, builtin_i16x8_le_u);\n\n// i16x8.gt_s -> v128.gt\nfunction builtin_i16x8_gt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_gt_s, builtin_i16x8_gt_s);\n\n// i16x8.gt_u -> v128.gt\nfunction builtin_i16x8_gt_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_gt_u, builtin_i16x8_gt_u);\n\n// i16x8.ge_s -> v128.ge\nfunction builtin_i16x8_ge_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_ge_s, builtin_i16x8_ge_s);\n\n// i16x8.ge_u -> v128.ge\nfunction builtin_i16x8_ge_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_ge_u, builtin_i16x8_ge_u);\n\n// i16x8.narrow_i32x4_s -> v128.narrow\nfunction builtin_i16x8_narrow_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_narrow(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_narrow_i32x4_s, builtin_i16x8_narrow_i32x4_s);\n\n// i16x8.narrow_i32x4_u -> v128.narrow\nfunction builtin_i16x8_narrow_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_narrow(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_narrow_i32x4_u, builtin_i16x8_narrow_i32x4_u);\n\n// i16x8.extend_low_i8x16_s -> v128.extend_low\nfunction builtin_i16x8_extend_low_i8x16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extend_low_i8x16_s, builtin_i16x8_extend_low_i8x16_s);\n\n// i16x8.extend_low_i8x16_u -> v128.extend_low\nfunction builtin_i16x8_extend_low_i8x16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extend_low_i8x16_u, builtin_i16x8_extend_low_i8x16_u);\n\n// i16x8.extend_high_i8x16_s -> v128.extend_high\nfunction builtin_i16x8_extend_high_i8x16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extend_high_i8x16_s, builtin_i16x8_extend_high_i8x16_s);\n\n// i16x8.extend_high_i8x16_u -> v128.extend_high\nfunction builtin_i16x8_extend_high_i8x16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extend_high_i8x16_u, builtin_i16x8_extend_high_i8x16_u);\n\n// i16x8.extadd_pairwise_i8x16_s -> v128.extadd_pairwise\nfunction builtin_i16x8_extadd_pairwise_i8x16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extadd_pairwise(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extadd_pairwise_i8x16_s, builtin_i16x8_extadd_pairwise_i8x16_s);\n\n// i16x8.extadd_pairwise_i8x16_u -> v128.extadd_pairwise\nfunction builtin_i16x8_extadd_pairwise_i8x16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extadd_pairwise(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extadd_pairwise_i8x16_u, builtin_i16x8_extadd_pairwise_i8x16_u);\n\n// i16x8.q15mulr_sat_s -> v128.q15mulr_sat\nfunction builtin_i16x8_q15mulr_sat_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_q15mulr_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_q15mulr_sat_s, builtin_i16x8_q15mulr_sat_s);\n\n// i16x8.extmul_low_i8x16_s -> v128.extmul_low\nfunction builtin_i16x8_extmul_low_i8x16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extmul_low_i8x16_s, builtin_i16x8_extmul_low_i8x16_s);\n\n// i16x8.extmul_low_i8x16_u -> v128.extmul_low\nfunction builtin_i16x8_extmul_low_i8x16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extmul_low_i8x16_u, builtin_i16x8_extmul_low_i8x16_u);\n\n// i16x8.extmul_high_i8x16_s -> v128.extmul_high\nfunction builtin_i16x8_extmul_high_i8x16_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extmul_high_i8x16_s, builtin_i16x8_extmul_high_i8x16_s);\n\n// i16x8.extmul_high_i8x16_u -> v128.extmul_high\nfunction builtin_i16x8_extmul_high_i8x16_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u8 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_extmul_high_i8x16_u, builtin_i16x8_extmul_high_i8x16_u);\n\n// i16x8.shuffle -> v128.shuffle\nfunction builtin_i16x8_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shuffle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_shuffle, builtin_i16x8_shuffle);\n\n// i16x8.swizzle -> v128.swizzle\nfunction builtin_i16x8_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n ctx.typeArguments = null;\n ctx.contextualType = Type.v128;\n return builtin_v128_swizzle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i16x8_swizzle, builtin_i16x8_swizzle);\n\n// i32x4.splat -> v128.splat\nfunction builtin_i32x4_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_splat, builtin_i32x4_splat);\n\n// i32x4.extract_lane -> v128.extract_lane\nfunction builtin_i32x4_extract_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extract_lane, builtin_i32x4_extract_lane);\n\n// i32x4.replace_lane -> v128.replace_lane\nfunction builtin_i32x4_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_replace_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_replace_lane, builtin_i32x4_replace_lane);\n\n// i32x4.add -> v128.add\nfunction builtin_i32x4_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_add, builtin_i32x4_add);\n\n// i32x4.sub -> v128.sub\nfunction builtin_i32x4_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_sub, builtin_i32x4_sub);\n\n// i32x4.mul -> v128.mul\nfunction builtin_i32x4_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_mul, builtin_i32x4_mul);\n\n// i32x4.min_s -> v128.min\nfunction builtin_i32x4_min_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_min_s, builtin_i32x4_min_s);\n\n// i32x4.min_u -> v128.min\nfunction builtin_i32x4_min_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_min_u, builtin_i32x4_min_u);\n\n// i32x4.max_s -> v128.max\nfunction builtin_i32x4_max_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_max_s, builtin_i32x4_max_s);\n\n// i32x4.max_u -> v128.max\nfunction builtin_i32x4_max_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_max_u, builtin_i32x4_max_u);\n\n// i32x4.dot_i16x8_s -> v128.dot\nfunction builtin_i32x4_dot_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_dot(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_dot_i16x8_s, builtin_i32x4_dot_i16x8_s);\n\n// i32x4.abs -> v128.abs\nfunction builtin_i32x4_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_abs, builtin_i32x4_abs);\n\n// i32x4.neg -> v128.neg\nfunction builtin_i32x4_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_neg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_neg, builtin_i32x4_neg);\n\n// i32x4.shl -> v128.shl\nfunction builtin_i32x4_shl(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shl(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_shl, builtin_i32x4_shl);\n\n// i32x4.shr_s -> v128.shr\nfunction builtin_i32x4_shr_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_shr_s, builtin_i32x4_shr_s);\n\n// i32x4.shr_u -> v128.shr\nfunction builtin_i32x4_shr_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_shr_u, builtin_i32x4_shr_u);\n\n// i32x4.all_true -> v128.all_true\nfunction builtin_i32x4_all_true(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_all_true(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_all_true, builtin_i32x4_all_true);\n\n// i32x4.bitmask -> v128.bitmask\nfunction builtin_i32x4_bitmask(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_bitmask(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_bitmask, builtin_i32x4_bitmask);\n\n// i32x4.eq -> v128.eq\nfunction builtin_i32x4_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_eq, builtin_i32x4_eq);\n\n// i32x4.ne -> v128.ne\nfunction builtin_i32x4_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_ne, builtin_i32x4_ne);\n\n// i32x4.lt_s -> v128.lt\nfunction builtin_i32x4_lt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_lt_s, builtin_i32x4_lt_s);\n\n// i32x4.lt_u -> v128.lt\nfunction builtin_i32x4_lt_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_lt_u, builtin_i32x4_lt_u);\n\n// i32x4.le_s -> v128.le\nfunction builtin_i32x4_le_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_le_s, builtin_i32x4_le_s);\n\n// i32x4.le_u -> v128.le\nfunction builtin_i32x4_le_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_le_u, builtin_i32x4_le_u);\n\n// i32x4.gt_s -> v128.gt\nfunction builtin_i32x4_gt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_gt_s, builtin_i32x4_gt_s);\n\n// i32x4.gt_u -> v128.gt\nfunction builtin_i32x4_gt_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_gt_u, builtin_i32x4_gt_u);\n\n// i32x4.ge_s -> v128.ge\nfunction builtin_i32x4_ge_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_ge_s, builtin_i32x4_ge_s);\n\n// i32x4.ge_u -> v128.ge\nfunction builtin_i32x4_ge_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_ge_u, builtin_i32x4_ge_u);\n\n// i32x4.trunc_sat_f32x4_s -> v128.trunc_sat\nfunction builtin_i32x4_trunc_sat_f32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_trunc_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_trunc_sat_f32x4_s, builtin_i32x4_trunc_sat_f32x4_s);\n\n// i32x4.trunc_sat_f32x4_u -> v128.trunc_sat\nfunction builtin_i32x4_trunc_sat_f32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_trunc_sat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_trunc_sat_f32x4_u, builtin_i32x4_trunc_sat_f32x4_u);\n\n// i32x4.trunc_sat_f64x2_s_zero -> v128.trunc_sat_zero\nfunction builtin_i32x4_trunc_sat_f64x2_s_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_trunc_sat_zero(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_trunc_sat_f64x2_s_zero, builtin_i32x4_trunc_sat_f64x2_s_zero);\n\n// i32x4.trunc_sat_f64x2_u_zero -> v128.trunc_sat_zero\nfunction builtin_i32x4_trunc_sat_f64x2_u_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_trunc_sat_zero(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_trunc_sat_f64x2_u_zero, builtin_i32x4_trunc_sat_f64x2_u_zero);\n\n// i32x4.extend_low_i16x8_s -> // v128.extend_low\nfunction builtin_i32x4_extend_low_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extend_low_i16x8_s, builtin_i32x4_extend_low_i16x8_s);\n\n// i32x4.extend_low_i16x8_u -> v128.extend_low\nfunction builtin_i32x4_extend_low_i16x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extend_low_i16x8_u, builtin_i32x4_extend_low_i16x8_u);\n\n// i32x4.extend_high_i16x8_s -> v128.extend_high\nfunction builtin_i32x4_extend_high_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extend_high_i16x8_s, builtin_i32x4_extend_high_i16x8_s);\n\n// i32x4.extend_high_i16x8_u -> v128.extend_high\nfunction builtin_i32x4_extend_high_i16x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extend_high_i16x8_u, builtin_i32x4_extend_high_i16x8_u);\n\n// i32x4.extadd_pairwise_i16x8_s -> v128.extadd_pairwise\nfunction builtin_i32x4_extadd_pairwise_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extadd_pairwise(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extadd_pairwise_i16x8_s, builtin_i32x4_extadd_pairwise_i16x8_s);\n\n// i32x4.extadd_pairwise_i16x8_u -> v128.extadd_pairwise\nfunction builtin_i32x4_extadd_pairwise_i16x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extadd_pairwise(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extadd_pairwise_i16x8_u, builtin_i32x4_extadd_pairwise_i16x8_u);\n\n// i32x4.extmul_low_i16x8_s -> v128.extmul_low\nfunction builtin_i32x4_extmul_low_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extmul_low_i16x8_s, builtin_i32x4_extmul_low_i16x8_s);\n\n// i32x4.extmul_low_i16x8_u -> v128.extmul_low\nfunction builtin_i32x4_extmul_low_i16x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extmul_low_i16x8_u, builtin_i32x4_extmul_low_i16x8_u);\n\n// i32x4.extmul_high_i16x8_s -> v128.extmul_high\nfunction builtin_i32x4_extmul_high_i16x8_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extmul_high_i16x8_s, builtin_i32x4_extmul_high_i16x8_s);\n\n// i32x4.extmul_high_i16x8_u -> v128.extmul_high\nfunction builtin_i32x4_extmul_high_i16x8_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u16 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_extmul_high_i16x8_u, builtin_i32x4_extmul_high_i16x8_u);\n\n// i32x4.shuffle -> v128.shuffle\nfunction builtin_i32x4_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shuffle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_shuffle, builtin_i32x4_shuffle);\n\n// i32x4.swizzle -> v128.swizzle\nfunction builtin_i32x4_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n ctx.typeArguments = null;\n ctx.contextualType = Type.v128;\n return builtin_v128_swizzle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i32x4_swizzle, builtin_i32x4_swizzle);\n\n// i64x2.splat -> v128.splat\nfunction builtin_i64x2_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_splat, builtin_i64x2_splat);\n\n// i64x2.extract_lane -> v128.extract_lane\nfunction builtin_i64x2_extract_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i64;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extract_lane, builtin_i64x2_extract_lane);\n\n// i64x2.replace_lane -> v128.replace_lane\nfunction builtin_i64x2_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_replace_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_replace_lane, builtin_i64x2_replace_lane);\n\n// i64x2.add -> v128.add\nfunction builtin_i64x2_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_add, builtin_i64x2_add);\n\n// i64x2.sub -> v128.sub\nfunction builtin_i64x2_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_sub, builtin_i64x2_sub);\n\n// i64x2.mul -> v128.mul\nfunction builtin_i64x2_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_mul, builtin_i64x2_mul);\n\n// i64x2.abs -> v128.abs\nfunction builtin_i64x2_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_abs, builtin_i64x2_abs);\n\n// i64x2.neg -> v128.neg\nfunction builtin_i64x2_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_neg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_neg, builtin_i64x2_neg);\n\n// i64x2.shl -> v128.shl\nfunction builtin_i64x2_shl(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shl(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_shl, builtin_i64x2_shl);\n\n// i64x2.shr_s -> v128.shr\nfunction builtin_i64x2_shr_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_shr_s, builtin_i64x2_shr_s);\n\n// i64x2.shr_u -> v128.shr\nfunction builtin_i64x2_shr_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shr(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_shr_u, builtin_i64x2_shr_u);\n\n// i64x2.all_true -> v128.all_true\nfunction builtin_i64x2_all_true(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_all_true(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_all_true, builtin_i64x2_all_true);\n\n// i64x2.bitmask -> v128.bitmask\nfunction builtin_i64x2_bitmask(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.i32;\n return builtin_v128_bitmask(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_bitmask, builtin_i64x2_bitmask);\n\n// i64x2.eq -> v128.eq\nfunction builtin_i64x2_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_eq, builtin_i64x2_eq);\n\n// i64x2.ne -> v128.ne\nfunction builtin_i64x2_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_ne, builtin_i64x2_ne);\n\n// i64x2.lt_s -> v128.lt\nfunction builtin_i64x2_lt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_lt_s, builtin_i64x2_lt_s);\n\n// i64x2.le_s -> v128.le\nfunction builtin_i64x2_le_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_le_s, builtin_i64x2_le_s);\n\n// i64x2.gt_s -> v128.gt\nfunction builtin_i64x2_gt_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_gt_s, builtin_i64x2_gt_s);\n\n// i64x2.ge_s -> v128.ge\nfunction builtin_i64x2_ge_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_ge_s, builtin_i64x2_ge_s);\n\n// i64x2.extend_low_i32x4_s -> // v128.extend_low\nfunction builtin_i64x2_extend_low_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extend_low_i32x4_s, builtin_i64x2_extend_low_i32x4_s);\n\n// i64x2.extend_low_i32x4_u -> v128.extend_low\nfunction builtin_i64x2_extend_low_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extend_low_i32x4_u, builtin_i64x2_extend_low_i32x4_u);\n\n// i64x2.extend_high_i32x4_s -> v128.extend_high\nfunction builtin_i64x2_extend_high_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extend_high_i32x4_s, builtin_i64x2_extend_high_i32x4_s);\n\n// i64x2.extend_high_i32x4_u -> v128.extend_high\nfunction builtin_i64x2_extend_high_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extend_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extend_high_i32x4_u, builtin_i64x2_extend_high_i32x4_u);\n\n// i64x2.extmul_low_i32x4_s -> v128.extmul_low\nfunction builtin_i64x2_extmul_low_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extmul_low_i32x4_s, builtin_i64x2_extmul_low_i32x4_s);\n\n// i64x2.extmul_low_i32x4_u -> v128.extmul_low\nfunction builtin_i64x2_extmul_low_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extmul_low_i32x4_u, builtin_i64x2_extmul_low_i32x4_u);\n\n// i64x2.extmul_high_i32x4_s -> v128.extmul_high\nfunction builtin_i64x2_extmul_high_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extmul_high_i32x4_s, builtin_i64x2_extmul_high_i32x4_s);\n\n// i64x2.extmul_high_i32x4_u -> v128.extmul_high\nfunction builtin_i64x2_extmul_high_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_extmul_high(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_extmul_high_i32x4_u, builtin_i64x2_extmul_high_i32x4_u);\n\n// i64x2.shuffle -> v128.shuffle\nfunction builtin_i64x2_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shuffle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_shuffle, builtin_i64x2_shuffle);\n\n// i64x2.swizzle -> v128.swizzle\nfunction builtin_i64x2_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n ctx.typeArguments = null;\n ctx.contextualType = Type.v128;\n return builtin_v128_swizzle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.i64x2_swizzle, builtin_i64x2_swizzle);\n\n// f32x4.splat -> v128.splat\nfunction builtin_f32x4_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_splat, builtin_f32x4_splat);\n\n// f32x4.extract_lane -> v128.extract_lane\nfunction builtin_f32x4_extract_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.f32;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_extract_lane, builtin_f32x4_extract_lane);\n\n// f32x4.replace_lane -> v128.replace_lane\nfunction builtin_f32x4_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_replace_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_replace_lane, builtin_f32x4_replace_lane);\n\n// f32x4.add -> v128.add\nfunction builtin_f32x4_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_add, builtin_f32x4_add);\n\n// f32x4.sub -> v128.sub\nfunction builtin_f32x4_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_sub, builtin_f32x4_sub);\n\n// f32x4.mul -> v128.mul\nfunction builtin_f32x4_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_mul, builtin_f32x4_mul);\n\n// f32x4.div -> v128.div\nfunction builtin_f32x4_div(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_div, builtin_f32x4_div);\n\n// f32x4.neg -> v128.neg\nfunction builtin_f32x4_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_neg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_neg, builtin_f32x4_neg);\n\n// f32x4.min -> v128.min\nfunction builtin_f32x4_min(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_min, builtin_f32x4_min);\n\n// f32x4.max -> v128.max\nfunction builtin_f32x4_max(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_max, builtin_f32x4_max);\n\n// f32x4.pmin -> v128.pmin\nfunction builtin_f32x4_pmin(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_pmin(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_pmin, builtin_f32x4_pmin);\n\n// f32x4.pmax -> v128.pmax\nfunction builtin_f32x4_pmax(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_pmax(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_pmax, builtin_f32x4_pmax);\n\n// f32x4.abs -> v128.abs\nfunction builtin_f32x4_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_abs, builtin_f32x4_abs);\n\n// f32x4.sqrt -> v128.sqrt\nfunction builtin_f32x4_sqrt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sqrt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_sqrt, builtin_f32x4_sqrt);\n\n// f32x4.ceil -> v128.ceil\nfunction builtin_f32x4_ceil(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ceil(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_ceil, builtin_f32x4_ceil);\n\n// f32x4.floor -> v128.floor\nfunction builtin_f32x4_floor(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_floor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_floor, builtin_f32x4_floor);\n\n// f32x4.trunc -> v128.trunc\nfunction builtin_f32x4_trunc(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_trunc(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_trunc, builtin_f32x4_trunc);\n\n// f32x4.nearest -> v128.nearest\nfunction builtin_f32x4_nearest(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_nearest(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_nearest, builtin_f32x4_nearest);\n\n// f32x4.eq -> v128.eq\nfunction builtin_f32x4_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_eq, builtin_f32x4_eq);\n\n// f32x4.ne -> v128.ne\nfunction builtin_f32x4_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_ne, builtin_f32x4_ne);\n\n// f32x4.lt -> v128.lt\nfunction builtin_f32x4_lt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_lt, builtin_f32x4_lt);\n\n// f32x4.le -> v128.le\nfunction builtin_f32x4_le(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_le, builtin_f32x4_le);\n\n// f32x4.gt -> v128.gt\nfunction builtin_f32x4_gt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_gt, builtin_f32x4_gt);\n\n// f32x4.ge -> v128.ge\nfunction builtin_f32x4_ge(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_ge, builtin_f32x4_ge);\n\n// f32x4.convert_i32x4_s -> v128.convert\nfunction builtin_f32x4_convert_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_convert(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_convert_i32x4_s, builtin_f32x4_convert_i32x4_s);\n\n// f32x4.convert_i32x4_u -> v128.convert\nfunction builtin_f32x4_convert_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_convert(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_convert_i32x4_u, builtin_f32x4_convert_i32x4_u);\n\n// f32x4.demote_f64x2_zero -> v128.demote_zero\nfunction builtin_f32x4_demote_f64x2_zero(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_demote_zero(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_demote_f64x2_zero, builtin_f32x4_demote_f64x2_zero);\n\n// f32x4.shuffle -> v128.shuffle\nfunction builtin_f32x4_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shuffle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_shuffle, builtin_f32x4_shuffle);\n\n// f32x4.swizzle -> v128.swizzle\nfunction builtin_f32x4_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n ctx.typeArguments = null;\n ctx.contextualType = Type.v128;\n return builtin_v128_swizzle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f32x4_swizzle, builtin_f32x4_swizzle);\n\n// f64x2.splat -> v128.splat\nfunction builtin_f64x2_splat(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_splat(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_splat, builtin_f64x2_splat);\n\n// f64x2.extract_lane -> v128.extract_lane\nfunction builtin_f64x2_extract_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.f64;\n return builtin_v128_extract_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_extract_lane, builtin_f64x2_extract_lane);\n\n// f64x2.replace_lane -> v128.replace_lane\nfunction builtin_f64x2_replace_lane(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_replace_lane(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_replace_lane, builtin_f64x2_replace_lane);\n\n// f64x2.add -> v128.add\nfunction builtin_f64x2_add(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_add(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_add, builtin_f64x2_add);\n\n// f64x2.sub -> v128.sub\nfunction builtin_f64x2_sub(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sub(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_sub, builtin_f64x2_sub);\n\n// f64x2.mul -> v128.mul\nfunction builtin_f64x2_mul(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_mul(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_mul, builtin_f64x2_mul);\n\n// f64x2.div -> v128.div\nfunction builtin_f64x2_div(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_div(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_div, builtin_f64x2_div);\n\n// f64x2.neg -> v128.neg\nfunction builtin_f64x2_neg(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_neg(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_neg, builtin_f64x2_neg);\n\n// f64x2.min -> v128.min\nfunction builtin_f64x2_min(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_min(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_min, builtin_f64x2_min);\n\n// f64x2.max -> v128.max\nfunction builtin_f64x2_max(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_max(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_max, builtin_f64x2_max);\n\n// f64x2.pmin -> v128.pmin\nfunction builtin_f64x2_pmin(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_pmin(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_pmin, builtin_f64x2_pmin);\n\n// f64x2.pmax -> v128.pmax\nfunction builtin_f64x2_pmax(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_pmax(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_pmax, builtin_f64x2_pmax);\n\n// f64x2.abs -> v128.abs\nfunction builtin_f64x2_abs(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_abs(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_abs, builtin_f64x2_abs);\n\n// f64x2.sqrt -> v128.sqrt\nfunction builtin_f64x2_sqrt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_sqrt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_sqrt, builtin_f64x2_sqrt);\n\n// f64x2.ceil -> v128.ceil\nfunction builtin_f64x2_ceil(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ceil(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_ceil, builtin_f64x2_ceil);\n\n// f64x2.floor -> v128.floor\nfunction builtin_f64x2_floor(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_floor(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_floor, builtin_f64x2_floor);\n\n// f64x2.trunc -> v128.trunc\nfunction builtin_f64x2_trunc(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_trunc(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_trunc, builtin_f64x2_trunc);\n\n// f64x2.nearest -> v128.nearest\nfunction builtin_f64x2_nearest(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_nearest(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_nearest, builtin_f64x2_nearest);\n\n// f64x2.eq -> v128.eq\nfunction builtin_f64x2_eq(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_eq(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_eq, builtin_f64x2_eq);\n\n// f64x2.ne -> v128.ne\nfunction builtin_f64x2_ne(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ne(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_ne, builtin_f64x2_ne);\n\n// f64x2.lt -> v128.lt\nfunction builtin_f64x2_lt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_lt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_lt, builtin_f64x2_lt);\n\n// f64x2.le -> v128.le\nfunction builtin_f64x2_le(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_le(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_le, builtin_f64x2_le);\n\n// f64x2.gt -> v128.gt\nfunction builtin_f64x2_gt(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_gt(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_gt, builtin_f64x2_gt);\n\n// f64x2.ge -> v128.ge\nfunction builtin_f64x2_ge(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_ge(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_ge, builtin_f64x2_ge);\n\n// f64x2.convert_low_i32x4_s -> v128.convert_low\nfunction builtin_f64x2_convert_low_i32x4_s(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.i32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_convert_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_convert_low_i32x4_s, builtin_f64x2_convert_low_i32x4_s);\n\n// f64x2.convert_low_i32x4_u -> v128.convert_low\nfunction builtin_f64x2_convert_low_i32x4_u(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.u32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_convert_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_convert_low_i32x4_u, builtin_f64x2_convert_low_i32x4_u);\n\n// f64x2.promote_low_f32x4 -> v128.promote_low\nfunction builtin_f64x4_promote_low_f32x4(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f32 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_promote_low(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_promote_low_f32x4, builtin_f64x4_promote_low_f32x4);\n\n// f64x2.shuffle -> v128.shuffle\nfunction builtin_f64x2_shuffle(ctx: BuiltinFunctionContext): ExpressionRef {\n checkTypeAbsent(ctx);\n ctx.typeArguments = [ Type.f64 ];\n ctx.contextualType = Type.v128;\n return builtin_v128_shuffle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_shuffle, builtin_f64x2_shuffle);\n\n// f64x2.swizzle -> v128.swizzle\nfunction builtin_f64x2_swizzle(ctx: BuiltinFunctionContext): ExpressionRef {\n ctx.typeArguments = null;\n ctx.contextualType = Type.v128;\n return builtin_v128_swizzle(ctx);\n}\nbuiltinFunctions.set(BuiltinNames.f64x2_swizzle, builtin_f64x2_swizzle);\n\n// === Internal helpers =======================================================================\n\n/** Compiles the `visit_globals` function. */\nexport function compileVisitGlobals(compiler: Compiler): void {\n let module = compiler.module;\n let exprs = new Array();\n let sizeTypeRef = compiler.options.sizeTypeRef;\n let visitInstance = assert(compiler.program.visitInstance);\n\n // this function is @lazy: make sure it exists\n compiler.compileFunction(visitInstance, true);\n\n // TODO: for (let element of compiler.program.elementsByName.values()) {\n for (let _values = Map_values(compiler.program.elementsByName), i = 0, k = _values.length; i < k; ++i) {\n let element = unchecked(_values[i]);\n if (element.kind != ElementKind.Global) continue;\n let global = element;\n let globalType = global.type;\n let classReference = globalType.getClass();\n if (\n classReference &&\n !classReference.hasDecorator(DecoratorFlags.Unmanaged) &&\n global.is(CommonFlags.Compiled)\n ) {\n if (global.is(CommonFlags.Inlined)) {\n let value = global.constantIntegerValue;\n if (i64_low(value) || i64_high(value)) {\n exprs.push(\n module.call(visitInstance.internalName, [\n compiler.options.isWasm64\n ? module.i64(i64_low(value), i64_high(value))\n : module.i32(i64_low(value)),\n module.local_get(0, TypeRef.I32) // cookie\n ], TypeRef.None)\n );\n }\n } else {\n exprs.push(\n module.if(\n module.local_tee(1,\n module.global_get(global.internalName, sizeTypeRef),\n false // internal\n ),\n module.call(visitInstance.internalName, [\n module.local_get(1, sizeTypeRef), // tempRef != null\n module.local_get(0, TypeRef.I32) // cookie\n ], TypeRef.None)\n )\n );\n }\n }\n }\n module.addFunction(BuiltinNames.visit_globals,\n TypeRef.I32, // cookie\n TypeRef.None, // => void\n [ sizeTypeRef ],\n exprs.length\n ? module.block(null, exprs)\n : module.nop()\n );\n}\n\n/** Ensures that the visitor function of the specified class is compiled. */\nfunction ensureVisitMembersOf(compiler: Compiler, instance: Class): void {\n assert(instance.type.isManaged);\n if (instance.visitRef) return;\n\n let program = compiler.program;\n let module = compiler.module;\n let usizeType = program.options.usizeType;\n let sizeTypeRef = usizeType.toRef();\n let sizeTypeSize = usizeType.byteSize;\n let visitInstance = assert(program.visitInstance);\n let body = new Array();\n\n // If the class has a base class, call its visitor first\n let base = instance.base;\n if (base) {\n body.push(\n module.call(`${base.internalName}~visit`, [\n module.local_get(0, sizeTypeRef), // this\n module.local_get(1, TypeRef.I32) // cookie\n ], TypeRef.None)\n );\n }\n\n // Some standard library components provide a custom visitor implementation,\n // for example to visit all members of a collection, e.g. arrays and maps.\n let hasVisitImpl = false;\n if (instance.isDeclaredInLibrary) {\n let visitPrototype = instance.getMember(\"__visit\");\n if (visitPrototype) {\n assert(visitPrototype.kind == ElementKind.FunctionPrototype);\n let visitInstance = program.resolver.resolveFunction(visitPrototype, null);\n if (!visitInstance || !compiler.compileFunction(visitInstance)) {\n body.push(\n module.unreachable()\n );\n } else {\n let visitSignature = visitInstance.signature;\n let visitThisType = assert(visitSignature.thisType);\n assert(\n visitSignature.parameterTypes.length == 1 &&\n visitSignature.parameterTypes[0] == Type.u32 &&\n visitSignature.returnType == Type.void &&\n instance.type.isStrictlyAssignableTo(visitThisType) // incl. implemented on super\n );\n body.push(\n module.call(visitInstance.internalName, [\n module.local_get(0, sizeTypeRef), // this\n module.local_get(1, TypeRef.I32) // cookie\n ], TypeRef.None)\n );\n }\n hasVisitImpl = true;\n }\n }\n\n // Otherwise, if there is no custom visitor, generate a visitor function\n // according to class layout, visiting all _own_ managed members.\n let needsTempValue = false;\n if (!hasVisitImpl) {\n let members = instance.members;\n if (members) {\n // TODO: for (let member of members.values()) {\n for (let _values = Map_values(members), j = 0, l = _values.length; j < l; ++j) {\n let member = unchecked(_values[j]);\n if (member.kind != ElementKind.PropertyPrototype) continue;\n // Class should have resolved fields during finalization\n let property = (member).instance;\n if (!property) continue;\n let fieldType = property.type;\n if (!property.isField || property.getBoundClassOrInterface() != instance || !fieldType.isManaged) continue;\n let fieldOffset = property.memoryOffset;\n assert(fieldOffset >= 0);\n needsTempValue = true;\n body.push(\n // if ($2 = value) __visit($2, $1)\n module.if(\n module.local_tee(2,\n module.load(sizeTypeSize, false,\n module.local_get(0, sizeTypeRef),\n sizeTypeRef, fieldOffset\n ),\n false // internal\n ),\n module.call(visitInstance.internalName, [\n module.local_get(2, sizeTypeRef), // value\n module.local_get(1, TypeRef.I32) // cookie\n ], TypeRef.None)\n )\n );\n }\n }\n }\n\n // Create the visitor function\n instance.visitRef = module.addFunction(`${instance.internalName}~visit`,\n createType([sizeTypeRef, TypeRef.I32]),\n TypeRef.None,\n needsTempValue ? [ sizeTypeRef ] : null,\n module.flatten(body, TypeRef.None)\n );\n\n // And make sure the base visitor function exists\n if (base && base.type.isManaged) {\n // errored earlier if not managed\n ensureVisitMembersOf(compiler, base);\n }\n}\n\n/** Compiles the `__visit_members` function. */\nexport function compileVisitMembers(compiler: Compiler): void {\n let program = compiler.program;\n let module = compiler.module;\n let usizeType = program.options.usizeType;\n let sizeTypeRef = usizeType.toRef();\n let managedClasses = program.managedClasses;\n let visitInstance = assert(program.visitInstance);\n compiler.compileFunction(visitInstance, true); // is lazy, make sure it is compiled\n\n // Prepare a mapping of class names to visitor calls. Each name corresponds to\n // the respective sequential (0..N) class id.\n let names = new Array();\n let cases = new Array();\n let nextId = 0;\n for (let _keys = Map_keys(managedClasses), i = 0, k = _keys.length; i < k; ++i) {\n let instanceId = _keys[i];\n assert(instanceId == nextId++);\n let instance = assert(managedClasses.get(instanceId));\n names[i] = instance.internalName;\n if (instance.isPointerfree) {\n cases[i] = module.return();\n } else {\n cases[i] = module.block(null, [\n module.call(`${instance.internalName}~visit`, [\n module.local_get(0, sizeTypeRef), // this\n module.local_get(1, TypeRef.I32) // cookie\n ], TypeRef.None),\n module.return()\n ], TypeRef.None);\n ensureVisitMembersOf(compiler, instance);\n }\n }\n\n // Make a br_table of the mapping, calling visitor functions by unique class id\n let current = module.block(names[0], [\n module.switch(names, \"invalid\",\n // load(changetype(this) - 8)\n module.load(4, false,\n sizeTypeRef == TypeRef.I64\n ? module.binary(BinaryOp.SubI64,\n module.local_get(0, sizeTypeRef),\n module.i64(8)\n )\n : module.binary(BinaryOp.SubI32,\n module.local_get(0, sizeTypeRef),\n module.i32(8) // rtId is at -8\n ),\n TypeRef.I32, 0\n )\n )\n ], TypeRef.None);\n\n // Wrap blocks in order\n for (let i = 0, k = names.length - 1; i < k; ++i) {\n current = module.block(names[i + 1], [\n current,\n cases[i]\n ], TypeRef.None);\n }\n\n // Wrap the last id in an 'invalid' block to break out of on invalid ids\n current = module.block(\"invalid\", [\n current,\n cases[names.length - 1]\n ], TypeRef.None);\n\n // Add the function, executing an unreachable if breaking to 'invalid'\n module.addFunction(BuiltinNames.visit_members,\n createType([ sizeTypeRef, TypeRef.I32 ]), // this, cookie\n TypeRef.None, // => void\n null,\n module.flatten([\n current,\n module.unreachable()\n ])\n );\n}\n\nfunction typeToRuntimeFlags(type: Type): TypeinfoFlags {\n let flags = TypeinfoFlags.VALUE_ALIGN_0 * (1 << type.alignLog2);\n if (type.is(TypeFlags.Signed)) flags |= TypeinfoFlags.VALUE_SIGNED;\n if (type.is(TypeFlags.Float)) flags |= TypeinfoFlags.VALUE_FLOAT;\n if (type.is(TypeFlags.Nullable)) flags |= TypeinfoFlags.VALUE_NULLABLE;\n if (type.isManaged) flags |= TypeinfoFlags.VALUE_MANAGED;\n return flags / TypeinfoFlags.VALUE_ALIGN_0;\n}\n\n/** Compiles runtime type information for use by stdlib. */\nexport function compileRTTI(compiler: Compiler): void {\n let program = compiler.program;\n let module = compiler.module;\n let managedClasses = program.managedClasses;\n let count = managedClasses.size;\n let size = 4 + 4 * count; // count | TypeInfo*\n let data = new Uint8Array(size);\n writeI32(count, data, 0);\n let off = 4;\n let abvInstance = program.arrayBufferViewInstance;\n let abvPrototype = abvInstance.prototype;\n let arrayPrototype = program.arrayPrototype;\n let setPrototype = program.setPrototype;\n let mapPrototype = program.mapPrototype;\n let staticArrayPrototype = program.staticArrayPrototype;\n let lastId = 0;\n // TODO: for (let [instanceId, instance] of managedClasses) {\n for (let _keys = Map_keys(managedClasses), i = 0, k = _keys.length; i < k; ++i) {\n let instanceId = unchecked(_keys[i]);\n let instance = assert(managedClasses.get(instanceId));\n assert(instanceId == lastId++);\n let flags: TypeinfoFlags = 0;\n if (instance.isPointerfree) flags |= TypeinfoFlags.POINTERFREE;\n if (instance != abvInstance && instance.extendsPrototype(abvPrototype)) {\n let valueType = instance.getArrayValueType();\n flags |= TypeinfoFlags.ARRAYBUFFERVIEW;\n flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType);\n } else if (instance.extendsPrototype(arrayPrototype)) {\n let valueType = instance.getArrayValueType();\n flags |= TypeinfoFlags.ARRAY;\n flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType);\n } else if (instance.extendsPrototype(setPrototype)) {\n let typeArguments = assert(instance.getTypeArgumentsTo(setPrototype));\n assert(typeArguments.length == 1);\n flags |= TypeinfoFlags.SET;\n flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[0]);\n } else if (instance.extendsPrototype(mapPrototype)) {\n let typeArguments = assert(instance.getTypeArgumentsTo(mapPrototype));\n assert(typeArguments.length == 2);\n flags |= TypeinfoFlags.MAP;\n flags |= TypeinfoFlags.KEY_ALIGN_0 * typeToRuntimeFlags(typeArguments[0]);\n flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(typeArguments[1]);\n } else if (instance.extendsPrototype(staticArrayPrototype)) {\n let valueType = instance.getArrayValueType();\n flags |= TypeinfoFlags.STATICARRAY;\n flags |= TypeinfoFlags.VALUE_ALIGN_0 * typeToRuntimeFlags(valueType);\n }\n writeI32(flags, data, off); off += 4;\n instance.rttiFlags = flags;\n }\n assert(off == size);\n let usizeType = program.options.usizeType;\n let segment = compiler.addAlignedMemorySegment(data);\n if (usizeType.size == 8) {\n let offset = segment.offset;\n module.addGlobal(BuiltinNames.rtti_base, TypeRef.I64, false, module.i64(i64_low(offset), i64_high(offset)));\n } else {\n module.addGlobal(BuiltinNames.rtti_base, TypeRef.I32, false, module.i32(i64_low(segment.offset)));\n }\n}\n\n// Helpers\n\n/** Checks the constant type of a type argument *or* expression. */\nfunction checkConstantType(ctx: BuiltinFunctionContext): Type | null {\n let compiler = ctx.compiler;\n let operands = ctx.operands;\n let typeArguments = ctx.typeArguments;\n checkConstantType_expr = 0;\n if (operands.length == 0) { // requires type argument\n if (!typeArguments || typeArguments.length != 1) {\n compiler.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n ctx.reportNode.typeArgumentsRange, \"1\", typeArguments ? typeArguments.length.toString() : \"0\"\n );\n return null;\n }\n return typeArguments[0];\n }\n if (operands.length == 1) { // optional type argument\n if (typeArguments && typeArguments.length > 0) {\n if (typeArguments.length > 1) {\n compiler.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n ctx.reportNode.typeArgumentsRange, \"1\", typeArguments.length.toString()\n );\n return null;\n }\n checkConstantType_expr = compiler.compileExpression(operands[0], typeArguments[0], Constraints.ConvImplicit);\n } else {\n checkConstantType_expr = compiler.compileExpression(operands[0], Type.auto);\n }\n return compiler.currentType;\n }\n if (typeArguments && typeArguments.length > 1) {\n compiler.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n ctx.reportNode.typeArgumentsRange, \"1\", typeArguments.length.toString()\n );\n }\n compiler.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n ctx.reportNode.argumentsRange, \"1\", operands.length.toString()\n );\n return null;\n}\n\n/** Reifies a constant type check potentially involving an expression. */\nfunction reifyConstantType(ctx: BuiltinFunctionContext, expr: ExpressionRef): ExpressionRef {\n let module = ctx.compiler.module;\n if (checkConstantType_expr && mustPreserveSideEffects(checkConstantType_expr, module.ref)) {\n expr = module.block(null, [\n module.maybeDrop(checkConstantType_expr),\n expr\n ], getExpressionType(expr));\n }\n return expr;\n}\n\n/** Evaluates a compile-time constant immediate offset argument.*/\nfunction evaluateImmediateOffset(expression: Expression, compiler: Compiler): i32 {\n let module = compiler.module;\n let value: i32;\n if (compiler.options.isWasm64) {\n let expr = compiler.compileExpression(expression, Type.usize64, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n assert(getConstValueI64High(precomp) == 0); // TODO\n value = getConstValueI64Low(precomp);\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n expression.range\n );\n value = -1;\n }\n } else {\n let expr = compiler.compileExpression(expression, Type.usize32, Constraints.ConvImplicit);\n let precomp = module.runExpression(expr, ExpressionRunnerFlags.PreserveSideeffects);\n if (precomp) {\n value = getConstValueI32(precomp);\n } else {\n compiler.error(\n DiagnosticCode.Expression_must_be_a_compile_time_constant,\n expression.range\n );\n value = -1;\n }\n }\n return value;\n}\n\n/** Evaluates a compile-time constant immediate align argument. */\nfunction evaluateImmediateAlign(expression: Expression, naturalAlign: i32, compiler: Compiler): i32 {\n let align = evaluateImmediateOffset(expression, compiler);\n if (align < 0) return align;\n if (align < 1 || naturalAlign > 16) {\n compiler.error(\n DiagnosticCode._0_must_be_a_value_between_1_and_2_inclusive,\n expression.range, \"Alignment\", \"1\", naturalAlign.toString()\n );\n return -1;\n }\n if (!isPowerOf2(align)) {\n compiler.error(\n DiagnosticCode._0_must_be_a_power_of_two,\n expression.range, \"Alignment\"\n );\n return -1;\n }\n return align;\n}\n\n/** Checks that the specified feature is enabled. */\nfunction checkFeatureEnabled(ctx: BuiltinFunctionContext, feature: Feature): i32 {\n let compiler = ctx.compiler;\n if (!compiler.options.hasFeature(feature)) {\n compiler.error(\n DiagnosticCode.Feature_0_is_not_enabled,\n ctx.reportNode.range, featureToString(feature)\n );\n return 1;\n }\n return 0;\n}\n\n/** Checks a call with a single required type argument. Returns `1` on error. */\nfunction checkTypeRequired(ctx: BuiltinFunctionContext, setCurrentTypeOnError: bool = false): i32 {\n let compiler = ctx.compiler;\n let typeArguments = ctx.typeArguments;\n if (typeArguments) {\n let numTypeArguments = typeArguments.length;\n if (numTypeArguments == 1) return 0;\n assert(numTypeArguments); // invalid if 0, must not be set at all instead\n if (setCurrentTypeOnError) compiler.currentType = typeArguments[0];\n compiler.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n ctx.reportNode.typeArgumentsRange, \"1\", numTypeArguments.toString()\n );\n } else {\n compiler.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n ctx.reportNode.range, \"1\", \"0\"\n );\n }\n return 1;\n}\n\n/** Checks a call with a single optional type argument. Returns `1` on error. */\nfunction checkTypeOptional(ctx: BuiltinFunctionContext, setCurrentTypeOnError: bool = false): i32 {\n let typeArguments = ctx.typeArguments;\n if (typeArguments) {\n let compiler = ctx.compiler;\n let numTypeArguments = typeArguments.length;\n if (numTypeArguments == 1) return 0;\n assert(numTypeArguments); // invalid if 0, must not be set at all instead\n if (setCurrentTypeOnError) compiler.currentType = typeArguments[0];\n compiler.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n ctx.reportNode.typeArgumentsRange, \"1\", numTypeArguments.toString()\n );\n return 1;\n }\n return 0;\n}\n\n/** Checks a call that is not generic. Returns `1` on error. */\nfunction checkTypeAbsent(ctx: BuiltinFunctionContext): i32 {\n let typeArguments = ctx.typeArguments;\n if (typeArguments) {\n let prototype = ctx.prototype;\n prototype.program.error(\n DiagnosticCode.Type_0_is_not_generic,\n ctx.reportNode.typeArgumentsRange, prototype.internalName\n );\n return 1;\n }\n return 0;\n}\n\n/** Checks a call that requires a fixed number of arguments. Returns `1` on error. */\nfunction checkArgsRequired(ctx: BuiltinFunctionContext, expected: i32): i32 {\n let operands = ctx.operands;\n if (operands.length != expected) {\n ctx.compiler.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n ctx.reportNode.range, expected.toString(), operands.length.toString()\n );\n return 1;\n }\n return 0;\n}\n\n/** Checks a call that requires a variable number of arguments. Returns `1` on error. */\nfunction checkArgsOptional(ctx: BuiltinFunctionContext, expectedMinimum: i32, expectedMaximum: i32): i32 {\n let operands = ctx.operands;\n let numOperands = operands.length;\n if (numOperands < expectedMinimum) {\n ctx.compiler.error(\n DiagnosticCode.Expected_at_least_0_arguments_but_got_1,\n ctx.reportNode.range, expectedMinimum.toString(), numOperands.toString()\n );\n return 1;\n } else if (numOperands > expectedMaximum) {\n ctx.compiler.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n ctx.reportNode.range, expectedMaximum.toString(), numOperands.toString()\n );\n return 1;\n }\n return 0;\n}\n\n/** Makes an usize constant matching contextual type if reasonable. */\nfunction contextualUsize(compiler: Compiler, value: i64, contextualType: Type): ExpressionRef {\n let module = compiler.module;\n // Check if contextual type fits\n if (contextualType != Type.auto && contextualType.isIntegerValue) {\n switch (contextualType.kind) {\n case TypeKind.I32: {\n if (i64_is_i32(value)) {\n compiler.currentType = Type.i32;\n return module.i32(i64_low(value));\n }\n break;\n }\n case TypeKind.U32: {\n if (i64_is_u32(value)) {\n compiler.currentType = Type.u32;\n return module.i32(i64_low(value));\n }\n break;\n }\n case TypeKind.I64:\n case TypeKind.U64: {\n compiler.currentType = contextualType;\n return module.i64(i64_low(value), i64_high(value));\n }\n // isize/usize falls through\n // small int is probably not intended\n }\n }\n // Default to usize\n if (compiler.options.isWasm64) {\n compiler.currentType = Type.usize64;\n return module.i64(i64_low(value), i64_high(value));\n } else {\n compiler.currentType = Type.usize32;\n assert(!i64_high(value));\n return module.i32(i64_low(value));\n }\n}\n","/// \n\nimport { BLOCK_MAXSIZE } from \"./rt/common\";\nimport { Runtime } from \"shared/runtime\";\nimport { COMPARATOR, SORT } from \"./util/sort\";\nimport { REVERSE, FILL } from \"./util/bytes\";\nimport { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinReferenceArray } from \"./util/string\";\nimport { idof, isArray as builtin_isArray } from \"./builtins\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_EMPTYARRAY, E_HOLEYARRAY } from \"./util/error\";\n\n// @ts-ignore: decorator\n@inline @lazy const MIN_SIZE: usize = 8;\n\n/** Ensures that the given array has _at least_ the specified backing size. */\nfunction ensureCapacity(array: usize, newSize: usize, alignLog2: u32, canGrow: bool = true): void {\n // Depends on the fact that Arrays mimic ArrayBufferView\n let oldCapacity = changetype(array).byteLength;\n if (newSize > oldCapacity >>> alignLog2) {\n if (newSize > BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);\n let oldData = changetype(changetype(array).buffer);\n // Grows old capacity by factor of two.\n // Make sure we don't reach BLOCK_MAXSIZE for new growed capacity.\n let newCapacity = max(newSize, MIN_SIZE) << alignLog2;\n if (canGrow) newCapacity = max(min(oldCapacity << 1, BLOCK_MAXSIZE), newCapacity);\n let newData = __renew(oldData, newCapacity);\n // __new / __renew already init memory range as zeros in Incremental runtime.\n // So try to avoid this.\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(newData + oldCapacity, 0, newCapacity - oldCapacity);\n }\n if (newData != oldData) { // oldData has been free'd\n store(array, newData, offsetof(\"buffer\"));\n store(array, newData, offsetof(\"dataStart\"));\n __link(array, changetype(newData), false);\n }\n store(array, newCapacity, offsetof(\"byteLength\"));\n }\n}\n\nexport class Array {\n [key: number]: T;\n\n // Mimicking ArrayBufferView isn't strictly necessary here but is done to allow glue code\n // to work with typed and normal arrays interchangeably. Technically, normal arrays do not need\n // `dataStart` (equals `buffer`) and `byteLength` (equals computed `buffer.byteLength`), but the\n // block is 16 bytes anyway so it's fine to have a couple extra fields in there.\n\n private buffer: ArrayBuffer;\n @unsafe readonly dataStart: usize;\n private byteLength: i32; // Uses here as capacity\n\n // Also note that Array with non-nullable T must guard against uninitialized null values\n // whenever an element is accessed. Otherwise, the compiler wouldn't be able to guarantee\n // type-safety anymore. For lack of a better word, such an array is \"holey\".\n\n private length_: i32;\n\n static isArray(value: U): bool {\n return isReference() ? changetype(value) != 0 && builtin_isArray(value) : false;\n }\n\n static create(capacity: i32 = 0): Array {\n WARNING(\"'Array.create' is deprecated. Use 'new Array' instead, making sure initial elements are initialized.\");\n let array = new Array(capacity);\n array.length = 0;\n return array;\n }\n\n constructor(length: i32 = 0) {\n if (length > BLOCK_MAXSIZE >>> alignof()) throw new RangeError(E_INVALIDLENGTH);\n // reserve capacity for at least MIN_SIZE elements\n let bufferSize = max(length, MIN_SIZE) << alignof();\n let buffer = changetype(__new(bufferSize, idof()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(buffer), 0, bufferSize);\n }\n this.buffer = buffer; // links\n this.dataStart = changetype(buffer);\n this.byteLength = bufferSize;\n this.length_ = length;\n }\n\n get length(): i32 {\n return this.length_;\n }\n\n set length(newLength: i32) {\n ensureCapacity(changetype(this), newLength, alignof(), false);\n this.length_ = newLength;\n }\n\n every(fn: (value: T, index: i32, array: Array) => bool): bool {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n if (!fn(load(this.dataStart + (i << alignof())), i, this)) return false;\n }\n return true;\n }\n\n findIndex(fn: (value: T, index: i32, array: Array) => bool): i32 {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n if (fn(load(this.dataStart + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n findLastIndex(fn: (value: T, index: i32, array: Array) => bool): i32 {\n for (let i = this.length_ - 1; i >= 0; --i) {\n if (fn(load(this.dataStart + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n @operator(\"[]\") private __get(index: i32): T {\n if (index >= this.length_) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(this.dataStart + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n @unsafe @operator(\"{}\") private __uget(index: i32): T {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\") private __set(index: i32, value: T): void {\n if (index >= this.length_) {\n if (index < 0) throw new RangeError(E_INDEXOUTOFRANGE);\n ensureCapacity(changetype(this), index + 1, alignof());\n this.length_ = index + 1;\n }\n store(this.dataStart + (index << alignof()), value);\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n }\n\n at(index: i32): T {\n let len = this.length_;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(this.dataStart + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n fill(value: T, start: i32 = 0, end: i32 = i32.MAX_VALUE): Array {\n if (isManaged()) {\n FILL(this.dataStart, this.length_, changetype(value), start, end);\n __link(changetype(this), changetype(value), false);\n } else {\n FILL(this.dataStart, this.length_, value, start, end);\n }\n return this;\n }\n\n includes(value: T, fromIndex: i32 = 0): bool {\n if (isFloat()) {\n let len = this.length_;\n if (len == 0 || fromIndex >= len) return false;\n if (fromIndex < 0) fromIndex = max(len + fromIndex, 0);\n let ptr = this.dataStart;\n while (fromIndex < len) {\n let elem = load(ptr + (fromIndex << alignof()));\n // @ts-ignore\n if (elem == value || isNaN(elem) & isNaN(value)) return true;\n ++fromIndex;\n }\n return false;\n } else {\n return this.indexOf(value, fromIndex) >= 0;\n }\n }\n\n indexOf(value: T, fromIndex: i32 = 0): i32 {\n let len = this.length_;\n if (len == 0 || fromIndex >= len) return -1;\n if (fromIndex < 0) fromIndex = max(len + fromIndex, 0);\n let ptr = this.dataStart;\n while (fromIndex < len) {\n if (load(ptr + (fromIndex << alignof())) == value) return fromIndex;\n ++fromIndex;\n }\n return -1;\n }\n\n lastIndexOf(value: T, fromIndex: i32 = this.length_): i32 {\n let len = this.length_;\n if (len == 0) return -1;\n if (fromIndex < 0) fromIndex = len + fromIndex;\n else if (fromIndex >= len) fromIndex = len - 1;\n let ptr = this.dataStart;\n while (fromIndex >= 0) {\n if (load(ptr + (fromIndex << alignof())) == value) return fromIndex;\n --fromIndex;\n }\n return -1;\n }\n\n push(value: T): i32 {\n let oldLen = this.length_;\n let len = oldLen + 1;\n ensureCapacity(changetype(this), len, alignof());\n if (isManaged()) {\n store(this.dataStart + (oldLen << alignof()), changetype(value));\n __link(changetype(this), changetype(value), true);\n } else {\n store(this.dataStart + (oldLen << alignof()), value);\n }\n this.length_ = len;\n return len;\n }\n\n concat(other: Array): Array {\n let thisLen = this.length_;\n let otherLen = other.length_;\n let outLen = thisLen + otherLen;\n if (outLen > BLOCK_MAXSIZE >>> alignof()) throw new Error(E_INVALIDLENGTH);\n let out = changetype>(__newArray(outLen, alignof(), idof>()));\n let outStart = out.dataStart;\n let thisSize = thisLen << alignof();\n if (isManaged()) {\n let thisStart = this.dataStart;\n for (let offset: usize = 0; offset < thisSize; offset += sizeof()) {\n let ref = load(thisStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n outStart += thisSize;\n let otherStart = other.dataStart;\n let otherSize = otherLen << alignof();\n for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {\n let ref = load(otherStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(outStart, this.dataStart, thisSize);\n memory.copy(outStart + thisSize, other.dataStart, otherLen << alignof());\n }\n return out;\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Array {\n let ptr = this.dataStart;\n let len = this.length_;\n\n end = min(end, len);\n\n let to = target < 0 ? max(len + target, 0) : min(target, len);\n let from = start < 0 ? max(len + start, 0) : min(start, len);\n let last = end < 0 ? max(len + end, 0) : min(end, len);\n let count = min(last - from, len - to);\n\n memory.copy( // is memmove\n ptr + (to << alignof()),\n ptr + (from << alignof()),\n count << alignof()\n );\n return this;\n }\n\n pop(): T {\n let len = this.length_;\n if (len < 1) throw new RangeError(E_EMPTYARRAY);\n let val = load(this.dataStart + ((--len) << alignof()));\n this.length_ = len;\n return val;\n }\n\n forEach(fn: (value: T, index: i32, array: Array) => void): void {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n fn(load(this.dataStart + (i << alignof())), i, this);\n }\n }\n\n map(fn: (value: T, index: i32, array: Array) => U): Array {\n let len = this.length_;\n let out = changetype>(__newArray(len, alignof(), idof>()));\n let outStart = out.dataStart;\n for (let i = 0; i < min(len, this.length_); ++i) {\n let result = fn(load(this.dataStart + (i << alignof())), i, this);\n store(outStart + (i << alignof()), result);\n if (isManaged()) {\n __link(changetype(out), changetype(result), true);\n }\n }\n return out;\n }\n\n filter(fn: (value: T, index: i32, array: Array) => bool): Array {\n let result = changetype>(__newArray(0, alignof(), idof>()));\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n let value = load(this.dataStart + (i << alignof()));\n if (fn(value, i, this)) result.push(value);\n }\n return result;\n }\n\n reduce(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n acc = fn(acc, load(this.dataStart + (i << alignof())), i, this);\n }\n return acc;\n }\n\n reduceRight(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = this.length_ - 1; i >= 0; --i) {\n acc = fn(acc, load(this.dataStart + (i << alignof())), i, this);\n }\n return acc;\n }\n\n shift(): T {\n let len = this.length_;\n if (len < 1) throw new RangeError(E_EMPTYARRAY);\n let base = this.dataStart;\n let element = load(base);\n let lastIndex = len - 1;\n memory.copy(\n base,\n base + sizeof(),\n lastIndex << alignof()\n );\n if (isReference()) {\n store(base + (lastIndex << alignof()), 0);\n } else {\n // @ts-ignore\n store(base + (lastIndex << alignof()), 0);\n }\n this.length_ = lastIndex;\n return element;\n }\n\n some(fn: (value: T, index: i32, array: Array) => bool): bool {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n if (fn(load(this.dataStart + (i << alignof())), i, this)) return true;\n }\n return false;\n }\n\n unshift(value: T): i32 {\n let len = this.length_ + 1;\n ensureCapacity(changetype(this), len, alignof());\n let ptr = this.dataStart;\n memory.copy(\n ptr + sizeof(),\n ptr,\n (len - 1) << alignof()\n );\n store(ptr, value);\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n this.length_ = len;\n return len;\n }\n\n slice(start: i32 = 0, end: i32 = i32.MAX_VALUE): Array {\n let len = this.length_;\n start = start < 0 ? max(start + len, 0) : min(start, len);\n end = end < 0 ? max(end + len, 0) : min(end , len);\n len = max(end - start, 0);\n let slice = changetype>(__newArray(len, alignof(), idof>()));\n let sliceBase = slice.dataStart;\n let thisBase = this.dataStart + (start << alignof());\n if (isManaged()) {\n let off = 0;\n let end = len << alignof();\n while (off < end) {\n let ref = load(thisBase + off);\n store(sliceBase + off, ref);\n __link(changetype(slice), ref, true);\n off += sizeof();\n }\n } else {\n memory.copy(sliceBase, thisBase, len << alignof());\n }\n return slice;\n }\n\n splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): Array {\n let len = this.length_;\n start = start < 0 ? max(len + start, 0) : min(start, len);\n deleteCount = max(min(deleteCount, len - start), 0);\n let result = changetype>(__newArray(deleteCount, alignof(), idof>()));\n let resultStart = result.dataStart;\n let thisStart = this.dataStart;\n let thisBase = thisStart + (start << alignof());\n memory.copy(\n resultStart,\n thisBase,\n deleteCount << alignof()\n );\n let offset = start + deleteCount;\n if (len != offset) {\n memory.copy(\n thisBase,\n thisStart + (offset << alignof()),\n (len - offset) << alignof()\n );\n }\n this.length_ = len - deleteCount;\n return result;\n }\n\n reverse(): Array {\n REVERSE(this.dataStart, this.length_);\n return this;\n }\n\n sort(comparator: (a: T, b: T) => i32 = COMPARATOR()): Array {\n SORT(this.dataStart, this.length_, comparator);\n return this;\n }\n\n join(separator: string = \",\"): string {\n let ptr = this.dataStart;\n let len = this.length_;\n if (isBoolean()) return joinBooleanArray(ptr, len, separator);\n if (isInteger()) return joinIntegerArray(ptr, len, separator);\n if (isFloat()) return joinFloatArray(ptr, len, separator);\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (isString()) return joinStringArray(ptr, len, separator);\n }\n // For rest objects and arrays use general join routine\n if (isReference()) return joinReferenceArray(ptr, len, separator);\n ERROR(\"unspported element type\");\n return unreachable();\n }\n\n flat(): T {\n if (!isArray()) {\n ERROR(\"Cannot call flat() on Array where T is not an Array.\");\n }\n // Get the length and data start values\n let ptr = this.dataStart;\n let len = this.length_;\n\n // calculate the end size with an initial pass\n let size = 0;\n for (let i = 0; i < len; ++i) {\n let child = load(ptr + (i << alignof()));\n size += child == 0 ? 0 : load(child, offsetof(\"length_\"));\n }\n\n // calculate the byteLength of the resulting backing ArrayBuffer\n const align = alignof>();\n let byteLength = size << align;\n let outBuffer = changetype(__new(byteLength, idof()));\n\n // create the return value and initialize it\n let outArray = changetype(__new(offsetof(), idof()));\n store(changetype(outArray), size, offsetof(\"length_\"));\n\n // byteLength, dataStart, and buffer are all readonly\n store(changetype(outArray), byteLength, offsetof(\"byteLength\"));\n store(changetype(outArray), changetype(outBuffer), offsetof(\"dataStart\"));\n store(changetype(outArray), changetype(outBuffer), offsetof(\"buffer\"));\n __link(changetype(outArray), changetype(outBuffer), false);\n\n // set the elements\n let resultOffset: usize = 0;\n for (let i = 0; i < len; ++i) { // for each child\n let child = load(ptr + (i << alignof()));\n\n // ignore null arrays\n if (!child) continue;\n\n // copy the underlying buffer data to the result buffer\n let childDataLength = load(child, offsetof(\"length_\")) << align;\n memory.copy(\n changetype(outBuffer) + resultOffset,\n load(child, offsetof(\"dataStart\")),\n childDataLength\n );\n\n // advance the result length\n resultOffset += childDataLength;\n }\n\n // if the `valueof` type is managed, we must link each reference\n if (isManaged>()) {\n for (let i = 0; i < size; ++i) {\n let ref = load(changetype(outBuffer) + (i << usize(alignof>())));\n __link(changetype(outBuffer), ref, true);\n }\n }\n\n return outArray;\n }\n\n toString(): string {\n return this.join();\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n if (isManaged()) {\n let cur = this.dataStart;\n let end = cur + (this.length_ << alignof());\n while (cur < end) {\n let val = load(cur);\n if (val) __visit(val, cookie);\n cur += sizeof();\n }\n }\n __visit(changetype(this.buffer), cookie);\n }\n}\n","/**\n * @fileoverview Shared diagnostic handling.\n * @license Apache-2.0\n */\n\nimport {\n Source\n} from \"./ast\";\n\nimport {\n DiagnosticCode,\n diagnosticCodeToString\n} from \"./diagnosticMessages.generated\";\n\nimport {\n isLineBreak,\n isWhiteSpace,\n COLOR_CYAN,\n COLOR_YELLOW,\n COLOR_RED,\n COLOR_MAGENTA,\n COLOR_RESET,\n isColorsEnabled,\n setColorsEnabled,\n CharCode\n} from \"./util\";\n\nexport {\n DiagnosticCode,\n diagnosticCodeToString\n} from \"./diagnosticMessages.generated\";\n\n/** Indicates the category of a {@link DiagnosticMessage}. */\nexport const enum DiagnosticCategory {\n /** Overly pedantic message. */\n Pedantic,\n /** Informatory message. */\n Info,\n /** Warning message. */\n Warning,\n /** Error message. */\n Error\n}\n\nexport class Range {\n\n source!: Source;\n debugInfoRef: usize = 0;\n\n constructor(public start: i32, public end: i32) {}\n\n static join(a: Range, b: Range): Range {\n if (a.source != b.source) throw new Error(\"source mismatch\");\n let range = new Range(\n a.start < b.start ? a.start : b.start,\n a.end > b.end ? a.end : b.end\n );\n range.source = a.source;\n return range;\n }\n\n equals(other: Range): bool {\n return (\n this.source == other.source &&\n this.start == other.start &&\n this.end == other.end\n );\n }\n\n get atStart(): Range {\n let range = new Range(this.start, this.start);\n range.source = this.source;\n return range;\n }\n\n get atEnd(): Range {\n let range = new Range(this.end, this.end);\n range.source = this.source;\n return range;\n }\n\n toString(): string {\n return this.source.text.substring(this.start, this.end);\n }\n}\n\n/** Returns the string representation of the specified diagnostic category. */\nexport function diagnosticCategoryToString(category: DiagnosticCategory): string {\n switch (category) {\n case DiagnosticCategory.Pedantic: return \"PEDANTIC\";\n case DiagnosticCategory.Info: return \"INFO\";\n case DiagnosticCategory.Warning: return \"WARNING\";\n case DiagnosticCategory.Error: return \"ERROR\";\n default: {\n assert(false);\n return \"\";\n }\n }\n}\n\n/** Returns the ANSI escape sequence for the specified category. */\nexport function diagnosticCategoryToColor(category: DiagnosticCategory): string {\n switch (category) {\n case DiagnosticCategory.Pedantic: return COLOR_MAGENTA;\n case DiagnosticCategory.Info: return COLOR_CYAN;\n case DiagnosticCategory.Warning: return COLOR_YELLOW;\n case DiagnosticCategory.Error: return COLOR_RED;\n default: {\n assert(false);\n return \"\";\n }\n }\n}\n\n/** Represents a diagnostic message. */\nexport class DiagnosticMessage {\n\n /** Message code. */\n code: i32;\n /** Message category. */\n category: DiagnosticCategory;\n /** Message text. */\n message: string;\n /** Respective source range, if any. */\n range: Range | null = null;\n /** Related range, if any. */\n relatedRange: Range | null = null; // TODO: Make this a related message for chains?\n\n /** Constructs a new diagnostic message. */\n private constructor(code: i32, category: DiagnosticCategory, message: string) {\n this.code = code;\n this.category = category;\n this.message = message;\n }\n\n /** Creates a new diagnostic message of the specified category. */\n static create(\n code: DiagnosticCode,\n category: DiagnosticCategory,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): DiagnosticMessage {\n let message = diagnosticCodeToString(code);\n if (arg0 != null) message = message.replace(\"{0}\", arg0);\n if (arg1 != null) message = message.replace(\"{1}\", arg1);\n if (arg2 != null) message = message.replace(\"{2}\", arg2);\n return new DiagnosticMessage(code, category, message);\n }\n\n /** Tests if this message equals the specified. */\n equals(other: DiagnosticMessage): bool {\n if (this.code != other.code) return false;\n let thisRange = this.range;\n let otherRange = other.range;\n if (thisRange) {\n if (!otherRange || !thisRange.equals(otherRange)) return false;\n } else if (otherRange) {\n return false;\n }\n let thisRelatedRange = this.relatedRange;\n let otherRelatedRange = other.relatedRange;\n if (thisRelatedRange) {\n if (!otherRelatedRange || !thisRelatedRange.equals(otherRelatedRange)) return false;\n } else if (otherRelatedRange) {\n return false;\n }\n return this.message == other.message;\n }\n\n /** Adds a source range to this message. */\n withRange(range: Range): this {\n this.range = range;\n return this;\n }\n\n /** Adds a related source range to this message. */\n withRelatedRange(range: Range): this {\n this.relatedRange = range;\n return this;\n }\n\n /** Converts this message to a string. */\n toString(): string {\n let category = diagnosticCategoryToString(this.category);\n let range = this.range;\n let code = this.code;\n let message = this.message;\n if (range) {\n let source = range.source;\n let path = source.normalizedPath;\n let line = source.lineAt(range.start);\n let column = source.columnAt();\n let len = range.end - range.start;\n return `${category} ${code}: \"${message}\" in ${path}(${line},${column}+${len})`;\n }\n return `${category} ${code}: ${message}`;\n }\n}\n\n/** Formats a diagnostic message, optionally with terminal colors and source context. */\nexport function formatDiagnosticMessage(\n message: DiagnosticMessage,\n useColors: bool = false,\n showContext: bool = false\n): string {\n let wasColorsEnabled = setColorsEnabled(useColors);\n\n // general information\n let sb: string[] = [];\n if (isColorsEnabled()) sb.push(diagnosticCategoryToColor(message.category));\n sb.push(diagnosticCategoryToString(message.category));\n if (isColorsEnabled()) sb.push(COLOR_RESET);\n sb.push(message.code < 1000 ? \" AS\" : \" TS\");\n sb.push(message.code.toString());\n sb.push(\": \");\n sb.push(message.message);\n\n // include range information if available\n let range = message.range;\n if (range) {\n let source = range.source;\n let relatedRange = message.relatedRange;\n let minLine = 0;\n if (relatedRange) {\n // Justify context indentation when multiple ranges are present\n minLine = max(source.lineAt(range.start), relatedRange.source.lineAt(relatedRange.start));\n }\n\n // include context information if requested\n if (showContext) {\n sb.push(\"\\n\");\n sb.push(formatDiagnosticContext(range, minLine));\n } else {\n sb.push(\"\\n in \");\n sb.push(source.normalizedPath);\n }\n sb.push(\"(\");\n sb.push(source.lineAt(range.start).toString());\n sb.push(\",\");\n sb.push(source.columnAt().toString());\n sb.push(\")\");\n\n if (relatedRange) {\n let relatedSource = relatedRange.source;\n if (showContext) {\n sb.push(\"\\n\");\n sb.push(formatDiagnosticContext(relatedRange, minLine));\n } else {\n sb.push(\"\\n in \");\n sb.push(relatedSource.normalizedPath);\n }\n sb.push(\"(\");\n sb.push(relatedSource.lineAt(relatedRange.start).toString());\n sb.push(\",\");\n sb.push(relatedSource.columnAt().toString());\n sb.push(\")\");\n }\n }\n setColorsEnabled(wasColorsEnabled);\n return sb.join(\"\");\n}\n\n/** Formats the diagnostic context for the specified range, optionally with terminal colors. */\nfunction formatDiagnosticContext(range: Range, minLine: i32 = 0): string {\n let source = range.source;\n let text = source.text;\n let len = text.length;\n let start = range.start;\n let end = start;\n let lineNumber = source.lineAt(start).toString();\n let lineNumberLength = minLine\n ? max(minLine.toString().length, lineNumber.length)\n : lineNumber.length;\n let lineSpace = \" \".repeat(lineNumberLength);\n // Find preceeding line break\n while (start > 0 && !isLineBreak(text.charCodeAt(start - 1))) start--;\n // Skip leading whitespace (assume no supplementary whitespaces)\n while (start < len && isWhiteSpace(text.charCodeAt(start))) start++;\n // Find next line break\n while (end < len && !isLineBreak(text.charCodeAt(end))) end++;\n let sb: string[] = [\n lineSpace,\n \" :\\n \",\n \" \".repeat(lineNumberLength - lineNumber.length),\n lineNumber,\n \" │ \",\n text.substring(start, end).replaceAll(\"\\t\", \" \"),\n \"\\n \",\n lineSpace,\n \" │ \"\n ];\n while (start < range.start) {\n if (text.charCodeAt(start) == CharCode.Tab) {\n sb.push(\" \");\n start += 2;\n } else {\n sb.push(\" \");\n start++;\n }\n }\n if (isColorsEnabled()) sb.push(COLOR_RED);\n if (range.start == range.end) {\n sb.push(\"^\");\n } else {\n while (start++ < range.end) {\n let cc = text.charCodeAt(start);\n if (cc == CharCode.Tab) {\n sb.push(\"~~\");\n } else if (isLineBreak(cc)) {\n sb.push(start == range.start + 1 ? \"^\" : \"~\");\n break;\n } else {\n sb.push(\"~\");\n }\n }\n }\n if (isColorsEnabled()) sb.push(COLOR_RESET);\n sb.push(\"\\n \");\n sb.push(lineSpace);\n sb.push(\" └─ in \");\n sb.push(source.normalizedPath);\n return sb.join(\"\");\n}\n\n/** Base class of all diagnostic emitters. */\nexport abstract class DiagnosticEmitter {\n\n /** Diagnostic messages emitted so far. */\n diagnostics: DiagnosticMessage[];\n /** Diagnostic messages already seen, by range. */\n private seen: Map> = new Map();\n\n /** Initializes this diagnostic emitter. */\n protected constructor(diagnostics: DiagnosticMessage[] | null = null) {\n if (!diagnostics) diagnostics = [];\n this.diagnostics = diagnostics;\n }\n\n /** Emits a diagnostic message of the specified category. */\n emitDiagnostic(\n code: DiagnosticCode,\n category: DiagnosticCategory,\n range: Range | null,\n relatedRange: Range | null,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n let message = DiagnosticMessage.create(code, category, arg0, arg1, arg2);\n if (range) message = message.withRange(range);\n if (relatedRange) message.relatedRange = relatedRange;\n // It is possible that the same diagnostic is emitted twice, for example\n // when compiling generics with different types or when recompiling a loop\n // because our initial assumptions didn't hold. It is even possible to get\n // multiple instances of the same range during parsing. Deduplicate these.\n if (range) {\n let seen = this.seen;\n if (seen.has(range.source)) {\n let seenInSource = assert(seen.get(range.source));\n if (seenInSource.has(range.start)) {\n let seenMessagesAtPos = assert(seenInSource.get(range.start));\n for (let i = 0, k = seenMessagesAtPos.length; i < k; ++i) {\n if (seenMessagesAtPos[i].equals(message)) return;\n }\n seenMessagesAtPos.push(message);\n } else {\n seenInSource.set(range.start, [ message ]);\n }\n } else {\n let seenInSource = new Map();\n seenInSource.set(range.start, [ message ]);\n seen.set(range.source, seenInSource);\n }\n }\n this.diagnostics.push(message);\n // console.log(formatDiagnosticMessage(message, true, true) + \"\\n\"); // temporary\n // console.log(new Error(\"stack\").stack);\n }\n\n /** Emits an overly pedantic diagnostic message. */\n pedantic(\n code: DiagnosticCode,\n range: Range | null,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Pedantic, range, null, arg0, arg1, arg2);\n }\n\n /** Emits an overly pedantic diagnostic message with a related range. */\n pedanticRelated(\n code: DiagnosticCode,\n range: Range,\n relatedRange: Range,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Pedantic, range, relatedRange, arg0, arg1, arg2);\n }\n\n /** Emits an informatory diagnostic message. */\n info(\n code: DiagnosticCode,\n range: Range | null,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Info, range, null, arg0, arg1, arg2);\n }\n\n /** Emits an informatory diagnostic message with a related range. */\n infoRelated(\n code: DiagnosticCode,\n range: Range,\n relatedRange: Range,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Info, range, relatedRange, arg0, arg1, arg2);\n }\n\n /** Emits a warning diagnostic message. */\n warning(\n code: DiagnosticCode,\n range: Range | null,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Warning, range, null, arg0, arg1, arg2);\n }\n\n /** Emits a warning diagnostic message with a related range. */\n warningRelated(\n code: DiagnosticCode,\n range: Range,\n relatedRange: Range,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Warning, range, relatedRange, arg0, arg1, arg2);\n }\n\n /** Emits an error diagnostic message. */\n error(\n code: DiagnosticCode,\n range: Range | null,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Error, range, null, arg0, arg1, arg2);\n }\n\n /** Emits an error diagnostic message with a related range. */\n errorRelated(\n code: DiagnosticCode,\n range: Range,\n relatedRange: Range,\n arg0: string | null = null,\n arg1: string | null = null,\n arg2: string | null = null\n ): void {\n this.emitDiagnostic(code, DiagnosticCategory.Error, range, relatedRange, arg0, arg1, arg2);\n }\n}\n","import { itoa32, utoa32, itoa64, utoa64, dtoa } from \"./util/number\";\nimport { strtol, strtod } from \"./util/string\";\n\n// @ts-ignore: decorator\n@builtin @inline\nexport const NaN: f64 = 0 / 0; // context-aware\n\n// @ts-ignore: decorator\n@builtin @inline\nexport const Infinity: f64 = 1 / 0; // context-aware\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isNaN(value: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isFinite(value: T): bool;\n\n@final @unmanaged\nexport abstract class I8 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i8 = i8.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i8 = i8.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i8 {\n return strtol(value, radix);\n }\n\n toString(this: i8, radix: i32 = 10): String {\n return itoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class I16 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i16 = i16.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i16 = i16.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i16 {\n return strtol(value, radix);\n }\n\n toString(this: i16, radix: i32 = 10): String {\n return itoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class I32 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i32 = i32.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i32 = i32.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i32 {\n return strtol(value, radix);\n }\n\n toString(this: i32, radix: i32 = 10): String {\n return itoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class I64 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i64 = i64.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i64 = i64.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i64 {\n return strtol(value, radix);\n }\n\n toString(this: i64, radix: i32 = 10): String {\n return itoa64(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class Isize {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: isize = isize.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: isize = isize.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): isize {\n return strtol(value, radix);\n }\n\n toString(this: isize, radix: i32 = 10): String {\n if (sizeof() == 4) {\n return itoa32(this, radix);\n } else {\n return itoa64(this, radix);\n }\n }\n}\n\n@final @unmanaged\nexport abstract class U8 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u8 = u8.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u8 = u8.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u8 {\n return strtol(value, radix);\n }\n\n toString(this: u8, radix: i32 = 10): String {\n return utoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class U16 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u16 = u16.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u16 = u16.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u16 {\n return strtol(value, radix);\n }\n\n toString(this: u16, radix: i32 = 10): String {\n return utoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class U32 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u32 = u32.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u32 = u32.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u32 {\n return strtol(value, radix);\n }\n\n toString(this: u32, radix: i32 = 10): String {\n return utoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class U64 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u64 = u64.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u64 = u64.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u64 {\n return strtol(value, radix);\n }\n\n toString(this: u64, radix: i32 = 10): String {\n return utoa64(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class Usize {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: usize = usize.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: usize = usize.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): usize {\n return strtol(value, radix);\n }\n\n toString(this: usize, radix: i32 = 10): String {\n if (sizeof() == 4) {\n return utoa32(this, radix);\n } else {\n return utoa64(this, radix);\n }\n }\n}\n\n@final @unmanaged\nexport abstract class Bool {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: bool = bool.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: bool = bool.MAX_VALUE;\n\n toString(this: bool, radix: i32 = 0): String {\n return this ? \"true\" : \"false\";\n }\n}\n\nexport { Bool as Boolean };\n\n@final @unmanaged\nexport abstract class F32 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly EPSILON: f32 = f32.EPSILON;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: f32 = f32.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: f32 = f32.MAX_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_SAFE_INTEGER: f32 = f32.MIN_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_SAFE_INTEGER: f32 = f32.MAX_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly POSITIVE_INFINITY: f32 = f32.POSITIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NEGATIVE_INFINITY: f32 = f32.NEGATIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NaN: f32 = f32.NaN;\n\n static isNaN(value: f32): bool {\n return isNaN(value);\n }\n\n static isFinite(value: f32): bool {\n return isFinite(value);\n }\n\n static isSafeInteger(value: f32): bool {\n return abs(value) <= f32.MAX_SAFE_INTEGER && trunc(value) == value;\n }\n\n static isInteger(value: f32): bool {\n return isFinite(value) && trunc(value) == value;\n }\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): f32 {\n return strtol(value, radix);\n }\n\n /** @deprecated */\n static parseFloat(value: string): f32 {\n return strtod(value);\n }\n\n toString(this: f32, radix: i32 = 0): String {\n return dtoa(this);\n }\n}\n\n@final @unmanaged\nexport abstract class F64 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly EPSILON: f64 = f64.EPSILON;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: f64 = f64.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: f64 = f64.MAX_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_SAFE_INTEGER: f64 = f64.MIN_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_SAFE_INTEGER: f64 = f64.MAX_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly POSITIVE_INFINITY: f64 = f64.POSITIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NEGATIVE_INFINITY: f64 = f64.NEGATIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NaN: f64 = f64.NaN;\n\n static isNaN(value: f64): bool {\n return isNaN(value);\n }\n\n static isFinite(value: f64): bool {\n return isFinite(value);\n }\n\n static isSafeInteger(value: f64): bool {\n return abs(value) <= f64.MAX_SAFE_INTEGER && trunc(value) == value;\n }\n\n static isInteger(value: f64): bool {\n return isFinite(value) && trunc(value) == value;\n }\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): f64 {\n return strtol(value, radix);\n }\n\n /** @deprecated */\n static parseFloat(value: string): f64 {\n return strtod(value);\n }\n\n toString(this: f64, radix: i32 = 0): String {\n return dtoa(this);\n }\n}\n\nexport { F64 as Number };\n","/**\n * @fileoverview Various collections utility.\n * @license Apache-2.0\n */\n\n/** Clone map. Typically used to track contextual type arguments. */\nexport function cloneMap(map: Map | null): Map {\n if (!ASC_TARGET) { // JS\n // fast path for js target\n return new Map(map);\n } else {\n let out = new Map();\n if (map) {\n // TODO: for (let [k, v] of map) {\n for (let _keys = Map_keys(map), i = 0, k = _keys.length; i < k; ++i) {\n let k = unchecked(_keys[i]);\n let v = assert(map.get(k));\n out.set(k, v);\n }\n }\n return out;\n }\n}\n\n/** Merge two maps in into new one. */\nexport function mergeMaps(map1: Map, map2: Map): Map {\n if (!ASC_TARGET) { // JS\n let out = new Map(map1);\n map2.forEach((v, k) => out.set(k, v));\n return out;\n } else {\n let out = new Map();\n // TODO: for (let [k, v] of map1) {\n for (let _keys = Map_keys(map1), i = 0, k = _keys.length; i < k; ++i) {\n let k = unchecked(_keys[i]);\n let v = assert(map1.get(k));\n out.set(k, v);\n }\n // TODO: for (let [k, v] of map2) {\n for (let _keys = Map_keys(map2), i = 0, k = _keys.length; i < k; ++i) {\n let k = unchecked(_keys[i]);\n let v = assert(map2.get(k));\n out.set(k, v);\n }\n return out;\n }\n}\n\n/** BitSet represent growable sequence of N bits. It's faster alternative of Set when elements\n * are not too much sparsed. Also it's more memory and cache efficient than Array.\n * The best way to use it for short bit sequences (less than 32*(2**16)).\n */\nexport class BitSet {\n words!: Uint32Array;\n\n constructor() {\n this.clear();\n }\n\n get size(): i32 {\n let count = 0;\n let words = this.words;\n for (let i = 0, len = words.length; i < len; i++) {\n let word = unchecked(words[i]);\n if (word) count += popcnt(word);\n }\n return count;\n }\n\n add(index: i32): this {\n let idx = index >>> 5;\n let words = this.words;\n if (idx >= words.length) { // resize\n this.words = new Uint32Array(idx + 16);\n this.words.set(words);\n words = this.words;\n }\n unchecked(words[idx] |= 1 << index);\n return this;\n }\n\n delete(index: i32): void {\n let idx = index >>> 5;\n let words = this.words;\n if (idx >= words.length) return;\n unchecked(words[idx] &= ~(1 << index));\n }\n\n has(index: i32): bool {\n let idx = index >>> 5;\n let words = this.words;\n if (idx >= words.length) return false;\n return (unchecked(words[index >>> 5]) & (1 << index)) !== 0;\n }\n\n clear(): void {\n this.words = new Uint32Array(16);\n }\n\n toArray(): i32[] {\n let res = new Array(this.size);\n for (let i = 0, p = 0, len = this.words.length; i < len; ++i) {\n let word = unchecked(this.words[i]);\n while (word) {\n let mask = word & -word;\n unchecked(res[p++] = (i << 5) + popcnt(mask - 1));\n word ^= mask;\n }\n }\n return res;\n }\n\n toString(): string {\n return `BitSet { ${this.toArray()} }`;\n }\n}\n","/**\n * @fileoverview Collections glue code for WebAssembly.\n * @license Apache-2.0\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n// @ts-ignore: decorator\n@global @inline\nfunction Map_keys(map: Map): K[] {\n return map.keys(); // preliminary\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction Map_values(map: Map): V[] {\n return map.values(); // preliminary\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction Set_values(set: Set): V[] {\n return set.values(); // preliminary\n}\n","/**\n * @fileoverview Resolve infrastructure to obtain types and elements.\n *\n * Similar to the compiler making instructions of expressions, the resolver\n * obtains metadata of expressions. As such, for each `compileX` method in\n * the compiler there is one `lookupX` method in the resolver returning the\n * respective IR element, respectively one `resolveX` method returning the\n * respective type of an expression. It is also able to make new elements,\n * like instances of classes given its concrete type arguments.\n *\n * @license Apache-2.0\n */\n\nimport {\n Range,\n DiagnosticEmitter,\n DiagnosticCode\n} from \"./diagnostics\";\n\nimport {\n Program,\n ElementKind,\n OperatorKind,\n Element,\n Class,\n ClassPrototype,\n Interface,\n Function,\n FunctionPrototype,\n VariableLikeElement,\n Property,\n PropertyPrototype,\n Global,\n TypeDefinition,\n TypedElement,\n IndexSignature,\n isTypedElement,\n InterfacePrototype,\n DeclaredElement\n} from \"./program\";\n\nimport {\n Flow\n} from \"./flow\";\n\nimport {\n FunctionTypeNode,\n ParameterKind,\n TypeNode,\n NodeKind,\n NamedTypeNode,\n TypeName,\n TypeParameterNode,\n Node,\n IdentifierExpression,\n CallExpression,\n ElementAccessExpression,\n PropertyAccessExpression,\n LiteralExpression,\n LiteralKind,\n ParenthesizedExpression,\n AssertionExpression,\n Expression,\n IntegerLiteralExpression,\n UnaryPrefixExpression,\n UnaryPostfixExpression,\n AssertionKind,\n BinaryExpression,\n ThisExpression,\n SuperExpression,\n CommaExpression,\n InstanceOfExpression,\n TernaryExpression,\n isTypeOmitted,\n FunctionExpression,\n NewExpression,\n ArrayLiteralExpression,\n ArrowKind,\n ExpressionStatement\n} from \"./ast\";\n\nimport {\n Type,\n Signature,\n typesToString,\n TypeKind,\n TypeFlags\n} from \"./types\";\n\nimport {\n CommonFlags,\n CommonNames\n} from \"./common\";\n\nimport {\n cloneMap,\n isPowerOf2\n} from \"./util\";\n\nimport {\n Token,\n operatorTokenToString\n} from \"./tokenizer\";\n\nimport {\n BuiltinNames\n} from \"./builtins\";\n\n/** Indicates whether errors are reported or not. */\nexport const enum ReportMode {\n /** Report errors. */\n Report,\n /** Swallow errors. */\n Swallow\n}\n\n/** Provides tools to resolve types and expressions. */\nexport class Resolver extends DiagnosticEmitter {\n\n /** The program this resolver belongs to. */\n program: Program;\n\n /** Target expression of the previously resolved property or element access. */\n currentThisExpression: Expression | null = null;\n /** Element expression of the previously resolved element access. */\n currentElementExpression : Expression | null = null;\n /** Whether a new override has been discovered. */\n discoveredOverride: bool = false;\n\n /** Constructs the resolver for the specified program. */\n constructor(\n /** The program to construct a resolver for. */\n program: Program\n ) {\n super(program.diagnostics);\n this.program = program;\n }\n\n // ====================================================== Types ======================================================\n\n /** Resolves a {@link TypeNode} to a concrete {@link Type}. */\n resolveType(\n /** The type to resolve. */\n node: TypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n if (node.currentlyResolving) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n node.range, \"Recursive types\"\n );\n return null;\n }\n node.currentlyResolving = true;\n let resolved: Type | null = null;\n switch (node.kind) {\n case NodeKind.NamedType: {\n resolved = this.resolveNamedType(\n node,\n ctxElement,\n ctxTypes,\n reportMode\n );\n break;\n }\n case NodeKind.FunctionType: {\n resolved = this.resolveFunctionType(\n node,\n ctxElement,\n ctxTypes,\n reportMode\n );\n break;\n }\n default: assert(false);\n }\n node.currentlyResolving = false;\n return resolved;\n }\n\n /** Resolves a {@link NamedTypeNode} to a concrete {@link Type}. */\n private resolveNamedType(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let nameNode = node.name;\n let typeArgumentNodes = node.typeArguments;\n let isSimpleType = !nameNode.next;\n\n // Look up in contextual types if a simple type\n if (isSimpleType) {\n let simpleName = nameNode.identifier.text;\n if (ctxTypes && ctxTypes.has(simpleName)) {\n let type = assert(ctxTypes.get(simpleName));\n if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n node.range, type.toString()\n );\n }\n }\n if (node.isNullable) {\n if (type.isInternalReference) return type.asNullable();\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_cannot_be_nullable,\n node.range, type.toString()\n );\n }\n }\n return type;\n }\n }\n\n // Look up in context\n let element = this.resolveTypeName(nameNode, ctxElement, reportMode);\n if (!element) return null;\n\n // Use shadow type if present (i.e. namespace sharing a type)\n let shadowType = element.shadowType;\n if (shadowType) {\n element = shadowType;\n\n } else {\n\n // Handle enums (become i32)\n if (element.kind == ElementKind.Enum) {\n if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n node.range, element.internalName\n );\n }\n }\n if (node.isNullable) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_cannot_be_nullable,\n node.range, `${element.name}/i32`\n );\n }\n }\n return Type.i32;\n }\n\n // Handle classes and interfaces\n if (\n element.kind == ElementKind.ClassPrototype ||\n element.kind == ElementKind.InterfacePrototype\n ) {\n let instance = this.resolveClassInclTypeArguments(\n element,\n typeArgumentNodes,\n ctxElement,\n cloneMap(ctxTypes), // don't inherit\n node,\n reportMode\n );\n if (!instance) return null;\n return node.isNullable ? instance.type.asNullable() : instance.type;\n }\n }\n\n // Handle type definitions\n if (element.kind == ElementKind.TypeDefinition) {\n let typeDefinition = element;\n\n // Shortcut already resolved (mostly builtins)\n if (element.is(CommonFlags.Resolved)) {\n if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n node.range, element.internalName\n );\n }\n }\n let type = typeDefinition.type;\n if (node.isNullable) {\n if (type.isInternalReference) return type.asNullable();\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_cannot_be_nullable,\n nameNode.range, nameNode.identifier.text\n );\n }\n }\n return type;\n }\n\n // Handle special built-in types\n if (isSimpleType) {\n let text = nameNode.identifier.text;\n if (text == CommonNames.native) return this.resolveBuiltinNativeType(node, ctxElement, ctxTypes, reportMode);\n if (text == CommonNames.indexof) return this.resolveBuiltinIndexofType(node, ctxElement, ctxTypes, reportMode);\n if (text == CommonNames.valueof) return this.resolveBuiltinValueofType(node, ctxElement, ctxTypes, reportMode);\n if (text == CommonNames.returnof) return this.resolveBuiltinReturnTypeType(node, ctxElement, ctxTypes, reportMode);\n if (text == CommonNames.nonnull) return this.resolveBuiltinNotNullableType(node, ctxElement, ctxTypes, reportMode);\n }\n\n // Resolve normally\n let typeParameterNodes = typeDefinition.typeParameterNodes;\n let typeArguments: Type[] | null = null;\n if (typeParameterNodes) {\n typeArguments = this.resolveTypeArguments(\n typeParameterNodes,\n typeArgumentNodes,\n ctxElement,\n ctxTypes = cloneMap(ctxTypes), // update\n node,\n reportMode\n );\n if (!typeArguments) return null;\n } else if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n node.range, nameNode.identifier.text\n );\n }\n let type = this.resolveType(\n typeDefinition.typeNode,\n element,\n ctxTypes,\n reportMode\n );\n if (!type) return null;\n if (node.isNullable) {\n if (type.isInternalReference) return type.asNullable();\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_cannot_be_nullable,\n nameNode.range, nameNode.identifier.text\n );\n }\n }\n return type;\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n nameNode.range, nameNode.identifier.text\n );\n }\n return null;\n }\n\n /** Resolves a {@link FunctionTypeNode} to a concrete {@link Type}. */\n private resolveFunctionType(\n /** The type to resolve. */\n node: FunctionTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let explicitThisType = node.explicitThisType;\n let thisType: Type | null = null;\n if (explicitThisType) {\n thisType = this.resolveType(\n explicitThisType,\n ctxElement,\n ctxTypes,\n reportMode\n );\n if (!thisType) return null;\n }\n let parameterNodes = node.parameters;\n let numParameters = parameterNodes.length;\n let parameterTypes = new Array(numParameters);\n let requiredParameters = 0;\n let hasRest = false;\n for (let i = 0; i < numParameters; ++i) {\n let parameterNode = parameterNodes[i];\n switch (parameterNode.parameterKind) {\n case ParameterKind.Default: {\n requiredParameters = i + 1;\n break;\n }\n case ParameterKind.Rest: {\n assert(i == numParameters);\n hasRest = true;\n break;\n }\n }\n let parameterTypeNode = parameterNode.type;\n if (isTypeOmitted(parameterTypeNode)) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_expected,\n parameterTypeNode.range\n );\n }\n return null;\n }\n let parameterType = this.resolveType(\n parameterTypeNode,\n ctxElement,\n ctxTypes,\n reportMode\n );\n if (!parameterType) return null;\n parameterTypes[i] = parameterType;\n }\n let returnTypeNode = node.returnType;\n let returnType: Type | null;\n if (isTypeOmitted(returnTypeNode)) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_expected,\n returnTypeNode.range\n );\n }\n returnType = Type.void;\n } else {\n returnType = this.resolveType(\n returnTypeNode,\n ctxElement,\n ctxTypes,\n reportMode\n );\n if (!returnType) return null;\n }\n let signature = Signature.create(this.program, parameterTypes, returnType, thisType, requiredParameters, hasRest);\n return node.isNullable ? signature.type.asNullable() : signature.type;\n }\n\n private resolveBuiltinNativeType(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const typeArgumentNode = this.ensureOneTypeArgument(node, reportMode);\n if (!typeArgumentNode) return null;\n let typeArgument = this.resolveType(typeArgumentNode, ctxElement, ctxTypes, reportMode);\n if (!typeArgument) return null;\n switch (typeArgument.kind) {\n case TypeKind.I8:\n case TypeKind.I16:\n case TypeKind.I32: return Type.i32;\n case TypeKind.Isize: if (!this.program.options.isWasm64) return Type.i32;\n case TypeKind.I64: return Type.i64;\n case TypeKind.U8:\n case TypeKind.U16:\n case TypeKind.U32:\n case TypeKind.Bool: return Type.u32;\n case TypeKind.Usize: if (!this.program.options.isWasm64) return Type.u32;\n case TypeKind.U64: return Type.u64;\n case TypeKind.F32: return Type.f32;\n case TypeKind.F64: return Type.f64;\n case TypeKind.V128: return Type.v128;\n case TypeKind.Void: return Type.void;\n default: assert(false);\n }\n return null;\n }\n\n private resolveBuiltinIndexofType(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const typeArgumentNode = this.ensureOneTypeArgument(node, reportMode);\n if (!typeArgumentNode) return null;\n let typeArgument = this.resolveType(typeArgumentNode, ctxElement, ctxTypes, reportMode);\n if (!typeArgument) return null;\n let classReference = typeArgument.classReference;\n if (!classReference) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n typeArgumentNode.range, typeArgument.toString()\n );\n }\n return null;\n }\n let overload = classReference.lookupOverload(OperatorKind.IndexedGet);\n if (overload) {\n let parameterTypes = overload.signature.parameterTypes;\n if (overload.is(CommonFlags.Static)) {\n assert(parameterTypes.length == 2);\n return parameterTypes[1];\n } else {\n assert(parameterTypes.length == 1);\n return parameterTypes[0];\n }\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n typeArgumentNode.range, typeArgument.toString()\n );\n }\n return null;\n }\n\n private resolveBuiltinValueofType(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const typeArgumentNode = this.ensureOneTypeArgument(node, reportMode);\n if (!typeArgumentNode) return null;\n let typeArgument = this.resolveType(typeArgumentNode, ctxElement, ctxTypes, reportMode);\n if (!typeArgument) return null;\n let classReference = typeArgument.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.IndexedGet);\n if (overload) return overload.signature.returnType;\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n typeArgumentNode.range, typeArgument.toString()\n );\n }\n return null;\n }\n\n private resolveBuiltinReturnTypeType(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventualy diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const typeArgumentNode = this.ensureOneTypeArgument(node, reportMode);\n if (!typeArgumentNode) return null;\n let typeArgument = this.resolveType(typeArgumentNode, ctxElement, ctxTypes, reportMode);\n if (!typeArgument) return null;\n let signatureReference = typeArgument.getSignature();\n if (signatureReference) return signatureReference.returnType;\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_has_no_call_signatures,\n typeArgumentNode.range, typeArgument.toString()\n );\n }\n return null;\n }\n\n private resolveBuiltinNotNullableType(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const typeArgumentNode = this.ensureOneTypeArgument(node, reportMode);\n if (!typeArgumentNode) return null;\n let typeArgument = this.resolveType(typeArgumentNode, ctxElement, ctxTypes, reportMode);\n if (!typeArgument) return null;\n if (!typeArgument.isNullableReference) return typeArgument;\n return typeArgument.nonNullableType;\n }\n\n /** Resolves a type name to the program element it refers to. */\n resolveTypeName(\n /** The type name to resolve. */\n node: TypeName,\n /** Contextual element. */\n ctxElement: Element,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let element = ctxElement.lookup(node.identifier.text, true);\n if (!element) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n node.range, node.identifier.text\n );\n }\n return null;\n }\n let prev = node;\n let next = node.next;\n while (next) {\n if (!(element = element.getMember(next.identifier.text))) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Property_0_does_not_exist_on_type_1,\n next.range, next.identifier.text, prev.identifier.text\n );\n }\n return null;\n }\n prev = next;\n next = next.next;\n }\n return element;\n }\n\n /** Resolves an array of type arguments to concrete types. */\n resolveTypeArguments(\n /** Type parameter nodes present. */\n typeParameters: TypeParameterNode[],\n /** Type argument nodes provided. */\n typeArgumentNodes: TypeNode[] | null,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. Updated in place with the new set of contextual types. */\n ctxTypes: Map = new Map(),\n /** Alternative report node in case of empty type arguments. */\n alternativeReportNode: Node | null = null,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type[] | null {\n var\n minParameterCount = 0,\n maxParameterCount = 0;\n for (let i = 0, k = typeParameters.length; i < k; ++i) {\n if (!typeParameters[i].defaultType) ++minParameterCount;\n ++maxParameterCount;\n }\n let argumentCount = typeArgumentNodes ? typeArgumentNodes.length : 0;\n if (argumentCount < minParameterCount || argumentCount > maxParameterCount) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n argumentCount\n ? Range.join(\n typeArgumentNodes![0].range,\n typeArgumentNodes![argumentCount - 1].range\n )\n : alternativeReportNode!.range,\n (argumentCount < minParameterCount ? minParameterCount : maxParameterCount).toString(),\n argumentCount.toString()\n );\n }\n return null;\n }\n let typeArguments = new Array(maxParameterCount);\n let oldCtxTypes = cloneMap(ctxTypes);\n ctxTypes.clear();\n for (let i = 0; i < maxParameterCount; ++i) {\n let type = i < argumentCount\n ? this.resolveType( // reports\n typeArgumentNodes![i],\n ctxElement,\n oldCtxTypes, // update\n reportMode\n )\n : this.resolveType( // reports\n assert(typeParameters[i].defaultType),\n ctxElement,\n cloneMap(ctxTypes), // don't update\n reportMode\n );\n if (!type) return null;\n // TODO: check extendsType\n ctxTypes.set(typeParameters[i].name.text, type);\n typeArguments[i] = type;\n }\n return typeArguments;\n }\n\n /** Resolves respectively infers the concrete instance of a function by call context. */\n maybeInferCall(\n node: CallExpression,\n prototype: FunctionPrototype,\n ctxFlow: Flow,\n reportMode: ReportMode = ReportMode.Report\n ): Function | null {\n let typeArguments = node.typeArguments;\n\n // resolve generic call if type arguments have been provided\n if (typeArguments) {\n if (!prototype.is(CommonFlags.Generic)) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n node.expression.range, prototype.internalName\n );\n }\n return null;\n }\n return this.resolveFunctionInclTypeArguments(\n prototype,\n typeArguments,\n ctxFlow.sourceFunction,\n cloneMap(ctxFlow.contextualTypeArguments), // don't inherit\n node,\n reportMode\n );\n }\n\n // infer generic call if type arguments have been omitted\n if (prototype.is(CommonFlags.Generic)) {\n let contextualTypeArguments = cloneMap(ctxFlow.contextualTypeArguments);\n\n // fill up contextual types with auto for each generic component\n let typeParameterNodes = assert(prototype.typeParameterNodes);\n let numTypeParameters = typeParameterNodes.length;\n let typeParameterNames = new Set();\n for (let i = 0; i < numTypeParameters; ++i) {\n let name = typeParameterNodes[i].name.text;\n contextualTypeArguments.set(name, Type.auto);\n typeParameterNames.add(name);\n }\n\n let parameterNodes = prototype.functionTypeNode.parameters;\n let numParameters = parameterNodes.length;\n let argumentNodes = node.args;\n let numArguments = argumentNodes.length;\n\n // infer types with generic components while updating contextual types\n for (let i = 0; i < numParameters; ++i) {\n let argumentExpression = i < numArguments\n ? argumentNodes[i]\n : parameterNodes[i].initializer;\n if (!argumentExpression) {\n // optional but not have initializer should be handled in the other place\n if (parameterNodes[i].parameterKind == ParameterKind.Optional) {\n continue;\n }\n // missing initializer -> too few arguments\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expected_0_arguments_but_got_1,\n node.range, numParameters.toString(), numArguments.toString()\n );\n }\n return null;\n }\n let typeNode = parameterNodes[i].type;\n if (typeNode.hasGenericComponent(typeParameterNodes)) {\n let type = this.resolveExpression(argumentExpression, ctxFlow, Type.auto, ReportMode.Swallow);\n if (type) {\n this.propagateInferredGenericTypes(\n typeNode,\n type,\n prototype,\n contextualTypeArguments,\n typeParameterNames\n );\n }\n }\n }\n\n // apply concrete types to the generic function signature\n let resolvedTypeArguments = new Array(numTypeParameters);\n for (let i = 0; i < numTypeParameters; ++i) {\n let typeParameterNode = typeParameterNodes[i];\n let name = typeParameterNode.name.text;\n if (contextualTypeArguments.has(name)) {\n let inferredType = assert(contextualTypeArguments.get(name));\n if (inferredType != Type.auto) {\n resolvedTypeArguments[i] = inferredType;\n continue;\n }\n let defaultType = typeParameterNode.defaultType;\n if (defaultType) {\n // Default parameters are resolved in context of the called function, not the calling function\n let parent = prototype.parent;\n let defaultTypeContextualTypeArguments: Map | null = null;\n if (parent.kind == ElementKind.Class) {\n defaultTypeContextualTypeArguments = (parent).contextualTypeArguments;\n } else if (parent.kind == ElementKind.Function) {\n defaultTypeContextualTypeArguments = (parent).contextualTypeArguments;\n }\n let resolvedDefaultType = this.resolveType(\n defaultType,\n prototype,\n defaultTypeContextualTypeArguments,\n reportMode\n );\n if (!resolvedDefaultType) return null;\n resolvedTypeArguments[i] = resolvedDefaultType;\n continue;\n }\n }\n // unused template, e.g. `function test(): void {...}` called as `test()`\n // invalid because the type is effectively unknown inside the function body\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_argument_expected,\n node.expression.range.atEnd\n );\n }\n return null;\n }\n return this.resolveFunction(\n prototype,\n resolvedTypeArguments,\n cloneMap(ctxFlow.contextualTypeArguments),\n reportMode\n );\n }\n\n // otherwise resolve the non-generic call as usual\n return this.resolveFunction(prototype, null, new Map(), reportMode);\n }\n\n /** Updates contextual types with a possibly encapsulated inferred type. */\n private propagateInferredGenericTypes(\n /** The inferred type node. */\n node: TypeNode,\n /** The inferred type. */\n type: Type,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`, with unknown types initialized to `auto`. */\n ctxTypes: Map,\n /** The names of the type parameters being inferred. */\n typeParameterNames: Set\n ): void {\n if (node.kind == NodeKind.NamedType) {\n let namedTypeNode = node;\n let typeArgumentNodes = namedTypeNode.typeArguments;\n if (typeArgumentNodes && typeArgumentNodes.length > 0) { // foo(bar: Array)\n let classReference = type.classReference;\n if (classReference) {\n let classPrototype = this.resolveTypeName(namedTypeNode.name, ctxElement);\n if (!classPrototype || classPrototype.kind != ElementKind.ClassPrototype) return;\n if (classReference.prototype == classPrototype) {\n let typeArguments = classReference.typeArguments;\n if (typeArguments && typeArguments.length == typeArgumentNodes.length) {\n for (let i = 0, k = typeArguments.length; i < k; ++i) {\n this.propagateInferredGenericTypes(\n typeArgumentNodes[i],\n typeArguments[i],\n ctxElement,\n ctxTypes,\n typeParameterNames\n );\n }\n return;\n }\n }\n }\n } else { // foo(bar: T)\n let name = namedTypeNode.name.identifier.text;\n if (ctxTypes.has(name)) {\n let currentType = assert(ctxTypes.get(name));\n if (\n currentType == Type.auto ||\n (typeParameterNames.has(name) && currentType.isAssignableTo(type))\n ) ctxTypes.set(name, type);\n }\n }\n } else if (node.kind == NodeKind.FunctionType) { // foo(bar: (baz: T) => i32))\n let functionTypeNode = node;\n let parameterNodes = functionTypeNode.parameters;\n let signatureReference = type.signatureReference;\n if (signatureReference) {\n let parameterTypes = signatureReference.parameterTypes;\n for (let i = 0, k = min(parameterTypes.length, parameterNodes.length) ; i < k; ++i) {\n this.propagateInferredGenericTypes(\n parameterNodes[i].type,\n parameterTypes[i],\n ctxElement,\n ctxTypes,\n typeParameterNames\n );\n }\n let returnType = signatureReference.returnType;\n if (returnType != Type.void) {\n this.propagateInferredGenericTypes(\n functionTypeNode.returnType,\n returnType,\n ctxElement,\n ctxTypes,\n typeParameterNames\n );\n }\n let thisType = signatureReference.thisType;\n let explicitThisType = functionTypeNode.explicitThisType;\n if (thisType && explicitThisType) {\n this.propagateInferredGenericTypes(\n explicitThisType,\n thisType,\n ctxElement,\n ctxTypes,\n typeParameterNames\n );\n }\n return;\n }\n }\n }\n\n /** Gets the concrete type of an element. */\n getTypeOfElement(element: Element): Type | null {\n let kind = element.kind;\n if (kind == ElementKind.Global) {\n if (!this.ensureResolvedLazyGlobal(element, ReportMode.Swallow)) return null;\n }\n if (isTypedElement(kind)) {\n let type = (element).type;\n let classReference = type.getClassOrWrapper(this.program);\n if (classReference) {\n let wrappedType = classReference.wrappedType;\n if (wrappedType) type = wrappedType;\n }\n return type;\n }\n return null;\n }\n\n /** Gets the element of a concrete type. */\n getElementOfType(type: Type): Element | null {\n let classReference = type.getClassOrWrapper(this.program);\n if (classReference) return classReference;\n return null;\n }\n\n // =================================================== Expressions ===================================================\n\n /** Looks up the program element the specified expression refers to. */\n lookupExpression(\n /** The expression to look up. */\n node: Expression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n while (node.kind == NodeKind.Parenthesized) { // skip\n node = (node).expression;\n }\n switch (node.kind) {\n case NodeKind.Assertion: {\n return this.lookupAssertionExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Binary: {\n return this.lookupBinaryExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Call: {\n return this.lookupCallExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Comma: {\n return this.lookupCommaExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.ElementAccess: {\n return this.lookupElementAccessExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Function: {\n return this.lookupFunctionExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Identifier:\n case NodeKind.False:\n case NodeKind.Null:\n case NodeKind.True: {\n return this.lookupIdentifierExpression(\n node,\n ctxFlow, ctxFlow.sourceFunction, reportMode\n );\n }\n case NodeKind.This: {\n return this.lookupThisExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Super: {\n return this.lookupSuperExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.InstanceOf: {\n return this.lookupInstanceOfExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Literal: {\n return this.lookupLiteralExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.New: {\n return this.lookupNewExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.PropertyAccess: {\n return this.lookupPropertyAccessExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Ternary: {\n return this.lookupTernaryExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.UnaryPostfix: {\n return this.lookupUnaryPostfixExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.UnaryPrefix: {\n return this.lookupUnaryPrefixExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n }\n assert(false);\n return null;\n }\n\n /** resolving expressions */\n private resolvingExpressions: Set = new Set();\n\n /** Resolves an expression to its static type. */\n resolveExpression(\n /** The expression to resolve. */\n node: Expression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const resolvingExpressions = this.resolvingExpressions;\n if (resolvingExpressions.has(node)) return null;\n resolvingExpressions.add(node);\n const resolved = this.doResolveExpression(node, ctxFlow, ctxType, reportMode);\n resolvingExpressions.delete(node);\n return resolved;\n }\n\n /** Resolves an expression to its static type. (may cause stack overflow) */\n private doResolveExpression(\n node: Expression,\n ctxFlow: Flow,\n ctxType: Type = Type.auto,\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n while (node.kind == NodeKind.Parenthesized) { // skip\n node = (node).expression;\n }\n switch (node.kind) {\n case NodeKind.Assertion: {\n return this.resolveAssertionExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Binary: {\n return this.resolveBinaryExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Call: {\n return this.resolveCallExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Comma: {\n return this.resolveCommaExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.ElementAccess: {\n return this.resolveElementAccessExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Function: {\n return this.resolveFunctionExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Identifier:\n case NodeKind.False:\n case NodeKind.Null:\n case NodeKind.True: {\n return this.resolveIdentifierExpression(\n node,\n ctxFlow, ctxType, ctxFlow.sourceFunction, reportMode\n );\n }\n case NodeKind.This: {\n return this.resolveThisExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Super: {\n return this.resolveSuperExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.InstanceOf: {\n return this.resolveInstanceOfExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Literal: {\n return this.resolveLiteralExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.New: {\n return this.resolveNewExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.PropertyAccess: {\n return this.resolvePropertyAccessExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.Ternary: {\n return this.resolveTernaryExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.UnaryPostfix: {\n return this.resolveUnaryPostfixExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n case NodeKind.UnaryPrefix: {\n return this.resolveUnaryPrefixExpression(\n node,\n ctxFlow, ctxType, reportMode\n );\n }\n }\n assert(false);\n return null;\n }\n\n /** Looks up the program element the specified identifier expression refers to. */\n lookupIdentifierExpression(\n /** The expression to look up. */\n node: IdentifierExpression,\n /** Flow to search for scoped locals. */\n ctxFlow: Flow,\n /** Element to search. */\n ctxElement: Element = ctxFlow.sourceFunction, // differs for enums and namespaces\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n switch (node.kind) {\n case NodeKind.True:\n case NodeKind.False:\n case NodeKind.Null: {\n let type = this.resolveIdentifierExpression(node, ctxFlow, Type.auto, ctxElement, reportMode);\n return type ? this.getElementOfType(type) : null;\n }\n }\n let name = node.text;\n let element: Element | null;\n if (element = ctxFlow.lookup(name)) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return element;\n }\n let outerFlow = ctxFlow.outer;\n if (outerFlow) {\n if (element = outerFlow.lookup(name)) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return element;\n }\n }\n if (element = ctxElement.lookup(name)) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return element;\n }\n if (element = this.program.lookup(name)) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return element;\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Cannot_find_name_0,\n node.range, name\n );\n }\n return null;\n }\n\n /** Resolves an identifier to its static type. */\n private resolveIdentifierExpression(\n /** The expression to resolve. */\n node: IdentifierExpression,\n /** Flow to search for scoped locals. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** Element to search. */\n ctxElement: Element = ctxFlow.sourceFunction, // differs for enums and namespaces\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n switch (node.kind) {\n case NodeKind.True:\n case NodeKind.False: return Type.bool;\n case NodeKind.Null: {\n let classReference = ctxType.getClass();\n if (classReference) {\n return classReference.type.asNullable();\n } else {\n let signatureReference = ctxType.getSignature();\n if (signatureReference) {\n return signatureReference.type.asNullable();\n } else if (ctxType.isExternalReference) {\n return ctxType; // TODO: nullable?\n }\n }\n return this.program.options.usizeType;\n }\n }\n let element = this.lookupIdentifierExpression(node, ctxFlow, ctxElement, reportMode);\n if (!element) return null;\n if (element.kind == ElementKind.FunctionPrototype) {\n let instance = this.resolveFunction(element, null, new Map(), reportMode);\n if (!instance) return null;\n element = instance;\n }\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Resolves a lazily compiled global, i.e. a static class field or annotated `@lazy`. */\n private ensureResolvedLazyGlobal(global: Global, reportMode: ReportMode = ReportMode.Report): bool {\n if (global.is(CommonFlags.Resolved)) return true;\n let typeNode = global.typeNode;\n let type = typeNode\n ? this.resolveType(typeNode, global.parent, null, reportMode)\n : this.resolveExpression(\n assert(global.initializerNode),\n global.file.startFunction.flow,\n Type.auto,\n reportMode\n );\n if (!type) return false;\n global.setType(type); // also sets resolved\n return true;\n }\n\n /** Looks up the program element the specified property access expression refers to. */\n private lookupPropertyAccessExpression(\n /** The expression to look up. */\n node: PropertyAccessExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let targetNode = node.expression;\n let target = this.lookupExpression(targetNode, ctxFlow, ctxType, reportMode); // reports\n if (!target) return null;\n let propertyName = node.property.text;\n\n // Resolve variable-likes to their class type first\n switch (target.kind) {\n case ElementKind.Global: if (!this.ensureResolvedLazyGlobal(target, reportMode)) return null;\n case ElementKind.EnumValue:\n case ElementKind.Local: { // someVar.prop\n let variableLikeElement = target;\n let type = variableLikeElement.type;\n if (type == Type.void) return null; // errored earlier\n let classReference = type.getClassOrWrapper(this.program);\n if (!classReference) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Property_0_does_not_exist_on_type_1,\n node.property.range, propertyName, variableLikeElement.type.toString()\n );\n }\n return null;\n }\n target = classReference;\n break;\n }\n case ElementKind.PropertyPrototype: { // SomeClass.prop\n let propertyInstance = this.resolveProperty(target, reportMode);\n if (!propertyInstance) return null;\n target = propertyInstance;\n // fall-through\n }\n case ElementKind.Property: { // someInstance.prop\n let propertyInstance = target;\n let getterInstance = assert(propertyInstance.getterInstance); // must have a getter\n let type = getterInstance.signature.returnType;\n let classReference = type.getClassOrWrapper(this.program);\n if (!classReference) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Property_0_does_not_exist_on_type_1,\n node.property.range, propertyName, type.toString()\n );\n }\n return null;\n }\n target = classReference;\n break;\n }\n case ElementKind.IndexSignature: { // someInstance[x].prop\n let indexSignature = target;\n let parent = indexSignature.parent;\n assert(parent.kind == ElementKind.Class);\n let classInstance = parent;\n let elementExpression = assert(this.currentElementExpression);\n let indexedGet = classInstance.lookupOverload(OperatorKind.IndexedGet);\n if (!indexedGet) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n elementExpression.range, parent.internalName\n );\n }\n return null;\n }\n let returnType = indexedGet.signature.returnType;\n let classReference = returnType.getClassOrWrapper(this.program);\n if (!classReference) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Property_0_does_not_exist_on_type_1,\n node.property.range, propertyName, returnType.toString()\n );\n }\n return null;\n }\n target = classReference;\n break;\n }\n case ElementKind.FunctionPrototype: {\n // Function with shadow type, i.e. function Symbol() + type Symbol = _Symbol\n let shadowType = target.shadowType;\n if (shadowType) {\n if (!shadowType.is(CommonFlags.Resolved)) {\n let resolvedType = this.resolveType(shadowType.typeNode, shadowType.parent, null, reportMode);\n if (resolvedType) shadowType.setType(resolvedType);\n }\n let classReference = shadowType.type.classReference;\n if (classReference) target = classReference.prototype;\n break;\n } else if (!target.is(CommonFlags.Generic)) {\n // Inherit from 'Function' if not overridden, i.e. fn.call\n let ownMember = target.getMember(propertyName);\n if (!ownMember) {\n let functionInstance = this.resolveFunction(target, null, new Map(), ReportMode.Swallow);\n if (functionInstance) {\n let wrapper = functionInstance.type.getClassOrWrapper(this.program);\n if (wrapper) target = wrapper;\n }\n }\n }\n break;\n }\n }\n\n // Look up the member within\n switch (target.kind) {\n case ElementKind.ClassPrototype:\n case ElementKind.InterfacePrototype:\n case ElementKind.Class:\n case ElementKind.Interface: {\n do {\n let member = target.getMember(propertyName);\n if (member) {\n if (member.kind == ElementKind.PropertyPrototype) {\n let propertyInstance = this.resolveProperty(member, reportMode);\n if (!propertyInstance) return null;\n member = propertyInstance;\n if (propertyInstance.is(CommonFlags.Static)) {\n this.currentThisExpression = null;\n } else {\n this.currentThisExpression = targetNode;\n }\n } else {\n this.currentThisExpression = targetNode;\n }\n this.currentElementExpression = null;\n return member; // instance FIELD, static GLOBAL, FUNCTION_PROTOTYPE, PROPERTY...\n }\n // traverse inherited static members on the base prototype if target is a class prototype\n if (\n target.kind == ElementKind.ClassPrototype ||\n target.kind == ElementKind.InterfacePrototype\n ) {\n let classPrototype = target;\n let basePrototype = classPrototype.basePrototype;\n if (basePrototype) {\n target = basePrototype;\n } else {\n break;\n }\n // traverse inherited instance members on the base class if target is a class instance\n } else if (\n target.kind == ElementKind.Class ||\n target.kind == ElementKind.Interface\n ) {\n let classInstance = target;\n let baseInstance = classInstance.base;\n if (baseInstance) {\n target = baseInstance;\n } else {\n break;\n }\n } else {\n break;\n }\n } while (true);\n break;\n }\n default: { // enums or other namespace-like elements\n let member = target.getMember(propertyName);\n if (member) {\n this.currentThisExpression = targetNode;\n this.currentElementExpression = null;\n return member; // static ENUMVALUE, static GLOBAL, static FUNCTION_PROTOTYPE...\n }\n break;\n }\n }\n\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Property_0_does_not_exist_on_type_1,\n node.property.range, propertyName, target.internalName\n );\n }\n return null;\n }\n\n /** Resolves a property access expression to its static type. */\n private resolvePropertyAccessExpression(\n /** The expression to resolve. */\n node: PropertyAccessExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let element = this.lookupPropertyAccessExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Looks up the program element the specified element access expression refers to. */\n private lookupElementAccessExpression(\n /** The expression to look up. */\n node: ElementAccessExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let targetExpression = node.expression;\n let targetType = this.resolveExpression(targetExpression, ctxFlow, ctxType, reportMode);\n if (!targetType) return null;\n let classReference = targetType.getClassOrWrapper(this.program);\n if (classReference) {\n do {\n let indexSignature = classReference.indexSignature;\n if (indexSignature) {\n this.currentThisExpression = targetExpression;\n this.currentElementExpression = node.elementExpression;\n return indexSignature;\n }\n classReference = classReference.base;\n } while(classReference);\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Index_signature_is_missing_in_type_0,\n targetExpression.range, targetType.toString()\n );\n }\n return null;\n }\n\n /** Resolves an element access expression to its static type. */\n private resolveElementAccessExpression(\n /** The expression to resolve. */\n node: ElementAccessExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let element = this.lookupElementAccessExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Determines the final type of an integer literal given the specified contextual type. */\n determineIntegerLiteralType(\n /** Integer literal value. */\n expr: IntegerLiteralExpression,\n /** Has unary minus before literal. */\n negate: bool,\n /** Contextual type. */\n ctxType: Type\n ): Type {\n let intValue = expr.value;\n if (negate) {\n // x + i64.min > 0 -> underflow\n if (i64_gt(i64_add(intValue, i64_minimum), i64_zero)) {\n let range = expr.range;\n this.error(\n DiagnosticCode.Literal_0_does_not_fit_into_i64_or_u64_types,\n range, range.source.text.substring(range.start - 1, range.end)\n );\n } else if (i64_eq(intValue, i64_zero)) {\n // Special handling for -0\n if (ctxType.isFloatValue) {\n return ctxType.kind == TypeKind.F32\n ? Type.f32\n : Type.f64;\n } else if (!ctxType.isIntegerValue) {\n // If it's unknown just always assume this is f64\n return Type.f64;\n }\n }\n intValue = i64_neg(intValue);\n }\n if (ctxType.isValue) {\n // compile to contextual type if matching\n switch (ctxType.kind) {\n case TypeKind.Bool: {\n if (i64_is_bool(intValue)) return Type.bool;\n break;\n }\n case TypeKind.I8: {\n if (i64_is_i8(intValue)) return Type.i8;\n break;\n }\n case TypeKind.U8: {\n if (i64_is_u8(intValue)) return Type.u8;\n break;\n }\n case TypeKind.I16: {\n if (i64_is_i16(intValue)) return Type.i16;\n break;\n }\n case TypeKind.U16: {\n if (i64_is_u16(intValue)) return Type.u16;\n break;\n }\n case TypeKind.I32: {\n if (i64_is_i32(intValue)) return Type.i32;\n break;\n }\n case TypeKind.U32: {\n if (i64_is_u32(intValue)) return Type.u32;\n break;\n }\n case TypeKind.Isize: {\n if (!this.program.options.isWasm64) {\n if (i64_is_i32(intValue)) return Type.isize32;\n break;\n }\n return Type.isize64;\n }\n case TypeKind.Usize: {\n if (!this.program.options.isWasm64) {\n if (i64_is_u32(intValue)) return Type.usize32;\n break;\n }\n return Type.usize64;\n }\n case TypeKind.I64: return Type.i64;\n case TypeKind.U64: return Type.u64;\n case TypeKind.F32: return Type.f32;\n case TypeKind.F64: return Type.f64;\n }\n }\n // otherwise compile to best fitting type\n if (i64_is_i32(intValue)) return Type.i32;\n if (i64_is_u32(intValue)) return Type.u32;\n return Type.i64; // TODO: u64 if positive and larger than i64?\n }\n\n /** Looks up the program element the specified assertion expression refers to. */\n private lookupAssertionExpression(\n /** The expression to look up. */\n node: AssertionExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n switch (node.assertionKind) {\n case AssertionKind.As:\n case AssertionKind.Prefix: {\n let type = this.resolveType(\n assert(node.toType), // must be set if not NONNULL\n ctxFlow.sourceFunction,\n ctxFlow.contextualTypeArguments,\n reportMode\n );\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (element) return element;\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_illegal_in_this_context,\n node.range, type.toString()\n );\n }\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return null;\n }\n case AssertionKind.NonNull: {\n return this.lookupExpression(node.expression, ctxFlow, ctxType, reportMode);\n }\n case AssertionKind.Const: {\n // TODO: decide on the layout of ReadonlyArray first\n // let element = this.lookupExpression(node.expression, ctxFlow, ctxType, reportMode);\n // if (!element) return null;\n // if (element.kind == ElementKind.Class && (element).extends(this.program.arrayPrototype)) {\n // let elementType = assert((element).getTypeArgumentsTo(this.program.arrayPrototype))[0];\n // return this.resolveClass(this.program.readonlyArrayPrototype, [ elementType ]);\n // }\n this.error(\n DiagnosticCode.Not_implemented_0,\n node.range,\n \"Const assertion\"\n );\n return null;\n }\n }\n assert(false);\n return null;\n }\n\n /** Resolves an assertion expression to its static type. */\n private resolveAssertionExpression(\n /** The expression to resolve. */\n node: AssertionExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n switch (node.assertionKind) {\n case AssertionKind.As:\n case AssertionKind.Prefix: {\n return this.resolveType(\n assert(node.toType),\n ctxFlow.sourceFunction,\n ctxFlow.contextualTypeArguments,\n reportMode\n );\n }\n case AssertionKind.NonNull: {\n let type = this.resolveExpression(node.expression, ctxFlow, ctxType, reportMode);\n return type ? type.nonNullableType : null;\n }\n case AssertionKind.Const: {\n let element = this.lookupExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n default: assert(false);\n }\n return null;\n }\n\n /** Looks up the program element the specified unary prefix expression refers to. */\n private lookupUnaryPrefixExpression(\n /** The expression to look up. */\n node: UnaryPrefixExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let type = this.resolveUnaryPrefixExpression(node, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (!element) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, operatorTokenToString(node.operator), type.toString()\n );\n }\n }\n return element;\n }\n\n /** Resolves an unary prefix expression to its static type. */\n private resolveUnaryPrefixExpression(\n /** The expression to resolve. */\n node: UnaryPrefixExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let operand = node.operand;\n let operator = node.operator;\n switch (operator) {\n case Token.Minus: {\n // implicitly negate if an integer literal to distinguish between i32/u32/i64\n if (operand.isLiteralKind(LiteralKind.Integer)) {\n return this.determineIntegerLiteralType(\n operand,\n true,\n ctxType\n );\n }\n // fall-through\n }\n case Token.Plus:\n case Token.Plus_Plus:\n case Token.Minus_Minus: {\n let type = this.resolveExpression(operand, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let classReference = type.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromUnaryPrefixToken(operator));\n if (overload) return overload.signature.returnType;\n }\n if (!type.isNumericValue) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, operatorTokenToString(operator), type.toString()\n );\n }\n return null;\n }\n return type;\n }\n case Token.Exclamation: {\n let type = this.resolveExpression(operand, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let classReference = type.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.Not);\n if (overload) return overload.signature.returnType;\n }\n return Type.bool; // incl. references\n }\n case Token.Tilde: {\n let type = this.resolveExpression(operand, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let classReference = type.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.BitwiseNot);\n if (overload) return overload.signature.returnType;\n }\n if (!type.isNumericValue) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, \"~\", type.toString()\n );\n }\n return null;\n }\n return type.intType;\n }\n case Token.Dot_Dot_Dot: {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n node.range, \"Spread operator\"\n );\n }\n return null;\n }\n case Token.TypeOf: {\n return this.program.stringInstance.type;\n }\n default: assert(false);\n }\n return null;\n }\n\n /** Looks up the program element the specified unary postfix expression refers to. */\n private lookupUnaryPostfixExpression(\n /** The expression to resolve. */\n node: UnaryPostfixExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let type = this.resolveUnaryPostfixExpression(node, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (!element) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, operatorTokenToString(node.operator), type.toString()\n );\n }\n }\n return element;\n }\n\n /** Resolves an unary postfix expression to its static type. */\n private resolveUnaryPostfixExpression(\n /** The expression to resolve. */\n node: UnaryPostfixExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let operator = node.operator;\n switch (operator) {\n case Token.Plus_Plus:\n case Token.Minus_Minus: {\n let type = this.resolveExpression(node.operand, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let classReference = type.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromUnaryPostfixToken(operator));\n if (overload) return overload.signature.returnType;\n }\n if (!type.isNumericValue) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, operatorTokenToString(operator), type.toString()\n );\n }\n return null;\n }\n return type;\n }\n }\n assert(false);\n return null;\n }\n\n /** Looks up the program element the specified binary expression refers to. */\n private lookupBinaryExpression(\n /** The expression to look up. */\n node: BinaryExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let type = this.resolveBinaryExpression(node, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (element) return element; // otherwise void\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_illegal_in_this_context,\n node.range, type.toString()\n );\n }\n return null;\n }\n\n /** Resolves a binary expression to its static type. */\n private resolveBinaryExpression(\n /** The expression to resolve. */\n node: BinaryExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let left = node.left;\n let right = node.right;\n let operator = node.operator;\n\n switch (operator) {\n\n // assignment: result is the target's type\n\n case Token.Equals:\n case Token.Plus_Equals:\n case Token.Minus_Equals:\n case Token.Asterisk_Equals:\n case Token.Asterisk_Asterisk_Equals:\n case Token.Slash_Equals:\n case Token.Percent_Equals:\n case Token.LessThan_LessThan_Equals:\n case Token.GreaterThan_GreaterThan_Equals:\n case Token.GreaterThan_GreaterThan_GreaterThan_Equals:\n case Token.Ampersand_Equals:\n case Token.Bar_Equals:\n case Token.Caret_Equals: {\n return this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n }\n\n // comparison: result is Bool, preferring overloads, integer/float only\n\n case Token.LessThan:\n case Token.GreaterThan:\n case Token.LessThan_Equals:\n case Token.GreaterThan_Equals: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator));\n if (overload) return overload.signature.returnType;\n }\n if (!leftType.isNumericValue) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, operatorTokenToString(operator), leftType.toString()\n );\n }\n return null;\n }\n return Type.bool;\n }\n\n // equality: result is Bool, preferring overloads, incl. references\n\n case Token.Equals_Equals:\n case Token.Exclamation_Equals: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator));\n if (overload) return overload.signature.returnType;\n }\n return Type.bool;\n }\n\n // identity: result is Bool, not supporting overloads\n\n case Token.Equals_Equals_Equals:\n case Token.Exclamation_Equals_Equals: {\n return Type.bool;\n }\n\n // in operator\n\n case Token.In: {\n return Type.bool;\n }\n\n // arithmetics: result is common type of LHS and RHS, preferring overloads\n\n case Token.Plus:\n case Token.Minus:\n case Token.Asterisk:\n case Token.Slash:\n case Token.Percent: // mod has special logic, but also behaves like this\n case Token.Asterisk_Asterisk: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator));\n if (overload) return overload.signature.returnType;\n }\n let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode);\n if (!rightType) return null;\n let commonType = Type.commonType(leftType, rightType, ctxType);\n if (!commonType) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n node.range, operatorTokenToString(operator), leftType.toString(), rightType.toString()\n );\n }\n }\n return commonType;\n }\n\n // shift: result is LHS (RHS is converted to LHS), preferring overloads\n\n case Token.LessThan_LessThan:\n case Token.GreaterThan_GreaterThan:\n case Token.GreaterThan_GreaterThan_GreaterThan: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator));\n if (overload) return overload.signature.returnType;\n }\n if (!leftType.isIntegerValue) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_0_operator_cannot_be_applied_to_type_1,\n node.range, operatorTokenToString(operator), leftType.toString()\n );\n }\n return null;\n }\n return leftType;\n }\n\n // bitwise: result is common type of LHS and RHS with floats not being supported, preferring overloads\n\n case Token.Ampersand:\n case Token.Bar:\n case Token.Caret: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let classReference = leftType.getClassOrWrapper(this.program);\n if (classReference) {\n let overload = classReference.lookupOverload(OperatorKind.fromBinaryToken(operator));\n if (overload) return overload.signature.returnType;\n }\n let rightType = this.resolveExpression(right, ctxFlow, ctxType, reportMode);\n if (!rightType) return null;\n let commonType = Type.commonType(leftType, rightType, ctxType);\n if (!commonType || !commonType.isIntegerValue) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n node.range, operatorTokenToString(operator), leftType.toString(), rightType.toString()\n );\n }\n }\n return commonType;\n }\n\n // logical\n\n case Token.Ampersand_Ampersand: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode);\n if (!rightType) return null;\n let commonType = Type.commonType(leftType, rightType, ctxType);\n if (!commonType) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n node.range, \"&&\", leftType.toString(), rightType.toString()\n );\n }\n }\n return commonType;\n }\n case Token.Bar_Bar: {\n let leftType = this.resolveExpression(left, ctxFlow, ctxType, reportMode);\n if (!leftType) return null;\n let rightType = this.resolveExpression(right, ctxFlow, leftType, reportMode);\n if (!rightType) return null;\n let commonType = Type.commonType(leftType, rightType, ctxType);\n if (!commonType) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n node.range, \"||\", leftType.toString(), rightType.toString()\n );\n }\n return null;\n }\n // `LHS || RHS` can only be null if both LHS and RHS are null\n return leftType.is(TypeFlags.Nullable) && rightType.is(TypeFlags.Nullable)\n ? commonType\n : commonType.nonNullableType;\n }\n }\n assert(false);\n return null;\n }\n\n /** Looks up the program element the specified this expression refers to. */\n private lookupThisExpression(\n /** The expression to look up. */\n node: ThisExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n if (ctxFlow.isInline) {\n let thisLocal = ctxFlow.lookupLocal(CommonNames.this_);\n if (thisLocal) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return thisLocal;\n }\n }\n let parent = ctxFlow.sourceFunction.parent;\n if (parent) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return parent;\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode._this_cannot_be_referenced_in_current_location,\n node.range\n );\n }\n return null;\n }\n\n /** Resolves a this expression to its static type. */\n private resolveThisExpression(\n /** The expression to resolve. */\n node: ThisExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let element = this.lookupThisExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Looks up the program element the specified super expression refers to. */\n private lookupSuperExpression(\n /** The expression to look up. */\n node: SuperExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n if (ctxFlow.isInline) {\n let superLocal = ctxFlow.lookupLocal(CommonNames.super_);\n if (superLocal) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return superLocal;\n }\n }\n let parent: Element | null = ctxFlow.sourceFunction.parent;\n if (parent && parent.kind == ElementKind.Class) {\n let base = (parent).base;\n if (base) {\n this.currentThisExpression = null;\n this.currentElementExpression = null;\n return base;\n }\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode._super_can_only_be_referenced_in_a_derived_class,\n node.range\n );\n }\n return null;\n }\n\n /** Resolves a super expression to its static type. */\n private resolveSuperExpression(\n /** The expression to resolve. */\n node: SuperExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let element = this.lookupSuperExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Looks up the program element the specified literal expression refers to. */\n private lookupLiteralExpression(\n /** The expression to look up. */\n node: LiteralExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n this.currentThisExpression = node;\n this.currentElementExpression = null;\n switch (node.literalKind) {\n case LiteralKind.Integer: {\n let intType = this.determineIntegerLiteralType(\n node,\n false,\n ctxType\n );\n return assert(intType.getClassOrWrapper(this.program));\n }\n case LiteralKind.Float: {\n let fltType = ctxType == Type.f32 ? Type.f32 : Type.f64;\n return assert(fltType.getClassOrWrapper(this.program));\n }\n case LiteralKind.String:\n case LiteralKind.Template: {\n return this.program.stringInstance;\n }\n case LiteralKind.RegExp: {\n return this.program.regexpInstance;\n }\n case LiteralKind.Array: {\n let classReference = ctxType.getClass();\n if (classReference && classReference.prototype == this.program.arrayPrototype) {\n return this.getElementOfType(ctxType);\n }\n // otherwise infer, ignoring ctxType\n let expressions = (node).elementExpressions;\n let length = expressions.length;\n let elementType = Type.auto;\n let numNullLiterals = 0;\n for (let i = 0, k = length; i < k; ++i) {\n let expression = expressions[i];\n if (expression) {\n if (expression.kind == NodeKind.Null && length > 1) {\n ++numNullLiterals;\n } else {\n let currentType = this.resolveExpression(expression, ctxFlow, elementType);\n if (!currentType) return null;\n if (elementType == Type.auto) elementType = currentType;\n else if (currentType != elementType) {\n let commonType = Type.commonType(elementType, currentType, elementType);\n if (commonType) elementType = commonType;\n // otherwise triggers error on compilation\n }\n }\n }\n }\n if (elementType /* still */ == Type.auto) {\n if (numNullLiterals == length) { // all nulls infers as usize\n elementType = this.program.options.usizeType;\n } else {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.The_type_argument_for_type_parameter_0_cannot_be_inferred_from_the_usage_Consider_specifying_the_type_arguments_explicitly,\n node.range, \"T\"\n );\n }\n return null;\n }\n }\n if (\n numNullLiterals > 0 &&\n elementType.isInternalReference\n ) {\n elementType = elementType.asNullable();\n }\n return assert(this.resolveClass(this.program.arrayPrototype, [ elementType ]));\n }\n case LiteralKind.Object: {\n if (ctxType.isClass) return ctxType.classReference;\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n return null;\n }\n }\n assert(false);\n return null;\n }\n\n /** Resolves a literal expression to its static type. */\n private resolveLiteralExpression(\n /** The expression to resolve. */\n node: LiteralExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let element = this.lookupLiteralExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Looks up the program element the specified call expression refers to. */\n private lookupCallExpression(\n /** The expression to look up. */\n node: CallExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.void,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let type = this.resolveCallExpression(node, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (!element) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_illegal_in_this_context,\n node.range, type.toString()\n );\n }\n }\n return element;\n }\n\n /** Resolves a call expression to its static type. */\n private resolveCallExpression(\n /** The expression to resolve. */\n node: CallExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.void,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let targetExpression = node.expression;\n let target = this.lookupExpression( // reports\n targetExpression,\n ctxFlow,\n ctxType,\n reportMode\n );\n if (!target) return null;\n switch (target.kind) {\n case ElementKind.FunctionPrototype: {\n let functionPrototype = target;\n // `unchecked` behaves like parenthesized\n if (\n functionPrototype.internalName == BuiltinNames.unchecked &&\n node.args.length > 0\n ) {\n return this.resolveExpression(node.args[0], ctxFlow, ctxType, reportMode);\n }\n let functionInstance = this.maybeInferCall(node, functionPrototype, ctxFlow, reportMode);\n if (!functionInstance) return null;\n target = functionInstance;\n // fall-through\n }\n case ElementKind.Function: {\n return (target).signature.returnType;\n }\n case ElementKind.PropertyPrototype: {\n let propertyInstance = this.resolveProperty(target, reportMode);\n if (!propertyInstance) return null;\n target = propertyInstance;\n // fall-through\n }\n default: {\n if (!isTypedElement(target.kind)) break;\n let targetElement = this.getElementOfType((target).type);\n if (!targetElement || targetElement.kind != ElementKind.Class) break;\n target = targetElement;\n // fall-through\n }\n case ElementKind.Class: {\n let typeArguments = (target).getTypeArgumentsTo(this.program.functionPrototype);\n if (!(typeArguments && typeArguments.length)) break;\n let signature = assert(typeArguments[0].getSignature());\n return signature.returnType;\n }\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Cannot_invoke_an_expression_whose_type_lacks_a_call_signature_Type_0_has_no_compatible_call_signatures,\n targetExpression.range, target.internalName\n );\n }\n return null;\n }\n\n /** Looks up the program element the specified comma expression refers to. */\n private lookupCommaExpression(\n /** The expression to look up. */\n node: CommaExpression,\n /** Flow to search for scoped locals. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let expressions = node.expressions;\n return this.lookupExpression(expressions[assert(expressions.length) - 1], ctxFlow, ctxType, reportMode);\n }\n\n /** Resolves a comma expression to its static type. */\n private resolveCommaExpression(\n /** The expression to resolve. */\n node: CommaExpression,\n /** Flow to search for scoped locals. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let expressions = node.expressions;\n return this.resolveExpression(expressions[assert(expressions.length) - 1], ctxFlow, ctxType, reportMode);\n }\n\n /** Looks up the program element the specified instanceof expression refers to. */\n private lookupInstanceOfExpression(\n /** The expression to look up. */\n node: InstanceOfExpression,\n /** Flow to search for scoped locals. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n return assert(Type.bool.getClassOrWrapper(this.program));\n }\n\n /** Resolves an instanceof expression to its static type. */\n private resolveInstanceOfExpression(\n /** The expression to resolve. */\n node: InstanceOfExpression,\n /** Flow to search for scoped locals. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type = Type.auto,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n return Type.bool;\n }\n\n /** Looks up the program element the specified ternary expression refers to. */\n private lookupTernaryExpression(\n /** The expression to look up. */\n node: TernaryExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let type = this.resolveTernaryExpression(node, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (!element) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_illegal_in_this_context,\n node.range, type.toString()\n );\n }\n }\n return element;\n }\n\n /** Resolves a ternary expression to its static type. */\n private resolveTernaryExpression(\n /** The expression to resolve. */\n node: TernaryExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let thenType = this.resolveExpression(node.ifThen, ctxFlow, ctxType, reportMode);\n if (!thenType) return null;\n let elseType = this.resolveExpression(node.ifElse, ctxFlow, thenType, reportMode);\n if (!elseType) return null;\n let commonType = Type.commonType(thenType, elseType, ctxType);\n if (!commonType) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Operator_0_cannot_be_applied_to_types_1_and_2,\n node.range, \"?:\", thenType.toString(), elseType.toString()\n );\n }\n }\n return commonType;\n }\n\n /** Looks up the program element the specified new expression refers to. */\n private lookupNewExpression(\n /** The expression to look up. */\n node: NewExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let element = this.resolveTypeName(node.typeName, ctxFlow.sourceFunction, reportMode);\n if (!element) return null;\n if (element.kind == ElementKind.ClassPrototype) {\n return this.resolveClassInclTypeArguments(\n element,\n node.typeArguments,\n ctxFlow.sourceFunction,\n cloneMap(ctxFlow.contextualTypeArguments),\n node,\n reportMode\n );\n }\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.This_expression_is_not_constructable,\n node.range\n );\n }\n return null;\n }\n\n /** Resolves a new expression to its static type. */\n private resolveNewExpression(\n /** The expression to resolve. */\n node: NewExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n let element = this.lookupNewExpression(node, ctxFlow, ctxType, reportMode);\n if (!element) return null;\n let type = this.getTypeOfElement(element);\n if (!type) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expression_cannot_be_represented_by_a_type,\n node.range\n );\n }\n }\n return type;\n }\n\n /** Looks up the program element the specified function expression refers to. */\n private lookupFunctionExpression(\n /** The expression to look up. */\n node: FunctionExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Element | null {\n let type = this.resolveFunctionExpression(node, ctxFlow, ctxType, reportMode);\n if (!type) return null;\n let element = this.getElementOfType(type);\n if (!element) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_illegal_in_this_context,\n node.range, type.toString()\n );\n }\n }\n return element;\n }\n\n /** Resolves a function expression to its static type. */\n private resolveFunctionExpression(\n /** The expression to resolve. */\n node: FunctionExpression,\n /** Contextual flow. */\n ctxFlow: Flow,\n /** Contextual type. */\n ctxType: Type,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Type | null {\n const declaration = node.declaration;\n const signature = declaration.signature;\n const body = declaration.body;\n let functionType = this.resolveType(signature, ctxFlow.sourceFunction, ctxFlow.contextualTypeArguments, reportMode);\n if (\n functionType &&\n declaration.arrowKind != ArrowKind.None &&\n body && body.kind == NodeKind.Expression &&\n isTypeOmitted(signature.returnType)\n ) {\n // (x) => ret, infer return type accordingt to `ret`\n const expr = (body).expression;\n let signatureReference = assert(functionType.getSignature());\n // create a temp flow to resolve expression\n let tempFlow = Flow.createDefault(ctxFlow.sourceFunction);\n let parameters = signature.parameters;\n // return type of resolveFunctionType should have same parameter length with signature\n assert(signatureReference.parameterTypes.length == parameters.length);\n for (let i = 0, k = parameters.length; i < k; i++) {\n const parameter = parameters[i];\n const type = signatureReference.parameterTypes[i];\n tempFlow.addScopedDummyLocal(parameter.name.text, type, parameter);\n }\n const type = this.resolveExpression(expr, tempFlow, ctxType, reportMode);\n if (type) {\n functionType.signatureReference = Signature.create(\n this.program,\n signatureReference.parameterTypes,\n type,\n signatureReference.thisType,\n signatureReference.requiredParameters,\n signatureReference.hasRest,\n );\n }\n }\n return functionType;\n }\n\n // ==================================================== Elements =====================================================\n\n /** Resolves a function prototype using the specified concrete type arguments. */\n resolveFunction(\n /** The prototype of the function. */\n prototype: FunctionPrototype,\n /** Type arguments provided. */\n typeArguments: Type[] | null,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map = new Map(),\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Function | null {\n let classInstance: Class | null = null; // if an instance method\n let instanceKey = typeArguments ? typesToString(typeArguments) : \"\";\n\n // Instance method prototypes are pre-bound to their concrete class as their parent\n if (prototype.is(CommonFlags.Instance)) {\n classInstance = assert(prototype.getBoundClassOrInterface());\n\n // check if this exact concrete class and function combination is known already\n let resolvedInstance = prototype.getResolvedInstance(instanceKey);\n if (resolvedInstance) return resolvedInstance;\n\n // inherit class specific type arguments\n let classTypeArguments = classInstance.typeArguments;\n if (classTypeArguments) {\n let classTypeParameters = assert(classInstance.prototype.typeParameterNodes);\n let numClassTypeArguments = classTypeParameters.length;\n assert(numClassTypeArguments == classTypeParameters.length);\n for (let i = 0; i < numClassTypeArguments; ++i) {\n let classTypeParameterName = classTypeParameters[i].name.text;\n // override contextual\n ctxTypes.set(classTypeParameterName, classTypeArguments[i]);\n }\n }\n } else {\n assert(!prototype.isBound);\n let resolvedInstance = prototype.getResolvedInstance(instanceKey);\n if (resolvedInstance) return resolvedInstance;\n }\n\n // override whatever is contextual with actual function type arguments\n let signatureNode = prototype.functionTypeNode;\n let typeParameterNodes = prototype.typeParameterNodes;\n let numFunctionTypeArguments: i32;\n if (typeArguments && (numFunctionTypeArguments = typeArguments.length) > 0) {\n assert(typeParameterNodes && numFunctionTypeArguments == typeParameterNodes.length);\n for (let i = 0; i < numFunctionTypeArguments; ++i) {\n ctxTypes.set(\n (typeParameterNodes)[i].name.text,\n typeArguments[i]\n );\n }\n } else {\n assert(!typeParameterNodes || typeParameterNodes.length == 0);\n }\n\n // resolve `this` type if applicable\n let thisType: Type | null = null;\n let explicitThisType = signatureNode.explicitThisType;\n if (explicitThisType) {\n thisType = this.resolveType(\n explicitThisType,\n prototype.parent, // relative to function\n ctxTypes,\n reportMode\n );\n if (!thisType) return null;\n ctxTypes.set(CommonNames.this_, thisType);\n } else if (classInstance) {\n thisType = classInstance.type;\n ctxTypes.set(CommonNames.this_, thisType);\n }\n\n // resolve parameter types\n let signatureParameters = signatureNode.parameters;\n let numSignatureParameters = signatureParameters.length;\n let parameterTypes = new Array(numSignatureParameters);\n let requiredParameters = 0;\n for (let i = 0; i < numSignatureParameters; ++i) {\n let parameterDeclaration = signatureParameters[i];\n if (parameterDeclaration.parameterKind == ParameterKind.Default) {\n requiredParameters = i + 1;\n }\n let typeNode = parameterDeclaration.type;\n if (isTypeOmitted(typeNode)) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_expected,\n typeNode.range\n );\n }\n return null;\n }\n let parameterType = this.resolveType(\n typeNode,\n prototype.parent, // relative to function\n ctxTypes,\n reportMode\n );\n if (!parameterType) return null;\n if (parameterType == Type.void) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_expected,\n typeNode.range\n );\n }\n return null;\n }\n parameterTypes[i] = parameterType;\n }\n\n // resolve return type\n let returnType: Type;\n if (prototype.is(CommonFlags.Set)) {\n returnType = Type.void; // not annotated\n } else if (prototype.is(CommonFlags.Constructor)) {\n returnType = classInstance!.type; // not annotated\n } else {\n let typeNode = signatureNode.returnType;\n if (isTypeOmitted(typeNode)) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_expected,\n typeNode.range\n );\n }\n return null;\n }\n let type = this.resolveType(\n typeNode,\n prototype.parent, // relative to function\n ctxTypes,\n reportMode\n );\n if (!type) return null;\n returnType = type;\n }\n\n let signature = Signature.create(this.program, parameterTypes, returnType, thisType, requiredParameters);\n\n let nameInclTypeParameters = prototype.name;\n if (instanceKey.length) nameInclTypeParameters += `<${instanceKey}>`;\n let instance = new Function(\n nameInclTypeParameters,\n prototype,\n typeArguments,\n signature,\n ctxTypes\n );\n prototype.setResolvedInstance(instanceKey, instance);\n\n // check against overridden base member\n if (classInstance) {\n let methodOrPropertyName = instance.declaration.name.text;\n let baseClass = classInstance.base;\n if (baseClass) {\n let baseMember = baseClass.getMember(methodOrPropertyName);\n if (baseMember) {\n // note override discovery (used by stub finalization)\n this.discoveredOverride = true;\n // verify that this is a compatible override\n let incompatibleOverride = true;\n if (instance.isAny(CommonFlags.Get | CommonFlags.Set)) {\n if (baseMember.kind == ElementKind.PropertyPrototype) {\n let baseProperty = this.resolveProperty(baseMember, reportMode);\n if (baseProperty) {\n if (instance.is(CommonFlags.Get)) {\n let baseGetter = baseProperty.getterInstance;\n if (baseGetter && instance.signature.isAssignableTo(baseGetter.signature, true)) {\n incompatibleOverride = false;\n }\n } else {\n assert(instance.is(CommonFlags.Set));\n let baseSetter = baseProperty.setterInstance;\n if (baseSetter && instance.signature.isAssignableTo(baseSetter.signature, true)) {\n incompatibleOverride = false;\n }\n }\n }\n }\n } else if (instance.is(CommonFlags.Constructor)) {\n incompatibleOverride = false;\n } else {\n if (baseMember.kind == ElementKind.FunctionPrototype) {\n // Possibly generic. Resolve with same type arguments to obtain the correct one.\n let basePrototype = baseMember;\n let baseFunction = this.resolveFunction(basePrototype, typeArguments, new Map(), ReportMode.Swallow);\n if (baseFunction && instance.signature.isAssignableTo(baseFunction.signature, true)) {\n incompatibleOverride = false;\n }\n }\n }\n if (incompatibleOverride) {\n this.errorRelated(\n DiagnosticCode.This_overload_signature_is_not_compatible_with_its_implementation_signature,\n instance.identifierAndSignatureRange, baseMember.identifierAndSignatureRange\n );\n }\n }\n }\n }\n return instance;\n }\n\n /** Resolves a function prototypeby first resolving the specified type arguments. */\n resolveFunctionInclTypeArguments(\n /** The prototype of the function. */\n prototype: FunctionPrototype,\n /** Type arguments provided to be resolved. */\n typeArgumentNodes: TypeNode[] | null,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map,\n /** The node to use when reporting intermediate errors. */\n reportNode: Node,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Function | null {\n let resolvedTypeArguments: Type[] | null = null;\n\n // Resolve type arguments if generic\n if (prototype.is(CommonFlags.Generic)) {\n\n // If this is an instance method, first apply the class's type arguments\n if (prototype.is(CommonFlags.Instance)) {\n let classInstance = assert(prototype.getBoundClassOrInterface());\n let classTypeArguments = classInstance.typeArguments;\n if (classTypeArguments) {\n let typeParameterNodes = assert(classInstance.prototype.typeParameterNodes);\n let numClassTypeArguments = classTypeArguments.length;\n assert(numClassTypeArguments == typeParameterNodes.length);\n for (let i = 0; i < numClassTypeArguments; ++i) {\n ctxTypes.set(\n typeParameterNodes[i].name.text,\n classTypeArguments[i]\n );\n }\n }\n }\n\n resolvedTypeArguments = this.resolveTypeArguments( // reports\n assert(prototype.typeParameterNodes),\n typeArgumentNodes,\n ctxElement,\n ctxTypes, // update\n reportNode,\n reportMode\n );\n if (!resolvedTypeArguments) return null;\n\n // Otherwise make sure that no type arguments have been specified\n } else {\n if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n reportNode.range, prototype.internalName\n );\n }\n return null;\n }\n }\n\n // Continue with concrete types\n return this.resolveFunction(\n prototype,\n resolvedTypeArguments,\n ctxTypes,\n reportMode\n );\n }\n\n /** Resolves reachable overrides of the given instance method. */\n resolveOverrides(instance: Function): Function[] | null {\n let overridePrototypes = instance.prototype.unboundOverrides;\n if (!overridePrototypes) return null;\n\n let parentClassInstance = assert(instance.getBoundClassOrInterface());\n let overrides = new Set();\n\n // A method's `overrides` property contains its unbound override prototypes\n // so we first have to find the concrete classes it became bound to, obtain\n // their bound prototypes and make sure these are resolved.\n for (let _values = Set_values(overridePrototypes), i = 0, k = _values.length; i < k; ++i) {\n let unboundOverridePrototype = _values[i];\n assert(!unboundOverridePrototype.isBound);\n let unboundOverrideParent = unboundOverridePrototype.parent;\n let classInstances: Map | null;\n assert(unboundOverrideParent.kind == ElementKind.ClassPrototype);\n classInstances = (unboundOverrideParent).instances;\n if (!classInstances) continue;\n for (let _values = Map_values(classInstances), j = 0, l = _values.length; j < l; ++j) {\n let classInstance = _values[j];\n // Check if the parent class is a subtype of instance's class\n if (!classInstance.isAssignableTo(parentClassInstance)) continue;\n let overrideInstance: Function | null = null;\n if (instance.isAny(CommonFlags.Get | CommonFlags.Set)) {\n let propertyName = instance.declaration.name.text;\n let boundPropertyPrototype = assert(classInstance.getMember(propertyName));\n assert(boundPropertyPrototype.kind == ElementKind.PropertyPrototype);\n let boundPropertyInstance = this.resolveProperty(boundPropertyPrototype);\n if (!boundPropertyInstance) continue;\n if (instance.is(CommonFlags.Get)) {\n overrideInstance = boundPropertyInstance.getterInstance;\n } else {\n assert(instance.is(CommonFlags.Set));\n overrideInstance = boundPropertyInstance.setterInstance;\n }\n } else {\n let boundPrototype = classInstance.getMember(unboundOverridePrototype.name);\n if (boundPrototype) { // might have errored earlier and wasn't added\n assert(boundPrototype.kind == ElementKind.FunctionPrototype);\n overrideInstance = this.resolveFunction(boundPrototype, instance.typeArguments);\n }\n }\n if (overrideInstance) overrides.add(overrideInstance);\n }\n }\n return Set_values(overrides);\n }\n\n /** Currently resolving classes. */\n private resolveClassPending: Set = new Set();\n\n /** Resolves a class prototype using the specified concrete type arguments. */\n resolveClass(\n /** The prototype of the class. */\n prototype: ClassPrototype,\n /** Type arguments provided. */\n typeArguments: Type[] | null,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map = new Map(),\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Class | null {\n let instanceKey = typeArguments ? typesToString(typeArguments) : \"\";\n\n // Do not attempt to resolve the same class twice. This can return a class\n // that isn't fully resolved yet, but only on deeper levels of recursion.\n let instance = prototype.getResolvedInstance(instanceKey);\n if (instance) return instance;\n\n // Otherwise create\n let nameInclTypeParameters = prototype.name;\n if (instanceKey.length) nameInclTypeParameters += `<${instanceKey}>`;\n if (prototype.kind == ElementKind.InterfacePrototype) {\n instance = new Interface(nameInclTypeParameters, prototype, typeArguments);\n } else {\n instance = new Class(nameInclTypeParameters, prototype, typeArguments);\n }\n prototype.setResolvedInstance(instanceKey, instance);\n let pendingClasses = this.resolveClassPending;\n pendingClasses.add(instance);\n\n // Insert contextual type arguments for this operation. Internally, this method is always\n // called with matching type parameter / argument counts.\n if (typeArguments) {\n let typeParameterNodes = assert(prototype.typeParameterNodes);\n let numTypeParameters = typeParameterNodes.length;\n let numTypeArguments = typeArguments.length;\n assert(numTypeArguments == numTypeParameters);\n for (let i = 0; i < numTypeArguments; ++i) {\n ctxTypes.set(typeParameterNodes[i].name.text, typeArguments[i]);\n }\n } else {\n let typeParameterNodes = prototype.typeParameterNodes;\n assert(!(typeParameterNodes && typeParameterNodes.length > 0));\n }\n instance.contextualTypeArguments = ctxTypes;\n\n let anyPending = false;\n\n // Resolve base class if applicable\n let basePrototype = prototype.basePrototype;\n if (basePrototype) {\n let current: ClassPrototype | null = basePrototype;\n do {\n if (current == prototype) {\n this.error(\n DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression,\n prototype.identifierNode.range,\n prototype.internalName\n );\n return null;\n }\n current = current.basePrototype;\n } while (current);\n let extendsNode = assert(prototype.extendsNode); // must be present if it has a base prototype\n let base = this.resolveClassInclTypeArguments(\n basePrototype,\n extendsNode.typeArguments,\n prototype.parent, // relative to derived class\n cloneMap(ctxTypes), // don't inherit\n extendsNode,\n reportMode\n );\n if (!base) return null;\n instance.setBase(base);\n\n // If the base class is still pending, yield here and instead resolve any\n // derived classes once the base class's `finishResolveClass` is done.\n // This is guaranteed to never happen at the entry of the recursion, i.e.\n // where `resolveClass` is called from other code.\n if (pendingClasses.has(base)) anyPending = true;\n\n // Implicitly extend `Object` if a derived object\n } else if (prototype.implicitlyExtendsObject) {\n instance.setBase(this.program.objectInstance);\n }\n\n // Resolve interfaces if applicable\n let interfacePrototypes = prototype.interfacePrototypes;\n if (interfacePrototypes) {\n for (let i = 0, k = interfacePrototypes.length; i < k; ++i) {\n let interfacePrototype = interfacePrototypes[i];\n let current: ClassPrototype | null = interfacePrototype;\n do {\n if (current == prototype) {\n this.error(\n DiagnosticCode._0_is_referenced_directly_or_indirectly_in_its_own_base_expression,\n prototype.identifierNode.range,\n prototype.internalName\n );\n return null;\n }\n current = current.basePrototype;\n } while (current);\n let implementsNode = assert(prototype.implementsNodes![i]);\n let iface = this.resolveClassInclTypeArguments(\n interfacePrototype,\n implementsNode.typeArguments,\n prototype.parent,\n cloneMap(ctxTypes),\n implementsNode,\n reportMode\n );\n if (!iface) return null;\n assert(iface.kind == ElementKind.Interface);\n instance.addInterface(iface);\n\n // Like above, if any implemented interface is still pending, yield\n if (pendingClasses.has(iface)) anyPending = true;\n }\n }\n if (anyPending) return instance;\n\n // We only get here if the base class has been fully resolved already.\n this.finishResolveClass(instance, reportMode);\n return instance;\n }\n\n /** Checks whether an override's visibility is valid. */\n private checkOverrideVisibility(\n /** Name to report. */\n name: string,\n /** Overriding member. */\n thisMember: DeclaredElement,\n /** Overriding class. */\n thisClass: Class,\n /** Overridden member. */\n baseMember: DeclaredElement,\n /** Overridden class. */\n baseClass: Class,\n /** Report mode. */\n reportMode: ReportMode\n ): bool {\n let hasErrors = false;\n if (thisMember.is(CommonFlags.Constructor)) {\n assert(baseMember.is(CommonFlags.Constructor));\n if (baseMember.is(CommonFlags.Private)) {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Cannot_extend_a_class_0_Class_constructor_is_marked_as_private,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n baseClass.internalName\n );\n }\n hasErrors = true;\n }\n } else if (thisMember.is(CommonFlags.Private)) {\n if (baseMember.is(CommonFlags.Private)) {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Types_have_separate_declarations_of_a_private_property_0,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n name\n );\n }\n hasErrors = true;\n } else {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Property_0_is_private_in_type_1_but_not_in_type_2,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n name, thisClass.internalName, baseClass.internalName\n );\n }\n hasErrors = true;\n }\n } else if (thisMember.is(CommonFlags.Protected)) {\n if (baseMember.is(CommonFlags.Private)) {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Property_0_is_private_in_type_1_but_not_in_type_2,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n name, baseClass.internalName, thisClass.internalName\n );\n }\n hasErrors = true;\n } else if (baseMember.isPublic) {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Property_0_is_protected_in_type_1_but_public_in_type_2,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n name, thisClass.internalName, baseClass.internalName\n );\n }\n hasErrors = true;\n } else {\n assert(baseMember.is(CommonFlags.Protected));\n }\n } else if (thisMember.isPublic) {\n if (baseMember.is(CommonFlags.Private)) {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Property_0_is_private_in_type_1_but_not_in_type_2,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n name, baseClass.internalName, thisClass.internalName\n );\n }\n hasErrors = true;\n } else if (baseMember.is(CommonFlags.Protected)) {\n if (reportMode == ReportMode.Report) {\n this.errorRelated(\n DiagnosticCode.Property_0_is_protected_in_type_1_but_public_in_type_2,\n thisMember.identifierNode.range, baseMember.identifierNode.range,\n name, baseClass.internalName, thisClass.internalName\n );\n }\n hasErrors = true;\n } else {\n assert(baseMember.isPublic);\n }\n }\n return !hasErrors;\n }\n\n /** Finishes resolving the specified class. */\n private finishResolveClass(\n /** Class to finish resolving. */\n instance: Class,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode\n ): void {\n let members = instance.members;\n if (!members) instance.members = members = new Map();\n\n let pendingClasses = this.resolveClassPending;\n let unimplemented = new Map();\n // Alias implemented interface members\n let interfaces = instance.interfaces;\n if (interfaces) {\n for (let _values = Set_values(interfaces), i = 0, k = _values.length; i < k; ++i) {\n let iface = _values[i];\n assert(!pendingClasses.has(iface));\n let ifaceMembers = iface.members;\n if (ifaceMembers) {\n for (let _keys = Map_keys(ifaceMembers), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let ifaceMember = assert(ifaceMembers.get(memberName));\n let existingMember = instance.getMember(memberName);\n if (existingMember && !this.checkOverrideVisibility(memberName, existingMember, instance, ifaceMember, iface, reportMode)) {\n continue; // keep previous\n }\n members.set(memberName, ifaceMember);\n unimplemented.set(memberName, ifaceMember);\n }\n }\n }\n }\n\n // Alias base members\n let memoryOffset: u32 = 0;\n let base = instance.base;\n if (base) {\n let implicitlyExtendsObject = instance.prototype.implicitlyExtendsObject;\n assert(!pendingClasses.has(base));\n let baseMembers = base.members;\n if (baseMembers) {\n // TODO: for (let [baseMemberName, baseMember] of baseMembers) {\n for (let _keys = Map_keys(baseMembers), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let baseMember = assert(baseMembers.get(memberName));\n if (implicitlyExtendsObject && baseMember.is(CommonFlags.Static)) continue;\n let existingMember = instance.getMember(memberName);\n if (existingMember && !this.checkOverrideVisibility(memberName, existingMember, instance, baseMember, base, reportMode)) {\n continue; // keep previous\n }\n members.set(memberName, baseMember);\n if (baseMember.is(CommonFlags.Abstract)) {\n unimplemented.set(memberName, baseMember);\n } else {\n unimplemented.delete(memberName);\n }\n }\n }\n memoryOffset = base.nextMemoryOffset;\n }\n\n // Resolve instance members\n let prototype = instance.prototype;\n let instanceMemberPrototypes = prototype.instanceMembers;\n let properties = new Array();\n if (instanceMemberPrototypes) {\n // TODO: for (let member of instanceMemberPrototypes.values()) {\n for (let _values = Map_values(instanceMemberPrototypes), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n let memberName = member.name;\n if (base) {\n let baseMember = base.getMember(memberName);\n if (baseMember) this.checkOverrideVisibility(memberName, member, instance, baseMember, base, reportMode);\n }\n switch (member.kind) {\n case ElementKind.FunctionPrototype: {\n let boundPrototype = (member).toBound(instance);\n instance.add(boundPrototype.name, boundPrototype); // reports\n break;\n }\n case ElementKind.PropertyPrototype: {\n let boundPrototype = (member).toBound(instance);\n if (boundPrototype.isField) { // resolve and lay out\n let boundInstance = this.resolveProperty(boundPrototype, reportMode);\n if (boundInstance) {\n let fieldType = boundInstance.type;\n if (fieldType == Type.void) break; // failed to resolve earlier\n let needsLayout = true;\n if (base) {\n let existingMember = base.getMember(boundPrototype.name);\n if (existingMember && existingMember.kind == ElementKind.PropertyPrototype) {\n let existingPrototype = existingMember;\n let existingProperty = this.resolveProperty(existingPrototype, reportMode);\n if (existingProperty && existingProperty.isField) {\n if (existingProperty.type != boundInstance.type) {\n // make sure fields are invariant (Binaryen would otherwise error)\n this.errorRelated(\n DiagnosticCode.Property_0_in_type_1_is_not_assignable_to_the_same_property_in_base_type_2,\n boundInstance.identifierNode.range, existingProperty.identifierNode.range,\n boundInstance.name, instance.internalName, base.internalName\n );\n break; // keep existing\n }\n boundInstance.memoryOffset = existingProperty.memoryOffset;\n needsLayout = false;\n }\n }\n }\n if (needsLayout) {\n let byteSize = fieldType.byteSize;\n assert(isPowerOf2(byteSize));\n let mask = byteSize - 1;\n if (memoryOffset & mask) memoryOffset = (memoryOffset | mask) + 1;\n boundInstance.memoryOffset = memoryOffset;\n memoryOffset += byteSize;\n }\n boundPrototype.instance = boundInstance;\n instance.add(boundPrototype.name, boundPrototype); // reports\n // field materializes here, so check for supported type early\n // (other checks are performed once an element is compiled)\n let typeNode = assert(boundPrototype.fieldDeclaration).type;\n if (typeNode) this.program.checkTypeSupported(fieldType, typeNode);\n }\n } else {\n instance.add(boundPrototype.name, boundPrototype); // reports\n }\n break;\n }\n default: assert(false);\n }\n if (!member.is(CommonFlags.Abstract)) {\n unimplemented.delete(memberName);\n }\n }\n }\n\n // Check that property getters and setters match\n for (let i = 0, k = properties.length; i < k; ++i) {\n let property = properties[i];\n let propertyGetter = property.getterInstance;\n if (!propertyGetter) {\n this.error(\n DiagnosticCode.Property_0_only_has_a_setter_and_is_missing_a_getter,\n property.identifierNode.range, property.name\n );\n } else {\n let propertySetter = property.setterInstance;\n if (propertySetter && !propertyGetter.visibilityEquals(propertySetter)) {\n this.errorRelated(\n DiagnosticCode.Getter_and_setter_accessors_do_not_agree_in_visibility,\n propertyGetter.identifierNode.range, propertySetter.identifierNode.range\n );\n }\n }\n }\n\n if (instance.kind != ElementKind.Interface) {\n\n // Check that all required members are implemented\n if (!instance.is(CommonFlags.Abstract) && unimplemented.size > 0) {\n for (let _keys = Map_keys(unimplemented), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = _keys[i];\n let member = assert(unimplemented.get(memberName));\n this.errorRelated(\n DiagnosticCode.Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_2,\n instance.identifierNode.range, member.identifierNode.range,\n instance.internalName, memberName, member.parent.internalName\n );\n }\n }\n\n // Finalize memory offset\n instance.nextMemoryOffset = memoryOffset;\n\n // Link _own_ constructor if present\n {\n let ctorPrototype = instance.getMember(CommonNames.constructor);\n if (ctorPrototype && ctorPrototype.parent == instance) {\n assert(ctorPrototype.kind == ElementKind.FunctionPrototype);\n let ctorInstance = this.resolveFunction(\n ctorPrototype,\n null,\n assert(instance.contextualTypeArguments),\n reportMode\n );\n if (ctorInstance) instance.constructorInstance = ctorInstance;\n }\n }\n }\n\n // Fully resolve operator overloads (don't have type parameters on their own)\n let overloadPrototypes = prototype.operatorOverloadPrototypes;\n // TODO: for (let [overloadKind, overloadPrototype] of overloadPrototypes) {\n for (let _keys = Map_keys(overloadPrototypes), i = 0, k = _keys.length; i < k; ++i) {\n let overloadKind = unchecked(_keys[i]);\n let overloadPrototype = assert(overloadPrototypes.get(overloadKind));\n assert(overloadKind != OperatorKind.Invalid);\n if (overloadPrototype.is(CommonFlags.Generic)) {\n // Already errored during initialization: AS212: Decorator '@operator' is not valid here\n continue;\n }\n let operatorInstance: Function | null;\n if (overloadPrototype.is(CommonFlags.Instance)) {\n let boundPrototype = overloadPrototype.toBound(instance);\n operatorInstance = this.resolveFunction(\n boundPrototype,\n null,\n new Map(),\n reportMode\n );\n } else {\n operatorInstance = this.resolveFunction(\n overloadPrototype,\n null,\n new Map(),\n reportMode\n );\n }\n if (!operatorInstance) continue;\n let overloads = instance.operatorOverloads;\n if (!overloads) instance.operatorOverloads = overloads = new Map();\n // inc/dec are special in that an instance overload attempts to re-assign\n // the corresponding value, thus requiring a matching return type, while a\n // static overload works like any other overload.\n if (operatorInstance.is(CommonFlags.Instance)) {\n switch (overloadKind) {\n case OperatorKind.PrefixInc:\n case OperatorKind.PrefixDec:\n case OperatorKind.PostfixInc:\n case OperatorKind.PostfixDec: {\n let returnType = operatorInstance.signature.returnType;\n if (!returnType.isAssignableTo(instance.type)) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_assignable_to_type_1,\n overloadPrototype.functionTypeNode.returnType.range, returnType.toString(), instance.type.toString()\n );\n }\n }\n }\n }\n }\n if (!overloads.has(overloadKind)) {\n overloads.set(overloadKind, operatorInstance);\n if (overloadKind == OperatorKind.IndexedGet || overloadKind == OperatorKind.IndexedSet) {\n let index = instance.indexSignature;\n if (!index) instance.indexSignature = index = new IndexSignature(instance);\n if (overloadKind == OperatorKind.IndexedGet) {\n index.setType(operatorInstance.signature.returnType);\n }\n }\n } else {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Duplicate_decorator,\n operatorInstance.declaration.range\n );\n }\n }\n }\n\n // Remove this class from pending\n assert(pendingClasses.has(instance)); // must be pending\n pendingClasses.delete(instance);\n\n // Finish derived classes that we postponed in `resolveClass` due to the\n // base class still being pending, again triggering `finishResolveClass`\n // of any classes derived from those classes, ultimately leading to all\n // pending classes being resolved.\n for (let _values = Set_values(pendingClasses), i = 0, k = _values.length; i < k; ++i) {\n let pending = _values[i];\n let dependsOnInstance = pending.base == instance;\n let interfaces = pending.interfaces;\n if (interfaces) {\n let anyPending = false;\n for (let _values2 = Set_values(interfaces), j = 0, l = _values2.length; j < l; ++j) {\n let iface = _values2[j];\n if (iface == instance) dependsOnInstance = true;\n else if (pendingClasses.has(iface)) anyPending = true;\n }\n if (anyPending) continue;\n }\n if (dependsOnInstance) this.finishResolveClass(pending, reportMode);\n }\n }\n\n /** Resolves a class prototype by first resolving the specified type arguments. */\n resolveClassInclTypeArguments(\n /** The prototype of the class. */\n prototype: ClassPrototype,\n /** Type arguments provided to be resolved. */\n typeArgumentNodes: TypeNode[] | null,\n /** Contextual element. */\n ctxElement: Element,\n /** Contextual types, i.e. `T`. */\n ctxTypes: Map,\n /** The node to use when reporting intermediate errors. */\n reportNode: Node,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Class | null {\n let resolvedTypeArguments: Type[] | null = null;\n\n // Resolve type arguments if generic\n if (prototype.is(CommonFlags.Generic)) {\n resolvedTypeArguments = this.resolveTypeArguments( // reports\n assert(prototype.typeParameterNodes), // must be present if generic\n typeArgumentNodes,\n ctxElement,\n ctxTypes, // update\n reportNode,\n reportMode\n );\n if (!resolvedTypeArguments) return null;\n\n // Otherwise make sure that no type arguments have been specified\n } else {\n if (typeArgumentNodes && typeArgumentNodes.length > 0) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Type_0_is_not_generic,\n reportNode.range, prototype.internalName\n );\n }\n return null;\n }\n }\n\n // Continue with concrete types\n return this.resolveClass(\n prototype,\n resolvedTypeArguments,\n ctxTypes,\n reportMode\n );\n }\n\n /** Resolves a property prototype. */\n resolveProperty(\n /** The prototype of the property. */\n prototype: PropertyPrototype,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): Property | null {\n let instance = prototype.instance;\n if (instance) return instance;\n prototype.instance = instance = new Property(\n prototype,\n prototype.parent // same level as prototype\n );\n let getterPrototype = prototype.getterPrototype;\n if (getterPrototype) {\n let getterInstance = this.resolveFunction(\n getterPrototype,\n null,\n new Map(),\n reportMode\n );\n if (getterInstance) {\n instance.getterInstance = getterInstance;\n instance.setType(getterInstance.signature.returnType);\n }\n }\n let setterPrototype = prototype.setterPrototype;\n if (setterPrototype) {\n let setterInstance = this.resolveFunction(\n setterPrototype,\n null,\n new Map(),\n reportMode\n );\n if (setterInstance) {\n instance.setterInstance = setterInstance;\n if (!instance.is(CommonFlags.Resolved)) {\n assert(setterInstance.signature.parameterTypes.length == 1);\n instance.setType(setterInstance.signature.parameterTypes[0]);\n }\n }\n }\n return instance;\n }\n\n private ensureOneTypeArgument(\n /** The type to resolve. */\n node: NamedTypeNode,\n /** How to proceed with eventual diagnostics. */\n reportMode: ReportMode = ReportMode.Report\n ): TypeNode | null {\n let typeArgumentNodes = node.typeArguments;\n let numTypeArguments = 0;\n if (!typeArgumentNodes || (numTypeArguments = typeArgumentNodes.length) != 1) {\n if (reportMode == ReportMode.Report) {\n this.error(\n DiagnosticCode.Expected_0_type_arguments_but_got_1,\n node.range, \"1\", numTypeArguments.toString()\n );\n }\n return null;\n }\n return typeArgumentNodes[0];\n }\n}\n","/// \n\nimport { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from \"./rt/common\";\nimport { Runtime } from \"shared/runtime\";\nimport { COMPARATOR, SORT } from \"./util/sort\";\nimport { REVERSE, FILL } from \"./util/bytes\";\nimport { idof } from \"./builtins\";\nimport { Array } from \"./array\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_HOLEYARRAY } from \"./util/error\";\nimport { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinReferenceArray } from \"./util/string\";\n\n@final\nexport class StaticArray {\n [key: number]: T;\n\n // Note that the interface of StaticArray instances must be a semantically\n // compatible subset of Array in order for syntax highlighting to work\n // properly, for instance when creating static arrays from array literals.\n // The additionally provided static methods take care of dealing with static\n // arrays exclusively, without having to convert to Array first.\n\n static fromArray(source: Array): StaticArray {\n let length = source.length;\n let outSize = length << alignof();\n let out = changetype>(__new(outSize, idof>()));\n if (isManaged()) {\n let sourcePtr = source.dataStart;\n for (let i = 0; i < length; ++i) {\n let off = i << alignof();\n let ref = load(sourcePtr + off);\n store(changetype(out) + off, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(changetype(out), source.dataStart, outSize);\n }\n return out;\n }\n\n /** @deprecated Please use source.concat> instead. */\n static concat(source: StaticArray, other: StaticArray): StaticArray {\n return source.concat>(other);\n }\n\n /** @deprecated Please use source.slice> instead. */\n static slice(source: StaticArray, start: i32 = 0, end: i32 = i32.MAX_VALUE): StaticArray {\n return source.slice>(start, end);\n }\n\n constructor(length: i32) {\n if (length > BLOCK_MAXSIZE >>> alignof()) throw new RangeError(E_INVALIDLENGTH);\n let outSize = length << alignof();\n let out = changetype>(__new(outSize, idof>()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(out), 0, outSize);\n }\n return out;\n }\n\n get length(): i32 {\n return changetype(changetype(this) - TOTAL_OVERHEAD).rtSize >>> alignof();\n }\n\n at(index: i32): T {\n let len = this.length;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(changetype(this) + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n @operator(\"[]\") private __get(index: i32): T {\n if (index >= this.length) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(changetype(this) + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n @unsafe @operator(\"{}\") private __uget(index: i32): T {\n return load(changetype(this) + (index << alignof()));\n }\n\n @operator(\"[]=\") private __set(index: i32, value: T): void {\n if (index >= this.length) throw new RangeError(E_INDEXOUTOFRANGE);\n this.__uset(index, value);\n }\n\n @unsafe @operator(\"{}=\") private __uset(index: i32, value: T): void {\n store(changetype(this) + (index << alignof()), value);\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n }\n\n fill(value: T, start: i32 = 0, end: i32 = i32.MAX_VALUE): StaticArray {\n if (isManaged()) {\n FILL(changetype(this), this.length, changetype(value), start, end);\n __link(changetype(this), changetype(value), false);\n } else {\n FILL(changetype(this), this.length, value, start, end);\n }\n return this;\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): StaticArray {\n let ptr = changetype(this);\n let len = this.length;\n\n end = min(end, len);\n\n let to = target < 0 ? max(len + target, 0) : min(target, len);\n let from = start < 0 ? max(len + start, 0) : min(start, len);\n let last = end < 0 ? max(len + end, 0) : min(end, len);\n let count = min(last - from, len - to);\n\n memory.copy( // is memmove\n ptr + (to << alignof()),\n ptr + (from << alignof()),\n count << alignof()\n );\n return this;\n }\n\n includes(value: T, fromIndex: i32 = 0): bool {\n if (isFloat()) {\n let length = this.length;\n if (length == 0 || fromIndex >= length) return false;\n if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);\n while (fromIndex < length) {\n let elem = load(changetype(this) + (fromIndex << alignof()));\n // @ts-ignore\n if (elem == value || isNaN(elem) & isNaN(value)) return true;\n ++fromIndex;\n }\n return false;\n } else {\n return this.indexOf(value, fromIndex) >= 0;\n }\n }\n\n indexOf(value: T, fromIndex: i32 = 0): i32 {\n let length = this.length;\n if (length == 0 || fromIndex >= length) return -1;\n if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);\n while (fromIndex < length) {\n if (load(changetype(this) + (fromIndex << alignof())) == value) return fromIndex;\n ++fromIndex;\n }\n return -1;\n }\n\n lastIndexOf(value: T, fromIndex: i32 = this.length): i32 {\n let length = this.length;\n if (length == 0) return -1;\n if (fromIndex < 0) fromIndex = length + fromIndex;\n else if (fromIndex >= length) fromIndex = length - 1;\n while (fromIndex >= 0) {\n if (load(changetype(this) + (fromIndex << alignof())) == value) return fromIndex;\n --fromIndex;\n }\n return -1;\n }\n\n concat = Array>(other: U): U {\n let sourceLen = this.length;\n let otherLen = other.length;\n let outLen = sourceLen + otherLen;\n if (outLen > BLOCK_MAXSIZE >>> alignof()) {\n throw new Error(E_INVALIDLENGTH);\n }\n let sourceSize = sourceLen << alignof();\n let out = changetype(this); // FIXME: instanceof needs *some* value\n\n if (out instanceof Array) {\n out = changetype(__newArray(outLen, alignof(), idof>()));\n // ^ FIXME: Function returns type U, but can't __newArray(U extends Array)\n let outStart = changetype>(out).dataStart;\n let otherStart = changetype>(other).dataStart;\n let thisStart = changetype(this);\n\n if (isManaged()) {\n for (let offset: usize = 0; offset < sourceSize; offset += sizeof()) {\n let ref = load(thisStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n outStart += sourceSize;\n let otherSize = otherLen << alignof();\n for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {\n let ref = load(otherStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(outStart, thisStart, sourceSize);\n memory.copy(outStart + sourceSize, otherStart, otherLen << alignof());\n }\n } else if (out instanceof StaticArray) {\n out = changetype(__new(outLen << alignof(), idof>()));\n let outStart = changetype(out);\n let otherStart = changetype(other);\n let thisStart = changetype(this);\n\n if (isManaged()) {\n for (let offset: usize = 0; offset < sourceSize; offset += sizeof()) {\n let ref = load(thisStart + offset);\n store(outStart + offset, ref);\n __link(outStart, ref, true);\n }\n outStart += sourceSize;\n let otherSize = otherLen << alignof();\n for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {\n let ref = load(otherStart + offset);\n store(outStart + offset, ref);\n __link(outStart, ref, true);\n }\n } else {\n memory.copy(outStart, thisStart, sourceSize);\n memory.copy(outStart + sourceSize, otherStart, otherLen << alignof());\n }\n } else {\n ERROR(\"Only Array and StaticArray accept for 'U' parameter\");\n }\n return out;\n }\n\n slice = Array>(start: i32 = 0, end: i32 = i32.MAX_VALUE): U {\n let length = this.length;\n start = start < 0 ? max(start + length, 0) : min(start, length);\n end = end < 0 ? max(end + length, 0) : min(end, length);\n length = max(end - start, 0);\n\n let sourceStart = changetype(this) + (start << alignof());\n let size = length << alignof();\n let out = changetype(this); // FIXME: instanceof needs *some* value\n\n if (out instanceof Array) {\n // return Array\n out = changetype(__newArray(length, alignof(), idof>()));\n // ^ FIXME: Function returns type U, but can't __newArray(U extends Array)\n let outStart = changetype>(out).dataStart;\n if (isManaged()) {\n let off: usize = 0;\n while (off < size) {\n let ref = load(sourceStart + off);\n store(outStart + off, ref);\n __link(changetype(out), ref, true);\n off += sizeof();\n }\n } else {\n memory.copy(outStart, sourceStart, size);\n }\n } else if (out instanceof StaticArray) {\n // return StaticArray\n out = changetype(__new(size, idof>()));\n let outStart = changetype(out);\n if (isManaged()) {\n let off: usize = 0;\n while (off < size) {\n let ref = load(sourceStart + off);\n store(outStart + off, ref);\n __link(outStart, ref, true);\n off += sizeof();\n }\n } else {\n memory.copy(outStart, sourceStart, size);\n }\n } else {\n ERROR(\"Only Array and StaticArray accept for 'U' parameter\");\n }\n return out;\n }\n\n findIndex(fn: (value: T, index: i32, array: StaticArray) => bool): i32 {\n for (let i = 0, len = this.length; i < len; ++i) {\n if (fn(load(changetype(this) + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n findLastIndex(fn: (value: T, index: i32, array: StaticArray) => bool): i32 {\n for (let i = this.length - 1; i >= 0; --i) {\n if (fn(load(changetype(this) + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n forEach(fn: (value: T, index: i32, array: StaticArray) => void): void {\n for (let i = 0, len = this.length; i < len; ++i) {\n fn(load(changetype(this) + (i << alignof())), i, this);\n }\n }\n\n map(fn: (value: T, index: i32, array: StaticArray) => U): Array {\n let len = this.length;\n let out = changetype>(__newArray(len, alignof(), idof>()));\n let outStart = out.dataStart;\n for (let i = 0; i < len; ++i) {\n let result = fn(load(changetype(this) + (i << alignof())), i, this);\n store(outStart + (i << alignof()), result);\n if (isManaged()) {\n __link(changetype(out), changetype(result), true);\n }\n }\n return out;\n }\n\n filter(fn: (value: T, index: i32, array: StaticArray) => bool): Array {\n let result = changetype>(__newArray(0, alignof(), idof>()));\n for (let i = 0, len = this.length; i < len; ++i) {\n let value = load(changetype(this) + (i << alignof()));\n if (fn(value, i, this)) result.push(value);\n }\n return result;\n }\n\n reduce(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: StaticArray) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = 0, len = this.length; i < len; ++i) {\n acc = fn(acc, load(changetype(this) + (i << alignof())), i, this);\n }\n return acc;\n }\n\n reduceRight(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: StaticArray) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = this.length - 1; i >= 0; --i) {\n acc = fn(acc, load(changetype(this) + (i << alignof())), i, this);\n }\n return acc;\n }\n\n every(fn: (value: T, index: i32, array: StaticArray) => bool): bool {\n for (let i = 0, len = this.length; i < len; ++i) {\n if (!fn(load(changetype(this) + (i << alignof())), i, this)) return false;\n }\n return true;\n }\n\n some(fn: (value: T, index: i32, array: StaticArray) => bool): bool {\n for (let i = 0, len = this.length; i < len; ++i) {\n if (fn(load(changetype(this) + (i << alignof())), i, this)) return true;\n }\n return false;\n }\n\n sort(comparator: (a: T, b: T) => i32 = COMPARATOR()): StaticArray {\n SORT(changetype(this), this.length, comparator);\n return this;\n }\n\n join(separator: string = \",\"): string {\n if (isBoolean()) return joinBooleanArray(changetype(this), this.length, separator);\n if (isInteger()) return joinIntegerArray(changetype(this), this.length, separator);\n if (isFloat()) return joinFloatArray(changetype(this), this.length, separator);\n if (ASC_SHRINK_LEVEL < 1) {\n if (isString()) return joinStringArray(changetype(this), this.length, separator);\n }\n if (isReference()) return joinReferenceArray(changetype(this), this.length, separator);\n ERROR(\"unspported element type\");\n return unreachable();\n }\n\n reverse(): StaticArray {\n REVERSE(changetype(this), this.length);\n return this;\n }\n\n toString(): string {\n return this.join();\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n if (isManaged()) {\n let cur = changetype(this);\n let end = cur + changetype(changetype(this) - TOTAL_OVERHEAD).rtSize;\n while (cur < end) {\n let val = load(cur);\n if (val) __visit(val, cookie);\n cur += sizeof();\n }\n }\n }\n}\n","/**\n * @fileoverview Various math utility.\n * @license Apache-2.0\n */\n\n/** Tests if `x` is a power of two. */\nexport function isPowerOf2(x: i32): bool {\n return x != 0 && (x & (x - 1)) == 0;\n}\n\nexport function accuratePow64(x: f64, y: f64): f64 {\n if (!ASC_TARGET) { // ASC_TARGET == JS\n // Engines like V8, WebKit and SpiderMonkey uses powi fast path if exponent is integer\n // This speculative optimization leads to loose precisions like 10 ** 208 != 1e208\n // or/and 10 ** -5 != 1e-5 anymore. For avoid this behaviour we are forcing exponent\n // to fractional form and compensate this afterwards.\n if (isFinite(y) && Math.abs(y) >= 2 && Math.trunc(y) == y) {\n if (y < 0) {\n return Math.pow(x, y + 0.5) / Math.pow(x, 0.5);\n } else {\n return Math.pow(x, y - 0.5) * Math.pow(x, 0.5);\n }\n }\n }\n return Math.pow(x, y);\n}\n","/**\n * @fileoverview Various binary reading and writing utility.\n * @license Apache-2.0\n */\n\n/** Reads an 8-bit integer from the specified buffer. */\nexport function readI8(buffer: Uint8Array, offset: i32): i32 {\n return buffer[offset];\n}\n\n/** Writes an 8-bit integer to the specified buffer. */\nexport function writeI8(value: i32, buffer: Uint8Array, offset: i32): void {\n buffer[offset] = value;\n}\n\n/** Reads a 16-bit integer from the specified buffer. */\nexport function readI16(buffer: Uint8Array, offset: i32): i32 {\n return i32(buffer[offset ])\n | i32(buffer[offset + 1]) << 8;\n}\n\n/** Writes a 16-bit integer to the specified buffer. */\nexport function writeI16(value: i32, buffer: Uint8Array, offset: i32): void {\n buffer[offset ] = value;\n buffer[offset + 1] = value >>> 8;\n}\n\n/** Reads a 32-bit integer from the specified buffer. */\nexport function readI32(buffer: Uint8Array, offset: i32): i32 {\n return i32(buffer[offset ])\n | i32(buffer[offset + 1]) << 8\n | i32(buffer[offset + 2]) << 16\n | i32(buffer[offset + 3]) << 24;\n}\n\n/** Writes a 32-bit integer to the specified buffer. */\nexport function writeI32(value: i32, buffer: Uint8Array, offset: i32): void {\n buffer[offset ] = value;\n buffer[offset + 1] = value >>> 8;\n buffer[offset + 2] = value >>> 16;\n buffer[offset + 3] = value >>> 24;\n}\n\n/** Writes a 32-bit integer as a 64-bit integer to the specified buffer. */\nexport function writeI32AsI64(value: i32, buffer: Uint8Array, offset: i32, unsigned: bool = false): void {\n writeI32(value, buffer, offset);\n writeI32(unsigned || value >= 0 ? 0 : -1, buffer, offset + 4);\n}\n\n/** Reads a 64-bit integer from the specified buffer. */\nexport function readI64(buffer: Uint8Array, offset: i32): i64 {\n let lo = readI32(buffer, offset);\n let hi = readI32(buffer, offset + 4);\n return i64_new(lo, hi);\n}\n\n/** Writes a 64-bit integer to the specified buffer. */\nexport function writeI64(value: i64, buffer: Uint8Array, offset: i32): void {\n writeI32(i64_low(value), buffer, offset);\n writeI32(i64_high(value), buffer, offset + 4);\n}\n\n/** Writes a 64-bit integer as a 32-bit integer to the specified buffer. */\nexport function writeI64AsI32(value: i64, buffer: Uint8Array, offset: i32, unsigned: bool = false): void {\n assert(unsigned ? i64_is_u32(value) : i64_is_i32(value));\n writeI32(i64_low(value), buffer, offset);\n}\n\n/** Reads a 32-bit float from the specified buffer. */\nexport function readF32(buffer: Uint8Array, offset: i32): f32 {\n return i32_as_f32(readI32(buffer, offset));\n}\n\n/** Writes a 32-bit float to the specified buffer. */\nexport function writeF32(value: f32, buffer: Uint8Array, offset: i32): void {\n writeI32(f32_as_i32(value), buffer, offset);\n}\n\n/** Reads a 64-bit float from the specified buffer. */\nexport function readF64(buffer: Uint8Array, offset: i32): f64 {\n return i64_as_f64(readI64(buffer, offset));\n}\n\n/** Writes a 64-bit float to the specified buffer. */\nexport function writeF64(value: f64, buffer: Uint8Array, offset: i32): void {\n let valueI64 = f64_as_i64(value);\n writeI32(i64_low(valueI64), buffer, offset);\n writeI32(i64_high(valueI64), buffer, offset + 4);\n}\n\n/** Reads a 128-bit vector from the specified buffer. */\nexport function readV128(buffer: Uint8Array, offset: i32): Uint8Array {\n return buffer.slice(offset, offset + 16);\n}\n\n/** Writes a 128-bit vector to the specified buffer. */\nexport function writeV128(value: Uint8Array, buffer: Uint8Array, offset: i32): void {\n assert(value.length == 16);\n buffer.set(value, offset);\n}\n","/**\n * @fileoverview Floating point glue code for WebAssembly.\n * @license Apache-2.0\n */\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n// @ts-ignore: decorator\n@global @inline\nfunction f32_as_i32(value: f32): i32 {\n return reinterpret(value);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i32_as_f32(value: i32): f32 {\n return reinterpret(value);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction f64_as_i64(value: f64): i64 {\n return reinterpret(value);\n}\n\n// @ts-ignore: decorator\n@global @inline\nfunction i64_as_f64(value: i64): f64 {\n return reinterpret(value);\n}\n","import {\n NodeKind,\n DecoratorKind,\n LiteralKind,\n LiteralExpression,\n StringLiteralExpression,\n TemplateLiteralExpression,\n findDecorator,\n Source\n} from \"../ast\";\n\nimport {\n CommonFlags\n} from \"../common\";\n\nimport {\n ElementKind,\n Element,\n Program,\n Function,\n Global,\n Class,\n Interface,\n Enum,\n EnumValue,\n PropertyPrototype\n} from \"../program\";\n\nimport {\n Type,\n TypeFlags,\n Signature\n} from \"../types\";\n\nimport {\n CharCode,\n escapeString,\n indent,\n isIdentifier\n} from \"../util\";\n\nimport {\n ExportsWalker\n} from \"./util\";\n\n// Limitations\n//\n// - Instrumented globals are no longer WebAssembly.Global, hence cannot be\n// imported the same way as non-instrumented globals would allow. Affects both\n// globals imported here and globals imported elsewhere.\n//\n// - Since little is known about how class imports and exports will behave,\n// there is currently no glue generated for them. In IT there appears to be\n// a concept of protocols that may or may not map in the future. In GC there\n// doesn't appear to be a connection between classes and their methods so far.\n//\n// Instead, generated bindings are limited to lifting and lowering of plain\n// objects when the class has no constructor and no non-public elements. In\n// any other sitation an internal or external reference is passed.\n//\n// - Linking two instrumented modules with separate bindings produces\n// intermediate garbage (i.e. goes through a temporary JS object). Any native\n// mechanism enabling communication between modules directly would help here.\n//\n// - Cycles between the internal and the external GC cannot be resolved. Using\n// a common GC as envisioned by the GC proposal can help here, but so far it\n// seems that the same limitations as for IT will remain.\n//\n// - Duplicate Wasm imports don't yet work when instrumentation is required as\n// provided argument types cannot be told apart when these only come in as\n// numbers. It might be possible to modify the binary post compilation, but\n// this has not been attempted yet.\n//\n// Oddities\n//\n// - Interface Types `string` will be incompatible with JavaScript `String` and\n// it remains unclear how to proceed on this front. We could either use the IT\n// mechanism and accept potential hazards or keep using unfortunate glue code.\n//\n// - Functions with a variable number of arguments need some special glue to\n// inform the binary how many arguments have been provided so it can fill in\n// defaults for the omitted arguments. No native mechanism in sight, yet.\n//\n// - Optional BigInt arguments must be coerced to 0n since JS does not\n// implicitly coerce from `null` or `undefined`. Numbers do, however.\n//\n// - Generated bindings assume little endian architecture with typed arrays as\n// it appears to be more efficient than using a DataView and BE use cases\n// haven't been seen in the wild so far.\n//\n// - It is assumed that generated import bindings call JavaScript and that the\n// callee expects a properly coerced integer value, leading to more `>>> 0`\n// coercions than necessary when the import is actually another Wasm module.\n\n/** Maps special imports to their actual modules. */\nfunction importToModule(moduleName: string): string {\n // Map rtrace via `imports` in package.json\n if (moduleName == \"rtrace\") return \"#rtrace\";\n return moduleName;\n}\n\n/** Determines whether a module's imports should be instrumented. */\nfunction shouldInstrument(moduleName: string): bool {\n return moduleName != \"rtrace\";\n}\n\n/** A JavaScript bindings builder. */\nexport class JSBuilder extends ExportsWalker {\n\n /** Builds JavaScript bindings for the specified program. */\n static build(program: Program, esm: bool = true): string {\n return new JSBuilder(program, esm).build();\n }\n\n private esm: bool;\n private sb: string[] = [];\n private indentLevel: i32 = 0;\n\n private needsLiftBuffer: bool = false;\n private needsLowerBuffer: bool = false;\n private needsLiftString: bool = false;\n private needsLowerString: bool = false;\n private needsLiftArray: bool = false;\n private needsLowerArray: bool = false;\n private needsLiftTypedArray: bool = false;\n private needsLowerTypedArray: bool = false;\n private needsLiftStaticArray: bool = false;\n private needsLowerStaticArray: bool = false;\n private needsLiftInternref: bool = false;\n private needsLowerInternref: bool = false;\n private needsRetain: bool = false;\n private needsRelease: bool = false;\n private needsNotNull: bool = false;\n private needsSetU8: bool = false;\n private needsSetU16: bool = false;\n private needsSetU32: bool = false;\n private needsSetU64: bool = false;\n private needsSetF32: bool = false;\n private needsSetF64: bool = false;\n private needsGetI8: bool = false;\n private needsGetU8: bool = false;\n private needsGetI16: bool = false;\n private needsGetU16: bool = false;\n private needsGetI32: bool = false;\n private needsGetU32: bool = false;\n private needsGetI64: bool = false;\n private needsGetU64: bool = false;\n private needsGetF32: bool = false;\n private needsGetF64: bool = false;\n\n private deferredLifts: Set = new Set();\n private deferredLowers: Set = new Set();\n private deferredCode: string[] = new Array();\n\n private exports: string[] = new Array();\n private importMappings: Map = new Map();\n\n /** Constructs a new JavaScript bindings builder. */\n constructor(program: Program, esm: bool, includePrivate: bool = false) {\n super(program, includePrivate);\n this.esm = esm;\n }\n\n visitGlobal(name: string, element: Global): void {\n let sb = this.sb;\n let type = element.type;\n this.exports.push(name);\n if (!isPlainValue(type, Mode.Export)) {\n indent(sb, this.indentLevel);\n sb.push(name);\n sb.push(\": {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(\": \");\n sb.push(type.toString());\n sb.push(\"\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"valueOf() { return this.value; },\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"get value() {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"return \");\n this.makeLiftFromValue(\"exports.\" + name + \".value\", type, sb);\n sb.push(\";\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"}\");\n if (!element.is(CommonFlags.Const)) {\n sb.push(\",\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"set value(value) {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"exports.\");\n sb.push(name);\n sb.push(\".value = \");\n this.makeLowerToValue(\"value\", type, sb);\n sb.push(\";\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"}\");\n }\n sb.push(\"\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"},\\n\");\n }\n this.visitNamespace(name, element);\n }\n\n visitEnum(name: string, element: Enum): void {\n let sb = this.sb;\n this.exports.push(name);\n indent(sb, this.indentLevel);\n sb.push(name);\n sb.push(\": (values => (\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(\"\\n\");\n let members = element.members;\n if (members) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let value = _values[i];\n if (value.kind != ElementKind.EnumValue) continue;\n indent(sb, this.indentLevel);\n sb.push(\"values[values.\");\n sb.push(value.name);\n if (value.is(CommonFlags.Inlined)) {\n sb.push(\" = \");\n sb.push(i64_low((value).constantIntegerValue).toString());\n } else {\n sb.push(\" = exports[\\\"\");\n sb.push(escapeString(name + \".\" + value.name, CharCode.DoubleQuote));\n sb.push(\"\\\"].valueOf()\");\n }\n sb.push(\"] = \\\"\");\n sb.push(escapeString(value.name, CharCode.DoubleQuote));\n sb.push(\"\\\",\\n\");\n }\n }\n indent(sb, this.indentLevel);\n sb.push(\"values\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"))({}),\\n\");\n this.visitNamespace(name, element);\n }\n\n makeGlobalImport(moduleName: string, name: string, element: Global): void {\n let sb = this.sb;\n let type = element.type;\n indent(sb, this.indentLevel);\n if (isIdentifier(name)) {\n sb.push(name);\n } else {\n sb.push(\"\\\"\");\n sb.push(escapeString(name, CharCode.DoubleQuote));\n sb.push(\"\\\": \");\n }\n let moduleId = this.ensureModuleId(moduleName);\n if (isPlainValue(type, Mode.Import)) {\n sb.push(\"(\\n\");\n indent(sb, this.indentLevel + 1);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(\": \");\n sb.push(element.type.toString());\n sb.push(\"\\n\");\n indent(sb, this.indentLevel + 1);\n if (moduleName != \"env\") {\n sb.push(\"__module\");\n sb.push(moduleId.toString());\n sb.push(\".\");\n }\n sb.push(name);\n sb.push(\"\\n\");\n indent(sb, this.indentLevel);\n sb.push(\")\");\n } else {\n sb.push(\"{\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(\": \");\n sb.push(element.type.toString());\n sb.push(\"\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"// not supported: cannot lower before instantiate completes\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"}\");\n }\n sb.push(\",\\n\");\n }\n\n makeFunctionImport(moduleName: string, name: string, element: Function, code: string | null = null): void {\n let sb = this.sb;\n let signature = element.signature;\n indent(sb, this.indentLevel);\n if (isIdentifier(name)) {\n sb.push(name);\n } else {\n sb.push(\"\\\"\");\n sb.push(escapeString(name, CharCode.DoubleQuote));\n sb.push(\"\\\"\");\n }\n if (isPlainFunction(signature, Mode.Import) && !code) {\n sb.push(\": (\\n\");\n indent(sb, this.indentLevel + 1);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(element.signature.toString());\n sb.push(\"\\n\");\n indent(sb, this.indentLevel + 1);\n if (moduleName != \"env\") {\n sb.push(moduleName);\n sb.push(\".\");\n }\n sb.push(name);\n sb.push(\"\\n\");\n indent(sb, this.indentLevel);\n sb.push(\")\");\n } else {\n sb.push(\"(\");\n let parameterTypes = signature.parameterTypes;\n let parameterNames = new Array();\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n parameterNames.push(element.getParameterName(i));\n }\n sb.push(parameterNames.join(\", \"));\n sb.push(\") {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(element.signature.toString());\n sb.push(\"\\n\");\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n let type = parameterTypes[i];\n if (!isPlainValue(type, Mode.Export)) {\n let name = element.getParameterName(i);\n indent(sb, this.indentLevel);\n sb.push(name);\n sb.push(\" = \");\n this.makeLiftFromValue(name, type, sb);\n sb.push(\";\\n\");\n }\n }\n let expr = new Array();\n let moduleId = this.ensureModuleId(moduleName);\n if (code) {\n expr.push(\"(() => {\\n\");\n indent(expr, 1);\n expr.push(\"// @external.js\\n\");\n indentText(code, 1, expr);\n expr.push(\"\\n})()\");\n } else {\n if (moduleName != \"env\") {\n expr.push(\"__module\");\n expr.push(moduleId.toString());\n expr.push(\".\");\n }\n expr.push(name);\n expr.push(\"(\");\n expr.push(parameterNames.join(\", \"));\n expr.push(\")\");\n }\n code = expr.join(\"\");\n expr.length = 0;\n indentText(code, this.indentLevel, expr, true);\n code = expr.join(\"\");\n indent(sb, this.indentLevel);\n if (signature.returnType != Type.void) {\n sb.push(\"return \");\n this.makeLowerToValue(code, signature.returnType, sb);\n sb.push(\";\\n\");\n } else {\n sb.push(code);\n sb.push(\";\\n\");\n }\n indent(sb, --this.indentLevel);\n sb.push(\"}\");\n }\n sb.push(\",\\n\");\n }\n\n visitFunction(name: string, element: Function): void {\n if (element.is(CommonFlags.Private)) return;\n let sb = this.sb;\n let signature = element.signature;\n this.exports.push(name);\n if (!isPlainFunction(signature, Mode.Export)) {\n indent(sb, this.indentLevel);\n sb.push(name);\n sb.push(\"(\");\n let parameterTypes = signature.parameterTypes;\n let numReferences = 0;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (parameterTypes[i].isInternalReference) numReferences++;\n if (i > 0) sb.push(\", \");\n sb.push(element.getParameterName(i));\n }\n sb.push(\") {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(element.internalName);\n sb.push(signature.toString());\n sb.push(\"\\n\");\n let releases = new Array();\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n let type = parameterTypes[i];\n if (!isPlainValue(type, Mode.Import)) {\n let name = element.getParameterName(i);\n indent(sb, this.indentLevel);\n sb.push(name);\n sb.push(\" = \");\n let needsRetainRelease = type.isInternalReference && --numReferences > 0;\n if (needsRetainRelease) {\n this.needsRetain = true;\n this.needsRelease = true;\n sb.push(\"__retain(\");\n releases.push(name);\n }\n this.makeLowerToValue(name, type, sb);\n if (needsRetainRelease) {\n sb.push(\")\");\n }\n sb.push(\";\\n\");\n }\n }\n if (releases.length) {\n indent(sb, this.indentLevel++);\n sb.push(\"try {\\n\");\n }\n if (signature.requiredParameters < parameterTypes.length) {\n indent(sb, this.indentLevel);\n sb.push(\"exports.__setArgumentsLength(arguments.length);\\n\");\n }\n const expr = new Array();\n expr.push(\"exports.\");\n expr.push(name);\n expr.push(\"(\");\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (i > 0) expr.push(\", \");\n expr.push(element.getParameterName(i));\n }\n expr.push(\")\");\n if (signature.returnType != Type.void) {\n indent(sb, this.indentLevel);\n sb.push(\"return \");\n this.makeLiftFromValue(expr.join(\"\"), signature.returnType, sb);\n } else {\n indent(sb, this.indentLevel);\n sb.push(expr.join(\"\"));\n }\n sb.push(\";\\n\");\n if (releases.length) {\n indent(sb, this.indentLevel - 1);\n sb.push(\"} finally {\\n\");\n for (let i = 0, k = releases.length; i < k; ++i) {\n indent(sb, this.indentLevel);\n sb.push(\"__release(\");\n sb.push(releases[i]);\n sb.push(\");\\n\");\n }\n indent(sb, --this.indentLevel);\n sb.push(\"}\\n\");\n }\n indent(sb, --this.indentLevel);\n sb.push(\"},\\n\");\n }\n this.visitNamespace(name, element);\n }\n\n visitClass(name: string, element: Class): void {\n // not implemented\n }\n\n visitInterface(name: string, element: Interface): void {\n this.visitClass(name, element);\n }\n\n visitNamespace(name: string, element: Element): void {\n // not implemented\n }\n\n visitAlias(name: string, element: Element, originalName: string): void {\n // not implemented\n // let sb = this.sb;\n // sb.push(\"export const \");\n // sb.push(name);\n // sb.push(\" = \");\n // sb.push(originalName);\n // sb.push(\";\\n\");\n }\n\n getExternalCode(element: Function): string | null {\n let decorator = findDecorator(DecoratorKind.ExternalJs, element.decoratorNodes);\n if (decorator) {\n let args = decorator.args;\n if (args && args.length == 1) {\n let codeArg = args[0];\n if (codeArg.kind == NodeKind.Literal) {\n let literal = codeArg;\n if (literal.literalKind == LiteralKind.String) {\n return (literal).value;\n }\n if (literal.literalKind == LiteralKind.Template) {\n let parts = (literal).parts;\n if (parts.length == 1) {\n return parts[0];\n }\n }\n }\n }\n }\n return null;\n }\n\n build(): string {\n let exports = this.exports;\n let moduleImports = this.program.moduleImports;\n let program = this.program;\n let options = program.options;\n let sb = this.sb;\n\n sb.push(\"\"); // placeholder\n indent(sb, this.indentLevel++);\n if (!this.esm) sb.push(\"export \");\n sb.push(\"async function instantiate(module, imports = {}) {\\n\");\n const insertPos = sb.push(\"\") - 1;\n\n // Instrument module imports. Keeps raw (JS) imports on the respective\n // prototypes and overrides selectively where instrumentation is required.\n indent(sb, this.indentLevel++);\n sb.push(\"const adaptedImports = {\\n\");\n let sbLengthBefore = sb.length;\n for (let _keys = Map_keys(moduleImports), i = 0, k = _keys.length; i < k; ++i) {\n let moduleName = _keys[i];\n let moduleId = this.ensureModuleId(moduleName);\n let module = >moduleImports.get(moduleName);\n indent(sb, this.indentLevel);\n if (isIdentifier(moduleName)) {\n sb.push(moduleName);\n } else {\n sb.push(\"\\\"\");\n sb.push(escapeString(moduleName, CharCode.DoubleQuote));\n sb.push(\"\\\"\");\n }\n if (!shouldInstrument(moduleName)) {\n sb.push(\": __module\");\n sb.push(moduleId.toString());\n sb.push(\",\\n\");\n continue;\n }\n let resetPos = sb.length;\n sb.push(\": Object.assign(Object.create(\");\n if (moduleName == \"env\") {\n sb.push(\"globalThis\");\n } else {\n sb.push(\"__module\");\n sb.push(moduleId.toString());\n }\n sb.push(\"), \");\n if (moduleName == \"env\") {\n sb.push(\"imports.env || {}, \");\n }\n sb.push(\"{\\n\");\n ++this.indentLevel;\n let numInstrumented = 0;\n for (let _keys2 = Map_keys(module), j = 0, l = _keys2.length; j < l; ++j) {\n let name = _keys2[j];\n let elem = assert(module.get(name));\n if (elem.kind == ElementKind.Function) {\n let func = elem;\n let code = this.getExternalCode(func);\n if (!isPlainFunction(func.signature, Mode.Import) || !isIdentifier(name) || code) {\n this.makeFunctionImport(moduleName, name, elem, code);\n ++numInstrumented;\n }\n } else if (elem.kind == ElementKind.Global) {\n let global = elem;\n if (!isPlainValue(global.type, Mode.Import) || !isIdentifier(name)) {\n this.makeGlobalImport(moduleName, name, global);\n ++numInstrumented;\n }\n }\n }\n --this.indentLevel;\n if (!numInstrumented) {\n sb.length = resetPos;\n if (moduleName == \"env\") {\n sb.push(\": Object.assign(Object.create(globalThis), imports.env || {})\");\n } else {\n sb.push(\": __module\");\n sb.push(moduleId.toString());\n }\n sb.push(\",\\n\");\n } else {\n indent(sb, this.indentLevel);\n sb.push(\"}),\\n\");\n }\n }\n --this.indentLevel;\n let hasAdaptedImports = sb.length > sbLengthBefore;\n if (hasAdaptedImports) {\n indent(sb, this.indentLevel);\n sb.push(\"};\\n\");\n } else {\n sb.length = sbLengthBefore - 2; // incl. indent\n }\n\n let mappings = this.importMappings;\n let map = new Array();\n for (let _keys = Map_keys(mappings), i = 0, k = _keys.length; i < k; ++i) {\n let moduleName = _keys[i];\n if (moduleName == \"env\") {\n map.push(\" const env = imports.env;\\n\");\n } else {\n let moduleId = mappings.get(moduleName);\n if (moduleName == \"rtrace\") {\n // Rtrace is special in that it needs to be installed on the imports\n // object. Use sensible defaults and substitute the original import.\n map.push(\" ((rtrace) => {\\n\");\n map.push(\" delete imports.rtrace;\\n\");\n map.push(\" new rtrace.Rtrace({ getMemory() { return memory; }, onerror(err) { console.log(`RTRACE: ${err.stack}`); } }).install(imports);\\n\");\n map.push(\" })(imports.rtrace);\\n\");\n }\n map.push(\" const __module\");\n map.push(moduleId.toString());\n map.push(\" = imports\");\n if (isIdentifier(moduleName)) {\n map.push(\".\");\n map.push(moduleName);\n } else {\n map.push(\"[\\\"\");\n map.push(escapeString(moduleName, CharCode.DoubleQuote));\n map.push(\"\\\"]\");\n }\n map.push(\";\\n\");\n }\n }\n sb[insertPos] = map.join(\"\");\n\n indent(sb, this.indentLevel);\n sb.push(\"const { exports } = await WebAssembly.instantiate(module\");\n if (hasAdaptedImports) {\n sb.push(\", adaptedImports);\\n\");\n } else {\n sb.push(\", imports);\\n\");\n }\n indent(sb, this.indentLevel);\n sb.push(\"const memory = exports.memory || imports.env.memory;\\n\");\n indent(sb, this.indentLevel++);\n sb.push(\"const adaptedExports = Object.setPrototypeOf({\\n\");\n sbLengthBefore = sb.length;\n\n // Instrument module exports. Keeps raw (Wasm) exports on the prototype and\n // overrides selectively where instrumentation is required.\n this.walk();\n --this.indentLevel;\n let hasAdaptedExports = sb.length > sbLengthBefore;\n if (hasAdaptedExports) {\n indent(sb, this.indentLevel);\n sb.push(\"}, exports);\\n\");\n } else {\n if (\n this.needsLiftBuffer || this.needsLowerBuffer ||\n this.needsLiftString || this.needsLowerString ||\n this.needsLiftArray || this.needsLowerArray ||\n this.needsLiftTypedArray || this.needsLowerTypedArray ||\n this.needsLiftStaticArray\n ) {\n sb.length = sbLengthBefore - 2; // skip adaptedExports + 1x indent\n } else {\n sb.length = sbLengthBefore - 4; // skip memory and adaptedExports + 2x indent\n }\n }\n\n // Add external JS code fragments\n let deferredCode = this.deferredCode;\n if (deferredCode.length) {\n for (let i = 0, k = deferredCode.length; i < k; ++i) {\n sb.push(deferredCode[i]);\n }\n }\n\n // Add the respective lifting and lowering adapters\n if (this.needsLiftBuffer) {\n let objectInstance = program.OBJECTInstance;\n let rtSizeOffset = objectInstance.offsetof(\"rtSize\") - objectInstance.nextMemoryOffset;\n sb.push(` function __liftBuffer(pointer) {\n if (!pointer) return null;\n return memory.buffer.slice(pointer, pointer + new Uint32Array(memory.buffer)[pointer - ${-rtSizeOffset} >>> 2]);\n }\n`);\n }\n if (this.needsLowerBuffer) {\n let arrayBufferId = program.arrayBufferInstance.id;\n sb.push(` function __lowerBuffer(value) {\n if (value == null) return 0;\n const pointer = exports.__new(value.byteLength, ${arrayBufferId}) >>> 0;\n new Uint8Array(memory.buffer).set(new Uint8Array(value), pointer);\n return pointer;\n }\n`);\n }\n if (this.needsLiftString) {\n let objectInstance = program.OBJECTInstance;\n let rtSizeOffset = objectInstance.offsetof(\"rtSize\") - objectInstance.nextMemoryOffset;\n let chunkSize = 1024;\n sb.push(` function __liftString(pointer) {\n if (!pointer) return null;\n const\n end = pointer + new Uint32Array(memory.buffer)[pointer - ${-rtSizeOffset} >>> 2] >>> 1,\n memoryU16 = new Uint16Array(memory.buffer);\n let\n start = pointer >>> 1,\n string = \"\";\n while (end - start > ${chunkSize}) string += String.fromCharCode(...memoryU16.subarray(start, start += ${chunkSize}));\n return string + String.fromCharCode(...memoryU16.subarray(start, end));\n }\n`);\n }\n if (this.needsLowerString) {\n let stringId = program.stringInstance.id;\n sb.push(` function __lowerString(value) {\n if (value == null) return 0;\n const\n length = value.length,\n pointer = exports.__new(length << 1, ${stringId}) >>> 0,\n memoryU16 = new Uint16Array(memory.buffer);\n for (let i = 0; i < length; ++i) memoryU16[(pointer >>> 1) + i] = value.charCodeAt(i);\n return pointer;\n }\n`);\n }\n if (this.needsLiftArray) {\n let dataStartOffset = program.arrayBufferViewInstance.offsetof(\"dataStart\");\n let lengthOffset = program.arrayBufferViewInstance.nextMemoryOffset;\n this.needsGetU32 = true;\n sb.push(` function __liftArray(liftElement, align, pointer) {\n if (!pointer) return null;\n const\n dataStart = __getU32(pointer + ${dataStartOffset}),\n length = __dataview.getUint32(pointer + ${lengthOffset}, true),\n values = new Array(length);\n for (let i = 0; i < length; ++i) values[i] = liftElement(dataStart + (i << align >>> 0));\n return values;\n }\n`);\n }\n if (this.needsLowerArray) {\n let arrayBufferId = program.arrayBufferInstance.id;\n let arrayBufferViewInstance = program.arrayBufferViewInstance;\n let arraySize = arrayBufferViewInstance.nextMemoryOffset + 4; // + length\n let bufferOffset = arrayBufferViewInstance.offsetof(\"buffer\");\n let dataStartOffset = arrayBufferViewInstance.offsetof(\"dataStart\");\n let byteLengthOffset = arrayBufferViewInstance.offsetof(\"byteLength\");\n let lengthOffset = byteLengthOffset + 4;\n this.needsSetU32 = true;\n sb.push(` function __lowerArray(lowerElement, id, align, values) {\n if (values == null) return 0;\n const\n length = values.length,\n buffer = exports.__pin(exports.__new(length << align, ${arrayBufferId})) >>> 0,\n header = exports.__pin(exports.__new(${arraySize}, id)) >>> 0;\n __setU32(header + ${bufferOffset}, buffer);\n __dataview.setUint32(header + ${dataStartOffset}, buffer, true);\n __dataview.setUint32(header + ${byteLengthOffset}, length << align, true);\n __dataview.setUint32(header + ${lengthOffset}, length, true);\n for (let i = 0; i < length; ++i) lowerElement(buffer + (i << align >>> 0), values[i]);\n exports.__unpin(buffer);\n exports.__unpin(header);\n return header;\n }\n`);\n }\n if (this.needsLiftTypedArray) {\n let arrayBufferViewInstance = program.arrayBufferViewInstance;\n let dataStartOffset = arrayBufferViewInstance.offsetof(\"dataStart\");\n let byteLengthOffset = arrayBufferViewInstance.offsetof(\"byteLength\");\n this.needsGetU32 = true;\n sb.push(` function __liftTypedArray(constructor, pointer) {\n if (!pointer) return null;\n return new constructor(\n memory.buffer,\n __getU32(pointer + ${dataStartOffset}),\n __dataview.getUint32(pointer + ${byteLengthOffset}, true) / constructor.BYTES_PER_ELEMENT\n ).slice();\n }\n`);\n }\n if (this.needsLowerTypedArray) {\n let arrayBufferId = program.arrayBufferInstance.id;\n let arrayBufferViewInstance = program.arrayBufferViewInstance;\n let size = arrayBufferViewInstance.nextMemoryOffset;\n let bufferOffset = arrayBufferViewInstance.offsetof(\"buffer\");\n let dataStartOffset = arrayBufferViewInstance.offsetof(\"dataStart\");\n let byteLengthOffset = arrayBufferViewInstance.offsetof(\"byteLength\");\n this.needsSetU32 = true;\n sb.push(` function __lowerTypedArray(constructor, id, align, values) {\n if (values == null) return 0;\n const\n length = values.length,\n buffer = exports.__pin(exports.__new(length << align, ${arrayBufferId})) >>> 0,\n header = exports.__new(${size}, id) >>> 0;\n __setU32(header + ${bufferOffset}, buffer);\n __dataview.setUint32(header + ${dataStartOffset}, buffer, true);\n __dataview.setUint32(header + ${byteLengthOffset}, length << align, true);\n new constructor(memory.buffer, buffer, length).set(values);\n exports.__unpin(buffer);\n return header;\n }\n`);\n }\n if (this.needsLiftStaticArray) {\n let objectInstance = program.OBJECTInstance;\n let rtSizeOffset = objectInstance.offsetof(\"rtSize\") - objectInstance.nextMemoryOffset;\n this.needsGetU32 = true;\n sb.push(` function __liftStaticArray(liftElement, align, pointer) {\n if (!pointer) return null;\n const\n length = __getU32(pointer - ${-rtSizeOffset}) >>> align,\n values = new Array(length);\n for (let i = 0; i < length; ++i) values[i] = liftElement(pointer + (i << align >>> 0));\n return values;\n }\n`);\n }\n if (this.needsLowerStaticArray) {\n sb.push(` function __lowerStaticArray(lowerElement, id, align, values, typedConstructor) {\n if (values == null) return 0;\n const\n length = values.length,\n buffer = exports.__pin(exports.__new(length << align, id)) >>> 0;\n if (typedConstructor) {\n new typedConstructor(memory.buffer, buffer, length).set(values);\n } else {\n for (let i = 0; i < length; i++) lowerElement(buffer + (i << align >>> 0), values[i]);\n }\n exports.__unpin(buffer);\n return buffer;\n }\n`);\n }\n if (this.needsLiftInternref || this.needsLowerInternref) {\n sb.push(\" class Internref extends Number {}\\n\");\n }\n if (this.needsLiftInternref) {\n this.needsRetain = true;\n this.needsRelease = true;\n sb.push(` const registry = new FinalizationRegistry(__release);\n function __liftInternref(pointer) {\n if (!pointer) return null;\n const sentinel = new Internref(__retain(pointer));\n registry.register(sentinel, pointer);\n return sentinel;\n }\n`);\n }\n if (this.needsLowerInternref) {\n sb.push(` function __lowerInternref(value) {\n if (value == null) return 0;\n if (value instanceof Internref) return value.valueOf();\n throw TypeError(\"internref expected\");\n }\n`);\n }\n if (this.needsRetain || this.needsRelease) {\n sb.push(` const refcounts = new Map();\n`);\n }\n if (this.needsRetain) {\n sb.push(` function __retain(pointer) {\n if (pointer) {\n const refcount = refcounts.get(pointer);\n if (refcount) refcounts.set(pointer, refcount + 1);\n else refcounts.set(exports.__pin(pointer), 1);\n }\n return pointer;\n }\n`);\n }\n if (this.needsRelease) {\n sb.push(` function __release(pointer) {\n if (pointer) {\n const refcount = refcounts.get(pointer);\n if (refcount === 1) exports.__unpin(pointer), refcounts.delete(pointer);\n else if (refcount) refcounts.set(pointer, refcount - 1);\n else throw Error(\\`invalid refcount '\\${refcount}' for reference '\\${pointer}'\\`);\n }\n }\n`);\n }\n if (this.needsNotNull) {\n sb.push(` function __notnull() {\n throw TypeError(\"value must not be null\");\n }\n`);\n }\n if (\n this.needsSetU8 ||\n this.needsSetU16 ||\n this.needsSetU32 ||\n this.needsSetU64 ||\n this.needsSetF32 ||\n this.needsSetF64 ||\n this.needsGetI8 ||\n this.needsGetU8 ||\n this.needsGetI16 ||\n this.needsGetU16 ||\n this.needsGetI32 ||\n this.needsGetU32 ||\n this.needsGetI64 ||\n this.needsGetU64 ||\n this.needsGetF32 ||\n this.needsGetF64\n ) {\n sb.push(\" let __dataview = new DataView(memory.buffer);\\n\");\n }\n if (this.needsSetU8) sb.push(makeCheckedSetter(\"U8\", \"setUint8\"));\n if (this.needsSetU16) sb.push(makeCheckedSetter(\"U16\", \"setUint16\"));\n if (this.needsSetU32) sb.push(makeCheckedSetter(\"U32\", \"setUint32\"));\n if (this.needsSetU64) sb.push(makeCheckedSetter(\"U64\", \"setBigUint64\"));\n if (this.needsSetF32) sb.push(makeCheckedSetter(\"F32\", \"setFloat32\"));\n if (this.needsSetF64) sb.push(makeCheckedSetter(\"F64\", \"setFloat64\"));\n if (this.needsGetI8) sb.push(makeCheckedGetter(\"I8\", \"getInt8\"));\n if (this.needsGetU8) sb.push(makeCheckedGetter(\"U8\", \"getUint8\"));\n if (this.needsGetI16) sb.push(makeCheckedGetter(\"I16\", \"getInt16\"));\n if (this.needsGetU16) sb.push(makeCheckedGetter(\"U16\", \"getUint16\"));\n if (this.needsGetI32) sb.push(makeCheckedGetter(\"I32\", \"getInt32\"));\n if (this.needsGetU32) sb.push(makeCheckedGetter(\"U32\", \"getUint32\"));\n if (this.needsGetI64) sb.push(makeCheckedGetter(\"I64\", \"getBigInt64\"));\n if (this.needsGetU64) sb.push(makeCheckedGetter(\"U64\", \"getBigUint64\"));\n if (this.needsGetF32) sb.push(makeCheckedGetter(\"F32\", \"getFloat32\"));\n if (this.needsGetF64) sb.push(makeCheckedGetter(\"F64\", \"getFloat64\"));\n\n let exportStart = options.exportStart;\n if (exportStart) {\n sb.push(` exports.${exportStart}();\\n`);\n }\n\n if (hasAdaptedExports) {\n sb.push(\" return adaptedExports;\\n}\\n\");\n } else {\n sb.push(\" return exports;\\n}\\n\");\n }\n --this.indentLevel;\n assert(this.indentLevel == 0);\n\n if (this.esm) {\n sb.push(\"export const {\\n \");\n if (this.program.options.exportMemory) {\n sb.push(\"memory,\\n \");\n }\n if (this.program.options.exportTable) {\n sb.push(\"table,\\n \");\n }\n for (let i = 0, k = exports.length; i < k; ++i) {\n if (i > 0) sb.push(\",\\n \");\n sb.push(exports[i]);\n }\n sb.push(`\n} = await (async url => instantiate(\n await (async () => {\n try { return await globalThis.WebAssembly.compileStreaming(globalThis.fetch(url)); }\n catch { return globalThis.WebAssembly.compile(await (await import(\"node:fs/promises\")).readFile(url)); }\n })(), {\n`);\n let needsMaybeDefault = false;\n let importExpr = new Array();\n for (let _keys = Map_keys(mappings), i = 0, k = _keys.length; i < k; ++i) {\n let moduleName = _keys[i];\n if (moduleName == \"env\") {\n indent(sb, 2);\n sb.push(\"env: globalThis,\\n\");\n } else {\n let moduleId = this.ensureModuleId(moduleName);\n indent(sb, 2);\n if (isIdentifier(moduleName)) {\n sb.push(moduleName);\n } else {\n sb.push(\"\\\"\");\n sb.push(escapeString(moduleName, CharCode.DoubleQuote));\n sb.push(\"\\\"\");\n }\n sb.push(\": __maybeDefault(__import\");\n sb.push(moduleId.toString());\n sb.push(\"),\\n\");\n importExpr.push(\"import * as __import\");\n importExpr.push(moduleId.toString());\n importExpr.push(\" from \\\"\");\n importExpr.push(escapeString(importToModule(moduleName), CharCode.DoubleQuote));\n importExpr.push(\"\\\";\\n\");\n needsMaybeDefault = true;\n }\n }\n sb[0] = importExpr.join(\"\");\n sb.push(` }\n))(new URL(\"${escapeString(options.basenameHint, CharCode.DoubleQuote)}.wasm\", import.meta.url));\n`);\n if (needsMaybeDefault) {\n sb.push(`function __maybeDefault(module) {\n return typeof module.default === \"object\" && Object.keys(module).length == 1\n ? module.default\n : module;\n}\n`);\n }\n }\n return sb.join(\"\");\n }\n\n ensureModuleId(moduleName: string): i32 {\n if (moduleName == \"env\") return -1;\n let importMap = this.importMappings;\n let moduleId = importMap.has(moduleName)\n ? i32(importMap.get(moduleName))\n : importMap.size;\n importMap.set(moduleName, moduleId);\n return moduleId;\n }\n\n /** Lifts a WebAssembly value to a JavaScript value, as an expression. */\n makeLiftFromValue(valueExpr: string, type: Type, sb: string[] = this.sb): void {\n if (type.isInternalReference) {\n // Lift reference types\n const clazz = assert(type.getClassOrWrapper(this.program));\n if (clazz.extendsPrototype(this.program.arrayBufferInstance.prototype)) {\n sb.push(\"__liftBuffer(\");\n this.needsLiftBuffer = true;\n } else if (clazz.extendsPrototype(this.program.stringInstance.prototype)) {\n sb.push(\"__liftString(\");\n this.needsLiftString = true;\n } else if (clazz.extendsPrototype(this.program.arrayPrototype)) {\n let valueType = clazz.getArrayValueType();\n sb.push(\"__liftArray(\");\n this.makeLiftFromMemoryFunc(valueType, sb);\n sb.push(\", \");\n sb.push(valueType.alignLog2.toString());\n sb.push(\", \");\n this.needsLiftArray = true;\n } else if (clazz.extendsPrototype(this.program.staticArrayPrototype)) {\n let valueType = clazz.getArrayValueType();\n sb.push(\"__liftStaticArray(\");\n this.makeLiftFromMemoryFunc(valueType, sb);\n sb.push(\", \");\n sb.push(valueType.alignLog2.toString());\n sb.push(\", \");\n this.needsLiftStaticArray = true;\n } else if (clazz.extendsPrototype(this.program.arrayBufferViewInstance.prototype)) {\n sb.push(\"__liftTypedArray(\");\n if (clazz.name == \"Uint64Array\") {\n sb.push(\"BigUint64Array\");\n } else if (clazz.name == \"Int64Array\") {\n sb.push(\"BigInt64Array\");\n } else {\n sb.push(clazz.name); // TODO: what if extended?\n }\n sb.push(\", \");\n this.needsLiftTypedArray = true;\n } else if (isPlainObject(clazz)) {\n sb.push(\"__liftRecord\");\n sb.push(clazz.id.toString());\n sb.push(\"(\");\n if (!this.deferredLifts.has(clazz)) {\n this.deferredLifts.add(clazz);\n let prevIndentLevel = this.indentLevel;\n this.indentLevel = 1;\n this.deferredCode.push(this.makeLiftRecord(clazz));\n this.indentLevel = prevIndentLevel;\n }\n } else {\n sb.push(\"__liftInternref(\");\n this.needsLiftInternref = true;\n }\n sb.push(valueExpr);\n if (!valueExpr.startsWith(\"__get\")) {\n // no need to coerce when lifting with indirection\n sb.push(\" >>> 0\");\n }\n sb.push(\")\");\n } else {\n // Lift and coerce basic values (from a Wasm export)\n if (type == Type.bool) { // i32 to boolean\n sb.push(`${valueExpr} != 0`);\n } else if (type.isUnsignedIntegerValue && type.size >= 32) {\n if (type.size == 64) { // i64 to unsigned bigint\n sb.push(`BigInt.asUintN(64, ${valueExpr})`);\n } else { // i32 to unsigned\n sb.push(`${valueExpr} >>> 0`);\n }\n } else {\n sb.push(valueExpr);\n }\n }\n }\n\n /** Lowers a JavaScript value to a WebAssembly value, as an expression. */\n makeLowerToValue(valueExpr: string, type: Type, sb: string[] = this.sb): void {\n if (type.isInternalReference) {\n // Lower reference types\n const clazz = assert(type.getClassOrWrapper(this.program));\n if (clazz.extendsPrototype(this.program.arrayBufferInstance.prototype)) {\n sb.push(\"__lowerBuffer(\");\n this.needsLowerBuffer = true;\n } else if (clazz.extendsPrototype(this.program.stringInstance.prototype)) {\n sb.push(\"__lowerString(\");\n this.needsLowerString = true;\n } else if (clazz.extendsPrototype(this.program.arrayPrototype)) {\n let valueType = clazz.getArrayValueType();\n sb.push(\"__lowerArray(\");\n this.makeLowerToMemoryFunc(valueType, sb);\n sb.push(\", \");\n sb.push(clazz.id.toString());\n sb.push(\", \");\n sb.push(clazz.getArrayValueType().alignLog2.toString());\n sb.push(\", \");\n this.needsLowerArray = true;\n } else if (clazz.extendsPrototype(this.program.staticArrayPrototype)) {\n let valueType = clazz.getArrayValueType();\n sb.push(\"__lowerStaticArray(\");\n this.makeLowerToMemoryFunc(valueType, sb);\n sb.push(\", \");\n sb.push(clazz.id.toString());\n sb.push(\", \");\n sb.push(valueType.alignLog2.toString());\n sb.push(\", \");\n this.needsLowerStaticArray = true;\n } else if (clazz.extendsPrototype(this.program.arrayBufferViewInstance.prototype)) {\n let valueType = clazz.getArrayValueType();\n sb.push(\"__lowerTypedArray(\");\n if (valueType == Type.u64) {\n sb.push(\"BigUint64Array\");\n } else if (valueType == Type.i64) {\n sb.push(\"BigInt64Array\");\n } else {\n sb.push(clazz.name); // TODO: what if extended?\n }\n sb.push(\", \");\n sb.push(clazz.id.toString());\n sb.push(\", \");\n sb.push(clazz.getArrayValueType().alignLog2.toString());\n sb.push(\", \");\n this.needsLowerTypedArray = true;\n } else if (isPlainObject(clazz)) {\n sb.push(\"__lowerRecord\");\n sb.push(clazz.id.toString());\n sb.push(\"(\");\n if (!this.deferredLowers.has(clazz)) {\n this.deferredLowers.add(clazz);\n let prevIndentLevel = this.indentLevel;\n this.indentLevel = 1;\n this.deferredCode.push(this.makeLowerRecord(clazz));\n this.indentLevel = prevIndentLevel;\n }\n } else {\n sb.push(\"__lowerInternref(\");\n this.needsLowerInternref = true;\n }\n sb.push(valueExpr);\n if (clazz.extendsPrototype(this.program.staticArrayPrototype)) {\n // optional last argument for __lowerStaticArray\n let valueType = clazz.getArrayValueType();\n if (valueType.isNumericValue) {\n sb.push(\", \");\n if (valueType == Type.u8 || valueType == Type.bool) {\n sb.push(\"Uint8Array\");\n } else if (valueType == Type.i8) {\n sb.push(\"Int8Array\");\n } else if (valueType == Type.u16) {\n sb.push(\"Uint16Array\");\n } else if (valueType == Type.i16) {\n sb.push(\"Int16Array\");\n } else if (valueType == Type.u32 || valueType == Type.usize32) {\n sb.push(\"Uint32Array\");\n } else if (valueType == Type.i32 || valueType == Type.isize32) {\n sb.push(\"Int32Array\");\n } else if (valueType == Type.u64 || valueType == Type.usize64) {\n sb.push(\"BigUint64Array\");\n } else if (valueType == Type.i64 || valueType == Type.isize64) {\n sb.push(\"BigInt64Array\");\n } else if (valueType == Type.f32) {\n sb.push(\"Float32Array\");\n } else if (valueType == Type.f64) {\n sb.push(\"Float64Array\");\n } else {\n // unreachable\n assert(false);\n }\n }\n }\n sb.push(\")\");\n if (!type.is(TypeFlags.Nullable)) {\n this.needsNotNull = true;\n sb.push(\" || __notnull()\");\n }\n } else {\n // Lower basic types\n sb.push(valueExpr); // basic value\n if (type.isIntegerValue && type.size == 64) {\n sb.push(\" || 0n\");\n } else if (type == Type.bool) {\n // may be stored to an Uint8Array, make sure to store 1/0\n sb.push(\" ? 1 : 0\");\n }\n }\n }\n\n ensureLiftFromMemoryFn(valueType: Type): string {\n if (valueType.isInternalReference) {\n if (this.program.options.isWasm64) {\n this.needsGetU64 = true;\n return \"__getU64\";\n } else {\n this.needsGetU32 = true;\n return \"__getU32\";\n }\n }\n if (valueType == Type.i8) {\n this.needsGetI8 = true;\n return \"__getI8\";\n }\n if (valueType == Type.u8 || valueType == Type.bool) {\n this.needsGetU8 = true;\n return \"__getU8\";\n }\n if (valueType == Type.i16) {\n this.needsGetI16 = true;\n return \"__getI16\";\n }\n if (valueType == Type.u16) {\n this.needsGetU16 = true;\n return \"__getU16\";\n }\n if (valueType == Type.i32 || valueType == Type.isize32) {\n this.needsGetI32 = true;\n return \"__getI32\";\n }\n if (valueType == Type.u32 || valueType == Type.usize32) {\n this.needsGetU32 = true;\n return \"__getU32\";\n }\n if (valueType == Type.i64 || valueType == Type.isize64) {\n this.needsGetI64 = true;\n return \"__getI64\";\n }\n if (valueType == Type.u64 || valueType == Type.usize64) {\n this.needsGetU64 = true;\n return \"__getU64\";\n }\n if (valueType == Type.f32) {\n this.needsGetF32 = true;\n return \"__getF32\";\n }\n if (valueType == Type.f64) {\n this.needsGetF64 = true;\n return \"__getF64\";\n }\n return \"(() => { throw Error(\\\"unsupported type\\\"); })\";\n }\n\n /** Lifts a WebAssembly memory address to a JavaScript value, as a function. */\n makeLiftFromMemoryFunc(valueType: Type, sb: string[] = this.sb): void {\n let fn = this.ensureLiftFromMemoryFn(valueType);\n if (\n // Compound or with coercion, see makeLiftFromValue\n valueType.isInternalReference ||\n valueType == Type.bool ||\n (valueType.isUnsignedIntegerValue && valueType.size >= 32)\n ) {\n sb.push(\"pointer => \");\n this.makeLiftFromValue(`${fn}(pointer)`, valueType, sb);\n } else {\n sb.push(fn);\n }\n }\n\n /** Lifts a WebAssembly memory address to a JavaScript value, as a call. */\n makeLiftFromMemoryCall(valueType: Type, sb: string[] = this.sb, pointerExpr: string = \"pointer\"): void {\n let fn = this.ensureLiftFromMemoryFn(valueType);\n if (valueType.isInternalReference) {\n this.makeLiftFromValue(`${fn}(${pointerExpr})`, valueType, sb);\n } else {\n sb.push(fn);\n sb.push(\"(\");\n sb.push(pointerExpr);\n sb.push(\")\");\n if (valueType == Type.bool) {\n sb.push(\" != 0\");\n }\n // Other integers are known to be coerced here by loading from a view\n }\n }\n\n ensureLowerToMemoryFn(valueType: Type): string {\n if (valueType.isInternalReference) {\n if (this.program.options.isWasm64) {\n this.needsSetU64 = true;\n return \"__setU64\";\n } else {\n this.needsSetU32 = true;\n return \"__setU32\";\n }\n }\n if (valueType == Type.i8 || valueType == Type.u8 || valueType == Type.bool) {\n this.needsSetU8 = true;\n return \"__setU8\";\n }\n if (valueType == Type.i16 || valueType == Type.u16) {\n this.needsSetU16 = true;\n return \"__setU16\";\n }\n if (valueType == Type.i32 || valueType == Type.u32 || valueType == Type.isize32 || valueType == Type.usize32) {\n this.needsSetU32 = true;\n return \"__setU32\";\n }\n if (valueType == Type.i64 || valueType == Type.u64 || valueType == Type.isize64 || valueType == Type.usize64) {\n this.needsSetU64 = true;\n return \"__setU64\";\n }\n if (valueType == Type.f32) {\n this.needsSetF32 = true;\n return \"__setF32\";\n }\n if (valueType == Type.f64) {\n this.needsSetF64 = true;\n return \"__setF64\";\n }\n return \"(() => { throw Error(\\\"unsupported type\\\") })\";\n }\n\n /** Lowers a JavaScript value to a WebAssembly memory address, as a function. */\n makeLowerToMemoryFunc(valueType: Type, sb: string[] = this.sb): void {\n let fn = this.ensureLowerToMemoryFn(valueType);\n if (valueType.isInternalReference) {\n sb.push(\"(pointer, value) => { \");\n sb.push(fn);\n sb.push(\"(pointer, \");\n this.makeLowerToValue(\"value\", valueType, sb);\n sb.push(\"); }\");\n } else {\n sb.push(fn);\n }\n }\n\n /** Lowers a JavaScript value to a WebAssembly memory address, as a call. */\n makeLowerToMemoryCall(valueType: Type, sb: string[] = this.sb, pointerExpr: string = \"pointer\", valueExpr: string = \"value\"): void {\n let fn = this.ensureLowerToMemoryFn(valueType);\n sb.push(fn);\n sb.push(\"(\");\n sb.push(pointerExpr);\n sb.push(\", \");\n this.makeLowerToValue(valueExpr, valueType, sb);\n sb.push(\")\");\n }\n\n makeLiftRecord(clazz: Class): string {\n assert(isPlainObject(clazz));\n let sb = new Array();\n indent(sb, this.indentLevel);\n sb.push(\"function __liftRecord\");\n sb.push(clazz.id.toString());\n sb.push(\"(pointer) {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(clazz.type.toString());\n sb.push(\"\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"// Hint: Opt-out from lifting as a record by providing an empty constructor\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"if (!pointer) return null;\\n\");\n indent(sb, this.indentLevel++);\n sb.push(\"return {\\n\");\n let members = clazz.members;\n if (members) {\n for (let _keys = Map_keys(members), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = _keys[i];\n let member = assert(members.get(memberName));\n if (member.kind != ElementKind.PropertyPrototype) continue;\n let property = (member).instance; // resolved during class finalization\n if (!property || !property.isField) continue;\n assert(property.memoryOffset >= 0);\n indent(sb, this.indentLevel);\n sb.push(property.name);\n sb.push(\": \");\n this.makeLiftFromMemoryCall(property.type, sb, `pointer + ${property.memoryOffset}`);\n sb.push(\",\\n\");\n }\n }\n indent(sb, --this.indentLevel);\n sb.push(\"};\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"}\\n\");\n return sb.join(\"\");\n }\n\n makeLowerRecord(clazz: Class): string {\n assert(isPlainObject(clazz));\n let sb = new Array();\n indent(sb, this.indentLevel);\n sb.push(\"function __lowerRecord\");\n sb.push(clazz.id.toString());\n sb.push(\"(value) {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"// \");\n sb.push(clazz.type.toString());\n sb.push(\"\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"// Hint: Opt-out from lowering as a record by providing an empty constructor\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"if (value == null) return 0;\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"const pointer = exports.__pin(exports.__new(\");\n sb.push(clazz.nextMemoryOffset.toString());\n sb.push(\", \");\n sb.push(clazz.id.toString());\n sb.push(\"));\\n\");\n let members = clazz.members;\n if (members) {\n for (let _keys = Map_keys(members), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = _keys[i];\n let member = assert(members.get(memberName));\n if (member.kind != ElementKind.PropertyPrototype) continue;\n let property = (member).instance; // resolved during class finalization\n if (!property || !property.isField) continue;\n assert(property.memoryOffset >= 0);\n indent(sb, this.indentLevel);\n this.makeLowerToMemoryCall(property.type, sb, `pointer + ${property.memoryOffset}`, `value.${memberName}`);\n sb.push(\";\\n\");\n }\n }\n indent(sb, this.indentLevel);\n sb.push(\"exports.__unpin(pointer);\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"return pointer;\\n\");\n indent(sb, --this.indentLevel);\n sb.push(\"}\\n\");\n return sb.join(\"\");\n }\n}\n\n// Helpers\n\nenum Mode {\n Import,\n Export\n}\n\nfunction isPlainValue(type: Type, kind: Mode): bool {\n if (kind == Mode.Import) {\n // may be stored to an Uint8Array, make sure to store 1/0\n if (type == Type.bool) return false;\n // requires coercion of undefined to 0n\n if (type.isIntegerValue && type.size == 64) return false;\n } else {\n // requires coercion from 1/0 to true/false\n if (type == Type.bool) return false;\n // requires coercion from signed to unsigned for u32 and u64.\n // Note, u8 and u16 doesn't overflow in native type so mark as plain\n if (type.isUnsignedIntegerValue && type.size >= 32) return false;\n }\n return !type.isInternalReference;\n}\n\nfunction isPlainFunction(signature: Signature, mode: Mode): bool {\n let parameterTypes = signature.parameterTypes;\n let inverseMode = mode == Mode.Import ? Mode.Export : Mode.Import;\n if (!isPlainValue(signature.returnType, mode)) return false;\n for (let i = 0, k = parameterTypes.length; i < k; ++i) {\n if (!isPlainValue(parameterTypes[i], inverseMode)) return false;\n }\n return true;\n}\n\nfunction isPlainObject(clazz: Class): bool {\n // A plain object does not inherit and does not have a constructor or private properties\n if (clazz.base && !clazz.prototype.implicitlyExtendsObject) return false;\n let members = clazz.members;\n if (members) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = _values[i];\n if (member.isAny(CommonFlags.Private | CommonFlags.Protected)) return false;\n if (member.is(CommonFlags.Constructor)) {\n // a generated constructor is ok\n if (member.declaration.range != Source.native.range) return false;\n }\n }\n }\n return true;\n}\n\nfunction indentText(text: string, indentLevel: i32, sb: string[], butFirst: bool = false): void {\n let lineStart = 0;\n let length = text.length;\n let pos = 0;\n while (pos < length) {\n if (text.charCodeAt(pos) == CharCode.LineFeed) {\n if (butFirst) butFirst = false;\n else indent(sb, indentLevel);\n sb.push(text.substring(lineStart, lineStart = pos + 1));\n }\n ++pos;\n }\n if (lineStart < length) {\n if (!butFirst) indent(sb, indentLevel);\n sb.push(text.substring(lineStart));\n }\n}\n\nexport function liftRequiresExportRuntime(type: Type): bool {\n // TODO: enable v128 in signatures in future\n // if (type.isVectorValue) return true;\n if (!type.isInternalReference) return false;\n let clazz = type.classReference;\n if (!clazz) {\n // functions lift as internref using __pin\n assert(type.signatureReference);\n return true;\n }\n let program = clazz.program;\n // flat collections lift via memory copy\n if (\n clazz.extendsPrototype(program.arrayBufferInstance.prototype) ||\n clazz.extendsPrototype(program.stringInstance.prototype) ||\n clazz.extendsPrototype(program.arrayBufferViewInstance.prototype)\n ) {\n return false;\n }\n // nested collections lift depending on element type\n if (\n clazz.extendsPrototype(program.arrayPrototype) ||\n clazz.extendsPrototype(program.staticArrayPrototype)\n ) {\n return liftRequiresExportRuntime(clazz.getArrayValueType());\n }\n // complex objects lift as internref using __pin. plain objects may or may not\n // involve the runtime: assume that they do to avoid potentially costly checks\n return true;\n}\n\nexport function lowerRequiresExportRuntime(type: Type): bool {\n // TODO: enable v128 in signatures in future\n // if (type.isVectorValue) return true;\n if (!type.isInternalReference) return false;\n let clazz = type.classReference;\n if (!clazz) {\n // lowers by reference\n assert(type.signatureReference);\n return false;\n }\n // lowers using __new\n let program = clazz.program;\n if (\n clazz.extendsPrototype(program.arrayBufferInstance.prototype) ||\n clazz.extendsPrototype(program.stringInstance.prototype) ||\n clazz.extendsPrototype(program.arrayBufferViewInstance.prototype) ||\n clazz.extendsPrototype(program.arrayPrototype) ||\n clazz.extendsPrototype(program.staticArrayPrototype)\n ) {\n return true;\n }\n // complex objects lower via internref by reference,\n // while plain objects lower using __new\n return isPlainObject(clazz);\n}\n\n/** Makes a checked setter function to memory for the given basic type. */\nfunction makeCheckedSetter(type: string, fn: string): string {\n return ` function __set${type}(pointer, value) {\n try {\n __dataview.${fn}(pointer, value, true);\n } catch {\n __dataview = new DataView(memory.buffer);\n __dataview.${fn}(pointer, value, true);\n }\n }\n`;\n}\n\n/** Makes a checked getter function from memory for the given basic type. */\nfunction makeCheckedGetter(type: string, fn: string): string {\n return ` function __get${type}(pointer) {\n try {\n return __dataview.${fn}(pointer, true);\n } catch {\n __dataview = new DataView(memory.buffer);\n return __dataview.${fn}(pointer, true);\n }\n }\n`;\n}\n","import { Math as JSMath } from \"./bindings/dom\";\nexport { JSMath };\n\nimport {\n pow_lut, exp_lut, exp2_lut, log_lut, log2_lut,\n powf_lut, expf_lut, exp2f_lut, logf_lut, log2f_lut\n} from \"./util/math\";\n\nimport {\n abs as builtin_abs,\n ceil as builtin_ceil,\n clz as builtin_clz,\n copysign as builtin_copysign,\n floor as builtin_floor,\n max as builtin_max,\n min as builtin_min,\n sqrt as builtin_sqrt,\n trunc as builtin_trunc\n} from \"./builtins\";\n\n// SUN COPYRIGHT NOTICE\n//\n// Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved.\n// Developed at SunPro, a Sun Microsystems, Inc. business.\n// Permission to use, copy, modify, and distribute this software\n// is freely granted, provided that this notice is preserved.\n//\n// Applies to all functions marked with a comment referring here.\n\n/** @internal */\n// @ts-ignore: decorator\n@lazy let rempio2_y0: f64, rempio2_y1: f64, res128_hi: u64;\n\n/** @internal */\n// @ts-ignore: decorator\n@lazy @inline const PIO2_TABLE = memory.data([\n 0x00000000A2F9836E, 0x4E441529FC2757D1, 0xF534DDC0DB629599, 0x3C439041FE5163AB,\n 0xDEBBC561B7246E3A, 0x424DD2E006492EEA, 0x09D1921CFE1DEB1C, 0xB129A73EE88235F5,\n 0x2EBB4484E99C7026, 0xB45F7E413991D639, 0x835339F49C845F8B, 0xBDF9283B1FF897FF,\n 0xDE05980FEF2F118B, 0x5A0A6D1F6D367ECF, 0x27CB09B74F463F66, 0x9E5FEA2D7527BAC7,\n 0xEBE5F17B3D0739F7, 0x8A5292EA6BFB5FB1, 0x1F8D5D0856033046, 0xFC7B6BABF0CFBC20,\n 0x9AF4361DA9E39161, 0x5EE61B086599855F, 0x14A068408DFFD880, 0x4D73273106061557\n]);\n\n/** @internal */\nfunction R(z: f64): f64 { // Rational approximation of (asin(x)-x)/x^3\n const // see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE above\n pS0 = reinterpret(0x3FC5555555555555), // 1.66666666666666657415e-01\n pS1 = reinterpret(0xBFD4D61203EB6F7D), // -3.25565818622400915405e-01\n pS2 = reinterpret(0x3FC9C1550E884455), // 2.01212532134862925881e-01\n pS3 = reinterpret(0xBFA48228B5688F3B), // -4.00555345006794114027e-02\n pS4 = reinterpret(0x3F49EFE07501B288), // 7.91534994289814532176e-04\n pS5 = reinterpret(0x3F023DE10DFDF709), // 3.47933107596021167570e-05\n qS1 = reinterpret(0xC0033A271C8A2D4B), // -2.40339491173441421878e+00\n qS2 = reinterpret(0x40002AE59C598AC8), // 2.02094576023350569471e+00\n qS3 = reinterpret(0xBFE6066C1B8D0159), // -6.88283971605453293030e-01\n qS4 = reinterpret(0x3FB3B8C5B12E9282); // 7.70381505559019352791e-02\n\n let p = z * (pS0 + z * (pS1 + z * (pS2 + z * (pS3 + z * (pS4 + z * pS5)))));\n let q = 1.0 + z * (qS1 + z * (qS2 + z * (qS3 + z * qS4)));\n return p / q;\n}\n\n/** @internal */\n// @ts-ignore: decorator\n@inline\nfunction expo2(x: f64, sign: f64): f64 { // exp(x)/2 for x >= log(DBL_MAX)\n const // see: musl/src/math/__expo2.c\n k = 2043,\n kln2 = reinterpret(0x40962066151ADD8B); // 0x1.62066151add8bp+10\n let scale = reinterpret(((0x3FF + k / 2) << 20) << 32);\n // in directed rounding correct sign before rounding or overflow is important\n return NativeMath.exp(x - kln2) * (sign * scale) * scale;\n}\n\n/** @internal */\n/* Helper function to eventually get bits of π/2 * |x|\n *\n * y = π/4 * (frac << clz(frac) >> 11)\n * return clz(frac)\n *\n * Right shift 11 bits to make upper half fit in `double`\n */\n// @ts-ignore: decorator\n@inline\nfunction pio2_right(q0: u64, q1: u64): u64 { // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c\n // Bits of π/4\n const p0: u64 = 0xC4C6628B80DC1CD1;\n const p1: u64 = 0xC90FDAA22168C234;\n\n const Ox1p_64 = reinterpret(0x3BF0000000000000); // 0x1p-64\n const Ox1p_75 = reinterpret(0x3B40000000000000); // 0x1p-75\n\n let shift = clz(q1);\n\n q1 = q1 << shift | q0 >> (64 - shift);\n q0 <<= shift;\n\n let lo = umuldi(p1, q1);\n let hi = res128_hi;\n\n let ahi = hi >> 11;\n let alo = lo >> 11 | hi << 53;\n let blo = (Ox1p_75 * p0 * q1 + Ox1p_75 * p1 * q0);\n\n rempio2_y0 = (ahi + u64(lo < blo));\n rempio2_y1 = Ox1p_64 * (alo + blo);\n\n return shift;\n}\n\n/** @internal */\n// @ts-ignore: decorator\n@inline\nfunction umuldi(u: u64, v: u64): u64 {\n let u1: u64 , v1: u64, w0: u64, w1: u64, t: u64;\n\n u1 = u & 0xFFFFFFFF;\n v1 = v & 0xFFFFFFFF;\n\n u >>= 32;\n v >>= 32;\n\n t = u1 * v1;\n w0 = t & 0xFFFFFFFF;\n t = u * v1 + (t >> 32);\n w1 = t >> 32;\n t = u1 * v + (t & 0xFFFFFFFF);\n\n res128_hi = u * v + w1 + (t >> 32);\n return (t << 32) + w0;\n}\n\n/** @internal */\nfunction pio2_large_quot(x: f64, u: i64): i32 { // see: jdh8/metallic/blob/master/src/math/double/rem_pio2.c\n let magnitude = u & 0x7FFFFFFFFFFFFFFF;\n let offset = (magnitude >> 52) - 1045;\n let shift = offset & 63;\n let tblPtr = PIO2_TABLE + ((offset >> 6) << 3);\n let s0: u64, s1: u64, s2: u64;\n\n let b0 = load(tblPtr, 0 << 3);\n let b1 = load(tblPtr, 1 << 3);\n let b2 = load(tblPtr, 2 << 3);\n\n // Get 192 bits of 0x1p-31 / π with `offset` bits skipped\n if (shift) {\n let rshift = 64 - shift;\n let b3 = load(tblPtr, 3 << 3);\n s0 = b1 >> rshift | b0 << shift;\n s1 = b2 >> rshift | b1 << shift;\n s2 = b3 >> rshift | b2 << shift;\n } else {\n s0 = b0;\n s1 = b1;\n s2 = b2;\n }\n\n let significand = (u & 0x000FFFFFFFFFFFFF) | 0x0010000000000000;\n\n // First 128 bits of fractional part of x/(2π)\n let blo = umuldi(s1, significand);\n let bhi = res128_hi;\n\n let ahi = s0 * significand;\n let clo = (s2 >> 32) * (significand >> 32);\n let plo = blo + clo;\n let phi = ahi + bhi + u64(plo < clo);\n\n // r: u128 = p << 2\n let rlo = plo << 2;\n let rhi = phi << 2 | plo >> 62;\n\n // s: i128 = r >> 127\n let slo = rhi >> 63;\n let shi = slo >> 1;\n let q = (phi >> 62) - slo;\n\n let shifter = 0x3CB0000000000000 - (pio2_right(rlo ^ slo, rhi ^ shi) << 52);\n let signbit = (u ^ rhi) & 0x8000000000000000;\n let coeff = reinterpret(shifter | signbit);\n\n rempio2_y0 *= coeff;\n rempio2_y1 *= coeff;\n\n return q;\n}\n\n/** @internal */\n// @ts-ignore: decorator\n@inline\nfunction rempio2(x: f64, u: u64, sign: i32): i32 {\n const\n pio2_1 = reinterpret(0x3FF921FB54400000), // 1.57079632673412561417e+00\n pio2_1t = reinterpret(0x3DD0B4611A626331), // 6.07710050650619224932e-11\n pio2_2 = reinterpret(0x3DD0B4611A600000), // 6.07710050630396597660e-11\n pio2_2t = reinterpret(0x3BA3198A2E037073), // 2.02226624879595063154e-21\n pio2_3 = reinterpret(0x3BA3198A2E000000), // 2.02226624871116645580e-21\n pio2_3t = reinterpret(0x397B839A252049C1), // 8.47842766036889956997e-32\n invpio2 = reinterpret(0x3FE45F306DC9C883); // 0.63661977236758134308\n\n let ix = (u >> 32) & 0x7FFFFFFF;\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (ix < 0x4002D97C) { // |x| < 3pi/4, special case with n=+-1\n let q = 1, z: f64, y0: f64, y1: f64;\n if (!sign) {\n z = x - pio2_1;\n if (ix != 0x3FF921FB) { // 33+53 bit pi is good enough\n y0 = z - pio2_1t;\n y1 = (z - y0) - pio2_1t;\n } else { // near pi/2, use 33+33+53 bit pi\n z -= pio2_2;\n y0 = z - pio2_2t;\n y1 = (z - y0) - pio2_2t;\n }\n } else { // negative x\n z = x + pio2_1;\n if (ix != 0x3FF921FB) { // 33+53 bit pi is good enough\n y0 = z + pio2_1t;\n y1 = (z - y0) + pio2_1t;\n } else { // near pi/2, use 33+33+53 bit pi\n z += pio2_2;\n y0 = z + pio2_2t;\n y1 = (z - y0) + pio2_2t;\n }\n q = -1;\n }\n rempio2_y0 = y0;\n rempio2_y1 = y1;\n return q;\n }\n }\n\n if (ix < 0x413921FB) { // |x| ~< 2^20*pi/2 (1647099)\n // Use precise Cody Waite scheme\n let q = nearest(x * invpio2);\n let r = x - q * pio2_1;\n let w = q * pio2_1t; // 1st round good to 85 bit\n let j = ix >> 20;\n let y0 = r - w;\n let hi = (reinterpret(y0) >> 32);\n let i = j - ((hi >> 20) & 0x7FF);\n\n if (i > 16) { // 2nd iteration needed, good to 118\n let t = r;\n w = q * pio2_2;\n r = t - w;\n w = q * pio2_2t - ((t - r) - w);\n y0 = r - w;\n hi = (reinterpret(y0) >> 32);\n i = j - ((hi >> 20) & 0x7FF);\n if (i > 49) { // 3rd iteration need, 151 bits acc\n let t = r;\n w = q * pio2_3;\n r = t - w;\n w = q * pio2_3t - ((t - r) - w);\n y0 = r - w;\n }\n }\n let y1 = (r - y0) - w;\n rempio2_y0 = y0;\n rempio2_y1 = y1;\n return q;\n }\n let q = pio2_large_quot(x, u);\n return select(-q, q, sign);\n}\n\n/** @internal */\n// @ts-ignore: decorator\n@inline\nfunction sin_kern(x: f64, y: f64, iy: i32): f64 { // see: musl/tree/src/math/__sin.c\n const\n S1 = reinterpret(0xBFC5555555555549), // -1.66666666666666324348e-01\n S2 = reinterpret(0x3F8111111110F8A6), // 8.33333333332248946124e-03\n S3 = reinterpret(0xBF2A01A019C161D5), // -1.98412698298579493134e-04\n S4 = reinterpret(0x3EC71DE357B1FE7D), // 2.75573137070700676789e-06\n S5 = reinterpret(0xBE5AE5E68A2B9CEB), // -2.50507602534068634195e-08\n S6 = reinterpret(0x3DE5D93A5ACFD57C); // 1.58969099521155010221e-10\n\n let z = x * x;\n let w = z * z;\n let r = S2 + z * (S3 + z * S4) + z * w * (S5 + z * S6);\n let v = z * x;\n if (!iy) {\n return x + v * (S1 + z * r);\n } else {\n return x - ((z * (0.5 * y - v * r) - y) - v * S1);\n }\n}\n\n/** @internal */\n// @ts-ignore: decorator\n@inline\nfunction cos_kern(x: f64, y: f64): f64 { // see: musl/tree/src/math/__cos.c\n const\n C1 = reinterpret(0x3FA555555555554C), // 4.16666666666666019037e-02\n C2 = reinterpret(0xBF56C16C16C15177), // -1.38888888888741095749e-03\n C3 = reinterpret(0x3EFA01A019CB1590), // 2.48015872894767294178e-05\n C4 = reinterpret(0xBE927E4F809C52AD), // -2.75573143513906633035e-07\n C5 = reinterpret(0x3E21EE9EBDB4B1C4), // 2.08757232129817482790e-09\n C6 = reinterpret(0xBDA8FAE9BE8838D4); // -1.13596475577881948265e-11\n\n let z = x * x;\n let w = z * z;\n let r = z * (C1 + z * (C2 + z * C3)) + w * w * (C4 + z * (C5 + z * C6));\n let hz = 0.5 * z;\n w = 1.0 - hz;\n return w + (((1.0 - w) - hz) + (z * r - x * y));\n}\n\n/** @internal */\nfunction tan_kern(x: f64, y: f64, iy: i32): f64 { // see: src/lib/msun/src/k_tan.c\n const\n T0 = reinterpret(0x3FD5555555555563), // 3.33333333333334091986e-01\n T1 = reinterpret(0x3FC111111110FE7A), // 1.33333333333201242699e-01\n T2 = reinterpret(0x3FABA1BA1BB341FE), // 5.39682539762260521377e-02\n T3 = reinterpret(0x3F9664F48406D637), // 2.18694882948595424599e-02\n T4 = reinterpret(0x3F8226E3E96E8493), // 8.86323982359930005737e-03\n T5 = reinterpret(0x3F6D6D22C9560328), // 3.59207910759131235356e-03\n T6 = reinterpret(0x3F57DBC8FEE08315), // 1.45620945432529025516e-03\n T7 = reinterpret(0x3F4344D8F2F26501), // 5.88041240820264096874e-04\n T8 = reinterpret(0x3F3026F71A8D1068), // 2.46463134818469906812e-04\n T9 = reinterpret(0x3F147E88A03792A6), // 7.81794442939557092300e-05\n T10 = reinterpret(0x3F12B80F32F0A7E9), // 7.14072491382608190305e-05\n T11 = reinterpret(0xBEF375CBDB605373), // -1.85586374855275456654e-05\n T12 = reinterpret(0x3EFB2A7074BF7AD4); // 2.59073051863633712884e-05\n\n const\n one = reinterpret(0x3FF0000000000000), // 1.00000000000000000000e+00\n pio4 = reinterpret(0x3FE921FB54442D18), // 7.85398163397448278999e-01\n pio4lo = reinterpret(0x3C81A62633145C07); // 3.06161699786838301793e-17\n\n let z: f64, r: f64, v: f64, w: f64, s: f64;\n let hx = (reinterpret(x) >> 32); // high word of x\n let ix = hx & 0x7FFFFFFF; // high word of |x|\n let big = ix >= 0x3FE59428;\n if (big) { // |x| >= 0.6744\n if (hx < 0) { x = -x, y = -y; }\n z = pio4 - x;\n w = pio4lo - y;\n x = z + w;\n y = 0.0;\n }\n z = x * x;\n w = z * z;\n r = T1 + w * (T3 + w * (T5 + w * (T7 + w * (T9 + w * T11))));\n v = z * (T2 + w * (T4 + w * (T6 + w * (T8 + w * (T10 + w * T12)))));\n s = z * x;\n r = y + z * (s * (r + v) + y);\n r += T0 * s;\n w = x + r;\n if (big) {\n v = iy;\n return (1 - ((hx >> 30) & 2)) * (v - 2.0 * (x - (w * w / (w + v) - r)));\n }\n if (iy == 1) return w;\n let a: f64, t: f64;\n z = w;\n z = reinterpret(reinterpret(z) & 0xFFFFFFFF00000000);\n v = r - (z - x); // z + v = r + x\n t = a = -one / w; // a = -1.0 / w\n t = reinterpret(reinterpret(t) & 0xFFFFFFFF00000000);\n s = one + t * z;\n return t + a * (s + t * v);\n}\n\n/** @internal */\nfunction dtoi32(x: f64): i32 {\n if (ASC_SHRINK_LEVEL > 0) {\n const inv32 = 1.0 / 4294967296;\n return (x - 4294967296 * floor(x * inv32));\n } else {\n let result = 0;\n let u = reinterpret(x);\n let e = (u >> 52) & 0x7FF;\n if (e <= 1023 + 30) {\n result = x;\n } else if (e <= 1023 + 30 + 53) {\n let v = (u & ((1 << 52) - 1)) | (1 << 52);\n v = v << e - 1023 - 52 + 32;\n result = (v >> 32);\n result = select(-result, result, u < 0);\n }\n return result;\n }\n}\n\n// @ts-ignore: decorator\n@lazy let random_seeded = false;\n\n// @ts-ignore: decorator\n@lazy let random_state0_64: u64, random_state1_64: u64;\n\n// @ts-ignore: decorator\n@lazy let random_state0_32: u32, random_state1_32: u32;\n\nfunction murmurHash3(h: u64): u64 { // Force all bits of a hash block to avalanche\n h ^= h >> 33; // see: https://github.com/aappleby/smhasher\n h *= 0xFF51AFD7ED558CCD;\n h ^= h >> 33;\n h *= 0xC4CEB9FE1A85EC53;\n h ^= h >> 33;\n return h;\n}\n\nfunction splitMix32(h: u32): u32 {\n h += 0x6D2B79F5;\n h = (h ^ (h >> 15)) * (h | 1);\n h ^= h + (h ^ (h >> 7)) * (h | 61);\n return h ^ (h >> 14);\n}\n\nexport namespace NativeMath {\n\n // @ts-ignore: decorator\n @lazy\n export const E = reinterpret(0x4005BF0A8B145769); // 2.7182818284590452354\n\n // @ts-ignore: decorator\n @lazy\n export const LN2 = reinterpret(0x3FE62E42FEFA39EF); // 0.69314718055994530942\n\n // @ts-ignore: decorator\n @lazy\n export const LN10 = reinterpret(0x40026BB1BBB55516); // 2.30258509299404568402\n\n // @ts-ignore: decorator\n @lazy\n export const LOG2E = reinterpret(0x3FF71547652B82FE); // 1.4426950408889634074\n\n // @ts-ignore: decorator\n @lazy\n export const LOG10E = reinterpret(0x3FDBCB7B1526E50E); // 0.43429448190325182765\n\n // @ts-ignore: decorator\n @lazy\n export const PI = reinterpret(0x400921FB54442D18); // 3.14159265358979323846\n\n // @ts-ignore: decorator\n @lazy\n export const SQRT1_2 = reinterpret(0x3FE6A09E667F3BCD); // 0.70710678118654752440\n\n // @ts-ignore: decorator\n @lazy\n export const SQRT2 = reinterpret(0x3FF6A09E667F3BCD); // 1.41421356237309504880\n\n // @ts-ignore: decorator\n @lazy\n export let sincos_sin: f64 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export let sincos_cos: f64 = 0;\n\n // @ts-ignore: decorator\n @inline export function abs(x: f64): f64 {\n return builtin_abs(x);\n }\n\n export function acos(x: f64): f64 { // see: musl/src/math/acos.c and SUN COPYRIGHT NOTICE above\n const\n pio2_hi = reinterpret(0x3FF921FB54442D18), // 1.57079632679489655800e+00\n pio2_lo = reinterpret(0x3C91A62633145C07), // 6.12323399573676603587e-17\n Ox1p_120f = reinterpret(0x03800000);\n\n let hx = (reinterpret(x) >> 32);\n let ix = hx & 0x7FFFFFFF;\n if (ix >= 0x3FF00000) {\n let lx = reinterpret(x);\n if ((ix - 0x3FF00000 | lx) == 0) {\n if (hx < 0) return 2 * pio2_hi + Ox1p_120f;\n return 0;\n }\n return 0 / (x - x);\n }\n if (ix < 0x3FE00000) {\n if (ix <= 0x3C600000) return pio2_hi + Ox1p_120f;\n return pio2_hi - (x - (pio2_lo - x * R(x * x)));\n }\n let s: f64, w: f64, z: f64;\n if (hx < 0) {\n // z = (1.0 + x) * 0.5;\n z = 0.5 + x * 0.5;\n s = builtin_sqrt(z);\n w = R(z) * s - pio2_lo;\n return 2 * (pio2_hi - (s + w));\n }\n // z = (1.0 - x) * 0.5;\n z = 0.5 - x * 0.5;\n s = builtin_sqrt(z);\n let df = reinterpret(reinterpret(s) & 0xFFFFFFFF00000000);\n let c = (z - df * df) / (s + df);\n w = R(z) * s + c;\n return 2 * (df + w);\n }\n\n export function acosh(x: f64): f64 { // see: musl/src/math/acosh.c\n const s = reinterpret(0x3FE62E42FEFA39EF);\n let u = reinterpret(x);\n // Prevent propagation for all input values less than 1.0.\n // Note musl lib didn't fix this yet.\n if (u < 0x3FF0000000000000) return (x - x) / 0.0;\n let e = u >> 52 & 0x7FF;\n if (e < 0x3FF + 1) return log1p(x - 1 + builtin_sqrt((x - 1) * (x - 1) + 2 * (x - 1)));\n if (e < 0x3FF + 26) return log(2 * x - 1 / (x + builtin_sqrt(x * x - 1)));\n return log(x) + s;\n }\n\n export function asin(x: f64): f64 { // see: musl/src/math/asin.c and SUN COPYRIGHT NOTICE above\n const\n pio2_hi = reinterpret(0x3FF921FB54442D18), // 1.57079632679489655800e+00\n pio2_lo = reinterpret(0x3C91A62633145C07), // 6.12323399573676603587e-17\n Ox1p_120f = reinterpret(0x03800000);\n\n let hx = (reinterpret(x) >> 32);\n let ix = hx & 0x7FFFFFFF;\n if (ix >= 0x3FF00000) {\n let lx = reinterpret(x);\n if ((ix - 0x3FF00000 | lx) == 0) return x * pio2_hi + Ox1p_120f;\n return 0 / (x - x);\n }\n if (ix < 0x3FE00000) {\n if (ix < 0x3E500000 && ix >= 0x00100000) return x;\n return x + x * R(x * x);\n }\n // let z = (1.0 - builtin_abs(x)) * 0.5;\n let z = 0.5 - builtin_abs(x) * 0.5;\n let s = builtin_sqrt(z);\n let r = R(z);\n if (ix >= 0x3FEF3333) x = pio2_hi - (2 * (s + s * r) - pio2_lo);\n else {\n let f = reinterpret(reinterpret(s) & 0xFFFFFFFF00000000);\n let c = (z - f * f) / (s + f);\n x = 0.5 * pio2_hi - (2 * s * r - (pio2_lo - 2 * c) - (0.5 * pio2_hi - 2 * f));\n }\n return select(-x, x, hx < 0);\n }\n\n export function asinh(x: f64): f64 { // see: musl/src/math/asinh.c\n const c = reinterpret(0x3FE62E42FEFA39EF); // 0.693147180559945309417232121458176568\n let u = reinterpret(x);\n let e = u >> 52 & 0x7FF;\n let y = reinterpret(u & 0x7FFFFFFFFFFFFFFF);\n if (e >= 0x3FF + 26) y = log(y) + c;\n else if (e >= 0x3FF + 1) y = log(2 * y + 1 / (builtin_sqrt(y * y + 1) + y));\n else if (e >= 0x3FF - 26) y = log1p(y + y * y / (builtin_sqrt(y * y + 1) + 1));\n return builtin_copysign(y, x);\n }\n\n export function atan(x: f64): f64 { // see musl/src/math/atan.c and SUN COPYRIGHT NOTICE above\n const\n atanhi0 = reinterpret(0x3FDDAC670561BB4F), // 4.63647609000806093515e-01\n atanhi1 = reinterpret(0x3FE921FB54442D18), // 7.85398163397448278999e-01\n atanhi2 = reinterpret(0x3FEF730BD281F69B), // 9.82793723247329054082e-01\n atanhi3 = reinterpret(0x3FF921FB54442D18), // 1.57079632679489655800e+00\n atanlo0 = reinterpret(0x3C7A2B7F222F65E2), // 2.26987774529616870924e-17\n atanlo1 = reinterpret(0x3C81A62633145C07), // 3.06161699786838301793e-17\n atanlo2 = reinterpret(0x3C7007887AF0CBBD), // 1.39033110312309984516e-17\n atanlo3 = reinterpret(0x3C91A62633145C07), // 6.12323399573676603587e-17\n aT0 = reinterpret(0x3FD555555555550D), // 3.33333333333329318027e-01\n aT1 = reinterpret(0xBFC999999998EBC4), // -1.99999999998764832476e-01\n aT2 = reinterpret(0x3FC24924920083FF), // 1.42857142725034663711e-01\n aT3 = reinterpret(0xBFBC71C6FE231671), // -1.11111104054623557880e-01,\n aT4 = reinterpret(0x3FB745CDC54C206E), // 9.09088713343650656196e-02\n aT5 = reinterpret(0xBFB3B0F2AF749A6D), // -7.69187620504482999495e-02\n aT6 = reinterpret(0x3FB10D66A0D03D51), // 6.66107313738753120669e-02\n aT7 = reinterpret(0xBFADDE2D52DEFD9A), // -5.83357013379057348645e-02\n aT8 = reinterpret(0x3FA97B4B24760DEB), // 4.97687799461593236017e-02\n aT9 = reinterpret(0xBFA2B4442C6A6C2F), // -3.65315727442169155270e-02\n aT10 = reinterpret(0x3F90AD3AE322DA11), // 1.62858201153657823623e-02\n Ox1p_120f = reinterpret(0x03800000);\n\n let ix = (reinterpret(x) >> 32);\n let sx = x;\n ix &= 0x7FFFFFFF;\n let z: f64;\n if (ix >= 0x44100000) {\n if (isNaN(x)) return x;\n z = atanhi3 + Ox1p_120f;\n return builtin_copysign(z, sx);\n }\n let id: i32;\n if (ix < 0x3FDC0000) {\n if (ix < 0x3E400000) return x;\n id = -1;\n } else {\n x = builtin_abs(x);\n if (ix < 0x3FF30000) {\n if (ix < 0x3FE60000) {\n id = 0;\n x = (2.0 * x - 1.0) / (2.0 + x);\n } else {\n id = 1;\n x = (x - 1.0) / (x + 1.0);\n }\n } else {\n if (ix < 0x40038000) {\n id = 2;\n x = (x - 1.5) / (1.0 + 1.5 * x);\n } else {\n id = 3;\n x = -1.0 / x;\n }\n }\n }\n z = x * x;\n let w = z * z;\n let s1 = z * (aT0 + w * (aT2 + w * (aT4 + w * (aT6 + w * (aT8 + w * aT10)))));\n let s2 = w * (aT1 + w * (aT3 + w * (aT5 + w * (aT7 + w * aT9))));\n let s3 = x * (s1 + s2);\n if (id < 0) return x - s3;\n switch (id) {\n case 0: { z = atanhi0 - ((s3 - atanlo0) - x); break; }\n case 1: { z = atanhi1 - ((s3 - atanlo1) - x); break; }\n case 2: { z = atanhi2 - ((s3 - atanlo2) - x); break; }\n case 3: { z = atanhi3 - ((s3 - atanlo3) - x); break; }\n default: unreachable();\n }\n return builtin_copysign(z, sx);\n }\n\n export function atanh(x: f64): f64 { // see: musl/src/math/atanh.c\n let u = reinterpret(x);\n let e = u >> 52 & 0x7FF;\n let y = builtin_abs(x);\n if (e < 0x3FF - 1) {\n if (e >= 0x3FF - 32) y = 0.5 * log1p(2 * y + 2 * y * y / (1 - y));\n } else {\n y = 0.5 * log1p(2 * (y / (1 - y)));\n }\n return builtin_copysign(y, x);\n }\n\n export function atan2(y: f64, x: f64): f64 { // see: musl/src/math/atan2.c and SUN COPYRIGHT NOTICE above\n const pi_lo = reinterpret(0x3CA1A62633145C07); // 1.2246467991473531772E-16\n if (isNaN(x) || isNaN(y)) return x + y;\n let u = reinterpret(x);\n let ix = (u >> 32);\n let lx = u;\n u = reinterpret(y);\n let iy = (u >> 32);\n let ly = u;\n if ((ix - 0x3FF00000 | lx) == 0) return atan(y);\n let m = ((iy >> 31) & 1) | ((ix >> 30) & 2);\n ix = ix & 0x7FFFFFFF;\n iy = iy & 0x7FFFFFFF;\n if ((iy | ly) == 0) {\n switch (m) {\n case 0:\n case 1: return y;\n case 2: return PI;\n case 3: return -PI;\n }\n }\n if ((ix | lx) == 0) return m & 1 ? -PI / 2 : PI / 2;\n if (ix == 0x7FF00000) {\n if (iy == 0x7FF00000) {\n let t = m & 2 ? 3 * PI / 4 : PI / 4;\n return m & 1 ? -t : t;\n } else {\n let t = m & 2 ? PI : 0;\n return m & 1 ? -t : t;\n }\n }\n let z: f64;\n if (ix + (64 << 20) < iy || iy == 0x7FF00000) return m & 1 ? -PI / 2 : PI / 2;\n if ((m & 2) && iy + (64 << 20) < ix) z = 0;\n else z = atan(builtin_abs(y / x));\n switch (m) {\n case 0: return z;\n case 1: return -z;\n case 2: return PI - (z - pi_lo);\n case 3: return (z - pi_lo) - PI;\n }\n unreachable();\n return 0;\n }\n\n export function cbrt(x: f64): f64 { // see: musl/src/math/cbrt.c and SUN COPYRIGHT NOTICE above\n const\n B1 = 715094163,\n B2 = 696219795,\n P0 = reinterpret(0x3FFE03E60F61E692), // 1.87595182427177009643\n P1 = reinterpret(0xBFFE28E092F02420), // -1.88497979543377169875\n P2 = reinterpret(0x3FF9F1604A49D6C2), // 1.621429720105354466140\n P3 = reinterpret(0xBFE844CBBEE751D9), // -0.758397934778766047437\n P4 = reinterpret(0x3FC2B000D4E4EDD7), // 0.145996192886612446982\n Ox1p54 = reinterpret(0x4350000000000000); // 0x1p54\n\n let u = reinterpret(x);\n let hx = (u >> 32) & 0x7FFFFFFF;\n if (hx >= 0x7FF00000) return x + x;\n if (hx < 0x00100000) {\n u = reinterpret(x * Ox1p54);\n hx = (u >> 32) & 0x7FFFFFFF;\n if (hx == 0) return x;\n hx = hx / 3 + B2;\n } else {\n hx = hx / 3 + B1;\n }\n u &= 1 << 63;\n u |= hx << 32;\n let t = reinterpret(u);\n let r = (t * t) * (t / x);\n t = t * ((P0 + r * (P1 + r * P2)) + ((r * r) * r) * (P3 + r * P4));\n t = reinterpret((reinterpret(t) + 0x80000000) & 0xFFFFFFFFC0000000);\n let s = t * t;\n r = x / s;\n r = (r - t) / (2 * t + r);\n t = t + t * r;\n return t;\n }\n\n // @ts-ignore: decorator\n @inline\n export function ceil(x: f64): f64 {\n return builtin_ceil(x);\n }\n\n export function clz32(x: f64): f64 {\n if (!isFinite(x)) return 32;\n /*\n * Wasm (MVP) and JS have different approaches for double->int conversions.\n *\n * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT\n * our float-point arguments before actual convertion to integers.\n */\n return builtin_clz(dtoi32(x));\n }\n\n export function cos(x: f64): f64 { // see: musl/src/math/cos.c\n let u = reinterpret(x);\n let ux = u32(u >> 32);\n let sign = ux >> 31;\n\n ux &= 0x7FFFFFFF;\n\n // |x| ~< pi/4\n if (ux <= 0x3FE921FB) {\n if (ux < 0x3E46A09E) { // |x| < 2**-27 * sqrt(2)\n return 1.0;\n }\n return cos_kern(x, 0);\n }\n\n // sin(Inf or NaN) is NaN\n if (ux >= 0x7FF00000) return x - x;\n\n // argument reduction needed\n let n = rempio2(x, u, sign);\n let y0 = rempio2_y0;\n let y1 = rempio2_y1;\n\n x = n & 1 ? sin_kern(y0, y1, 1) : cos_kern(y0, y1);\n return (n + 1) & 2 ? -x : x;\n }\n\n export function cosh(x: f64): f64 { // see: musl/src/math/cosh.c\n let u = reinterpret(x);\n u &= 0x7FFFFFFFFFFFFFFF;\n x = reinterpret(u);\n let w = (u >> 32);\n let t: f64;\n if (w < 0x3FE62E42) {\n if (w < 0x3FF00000 - (26 << 20)) return 1;\n t = expm1(x);\n // return 1 + t * t / (2 * (1 + t));\n return 1 + t * t / (2 + 2 * t);\n }\n if (w < 0x40862E42) {\n t = exp(x);\n return 0.5 * (t + 1 / t);\n }\n t = expo2(x, 1);\n return t;\n }\n\n export function exp(x: f64): f64 { // see: musl/src/math/exp.c and SUN COPYRIGHT NOTICE above\n if (ASC_SHRINK_LEVEL < 1) {\n return exp_lut(x);\n } else {\n const\n ln2hi = reinterpret(0x3FE62E42FEE00000), // 6.93147180369123816490e-01\n ln2lo = reinterpret(0x3DEA39EF35793C76), // 1.90821492927058770002e-10\n invln2 = reinterpret(0x3FF71547652B82FE), // 1.44269504088896338700e+00\n P1 = reinterpret(0x3FC555555555553E), // 1.66666666666666019037e-01\n P2 = reinterpret(0xBF66C16C16BEBD93), // -2.77777777770155933842e-03\n P3 = reinterpret(0x3F11566AAF25DE2C), // 6.61375632143793436117e-05\n P4 = reinterpret(0xBEBBBD41C5D26BF1), // -1.65339022054652515390e-06\n P5 = reinterpret(0x3E66376972BEA4D0), // 4.13813679705723846039e-08\n overflow = reinterpret(0x40862E42FEFA39EF), // 709.782712893383973096\n underflow = reinterpret(0xC0874910D52D3051), // -745.13321910194110842\n Ox1p1023 = reinterpret(0x7FE0000000000000); // 0x1p1023\n\n let hx = u32(reinterpret(x) >> 32);\n let sign = hx >> 31;\n hx &= 0x7FFFFFFF;\n if (hx >= 0x4086232B) {\n if (isNaN(x)) return x;\n if (x > overflow) return x * Ox1p1023;\n if (x < underflow) return 0;\n }\n let hi: f64, lo: f64 = 0;\n let k = 0;\n if (hx > 0x3FD62E42) {\n if (hx >= 0x3FF0A2B2) {\n k = i32(invln2 * x + builtin_copysign(0.5, x));\n } else {\n k = 1 - (sign << 1);\n }\n hi = x - k * ln2hi;\n lo = k * ln2lo;\n x = hi - lo;\n } else if (hx > 0x3E300000) {\n hi = x;\n } else return 1.0 + x;\n let xs = x * x;\n // let c = x - xp2 * (P1 + xp2 * (P2 + xp2 * (P3 + xp2 * (P4 + xp2 * P5))));\n let xq = xs * xs;\n let c = x - (xs * P1 + xq * ((P2 + xs * P3) + xq * (P4 + xs * P5)));\n let y = 1.0 + (x * c / (2 - c) - lo + hi);\n return k == 0 ? y : scalbn(y, k);\n }\n }\n\n export function exp2(x: f64): f64 {\n return exp2_lut(x);\n }\n\n export function expm1(x: f64): f64 { // see: musl/src/math/expm1.c and SUN COPYRIGHT NOTICE above\n const\n o_threshold = reinterpret(0x40862E42FEFA39EF), // 7.09782712893383973096e+02\n ln2_hi = reinterpret(0x3FE62E42FEE00000), // 6.93147180369123816490e-01\n ln2_lo = reinterpret(0x3DEA39EF35793C76), // 1.90821492927058770002e-10\n invln2 = reinterpret(0x3FF71547652B82FE), // 1.44269504088896338700e+00\n Q1 = reinterpret(0xBFA11111111110F4), // -3.33333333333331316428e-02\n Q2 = reinterpret(0x3F5A01A019FE5585), // 1.58730158725481460165e-03\n Q3 = reinterpret(0xBF14CE199EAADBB7), // -7.93650757867487942473e-05\n Q4 = reinterpret(0x3ED0CFCA86E65239), // 4.00821782732936239552e-06\n Q5 = reinterpret(0xBE8AFDB76E09C32D), // -2.01099218183624371326e-07\n Ox1p1023 = reinterpret(0x7FE0000000000000); // 0x1p1023\n\n let u = reinterpret(x);\n let hx = u32(u >> 32) & 0x7FFFFFFF;\n let sign = u32(u >> 63);\n let k = 0;\n if (hx >= 0x4043687A) {\n if (isNaN(x)) return x;\n if (sign) return -1;\n if (x > o_threshold) return x * Ox1p1023;\n }\n let c = 0.0, t: f64;\n if (hx > 0x3FD62E42) {\n k = select(\n 1 - (sign << 1),\n i32(invln2 * x + builtin_copysign(0.5, x)),\n hx < 0x3FF0A2B2\n );\n t = k;\n let hi = x - t * ln2_hi;\n let lo = t * ln2_lo;\n x = hi - lo;\n c = (hi - x) - lo;\n } else if (hx < 0x3C900000) return x;\n let hfx = 0.5 * x;\n let hxs = x * hfx;\n // let r1 = 1.0 + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));\n let hxq = hxs * hxs;\n let r1 = (1.0 + hxs * Q1) + hxq * ((Q2 + hxs * Q3) + hxq * (Q4 + hxs * Q5));\n t = 3.0 - r1 * hfx;\n let e = hxs * ((r1 - t) / (6.0 - x * t));\n if (k == 0) return x - (x * e - hxs);\n e = x * (e - c) - c;\n e -= hxs;\n if (k == -1) return 0.5 * (x - e) - 0.5;\n if (k == 1) {\n if (x < -0.25) return -2.0 * (e - (x + 0.5));\n return 1.0 + 2.0 * (x - e);\n }\n u = (0x3FF + k) << 52;\n let twopk = reinterpret(u);\n let y: f64;\n if (k < 0 || k > 56) {\n y = x - e + 1.0;\n if (k == 1024) y = y * 2.0 * Ox1p1023;\n else y = y * twopk;\n return y - 1.0;\n }\n u = (0x3FF - k) << 52;\n y = reinterpret(u);\n if (k < 20) y = (1 - y) - e;\n else y = 1 - (e + y);\n return (x + y) * twopk;\n }\n\n // @ts-ignore: decorator\n @inline\n export function floor(x: f64): f64 {\n return builtin_floor(x);\n }\n\n // @ts-ignore: decorator\n @inline\n export function fround(x: f64): f64 {\n return x;\n }\n\n export function hypot(x: f64, y: f64): f64 { // see: musl/src/math/hypot.c\n const\n SPLIT = reinterpret(0x41A0000000000000) + 1, // 0x1p27 + 1\n Ox1p700 = reinterpret(0x6BB0000000000000),\n Ox1p_700 = reinterpret(0x1430000000000000);\n\n let ux = reinterpret(x);\n let uy = reinterpret(y);\n ux &= 0x7FFFFFFFFFFFFFFF;\n uy &= 0x7FFFFFFFFFFFFFFF;\n if (ux < uy) {\n let ut = ux;\n ux = uy;\n uy = ut;\n }\n let ex = i32(ux >> 52);\n let ey = i32(uy >> 52);\n y = reinterpret(uy);\n if (ey == 0x7FF) return y;\n x = reinterpret(ux);\n if (ex == 0x7FF || uy == 0) return x;\n if (ex - ey > 64) return x + y;\n let z = 1.0;\n if (ex > 0x3FF + 510) {\n z = Ox1p700;\n x *= Ox1p_700;\n y *= Ox1p_700;\n } else if (ey < 0x3FF - 450) {\n z = Ox1p_700;\n x *= Ox1p700;\n y *= Ox1p700;\n }\n let c = x * SPLIT;\n let h = x - c + c;\n let l = x - h;\n let hx = x * x;\n let lx = h * h - hx + (2 * h + l) * l;\n c = y * SPLIT;\n h = y - c + c;\n l = y - h;\n let hy = y * y;\n let ly = h * h - hy + (2 * h + l) * l;\n return z * builtin_sqrt(ly + lx + hy + hx);\n }\n\n export function imul(x: f64, y: f64): f64 {\n /*\n * Wasm (MVP) and JS have different approaches for double->int conversions.\n *\n * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT\n * our float-point arguments before actual convertion to integers.\n */\n if (!isFinite(x + y)) return 0;\n return dtoi32(x) * dtoi32(y);\n }\n\n export function log(x: f64): f64 { // see: musl/src/math/log.c and SUN COPYRIGHT NOTICE above\n if (ASC_SHRINK_LEVEL < 1) {\n return log_lut(x);\n } else {\n const\n ln2_hi = reinterpret(0x3FE62E42FEE00000), // 6.93147180369123816490e-01\n ln2_lo = reinterpret(0x3DEA39EF35793C76), // 1.90821492927058770002e-10\n Lg1 = reinterpret(0x3FE5555555555593), // 6.666666666666735130e-01\n Lg2 = reinterpret(0x3FD999999997FA04), // 3.999999999940941908e-01\n Lg3 = reinterpret(0x3FD2492494229359), // 2.857142874366239149e-01\n Lg4 = reinterpret(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01\n Lg5 = reinterpret(0x3FC7466496CB03DE), // 1.818357216161805012e-01\n Lg6 = reinterpret(0x3FC39A09D078C69F), // 1.531383769920937332e-01\n Lg7 = reinterpret(0x3FC2F112DF3E5244), // 1.479819860511658591e-01\n Ox1p54 = reinterpret(0x4350000000000000); // 0x1p54\n\n let u = reinterpret(x);\n let hx = u32(u >> 32);\n let k = 0;\n let sign = hx >> 31;\n if (sign || hx < 0x00100000) {\n if (u << 1 == 0) return -1 / (x * x);\n if (sign) return (x - x) / 0.0;\n k -= 54;\n x *= Ox1p54;\n u = reinterpret(x);\n hx = u32(u >> 32);\n } else if (hx >= 0x7FF00000) {\n return x;\n } else if (hx == 0x3FF00000 && u << 32 == 0) {\n return 0;\n }\n hx += 0x3FF00000 - 0x3FE6A09E;\n k += (hx >> 20) - 0x3FF;\n hx = (hx & 0x000FFFFF) + 0x3FE6A09E;\n u = hx << 32 | (u & 0xFFFFFFFF);\n x = reinterpret(u);\n let f = x - 1.0;\n let hfsq = 0.5 * f * f;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));\n let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));\n let r = t2 + t1;\n let dk = k;\n return s * (hfsq + r) + dk * ln2_lo - hfsq + f + dk * ln2_hi;\n }\n }\n\n export function log10(x: f64): f64 { // see: musl/src/math/log10.c and SUN COPYRIGHT NOTICE above\n const\n ivln10hi = reinterpret(0x3FDBCB7B15200000), // 4.34294481878168880939e-01\n ivln10lo = reinterpret(0x3DBB9438CA9AADD5), // 2.50829467116452752298e-11\n log10_2hi = reinterpret(0x3FD34413509F6000), // 3.01029995663611771306e-01\n log10_2lo = reinterpret(0x3D59FEF311F12B36), // 3.69423907715893078616e-13\n Lg1 = reinterpret(0x3FE5555555555593), // 6.666666666666735130e-01\n Lg2 = reinterpret(0x3FD999999997FA04), // 3.999999999940941908e-01\n Lg3 = reinterpret(0x3FD2492494229359), // 2.857142874366239149e-01\n Lg4 = reinterpret(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01\n Lg5 = reinterpret(0x3FC7466496CB03DE), // 1.818357216161805012e-01\n Lg6 = reinterpret(0x3FC39A09D078C69F), // 1.531383769920937332e-01\n Lg7 = reinterpret(0x3FC2F112DF3E5244), // 1.479819860511658591e-01\n Ox1p54 = reinterpret(0x4350000000000000); // 0x1p54\n\n let u = reinterpret(x);\n let hx = u32(u >> 32);\n let k = 0;\n let sign = hx >> 31;\n if (sign || hx < 0x00100000) {\n if (u << 1 == 0) return -1 / (x * x);\n if (sign) return (x - x) / 0.0;\n k -= 54;\n x *= Ox1p54;\n u = reinterpret(x);\n hx = u32(u >> 32);\n } else if (hx >= 0x7FF00000) {\n return x;\n } else if (hx == 0x3FF00000 && u << 32 == 0) {\n return 0;\n }\n hx += 0x3FF00000 - 0x3FE6A09E;\n k += i32(hx >> 20) - 0x3FF;\n hx = (hx & 0x000FFFFF) + 0x3FE6A09E;\n u = hx << 32 | (u & 0xFFFFFFFF);\n x = reinterpret(u);\n let f = x - 1.0;\n let hfsq = 0.5 * f * f;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));\n let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));\n let r = t2 + t1;\n let hi = f - hfsq;\n u = reinterpret(hi);\n u &= 0xFFFFFFFF00000000;\n hi = reinterpret(u);\n let lo = f - hi - hfsq + s * (hfsq + r);\n let val_hi = hi * ivln10hi;\n let dk = k;\n let y = dk * log10_2hi;\n let val_lo = dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi;\n w = y + val_hi;\n val_lo += (y - w) + val_hi;\n return val_lo + w;\n }\n\n export function log1p(x: f64): f64 { // see: musl/src/math/log1p.c and SUN COPYRIGHT NOTICE above\n const\n ln2_hi = reinterpret(0x3FE62E42FEE00000), // 6.93147180369123816490e-01\n ln2_lo = reinterpret(0x3DEA39EF35793C76), // 1.90821492927058770002e-10\n Lg1 = reinterpret(0x3FE5555555555593), // 6.666666666666735130e-01\n Lg2 = reinterpret(0x3FD999999997FA04), // 3.999999999940941908e-01\n Lg3 = reinterpret(0x3FD2492494229359), // 2.857142874366239149e-01\n Lg4 = reinterpret(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01\n Lg5 = reinterpret(0x3FC7466496CB03DE), // 1.818357216161805012e-01\n Lg6 = reinterpret(0x3FC39A09D078C69F), // 1.531383769920937332e-01\n Lg7 = reinterpret(0x3FC2F112DF3E5244); // 1.479819860511658591e-01\n\n let u = reinterpret(x);\n let hx = u32(u >> 32);\n let k = 1;\n let c = 0.0, f = 0.0;\n if (hx < 0x3FDA827A || bool(hx >> 31)) {\n if (hx >= 0xBFF00000) {\n if (x == -1) return x / 0.0;\n return (x - x) / 0.0;\n }\n if (hx << 1 < 0x3CA00000 << 1) return x;\n if (hx <= 0xBFD2BEC4) {\n k = 0;\n c = 0;\n f = x;\n }\n } else if (hx >= 0x7FF00000) return x;\n if (k) {\n u = reinterpret(1 + x);\n let hu = u32(u >> 32);\n hu += 0x3FF00000 - 0x3FE6A09E;\n k = i32(hu >> 20) - 0x3FF;\n if (k < 54) {\n let uf = reinterpret(u);\n c = k >= 2 ? 1 - (uf - x) : x - (uf - 1);\n c /= uf;\n } else c = 0;\n hu = (hu & 0x000FFFFF) + 0x3FE6A09E;\n u = hu << 32 | (u & 0xFFFFFFFF);\n f = reinterpret(u) - 1;\n }\n let hfsq = 0.5 * f * f;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));\n let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));\n let r = t2 + t1;\n let dk = k;\n return s * (hfsq + r) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;\n }\n\n export function log2(x: f64): f64 { // see: musl/src/math/log2.c and SUN COPYRIGHT NOTICE above\n if (ASC_SHRINK_LEVEL < 1) {\n return log2_lut(x);\n } else {\n const\n ivln2hi = reinterpret(0x3FF7154765200000), // 1.44269504072144627571e+00\n ivln2lo = reinterpret(0x3DE705FC2EEFA200), // 1.67517131648865118353e-10\n Lg1 = reinterpret(0x3FE5555555555593), // 6.666666666666735130e-01\n Lg2 = reinterpret(0x3FD999999997FA04), // 3.999999999940941908e-01\n Lg3 = reinterpret(0x3FD2492494229359), // 2.857142874366239149e-01\n Lg4 = reinterpret(0x3FCC71C51D8E78AF), // 2.222219843214978396e-01\n Lg5 = reinterpret(0x3FC7466496CB03DE), // 1.818357216161805012e-01\n Lg6 = reinterpret(0x3FC39A09D078C69F), // 1.531383769920937332e-01\n Lg7 = reinterpret(0x3FC2F112DF3E5244), // 1.479819860511658591e-01\n Ox1p54 = reinterpret(0x4350000000000000); // 1p54\n\n let u = reinterpret(x);\n let hx = u32(u >> 32);\n let k = 0;\n let sign = hx >> 31;\n if (sign || hx < 0x00100000) {\n if (u << 1 == 0) return -1 / (x * x);\n if (sign) return (x - x) / 0.0;\n k -= 54;\n x *= Ox1p54;\n u = reinterpret(x);\n hx = u32(u >> 32);\n } else if (hx >= 0x7FF00000) {\n return x;\n } else if (hx == 0x3FF00000 && u << 32 == 0) {\n return 0;\n }\n hx += 0x3FF00000 - 0x3FE6A09E;\n k += i32(hx >> 20) - 0x3FF;\n hx = (hx & 0x000FFFFF) + 0x3FE6A09E;\n u = hx << 32 | (u & 0xFFFFFFFF);\n x = reinterpret(u);\n let f = x - 1.0;\n let hfsq = 0.5 * f * f;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * (Lg4 + w * Lg6));\n let t2 = z * (Lg1 + w * (Lg3 + w * (Lg5 + w * Lg7)));\n let r = t2 + t1;\n let hi = f - hfsq;\n u = reinterpret(hi);\n u &= 0xFFFFFFFF00000000;\n hi = reinterpret(u);\n let lo = f - hi - hfsq + s * (hfsq + r);\n let val_hi = hi * ivln2hi;\n let val_lo = (lo + hi) * ivln2lo + lo * ivln2hi;\n let y = k;\n w = y + val_hi;\n val_lo += (y - w) + val_hi;\n val_hi = w;\n return val_lo + val_hi;\n }\n }\n\n // @ts-ignore: decorator\n @inline\n export function max(value1: f64, value2: f64): f64 {\n return builtin_max(value1, value2);\n }\n\n // @ts-ignore: decorator\n @inline\n export function min(value1: f64, value2: f64): f64 {\n return builtin_min(value1, value2);\n }\n\n export function pow(x: f64, y: f64): f64 { // see: musl/src/math/pow.c and SUN COPYRIGHT NOTICE above\n // TODO: remove this fast pathes after introduced own mid-end IR with \"stdlib call simplify\" transforms\n if (builtin_abs(y) <= 2) {\n if (y == 2.0) return x * x;\n if (y == 0.5) {\n return select(\n builtin_abs(builtin_sqrt(x)),\n Infinity,\n x != -Infinity\n );\n }\n if (y == -1.0) return 1 / x;\n if (y == 1.0) return x;\n if (y == 0.0) return 1.0;\n }\n if (ASC_SHRINK_LEVEL < 1) {\n return pow_lut(x, y);\n } else {\n const\n dp_h1 = reinterpret(0x3FE2B80340000000), // 5.84962487220764160156e-01\n dp_l1 = reinterpret(0x3E4CFDEB43CFD006), // 1.35003920212974897128e-08\n two53 = reinterpret(0x4340000000000000), // 9007199254740992.0\n huge = reinterpret(0x7E37E43C8800759C), // 1e+300\n tiny = reinterpret(0x01A56E1FC2F8F359), // 1e-300\n L1 = reinterpret(0x3FE3333333333303), // 5.99999999999994648725e-01\n L2 = reinterpret(0x3FDB6DB6DB6FABFF), // 4.28571428578550184252e-01\n L3 = reinterpret(0x3FD55555518F264D), // 3.33333329818377432918e-01\n L4 = reinterpret(0x3FD17460A91D4101), // 2.72728123808534006489e-01\n L5 = reinterpret(0x3FCD864A93C9DB65), // 2.30660745775561754067e-01\n L6 = reinterpret(0x3FCA7E284A454EEF), // 2.06975017800338417784e-01\n P1 = reinterpret(0x3FC555555555553E), // 1.66666666666666019037e-01\n P2 = reinterpret(0xBF66C16C16BEBD93), // -2.77777777770155933842e-03\n P3 = reinterpret(0x3F11566AAF25DE2C), // 6.61375632143793436117e-05\n P4 = reinterpret(0xBEBBBD41C5D26BF1), // -1.65339022054652515390e-06\n P5 = reinterpret(0x3E66376972BEA4D0), // 4.13813679705723846039e-08\n lg2 = reinterpret(0x3FE62E42FEFA39EF), // 6.93147180559945286227e-01\n lg2_h = reinterpret(0x3FE62E4300000000), // 6.93147182464599609375e-01\n lg2_l = reinterpret(0xBE205C610CA86C39), // -1.90465429995776804525e-09\n ovt = reinterpret(0x3C971547652B82FE), // 8.0085662595372944372e-017\n cp = reinterpret(0x3FEEC709DC3A03FD), // 9.61796693925975554329e-01\n cp_h = reinterpret(0x3FEEC709E0000000), // 9.61796700954437255859e-01\n cp_l = reinterpret(0xBE3E2FE0145B01F5), // -7.02846165095275826516e-09\n ivln2 = reinterpret(0x3FF71547652B82FE), // 1.44269504088896338700e+00\n ivln2_h = reinterpret(0x3FF7154760000000), // 1.44269502162933349609e+00\n ivln2_l = reinterpret(0x3E54AE0BF85DDF44), // 1.92596299112661746887e-08\n inv3 = reinterpret(0x3FD5555555555555); // 0.3333333333333333333333\n\n let u_ = reinterpret(x);\n let hx = i32(u_ >> 32);\n let lx = u_;\n u_ = reinterpret(y);\n let hy = i32(u_ >> 32);\n let ly = u_;\n let ix = hx & 0x7FFFFFFF;\n let iy = hy & 0x7FFFFFFF;\n if ((iy | ly) == 0) return 1.0; // x**0 = 1, even if x is NaN\n // if (hx == 0x3FF00000 && lx == 0) return 1.0; // C: 1**y = 1, even if y is NaN, JS: NaN\n if ( // NaN if either arg is NaN\n ix > 0x7FF00000 || (ix == 0x7FF00000 && lx != 0) ||\n iy > 0x7FF00000 || (iy == 0x7FF00000 && ly != 0)\n ) return x + y;\n let yisint = 0, k: i32;\n if (hx < 0) {\n if (iy >= 0x43400000) yisint = 2;\n else if (iy >= 0x3FF00000) {\n k = (iy >> 20) - 0x3FF;\n let offset = select(52, 20, k > 20) - k;\n let Ly = select(ly, iy, k > 20);\n let jj = Ly >> offset;\n if ((jj << offset) == Ly) yisint = 2 - (jj & 1);\n }\n }\n if (ly == 0) {\n if (iy == 0x7FF00000) { // y is +-inf\n if (((ix - 0x3FF00000) | lx) == 0) return NaN; // C: (-1)**+-inf is 1, JS: NaN\n else if (ix >= 0x3FF00000) return hy >= 0 ? y : 0.0; // (|x|>1)**+-inf = inf,0\n else return hy >= 0 ? 0.0 : -y; // (|x|<1)**+-inf = 0,inf\n }\n if (iy == 0x3FF00000) {\n if (hy >= 0) return x;\n return 1 / x;\n }\n if (hy == 0x40000000) return x * x;\n if (hy == 0x3FE00000) {\n if (hx >= 0) return builtin_sqrt(x);\n }\n }\n let ax = builtin_abs(x), z: f64;\n if (lx == 0) {\n if (ix == 0 || ix == 0x7FF00000 || ix == 0x3FF00000) {\n z = ax;\n if (hy < 0) z = 1.0 / z;\n if (hx < 0) {\n if (((ix - 0x3FF00000) | yisint) == 0) {\n let d = z - z;\n z = d / d;\n } else if (yisint == 1) z = -z;\n }\n return z;\n }\n }\n let s = 1.0;\n if (hx < 0) {\n if (yisint == 0) {\n let d = x - x;\n return d / d;\n }\n if (yisint == 1) s = -1.0;\n }\n let t1: f64, t2: f64, p_h: f64, p_l: f64, r: f64, t: f64, u: f64, v: f64, w: f64;\n let j: i32, n: i32;\n if (iy > 0x41E00000) {\n if (iy > 0x43F00000) {\n if (ix <= 0x3FEFFFFF) return hy < 0 ? huge * huge : tiny * tiny;\n if (ix >= 0x3FF00000) return hy > 0 ? huge * huge : tiny * tiny;\n }\n if (ix < 0x3FEFFFFF) return hy < 0 ? s * huge * huge : s * tiny * tiny;\n if (ix > 0x3FF00000) return hy > 0 ? s * huge * huge : s * tiny * tiny;\n t = ax - 1.0;\n w = (t * t) * (0.5 - t * (inv3 - t * 0.25));\n u = ivln2_h * t;\n v = t * ivln2_l - w * ivln2;\n t1 = u + v;\n t1 = reinterpret(reinterpret(t1) & 0xFFFFFFFF00000000);\n t2 = v - (t1 - u);\n } else {\n let ss: f64, s2: f64, s_h: f64, s_l: f64, t_h: f64, t_l: f64;\n n = 0;\n if (ix < 0x00100000) {\n ax *= two53;\n n -= 53;\n ix = (reinterpret(ax) >> 32);\n }\n n += (ix >> 20) - 0x3FF;\n j = ix & 0x000FFFFF;\n ix = j | 0x3FF00000;\n if (j <= 0x3988E) k = 0;\n else if (j < 0xBB67A) k = 1;\n else {\n k = 0;\n n += 1;\n ix -= 0x00100000;\n }\n ax = reinterpret(reinterpret(ax) & 0xFFFFFFFF | (ix << 32));\n let bp = select(1.5, 1.0, k); // k ? 1.5 : 1.0\n u = ax - bp;\n v = 1.0 / (ax + bp);\n ss = u * v;\n s_h = ss;\n s_h = reinterpret(reinterpret(s_h) & 0xFFFFFFFF00000000);\n t_h = reinterpret(u64(((ix >> 1) | 0x20000000) + 0x00080000 + (k << 18)) << 32);\n t_l = ax - (t_h - bp);\n s_l = v * ((u - s_h * t_h) - s_h * t_l);\n s2 = ss * ss;\n r = s2 * s2 * (L1 + s2 * (L2 + s2 * (L3 + s2 * (L4 + s2 * (L5 + s2 * L6)))));\n r += s_l * (s_h + ss);\n s2 = s_h * s_h;\n t_h = 3.0 + s2 + r;\n t_h = reinterpret(reinterpret(t_h) & 0xFFFFFFFF00000000);\n t_l = r - ((t_h - 3.0) - s2);\n u = s_h * t_h;\n v = s_l * t_h + t_l * ss;\n p_h = u + v;\n p_h = reinterpret(reinterpret(p_h) & 0xFFFFFFFF00000000);\n p_l = v - (p_h - u);\n let z_h = cp_h * p_h;\n let dp_l = select(dp_l1, 0.0, k);\n let z_l = cp_l * p_h + p_l * cp + dp_l;\n t = n;\n let dp_h = select(dp_h1, 0.0, k);\n t1 = ((z_h + z_l) + dp_h) + t;\n t1 = reinterpret(reinterpret(t1) & 0xFFFFFFFF00000000);\n t2 = z_l - (((t1 - t) - dp_h) - z_h);\n }\n let y1 = y;\n y1 = reinterpret(reinterpret(y1) & 0xFFFFFFFF00000000);\n p_l = (y - y1) * t1 + y * t2;\n p_h = y1 * t1;\n z = p_l + p_h;\n u_ = reinterpret(z);\n j = u32(u_ >> 32);\n let i = u_;\n if (j >= 0x40900000) {\n if (((j - 0x40900000) | i) != 0) return s * huge * huge;\n if (p_l + ovt > z - p_h) return s * huge * huge;\n } else if ((j & 0x7FFFFFFF) >= 0x4090CC00) {\n if (((j - 0xC090CC00) | i) != 0) return s * tiny * tiny;\n if (p_l <= z - p_h) return s * tiny * tiny;\n }\n i = j & 0x7FFFFFFF;\n k = (i >> 20) - 0x3FF;\n n = 0;\n if (i > 0x3FE00000) {\n n = j + (0x00100000 >> (k + 1));\n k = ((n & 0x7FFFFFFF) >> 20) - 0x3FF;\n t = 0.0;\n t = reinterpret(u64(n & ~(0x000FFFFF >> k)) << 32);\n n = ((n & 0x000FFFFF) | 0x00100000) >> (20 - k);\n if (j < 0) n = -n;\n p_h -= t;\n }\n t = p_l + p_h;\n t = reinterpret(reinterpret(t) & 0xFFFFFFFF00000000);\n u = t * lg2_h;\n v = (p_l - (t - p_h)) * lg2 + t * lg2_l;\n z = u + v;\n w = v - (z - u);\n t = z * z;\n t1 = z - t * (P1 + t * (P2 + t * (P3 + t * (P4 + t * P5))));\n r = (z * t1) / (t1 - 2.0) - (w + z * w);\n z = 1.0 - (r - z);\n j = u32(reinterpret(z) >> 32);\n j += n << 20;\n if ((j >> 20) <= 0) z = scalbn(z, n);\n else z = reinterpret(reinterpret(z) & 0xFFFFFFFF | (j << 32));\n return s * z;\n }\n }\n\n export function seedRandom(value: i64): void {\n // Instead zero seed use golden ratio:\n // phi = (1 + sqrt(5)) / 2\n // trunc(2^64 / phi) = 0x9e3779b97f4a7c15\n if (value == 0) value = 0x9e3779b97f4a7c15;\n random_state0_64 = murmurHash3(value);\n random_state1_64 = murmurHash3(~random_state0_64);\n random_state0_32 = splitMix32(value);\n random_state1_32 = splitMix32(random_state0_32);\n random_seeded = true;\n }\n\n export function random(): f64 { // see: v8/src/base/utils/random-number-generator.cc\n if (!random_seeded) seedRandom(reinterpret(seed()));\n let s1 = random_state0_64;\n let s0 = random_state1_64;\n random_state0_64 = s0;\n s1 ^= s1 << 23;\n s1 ^= s1 >> 17;\n s1 ^= s0;\n s1 ^= s0 >> 26;\n random_state1_64 = s1;\n let r = (s0 >> 12) | 0x3FF0000000000000;\n return reinterpret(r) - 1;\n }\n\n export function round(x: f64): f64 {\n if (ASC_SHRINK_LEVEL > 0) {\n return builtin_ceil(x) - f64(builtin_ceil(x) - 0.5 > x);\n } else {\n let roundUp = builtin_ceil(x);\n return select(roundUp, roundUp - 1.0, roundUp - 0.5 <= x);\n }\n }\n\n export function sign(x: f64): f64 {\n if (ASC_SHRINK_LEVEL > 0) {\n return select(builtin_copysign(1, x), x, builtin_abs(x) > 0);\n } else {\n return select(1, select(-1, x, x < 0), x > 0);\n }\n }\n\n // @ts-ignore: decorator\n @inline\n export function signbit(x: f64): bool {\n return bool(reinterpret(x) >>> 63);\n }\n\n export function sin(x: f64): f64 { // see: musl/src/math/sin.c\n let u = reinterpret(x);\n let ux = u32(u >> 32);\n let sign = ux >> 31;\n\n ux &= 0x7FFFFFFF;\n\n // |x| ~< pi/4\n if (ux <= 0x3FE921FB) {\n if (ux < 0x3E500000) { // |x| < 2**-26\n return x;\n }\n return sin_kern(x, 0.0, 0);\n }\n\n // sin(Inf or NaN) is NaN\n if (ux >= 0x7FF00000) return x - x;\n\n // argument reduction needed\n let n = rempio2(x, u, sign);\n let y0 = rempio2_y0;\n let y1 = rempio2_y1;\n\n x = n & 1 ? cos_kern(y0, y1) : sin_kern(y0, y1, 1);\n return n & 2 ? -x : x;\n }\n\n export function sinh(x: f64): f64 { // see: musl/src/math/sinh.c\n let u = reinterpret(x) & 0x7FFFFFFFFFFFFFFF;\n let a = reinterpret(u);\n let w = u32(u >> 32);\n let h = builtin_copysign(0.5, x);\n if (w < 0x40862E42) {\n let t = expm1(a);\n if (w < 0x3FF00000) {\n if (w < 0x3FF00000 - (26 << 20)) return x;\n return h * (2 * t - t * t / (t + 1));\n }\n return h * (t + t / (t + 1));\n }\n return expo2(a, 2 * h);\n }\n\n // @ts-ignore: decorator\n @inline\n export function sqrt(x: f64): f64 {\n return builtin_sqrt(x);\n }\n\n export function tan(x: f64): f64 { // see: musl/src/math/tan.c\n let u = reinterpret(x);\n let ux = u32(u >> 32);\n let sign = ux >>> 31;\n\n ux &= 0x7FFFFFFF;\n\n // |x| ~< pi/4\n if (ux <= 0x3FE921FB) {\n if (ux < 0x3E400000) { // |x| < 2**-27\n return x;\n }\n return tan_kern(x, 0.0, 1);\n }\n\n // tan(Inf or NaN) is NaN\n if (ux >= 0x7FF00000) return x - x;\n\n let n = rempio2(x, u, sign);\n return tan_kern(rempio2_y0, rempio2_y1, 1 - ((n & 1) << 1));\n }\n\n export function tanh(x: f64): f64 { // see: musl/src/math/tanh.c\n let u = reinterpret(x);\n u &= 0x7FFFFFFFFFFFFFFF;\n let y = reinterpret(u);\n let w = u32(u >> 32);\n let t: f64;\n if (w > 0x3FE193EA) {\n if (w > 0x40340000) {\n t = 1 - 0 / y;\n } else {\n t = expm1(2 * y);\n t = 1 - 2 / (t + 2);\n }\n } else if (w > 0x3FD058AE) {\n t = expm1(2 * y);\n t = t / (t + 2);\n } else if (w >= 0x00100000) {\n t = expm1(-2 * y);\n t = -t / (t + 2);\n } else t = y;\n return builtin_copysign(t, x);\n }\n\n // @ts-ignore: decorator\n @inline\n export function trunc(x: f64): f64 {\n return builtin_trunc(x);\n }\n\n export function scalbn(x: f64, n: i32): f64 { // see: https://git.musl-libc.org/cgit/musl/tree/src/math/scalbn.c\n const\n Ox1p53 = reinterpret(0x4340000000000000),\n Ox1p1023 = reinterpret(0x7FE0000000000000),\n Ox1p_1022 = reinterpret(0x0010000000000000);\n\n let y = x;\n if (n > 1023) {\n y *= Ox1p1023;\n n -= 1023;\n if (n > 1023) {\n y *= Ox1p1023;\n n = builtin_min(n - 1023, 1023);\n }\n } else if (n < -1022) {\n // make sure final n < -53 to avoid double\n // rounding in the subnormal range\n y *= Ox1p_1022 * Ox1p53;\n n += 1022 - 53;\n if (n < -1022) {\n y *= Ox1p_1022 * Ox1p53;\n n = builtin_max(n + 1022 - 53, -1022);\n }\n }\n return y * reinterpret((0x3FF + n) << 52);\n }\n\n export function mod(x: f64, y: f64): f64 { // see: musl/src/math/fmod.c\n if (builtin_abs(y) == 1.0) {\n // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))\n // TODO: move this rule to compiler's optimization pass.\n // It could be apply for any x % C_pot, where \"C_pot\" is pow of two const.\n return builtin_copysign(x - builtin_trunc(x), x);\n }\n let ux = reinterpret(x);\n let uy = reinterpret(y);\n let ex = i64(ux >> 52 & 0x7FF);\n let ey = i64(uy >> 52 & 0x7FF);\n let sx = ux >> 63;\n let uy1 = uy << 1;\n if (uy1 == 0 || ex == 0x7FF || isNaN(y)) {\n let m = x * y;\n return m / m;\n }\n let ux1 = ux << 1;\n if (ux1 <= uy1) {\n return x * f64(ux1 != uy1);\n }\n if (!ex) {\n ex -= builtin_clz(ux << 12);\n ux <<= 1 - ex;\n } else {\n ux &= u64(-1) >> 12;\n ux |= 1 << 52;\n }\n if (!ey) {\n ey -= builtin_clz(uy << 12);\n uy <<= 1 - ey;\n } else {\n uy &= u64(-1) >> 12;\n uy |= 1 << 52;\n }\n while (ex > ey) {\n if (ux >= uy) {\n if (ux == uy) return 0 * x;\n ux -= uy;\n }\n ux <<= 1;\n --ex;\n }\n if (ux >= uy) {\n if (ux == uy) return 0 * x;\n ux -= uy;\n }\n // for (; !(ux >> 52); ux <<= 1) --ex;\n let shift = builtin_clz(ux << 11);\n ex -= shift;\n ux <<= shift;\n if (ex > 0) {\n ux -= 1 << 52;\n ux |= ex << 52;\n } else {\n ux >>= -ex + 1;\n }\n return reinterpret(ux | (sx << 63));\n }\n\n export function rem(x: f64, y: f64): f64 { // see: musl/src/math/remquo.c\n let ux = reinterpret(x);\n let uy = reinterpret(y);\n let ex = i64(ux >> 52 & 0x7FF);\n let ey = i64(uy >> 52 & 0x7FF);\n if (uy << 1 == 0 || ex == 0x7FF || isNaN(y)) {\n let m = x * y;\n return m / m;\n }\n if (ux << 1 == 0) return x;\n let uxi = ux;\n if (!ex) {\n ex -= builtin_clz(uxi << 12);\n uxi <<= 1 - ex;\n } else {\n uxi &= u64(-1) >> 12;\n uxi |= 1 << 52;\n }\n if (!ey) {\n ey -= builtin_clz(uy << 12);\n uy <<= 1 - ey;\n } else {\n uy &= u64(-1) >> 12;\n uy |= 1 << 52;\n }\n let q: u32 = 0;\n do {\n if (ex < ey) {\n if (ex + 1 == ey) break; // goto end\n return x;\n }\n while (ex > ey) {\n if (uxi >= uy) {\n uxi -= uy;\n ++q;\n }\n uxi <<= 1;\n q <<= 1;\n --ex;\n }\n if (uxi >= uy) {\n uxi -= uy;\n ++q;\n }\n if (uxi == 0) ex = -60;\n else {\n let shift = builtin_clz(uxi << 11);\n ex -= shift;\n uxi <<= shift;\n }\n break;\n } while (false);\n // end:\n if (ex > 0) {\n uxi -= 1 << 52;\n uxi |= ex << 52;\n } else {\n uxi >>= -ex + 1;\n }\n x = reinterpret(uxi);\n y = builtin_abs(y);\n let x2 = x + x;\n if (ex == ey || (ex + 1 == ey && (x2 > y || (x2 == y && (q & 1))))) {\n x -= y;\n // ++q;\n }\n return ux < 0 ? -x : x;\n }\n\n export function sincos(x: f64): void { // see: musl/tree/src/math/sincos.c\n let u = reinterpret(x);\n let ux = u32(u >> 32);\n let sign = ux >> 31;\n ux &= 0x7FFFFFFF;\n\n if (ux <= 0x3FE921FB) { // |x| ~<= π/4\n if (ux < 0x3E46A09E) { // if |x| < 2**-27 * sqrt(2)\n sincos_sin = x;\n sincos_cos = 1;\n return;\n }\n sincos_sin = sin_kern(x, 0, 0);\n sincos_cos = cos_kern(x, 0);\n return;\n }\n // sin(Inf or NaN) is NaN\n if (ux >= 0x7F800000) {\n let xx = x - x;\n sincos_sin = xx;\n sincos_cos = xx;\n return;\n }\n // general argument reduction needed\n let n = rempio2(x, u, sign);\n let y0 = rempio2_y0;\n let y1 = rempio2_y1;\n let s = sin_kern(y0, y1, 1);\n let c = cos_kern(y0, y1);\n let sin = s, cos = c;\n if (n & 1) {\n sin = c;\n cos = -s;\n }\n if (n & 2) {\n sin = -sin;\n cos = -cos;\n }\n sincos_sin = sin;\n sincos_cos = cos;\n }\n}\n\n// @ts-ignore: decorator\n@lazy let rempio2f_y: f64;\n\n// @ts-ignore: decorator\n@lazy @inline const PIO2F_TABLE = memory.data([\n 0xA2F9836E4E441529,\n 0xFC2757D1F534DDC0,\n 0xDB6295993C439041,\n 0xFE5163ABDEBBC561\n]);\n\nfunction Rf(z: f32): f32 { // Rational approximation of (asin(x)-x)/x^3\n const // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above\n pS0 = reinterpret(0x3E2AAA75), // 1.6666586697e-01f\n pS1 = reinterpret(0xBD2F13BA), // -4.2743422091e-02f\n pS2 = reinterpret(0xBC0DD36B), // -8.6563630030e-03f\n qS1 = reinterpret(0xBF34E5AE); // -7.0662963390e-01f\n\n let p = z * (pS0 + z * (pS1 + z * pS2));\n let q: f32 = 1 + z * qS1;\n return p / q;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction expo2f(x: f32, sign: f32): f32 { // exp(x)/2 for x >= log(DBL_MAX)\n const // see: musl/src/math/__expo2f.c\n k = 235,\n kln2 = reinterpret(0x4322E3BC); // 0x1.45c778p+7f\n let scale = reinterpret(u32(0x7F + (k >> 1)) << 23);\n // in directed rounding correct sign before rounding or overflow is important\n return NativeMathf.exp(x - kln2) * (sign * scale) * scale;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction pio2f_large_quot(x: f32, u: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c\n const coeff = reinterpret(0x3BF921FB54442D18); // π * 0x1p-65 = 8.51530395021638647334e-20\n\n let offset = (u >> 23) - 152;\n let shift = u64(offset & 63);\n let tblPtr = PIO2F_TABLE + (offset >> 6 << 3);\n\n let b0 = load(tblPtr, 0 << 3);\n let b1 = load(tblPtr, 1 << 3);\n let lo: u64;\n\n if (shift > 32) {\n let b2 = load(tblPtr, 2 << 3);\n lo = b2 >> (96 - shift);\n lo |= b1 << (shift - 32);\n } else {\n lo = b1 >> (32 - shift);\n }\n\n let hi = (b1 >> (64 - shift)) | (b0 << shift);\n let mantissa: u64 = (u & 0x007FFFFF) | 0x00800000;\n let product = mantissa * hi + (mantissa * lo >> 32);\n let r: i64 = product << 2;\n let q = i32((product >> 62) + (r >>> 63));\n rempio2f_y = copysign(coeff, x) * r;\n return q;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction rempio2f(x: f32, u: u32, sign: i32): i32 { // see: jdh8/metallic/blob/master/src/math/float/rem_pio2f.c\n const\n pi2hi = reinterpret(0x3FF921FB50000000), // 1.57079631090164184570\n pi2lo = reinterpret(0x3E5110B4611A6263), // 1.58932547735281966916e-8\n _2_pi = reinterpret(0x3FE45F306DC9C883); // 0.63661977236758134308\n\n if (u < 0x4DC90FDB) { // π * 0x1p28\n let q = nearest(x * _2_pi);\n rempio2f_y = x - q * pi2hi - q * pi2lo;\n return q;\n }\n\n let q = pio2f_large_quot(x, u);\n return select(-q, q, sign);\n}\n\n// |sin(x)/x - s(x)| < 2**-37.5 (~[-4.89e-12, 4.824e-12]).\n// @ts-ignore: decorator\n@inline\nfunction sin_kernf(x: f64): f32 { // see: musl/tree/src/math/__sindf.c\n const\n S1 = reinterpret(0xBFC5555554CBAC77), // -0x15555554cbac77.0p-55\n S2 = reinterpret(0x3F811110896EFBB2), // 0x111110896efbb2.0p-59\n S3 = reinterpret(0xBF2A00F9E2CAE774), // -0x1a00f9e2cae774.0p-65\n S4 = reinterpret(0x3EC6CD878C3B46A7); // 0x16cd878c3b46a7.0p-71\n\n let z = x * x;\n let w = z * z;\n let r = S3 + z * S4;\n let s = z * x;\n return f32((x + s * (S1 + z * S2)) + s * w * r);\n}\n\n// |cos(x) - c(x)| < 2**-34.1 (~[-5.37e-11, 5.295e-11]).\n// @ts-ignore: decorator\n@inline\nfunction cos_kernf(x: f64): f32 { // see: musl/tree/src/math/__cosdf.c\n const\n C0 = reinterpret(0xBFDFFFFFFD0C5E81), // -0x1ffffffd0c5e81.0p-54\n C1 = reinterpret(0x3FA55553E1053A42), // 0x155553e1053a42.0p-57\n C2 = reinterpret(0xBF56C087E80F1E27), // -0x16c087e80f1e27.0p-62\n C3 = reinterpret(0x3EF99342E0EE5069); // 0x199342e0ee5069.0p-68\n\n let z = x * x;\n let w = z * z;\n let r = C2 + z * C3;\n return f32(((1 + z * C0) + w * C1) + (w * z) * r);\n}\n\n// |tan(x)/x - t(x)| < 2**-25.5 (~[-2e-08, 2e-08]).\n// @ts-ignore: decorator\n@inline\nfunction tan_kernf(x: f64, odd: i32): f32 { // see: musl/tree/src/math/__tandf.c\n const\n T0 = reinterpret(0x3FD5554D3418C99F), // 0x15554d3418c99f.0p-54\n T1 = reinterpret(0x3FC112FD38999F72), // 0x1112fd38999f72.0p-55\n T2 = reinterpret(0x3FAB54C91D865AFE), // 0x1b54c91d865afe.0p-57\n T3 = reinterpret(0x3F991DF3908C33CE), // 0x191df3908c33ce.0p-58\n T4 = reinterpret(0x3F685DADFCECF44E), // 0x185dadfcecf44e.0p-61\n T5 = reinterpret(0x3F8362B9BF971BCD); // 0x1362b9bf971bcd.0p-59\n\n let z = x * x;\n let r = T4 + z * T5;\n let t = T2 + z * T3;\n let w = z * z;\n let s = z * x;\n let u = T0 + z * T1;\n\n r = (x + s * u) + (s * w) * (t + w * r);\n return f32(odd ? -1 / r : r);\n}\n\n// See: jdh8/metallic/src/math/float/log2f.c and jdh8/metallic/src/math/float/kernel/atanh.h\n// @ts-ignore: decorator\n@inline\nfunction log2f(x: f64): f64 {\n const\n log2e = reinterpret(0x3FF71547652B82FE), // 1.44269504088896340736\n c0 = reinterpret(0x3FD555554FD9CAEF), // 0.33333332822728226129\n c1 = reinterpret(0x3FC999A7A8AF4132), // 0.20000167595436263505\n c2 = reinterpret(0x3FC2438D79437030), // 0.14268654271188685375\n c3 = reinterpret(0x3FBE2F663B001C97); // 0.11791075649681414150\n\n let i = reinterpret(x);\n let exponent = (i - 0x3FE6A09E667F3BCD) >> 52;\n x = reinterpret(i - (exponent << 52));\n x = (x - 1) / (x + 1);\n let xx = x * x;\n let y = x + x * xx * (c0 + c1 * xx + (c2 + c3 * xx) * (xx * xx));\n return (2 * log2e) * y + exponent;\n}\n\n// See: jdh8/metallic/src/math/float/exp2f.h and jdh8/metallic/blob/master/src/math/float/kernel/exp2f.h\n// @ts-ignore: decorator\n@inline\nfunction exp2f(x: f64): f64 {\n const\n c0 = reinterpret(0x3FE62E4302FCC24A), // 6.931471880289532425e-1\n c1 = reinterpret(0x3FCEBFBE07D97B91), // 2.402265108421173406e-1\n c2 = reinterpret(0x3FAC6AF6CCFC1A65), // 5.550357105498874537e-2\n c3 = reinterpret(0x3F83B29E3CE9AEF6), // 9.618030771171497658e-3\n c4 = reinterpret(0x3F55F0896145A89F), // 1.339086685300950937e-3\n c5 = reinterpret(0x3F2446C81E384864); // 1.546973499989028719e-4\n\n if (x < -1022) return 0;\n if (x >= 1024) return Infinity;\n\n let n = nearest(x);\n x -= n;\n let xx = x * x;\n let y = 1 + x * (c0 + c1 * x + (c2 + c3 * x) * xx + (c4 + c5 * x) * (xx * xx));\n return reinterpret(reinterpret(y) + (n << 52));\n}\n\nexport namespace NativeMathf {\n\n // @ts-ignore: decorator\n @lazy\n export const E = NativeMath.E;\n\n // @ts-ignore: decorator\n @lazy\n export const LN2 = NativeMath.LN2;\n\n // @ts-ignore: decorator\n @lazy\n export const LN10 = NativeMath.LN10;\n\n // @ts-ignore: decorator\n @lazy\n export const LOG2E = NativeMath.LOG2E;\n\n // @ts-ignore: decorator\n @lazy\n export const LOG10E = NativeMath.LOG10E;\n\n // @ts-ignore: decorator\n @lazy\n export const PI = NativeMath.PI;\n\n // @ts-ignore: decorator\n @lazy\n export const SQRT1_2 = NativeMath.SQRT1_2;\n\n // @ts-ignore: decorator\n @lazy\n export const SQRT2 = NativeMath.SQRT2;\n\n // @ts-ignore: decorator\n @lazy\n export let sincos_sin: f32 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export let sincos_cos: f32 = 0;\n\n // @ts-ignore: decorator\n @inline\n export function abs(x: f32): f32 {\n return builtin_abs(x);\n }\n\n export function acos(x: f32): f32 { // see: musl/src/math/acosf.c and SUN COPYRIGHT NOTICE above\n const\n pio2_hi = reinterpret(0x3FC90FDA), // 1.5707962513e+00f\n pio2_lo = reinterpret(0x33A22168), // 7.5497894159e-08f\n Ox1p_120f = reinterpret(0x03800000); // 0x1p-120f\n\n let hx = reinterpret(x);\n let ix = hx & 0x7FFFFFFF;\n if (ix >= 0x3F800000) {\n if (ix == 0x3F800000) {\n return select(2 * pio2_hi + Ox1p_120f, 0, hx < 0);\n }\n return 0 / (x - x);\n }\n if (ix < 0x3F000000) {\n if (ix <= 0x32800000) return pio2_hi + Ox1p_120f;\n return pio2_hi - (x - (pio2_lo - x * Rf(x * x)));\n }\n let z: f32, w: f32, s: f32;\n if (hx < 0) {\n // z = (1 + x) * 0.5;\n z = 0.5 + x * 0.5;\n s = builtin_sqrt(z);\n w = Rf(z) * s - pio2_lo;\n return 2 * (pio2_hi - (s + w));\n }\n // z = (1 - x) * 0.5;\n z = 0.5 - x * 0.5;\n s = builtin_sqrt(z);\n hx = reinterpret(s);\n let df = reinterpret(hx & 0xFFFFF000);\n let c = (z - df * df) / (s + df);\n w = Rf(z) * s + c;\n return 2 * (df + w);\n }\n\n export function acosh(x: f32): f32 { // see: musl/src/math/acoshf.c\n const s = reinterpret(0x3F317218); // 0.693147180559945309417232121458176568f\n let u = reinterpret(x);\n let a = u & 0x7FFFFFFF;\n if (a < 0x3F800000 + (1 << 23)) { // |x| < 2, invalid if x < 1\n let xm1 = x - 1;\n return log1p(xm1 + builtin_sqrt(xm1 * (xm1 + 2)));\n }\n if (u < 0x3F800000 + (12 << 23)) { // 2 <= x < 0x1p12\n return log(2 * x - 1 / (x + builtin_sqrt(x * x - 1)));\n }\n // x >= 0x1p12 or x <= -2 or NaN\n return log(x) + s;\n }\n\n export function asin(x: f32): f32 { // see: musl/src/math/asinf.c and SUN COPYRIGHT NOTICE above\n const\n pio2 = reinterpret(0x3FC90FDB), // 1.570796326794896558e+00f\n Ox1p_120f = reinterpret(0x03800000); // 0x1p-120f\n\n let sx = x;\n let hx = reinterpret(x) & 0x7FFFFFFF;\n if (hx >= 0x3F800000) {\n if (hx == 0x3F800000) return x * pio2 + Ox1p_120f;\n return 0 / (x - x);\n }\n if (hx < 0x3F000000) {\n if (hx < 0x39800000 && hx >= 0x00800000) return x;\n return x + x * Rf(x * x);\n }\n // let z: f32 = (1 - builtin_abs(x)) * 0.5;\n let z: f32 = 0.5 - builtin_abs(x) * 0.5;\n let s = builtin_sqrt(z); // sic\n x = f32(pio2 - 2 * (s + s * Rf(z)));\n return builtin_copysign(x, sx);\n }\n\n export function asinh(x: f32): f32 { // see: musl/src/math/asinhf.c\n const c = reinterpret(0x3F317218); // 0.693147180559945309417232121458176568f\n let u = reinterpret(x) & 0x7FFFFFFF;\n let y = reinterpret(u);\n if (u >= 0x3F800000 + (12 << 23)) y = log(y) + c;\n else if (u >= 0x3F800000 + (1 << 23)) y = log(2 * y + 1 / (builtin_sqrt(y * y + 1) + y));\n else if (u >= 0x3F800000 - (12 << 23)) y = log1p(y + y * y / (builtin_sqrt(y * y + 1) + 1));\n return builtin_copysign(y, x);\n }\n\n export function atan(x: f32): f32 { // see: musl/src/math/atanf.c and SUN COPYRIGHT NOTICE above\n const\n atanhi0 = reinterpret(0x3EED6338), // 4.6364760399e-01f\n atanhi1 = reinterpret(0x3F490FDA), // 7.8539812565e-01f\n atanhi2 = reinterpret(0x3F7B985E), // 9.8279368877e-01f\n atanhi3 = reinterpret(0x3FC90FDA), // 1.5707962513e+00f\n atanlo0 = reinterpret(0x31AC3769), // 5.0121582440e-09f\n atanlo1 = reinterpret(0x33222168), // 3.7748947079e-08f\n atanlo2 = reinterpret(0x33140FB4), // 3.4473217170e-08f\n atanlo3 = reinterpret(0x33A22168), // 7.5497894159e-08f\n aT0 = reinterpret(0x3EAAAAA9), // 3.3333328366e-01f\n aT1 = reinterpret(0xBE4CCA98), // -1.9999158382e-01f\n aT2 = reinterpret(0x3E11F50D), // 1.4253635705e-01f\n aT3 = reinterpret(0xBDDA1247), // -1.0648017377e-01f\n aT4 = reinterpret(0x3D7CAC25), // 6.1687607318e-02f\n Ox1p_120f = reinterpret(0x03800000); // 0x1p-120f\n\n let ix = reinterpret(x);\n let sx = x;\n ix &= 0x7FFFFFFF;\n let z: f32;\n if (ix >= 0x4C800000) {\n if (isNaN(x)) return x;\n z = atanhi3 + Ox1p_120f;\n return builtin_copysign(z, sx);\n }\n let id: i32;\n if (ix < 0x3EE00000) {\n if (ix < 0x39800000) return x;\n id = -1;\n } else {\n x = builtin_abs(x);\n if (ix < 0x3F980000) {\n if (ix < 0x3F300000) {\n id = 0;\n x = (2.0 * x - 1.0) / (2.0 + x);\n } else {\n id = 1;\n x = (x - 1.0) / (x + 1.0);\n }\n } else {\n if (ix < 0x401C0000) {\n id = 2;\n x = (x - 1.5) / (1.0 + 1.5 * x);\n } else {\n id = 3;\n x = -1.0 / x;\n }\n }\n }\n z = x * x;\n let w = z * z;\n let s1 = z * (aT0 + w * (aT2 + w * aT4));\n let s2 = w * (aT1 + w * aT3);\n let s3 = x * (s1 + s2);\n if (id < 0) return x - s3;\n switch (id) {\n case 0: { z = atanhi0 - ((s3 - atanlo0) - x); break; }\n case 1: { z = atanhi1 - ((s3 - atanlo1) - x); break; }\n case 2: { z = atanhi2 - ((s3 - atanlo2) - x); break; }\n case 3: { z = atanhi3 - ((s3 - atanlo3) - x); break; }\n default: unreachable();\n }\n return builtin_copysign(z, sx);\n }\n\n export function atanh(x: f32): f32 { // see: musl/src/math/atanhf.c\n let u = reinterpret(x);\n let y = builtin_abs(x);\n if (u < 0x3F800000 - (1 << 23)) {\n if (u >= 0x3F800000 - (32 << 23)) y = 0.5 * log1p(2 * y * (1.0 + y / (1 - y)));\n } else y = 0.5 * log1p(2 * (y / (1 - y)));\n return builtin_copysign(y, x);\n }\n\n export function atan2(y: f32, x: f32): f32 { // see: musl/src/math/atan2f.c and SUN COPYRIGHT NOTICE above\n const\n pi = reinterpret(0x40490FDB), // 3.1415927410e+00f\n pi_lo = reinterpret(0xB3BBBD2E); // -8.7422776573e-08f\n\n if (isNaN(x) || isNaN(y)) return x + y;\n let ix = reinterpret(x);\n let iy = reinterpret(y);\n if (ix == 0x3F800000) return atan(y);\n let m = u32(((iy >> 31) & 1) | ((ix >> 30) & 2));\n ix &= 0x7FFFFFFF;\n iy &= 0x7FFFFFFF;\n if (iy == 0) {\n switch (m) {\n case 0:\n case 1: return y;\n case 2: return pi;\n case 3: return -pi;\n }\n }\n if (ix == 0) return m & 1 ? -pi / 2 : pi / 2;\n if (ix == 0x7F800000) {\n if (iy == 0x7F800000) {\n let t: f32 = m & 2 ? 3 * pi / 4 : pi / 4;\n return m & 1 ? -t : t;\n } else {\n let t: f32 = m & 2 ? pi : 0.0;\n return m & 1 ? -t : t;\n }\n }\n if (ix + (26 << 23) < iy || iy == 0x7F800000) return m & 1 ? -pi / 2 : pi / 2;\n let z: f32;\n if ((m & 2) && iy + (26 << 23) < ix) z = 0.0;\n else z = atan(builtin_abs(y / x));\n switch (m) {\n case 0: return z;\n case 1: return -z;\n case 2: return pi - (z - pi_lo);\n case 3: return (z - pi_lo) - pi;\n }\n unreachable();\n return 0;\n }\n\n export function cbrt(x: f32): f32 { // see: musl/src/math/cbrtf.c and SUN COPYRIGHT NOTICE above\n const\n B1 = 709958130,\n B2 = 642849266,\n Ox1p24f = reinterpret(0x4B800000);\n\n let u = reinterpret(x);\n let hx = u & 0x7FFFFFFF;\n if (hx >= 0x7F800000) return x + x;\n if (hx < 0x00800000) {\n if (hx == 0) return x;\n u = reinterpret(x * Ox1p24f);\n hx = u & 0x7FFFFFFF;\n hx = hx / 3 + B2;\n } else {\n hx = hx / 3 + B1;\n }\n u &= 0x80000000;\n u |= hx;\n let t = reinterpret(u);\n let r = t * t * t;\n t = t * (x + x + r) / (x + r + r);\n r = t * t * t;\n t = t * (x + x + r) / (x + r + r);\n return t;\n }\n\n // @ts-ignore: decorator\n @inline\n export function ceil(x: f32): f32 {\n return builtin_ceil(x);\n }\n\n export function clz32(x: f32): f32 {\n if (!isFinite(x)) return 32;\n return builtin_clz(dtoi32(x));\n }\n\n export function cos(x: f32): f32 { // see: musl/src/math/cosf.c\n const\n c1pio2 = reinterpret(0x3FF921FB54442D18), // M_PI_2 * 1\n c2pio2 = reinterpret(0x400921FB54442D18), // M_PI_2 * 2\n c3pio2 = reinterpret(0x4012D97C7F3321D2), // M_PI_2 * 3\n c4pio2 = reinterpret(0x401921FB54442D18); // M_PI_2 * 4\n\n let ux = reinterpret(x);\n let sign = ux >> 31;\n ux &= 0x7FFFFFFF;\n\n if (ux <= 0x3F490FDA) { // |x| ~<= π/4\n if (ux < 0x39800000) { // |x| < 2**-12\n // raise inexact if x != 0\n return 1;\n }\n return cos_kernf(x);\n }\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (ux <= 0x407B53D1) { // |x| ~<= 5π/4\n if (ux > 0x4016CBE3) { // |x| ~> 3π/4\n return -cos_kernf(sign ? x + c2pio2 : x - c2pio2);\n } else {\n return sign ? sin_kernf(x + c1pio2) : sin_kernf(c1pio2 - x);\n }\n }\n if (ux <= 0x40E231D5) { // |x| ~<= 9π/4\n if (ux > 0x40AFEDDF) { // |x| ~> 7π/4\n return cos_kernf(sign ? x + c4pio2 : x - c4pio2);\n } else {\n return sign ? sin_kernf(-x - c3pio2) : sin_kernf(x - c3pio2);\n }\n }\n }\n\n // cos(Inf or NaN) is NaN\n if (ux >= 0x7F800000) return x - x;\n\n // general argument reduction needed\n let n = rempio2f(x, ux, sign);\n let y = rempio2f_y;\n\n let t = n & 1 ? sin_kernf(y) : cos_kernf(y);\n return (n + 1) & 2 ? -t : t;\n }\n\n export function cosh(x: f32): f32 { // see: musl/src/math/coshf.c\n let u = reinterpret(x);\n u &= 0x7FFFFFFF;\n x = reinterpret(u);\n if (u < 0x3F317217) {\n if (u < 0x3F800000 - (12 << 23)) return 1;\n let t = expm1(x);\n // return 1 + t * t / (2 * (1 + t));\n return 1 + t * t / (2 + 2 * t);\n }\n if (u < 0x42B17217) {\n let t = exp(x);\n // return 0.5 * (t + 1 / t);\n return 0.5 * t + 0.5 / t;\n }\n return expo2f(x, 1);\n }\n\n // @ts-ignore: decorator\n @inline\n export function floor(x: f32): f32 {\n return builtin_floor(x);\n }\n\n export function exp(x: f32): f32 { // see: musl/src/math/expf.c and SUN COPYRIGHT NOTICE above\n if (ASC_SHRINK_LEVEL < 1) {\n return expf_lut(x);\n } else {\n const\n ln2hi = reinterpret(0x3F317200), // 6.9314575195e-1f\n ln2lo = reinterpret(0x35BFBE8E), // 1.4286067653e-6f\n invln2 = reinterpret(0x3FB8AA3B), // 1.4426950216e+0f\n P1 = reinterpret(0x3E2AAA8F), // 1.6666625440e-1f\n P2 = reinterpret(0xBB355215), // -2.7667332906e-3f\n Ox1p127f = reinterpret(0x7F000000); // 0x1p+127f\n\n let hx = reinterpret(x);\n let sign = hx >> 31;\n hx &= 0x7FFFFFFF;\n if (hx >= 0x42AEAC50) {\n if (hx > 0x7F800000) return x; // NaN\n if (hx >= 0x42B17218) {\n if (!sign) return x * Ox1p127f;\n else if (hx >= 0x42CFF1B5) return 0;\n }\n }\n let hi: f32, lo: f32;\n let k: i32;\n if (hx > 0x3EB17218) {\n if (hx > 0x3F851592) {\n k = i32(invln2 * x + builtin_copysign(0.5, x));\n } else {\n k = 1 - (sign << 1);\n }\n hi = x - k * ln2hi;\n lo = k * ln2lo;\n x = hi - lo;\n } else if (hx > 0x39000000) {\n k = 0;\n hi = x;\n lo = 0;\n } else {\n return 1 + x;\n }\n let xx = x * x;\n let c = x - xx * (P1 + xx * P2);\n let y: f32 = 1 + (x * c / (2 - c) - lo + hi);\n return k == 0 ? y : scalbn(y, k);\n }\n }\n\n export function exp2(x: f32): f32 {\n return exp2f_lut(x);\n }\n\n export function expm1(x: f32): f32 { // see: musl/src/math/expm1f.c and SUN COPYRIGHT NOTICE above\n const\n ln2_hi = reinterpret(0x3F317180), // 6.9313812256e-01f\n ln2_lo = reinterpret(0x3717F7D1), // 9.0580006145e-06f\n invln2 = reinterpret(0x3FB8AA3B), // 1.4426950216e+00f\n Q1 = reinterpret(0xBD088868), // -3.3333212137e-02f\n Q2 = reinterpret(0x3ACF3010), // 1.5807170421e-03f\n Ox1p127f = reinterpret(0x7F000000); // 0x1p+127f\n\n let u = reinterpret(x);\n let hx = u & 0x7FFFFFFF;\n let sign = u >> 31;\n if (hx >= 0x4195B844) {\n if (hx > 0x7F800000) return x;\n if (sign) return -1;\n if (hx > 0x42B17217) { // x > log(FLT_MAX)\n x *= Ox1p127f;\n return x;\n }\n }\n let c: f32 = 0.0, t: f32, k: i32;\n if (hx > 0x3EB17218) {\n k = select(\n 1 - (sign << 1),\n i32(invln2 * x + builtin_copysign(0.5, x)),\n hx < 0x3F851592\n );\n t = k;\n let hi = x - t * ln2_hi;\n let lo = t * ln2_lo;\n x = hi - lo;\n c = (hi - x) - lo;\n } else if (hx < 0x33000000) {\n return x;\n } else k = 0;\n let hfx: f32 = 0.5 * x;\n let hxs: f32 = x * hfx;\n let r1: f32 = 1.0 + hxs * (Q1 + hxs * Q2);\n t = 3.0 - r1 * hfx;\n let e = hxs * ((r1 - t) / (6.0 - x * t));\n if (k == 0) return x - (x * e - hxs);\n e = x * (e - c) - c;\n e -= hxs;\n if (k == -1) return 0.5 * (x - e) - 0.5;\n if (k == 1) {\n if (x < -0.25) return -2.0 * (e - (x + 0.5));\n return 1.0 + 2.0 * (x - e);\n }\n u = (0x7F + k) << 23;\n let twopk = reinterpret(u);\n let y: f32;\n if (k < 0 || k > 56) {\n y = x - e + 1.0;\n if (k == 128) y = y * 2.0 * Ox1p127f;\n else y = y * twopk;\n return y - 1.0;\n }\n u = (0x7F - k) << 23;\n y = reinterpret(u);\n if (k < 20) y = (1 - y) - e;\n else y = 1 - (e + y);\n return (x + y) * twopk;\n }\n\n // @ts-ignore: decorator\n @inline\n export function fround(x: f32): f32 {\n return x;\n }\n\n export function hypot(x: f32, y: f32): f32 { // see: musl/src/math/hypotf.c\n const\n Ox1p90f = reinterpret(0x6C800000),\n Ox1p_90f = reinterpret(0x12800000);\n\n let ux = reinterpret(x);\n let uy = reinterpret(y);\n ux &= 0x7FFFFFFF;\n uy &= 0x7FFFFFFF;\n if (ux < uy) {\n let ut = ux;\n ux = uy;\n uy = ut;\n }\n x = reinterpret(ux);\n y = reinterpret(uy);\n if (uy == 0xFF << 23) return y;\n if (ux >= 0xFF << 23 || uy == 0 || ux - uy >= 25 << 23) return x + y;\n let z: f32 = 1;\n if (ux >= (0x7F + 60) << 23) {\n z = Ox1p90f;\n x *= Ox1p_90f;\n y *= Ox1p_90f;\n } else if (uy < (0x7F - 60) << 23) {\n z = Ox1p_90f;\n x *= Ox1p90f;\n y *= Ox1p90f;\n }\n return z * builtin_sqrt(f32(x * x + y * y));\n }\n\n // @ts-ignore: decorator\n @inline\n export function imul(x: f32, y: f32): f32 {\n /*\n * Wasm (MVP) and JS have different approaches for double->int conversions.\n *\n * For emulate JS conversion behavior and avoid trapping from wasm we should modulate by MAX_INT\n * our float-point arguments before actual convertion to integers.\n */\n if (!isFinite(x + y)) return 0;\n return (dtoi32(x) * dtoi32(y));\n }\n\n export function log(x: f32): f32 { // see: musl/src/math/logf.c and SUN COPYRIGHT NOTICE above\n if (ASC_SHRINK_LEVEL < 1) {\n return logf_lut(x);\n } else {\n const\n ln2_hi = reinterpret(0x3F317180), // 6.9313812256e-01f\n ln2_lo = reinterpret(0x3717F7D1), // 9.0580006145e-06f\n Lg1 = reinterpret(0x3F2AAAAA), // 0xaaaaaa.0p-24f\n Lg2 = reinterpret(0x3ECCCE13), // 0xccce13.0p-25f\n Lg3 = reinterpret(0x3E91E9EE), // 0x91e9ee.0p-25f\n Lg4 = reinterpret(0x3E789E26), // 0xf89e26.0p-26f\n Ox1p25f = reinterpret(0x4C000000);\n\n let u = reinterpret(x);\n let k = 0;\n let sign = u >> 31;\n if (sign || u < 0x00800000) {\n if (u << 1 == 0) return -1 / (x * x);\n if (sign) return (x - x) / 0;\n k -= 25;\n x *= Ox1p25f;\n u = reinterpret(x);\n } else if (u >= 0x7F800000) {\n return x;\n } else if (u == 0x3F800000) {\n return 0;\n }\n u += 0x3F800000 - 0x3F3504F3;\n k += i32(u >> 23) - 0x7F;\n u = (u & 0x007FFFFF) + 0x3F3504F3;\n x = reinterpret(u);\n let f = x - 1.0;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * Lg4);\n let t2 = z * (Lg1 + w * Lg3);\n let r = t2 + t1;\n let hfsq = 0.5 * f * f;\n let dk = k;\n return s * (hfsq + r) + dk * ln2_lo - hfsq + f + dk * ln2_hi;\n }\n }\n\n export function log10(x: f32): f32 { // see: musl/src/math/log10f.c and SUN COPYRIGHT NOTICE above\n const\n ivln10hi = reinterpret(0x3EDE6000), // 4.3432617188e-01f\n ivln10lo = reinterpret(0xB804EAD9), // -3.1689971365e-05f\n log10_2hi = reinterpret(0x3E9A2080), // 3.0102920532e-01f\n log10_2lo = reinterpret(0x355427DB), // 7.9034151668e-07f\n Lg1 = reinterpret(0x3F2AAAAA), // 0xaaaaaa.0p-24f, 0.66666662693f\n Lg2 = reinterpret(0x3ECCCE13), // 0xccce13.0p-25f, 0.40000972152f\n Lg3 = reinterpret(0x3E91E9EE), // 0x91e9ee.0p-25f, 0.28498786688f\n Lg4 = reinterpret(0x3E789E26), // 0xf89e26.0p-26f, 0.24279078841f\n Ox1p25f = reinterpret(0x4C000000); // 0x1p25f\n\n let ux = reinterpret(x);\n let k = 0;\n let sign = ux >> 31;\n if (sign || ux < 0x00800000) {\n if (ux << 1 == 0) return -1 / (x * x);\n if (sign) return (x - x) / 0.0;\n k -= 25;\n x *= Ox1p25f;\n ux = reinterpret(x);\n } else if (ux >= 0x7F800000) {\n return x;\n } else if (ux == 0x3F800000) {\n return 0;\n }\n ux += 0x3F800000 - 0x3F3504F3;\n k += i32(ux >> 23) - 0x7F;\n ux = (ux & 0x007FFFFF) + 0x3F3504F3;\n x = reinterpret(ux);\n let f = x - 1.0;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * Lg4);\n let t2 = z * (Lg1 + w * Lg3);\n let r = t2 + t1;\n let hfsq: f32 = 0.5 * f * f;\n let hi = f - hfsq;\n ux = reinterpret(hi);\n ux &= 0xFFFFF000;\n hi = reinterpret(ux);\n let lo = f - hi - hfsq + s * (hfsq + r);\n let dk = k;\n return dk * log10_2lo + (lo + hi) * ivln10lo + lo * ivln10hi + hi * ivln10hi + dk * log10_2hi;\n }\n\n export function log1p(x: f32): f32 { // see: musl/src/math/log1pf.c and SUN COPYRIGHT NOTICE above\n const\n ln2_hi = reinterpret(0x3F317180), // 6.9313812256e-01\n ln2_lo = reinterpret(0x3717F7D1), // 9.0580006145e-06\n Lg1 = reinterpret(0x3F2AAAAA), // 0xaaaaaa.0p-24f, 0.66666662693f\n Lg2 = reinterpret(0x3ECCCE13), // 0xccce13.0p-25f, 0.40000972152f\n Lg3 = reinterpret(0x3E91E9EE), // 0x91e9ee.0p-25f, 0.28498786688f\n Lg4 = reinterpret(0x3E789E26); // 0xf89e26.0p-26f, 0.24279078841f\n\n let ix = reinterpret(x);\n let c: f32 = 0;\n let f: f32 = 0;\n let k = 1;\n if (ix < 0x3ED413D0 || bool(ix >> 31)) {\n if (ix >= 0xBF800000) {\n if (x == -1) return x / 0.0;\n return (x - x) / 0.0;\n }\n if (ix << 1 < 0x33800000 << 1) return x;\n if (ix <= 0xBE95F619) {\n k = 0;\n c = 0;\n f = x;\n }\n } else if (ix >= 0x7F800000) return x;\n if (k) {\n let uf: f32 = 1 + x;\n let iu = reinterpret(uf);\n iu += 0x3F800000 - 0x3F3504F3;\n k = i32(iu >> 23) - 0x7F;\n if (k < 25) {\n c = k >= 2 ? 1 - (uf - x) : x - (uf - 1);\n c /= uf;\n } else c = 0;\n iu = (iu & 0x007FFFFF) + 0x3F3504F3;\n f = reinterpret(iu) - 1;\n }\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * Lg4);\n let t2 = z * (Lg1 + w * Lg3);\n let r = t2 + t1;\n let hfsq: f32 = 0.5 * f * f;\n let dk = k;\n return s * (hfsq + r) + (dk * ln2_lo + c) - hfsq + f + dk * ln2_hi;\n }\n\n export function log2(x: f32): f32 { // see: musl/src/math/log2f.c and SUN COPYRIGHT NOTICE above\n if (ASC_SHRINK_LEVEL < 1) {\n return log2f_lut(x);\n } else {\n const\n ivln2hi = reinterpret(0x3FB8B000), // 1.4428710938e+00f\n ivln2lo = reinterpret(0xB9389AD4), // -1.7605285393e-04\n Lg1 = reinterpret(0x3F2AAAAA), // 0xaaaaaa.0p-24f, 0.66666662693f\n Lg2 = reinterpret(0x3ECCCE13), // 0xccce13.0p-25f, 0.40000972152f\n Lg3 = reinterpret(0x3E91E9EE), // 0x91e9ee.0p-25f, 0.28498786688f\n Lg4 = reinterpret(0x3E789E26), // 0xf89e26.0p-26f, 0.24279078841f\n Ox1p25f = reinterpret(0x4C000000); // 0x1p25f\n\n let ux = reinterpret(x);\n let k = 0;\n let sign = ux >> 31;\n if (sign || ux < 0x00800000) {\n if (ux << 1 == 0) return -1 / (x * x);\n if (sign) return (x - x) / 0.0;\n k -= 25;\n x *= Ox1p25f;\n ux = reinterpret(x);\n } else if (ux >= 0x7F800000) {\n return x;\n } else if (ux == 0x3F800000) {\n return 0;\n }\n ux += 0x3F800000 - 0x3F3504F3;\n k += i32(ux >> 23) - 0x7F;\n ux = (ux & 0x007FFFFF) + 0x3F3504F3;\n x = reinterpret(ux);\n let f = x - 1.0;\n let s = f / (2.0 + f);\n let z = s * s;\n let w = z * z;\n let t1 = w * (Lg2 + w * Lg4);\n let t2 = z * (Lg1 + w * Lg3);\n let r = t2 + t1;\n let hfsq: f32 = 0.5 * f * f;\n let hi = f - hfsq;\n let u = reinterpret(hi);\n u &= 0xFFFFF000;\n hi = reinterpret(u);\n let lo: f32 = f - hi - hfsq + s * (hfsq + r);\n let dk = k;\n return (lo + hi) * ivln2lo + lo * ivln2hi + hi * ivln2hi + dk;\n }\n }\n\n // @ts-ignore: decorator\n @inline\n export function max(value1: f32, value2: f32): f32 {\n return builtin_max(value1, value2);\n }\n\n // @ts-ignore: decorator\n @inline\n export function min(value1: f32, value2: f32): f32 {\n return builtin_min(value1, value2);\n }\n\n export function pow(x: f32, y: f32): f32 {\n // TODO: remove this fast pathes after introduced own mid-end IR with \"stdlib call simplify\" transforms\n if (builtin_abs(y) <= 2) {\n if (y == 2.0) return x * x;\n if (y == 0.5) {\n return select(\n builtin_abs(builtin_sqrt(x)),\n Infinity,\n x != -Infinity\n );\n }\n if (y == -1.0) return 1 / x;\n if (y == 1.0) return x;\n if (y == 0.0) return 1.0;\n }\n if (ASC_SHRINK_LEVEL < 1) {\n // see: musl/src/math/powf.c\n return powf_lut(x, y);\n } else {\n // based on: jdh8/metallic/src/math/float/powf.c\n if (y == 0) return 1;\n // @ts-ignore: cast\n if (isNaN(x) | isNaN(y)) {\n return NaN;\n }\n let sign: u32 = 0;\n let uy = reinterpret(y);\n let ux = reinterpret(x);\n let sx = ux >> 31;\n ux &= 0x7FFFFFFF;\n if (sx && nearest(y) == y) {\n x = -x;\n sx = 0;\n sign = u32(nearest(y * 0.5) != y * 0.5) << 31;\n }\n let m: u32;\n if (ux == 0x3F800000) { // x == 1\n m = sx | u32((uy & 0x7FFFFFFF) == 0x7F800000) ? 0x7FC00000 : 0x3F800000;\n } else if (ux == 0) {\n m = uy < 0 ? 0x7F800000 : 0;\n } else if (ux == 0x7F800000) {\n m = uy < 0 ? 0 : 0x7F800000;\n } else if (sx) {\n m = 0x7FC00000;\n } else {\n m = reinterpret(exp2f(y * log2f(x)));\n }\n return reinterpret(m | sign);\n }\n }\n\n // @ts-ignore: decorator\n @inline\n export function seedRandom(value: i64): void {\n NativeMath.seedRandom(value);\n }\n\n // Using xoroshiro64starstar from http://xoshiro.di.unimi.it/xoroshiro64starstar.c\n export function random(): f32 {\n if (!random_seeded) seedRandom(reinterpret(seed()));\n\n let s0 = random_state0_32;\n let s1 = random_state1_32;\n let r = rotl(s0 * 0x9E3779BB, 5) * 5;\n\n s1 ^= s0;\n random_state0_32 = rotl(s0, 26) ^ s1 ^ (s1 << 9);\n random_state1_32 = rotl(s1, 13);\n\n return reinterpret((r >> 9) | (127 << 23)) - 1.0;\n }\n\n export function round(x: f32): f32 {\n if (ASC_SHRINK_LEVEL > 0) {\n return builtin_ceil(x) - f32(builtin_ceil(x) - 0.5 > x);\n } else {\n let roundUp = builtin_ceil(x);\n return select(roundUp, roundUp - 1.0, roundUp - 0.5 <= x);\n }\n }\n\n export function sign(x: f32): f32 {\n if (ASC_SHRINK_LEVEL > 0) {\n return select(builtin_copysign(1, x), x, builtin_abs(x) > 0);\n } else {\n return select(1, select(-1, x, x < 0), x > 0);\n }\n }\n\n // @ts-ignore: decorator\n @inline\n export function signbit(x: f32): bool {\n return (reinterpret(x) >>> 31);\n }\n\n export function sin(x: f32): f32 { // see: musl/src/math/sinf.c\n const\n s1pio2 = reinterpret(0x3FF921FB54442D18), // M_PI_2 * 1\n s2pio2 = reinterpret(0x400921FB54442D18), // M_PI_2 * 2\n s3pio2 = reinterpret(0x4012D97C7F3321D2), // M_PI_2 * 3\n s4pio2 = reinterpret(0x401921FB54442D18); // M_PI_2 * 4\n\n let ux = reinterpret(x);\n let sign = ux >> 31;\n ux &= 0x7FFFFFFF;\n\n if (ux <= 0x3F490FDA) { // |x| ~<= π/4\n if (ux < 0x39800000) { // |x| < 2**-12\n return x;\n }\n return sin_kernf(x);\n }\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (ux <= 0x407B53D1) { // |x| ~<= 5π/4\n if (ux <= 0x4016CBE3) { // |x| ~<= 3π/4\n return sign ? -cos_kernf(x + s1pio2) : cos_kernf(x - s1pio2);\n }\n return sin_kernf(-(sign ? x + s2pio2 : x - s2pio2));\n }\n\n if (ux <= 0x40E231D5) { // |x| ~<= 9π/4\n if (ux <= 0x40AFEDDF) { // |x| ~<= 7π/4\n return sign ? cos_kernf(x + s3pio2) : -cos_kernf(x - s3pio2);\n }\n return sin_kernf(sign ? x + s4pio2 : x - s4pio2);\n }\n }\n\n // sin(Inf or NaN) is NaN\n if (ux >= 0x7F800000) return x - x;\n\n let n = rempio2f(x, ux, sign);\n let y = rempio2f_y;\n\n let t = n & 1 ? cos_kernf(y) : sin_kernf(y);\n return n & 2 ? -t : t;\n }\n\n export function sinh(x: f32): f32 { // see: musl/src/math/sinhf.c\n let u = reinterpret(x) & 0x7FFFFFFF;\n let a = reinterpret(u);\n let h = builtin_copysign(0.5, x);\n if (u < 0x42B17217) {\n let t = expm1(a);\n if (u < 0x3F800000) {\n if (u < 0x3F800000 - (12 << 23)) return x;\n return h * (2 * t - t * t / (t + 1));\n }\n return h * (t + t / (t + 1));\n }\n return expo2f(a, 2 * h);\n }\n\n // @ts-ignore: decorator\n @inline\n export function sqrt(x: f32): f32 {\n return builtin_sqrt(x);\n }\n\n export function tan(x: f32): f32 { // see: musl/src/math/tanf.c\n const\n t1pio2 = reinterpret(0x3FF921FB54442D18), // 1 * M_PI_2\n t2pio2 = reinterpret(0x400921FB54442D18), // 2 * M_PI_2\n t3pio2 = reinterpret(0x4012D97C7F3321D2), // 3 * M_PI_2\n t4pio2 = reinterpret(0x401921FB54442D18); // 4 * M_PI_2\n\n let ux = reinterpret(x);\n let sign = ux >> 31;\n ux &= 0x7FFFFFFF;\n\n if (ux <= 0x3F490FDA) { // |x| ~<= π/4\n if (ux < 0x39800000) { // |x| < 2**-12\n return x;\n }\n return tan_kernf(x, 0);\n }\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (ux <= 0x407B53D1) { // |x| ~<= 5π/4\n if (ux <= 0x4016CBE3) { // |x| ~<= 3π/4\n return tan_kernf((sign ? x + t1pio2 : x - t1pio2), 1);\n } else {\n return tan_kernf((sign ? x + t2pio2 : x - t2pio2), 0);\n }\n }\n if (ux <= 0x40E231D5) { // |x| ~<= 9π/4\n if (ux <= 0x40AFEDDF) { // |x| ~<= 7π/4\n return tan_kernf((sign ? x + t3pio2 : x - t3pio2), 1);\n } else {\n return tan_kernf((sign ? x + t4pio2 : x - t4pio2), 0);\n }\n }\n }\n\n // tan(Inf or NaN) is NaN\n if (ux >= 0x7F800000) return x - x;\n\n // argument reduction\n let n = rempio2f(x, ux, sign);\n let y = rempio2f_y;\n return tan_kernf(y, n & 1);\n }\n\n export function tanh(x: f32): f32 { // see: musl/src/math/tanhf.c\n let u = reinterpret(x);\n u &= 0x7FFFFFFF;\n let y = reinterpret(u);\n let t: f32;\n if (u > 0x3F0C9F54) {\n if (u > 0x41200000) t = 1 + 0 / y;\n else {\n t = expm1(2 * y);\n t = 1 - 2 / (t + 2);\n }\n } else if (u > 0x3E82C578) {\n t = expm1(2 * y);\n t = t / (t + 2);\n } else if (u >= 0x00800000) {\n t = expm1(-2 * y);\n t = -t / (t + 2);\n } else t = y;\n return builtin_copysign(t, x);\n }\n\n // @ts-ignore: decorator\n @inline\n export function trunc(x: f32): f32 {\n return builtin_trunc(x);\n }\n\n export function scalbn(x: f32, n: i32): f32 { // see: https://git.musl-libc.org/cgit/musl/tree/src/math/scalbnf.c\n const\n Ox1p24f = reinterpret(0x4B800000),\n Ox1p127f = reinterpret(0x7F000000),\n Ox1p_126f = reinterpret(0x00800000);\n\n let y = x;\n if (n > 127) {\n y *= Ox1p127f;\n n -= 127;\n if (n > 127) {\n y *= Ox1p127f;\n n = builtin_min(n - 127, 127);\n }\n } else if (n < -126) {\n y *= Ox1p_126f * Ox1p24f;\n n += 126 - 24;\n if (n < -126) {\n y *= Ox1p_126f * Ox1p24f;\n n = builtin_max(n + 126 - 24, -126);\n }\n }\n return y * reinterpret((0x7F + n) << 23);\n }\n\n export function mod(x: f32, y: f32): f32 { // see: musl/src/math/fmodf.c\n if (builtin_abs(y) == 1.0) {\n // x % 1, x % -1 ==> sign(x) * abs(x - 1.0 * trunc(x / 1.0))\n // TODO: move this rule to compiler's optimization pass.\n // It could be apply for any x % C_pot, where \"C_pot\" is pow of two const.\n return builtin_copysign(x - builtin_trunc(x), x);\n }\n let ux = reinterpret(x);\n let uy = reinterpret(y);\n let ex = i32(ux >> 23 & 0xFF);\n let ey = i32(uy >> 23 & 0xFF);\n let sm = ux & 0x80000000;\n let uy1 = uy << 1;\n if (uy1 == 0 || ex == 0xFF || isNaN(y)) {\n let m = x * y;\n return m / m;\n }\n let ux1 = ux << 1;\n if (ux1 <= uy1) {\n return x * f32(ux1 != uy1);\n }\n if (!ex) {\n ex -= builtin_clz(ux << 9);\n ux <<= 1 - ex;\n } else {\n ux &= -1 >> 9;\n ux |= 1 << 23;\n }\n if (!ey) {\n ey -= builtin_clz(uy << 9);\n uy <<= 1 - ey;\n } else {\n uy &= u32(-1) >> 9;\n uy |= 1 << 23;\n }\n while (ex > ey) {\n if (ux >= uy) {\n if (ux == uy) return 0 * x;\n ux -= uy;\n }\n ux <<= 1;\n --ex;\n }\n if (ux >= uy) {\n if (ux == uy) return 0 * x;\n ux -= uy;\n }\n // for (; !(ux >> 23); ux <<= 1) --ex;\n let shift = builtin_clz(ux << 8);\n ex -= shift;\n ux <<= shift;\n if (ex > 0) {\n ux -= 1 << 23;\n ux |= ex << 23;\n } else {\n ux >>= -ex + 1;\n }\n return reinterpret(ux | sm);\n }\n\n export function rem(x: f32, y: f32): f32 { // see: musl/src/math/remquof.c\n let ux = reinterpret(x);\n let uy = reinterpret(y);\n let ex = i32(ux >> 23 & 0xFF);\n let ey = i32(uy >> 23 & 0xFF);\n let uxi = ux;\n if (uy << 1 == 0 || ex == 0xFF || isNaN(y)) return (x * y) / (x * y);\n if (ux << 1 == 0) return x;\n if (!ex) {\n ex -= builtin_clz(uxi << 9);\n uxi <<= 1 - ex;\n } else {\n uxi &= u32(-1) >> 9;\n uxi |= 1 << 23;\n }\n if (!ey) {\n ey -= builtin_clz(uy << 9);\n uy <<= 1 - ey;\n } else {\n uy &= u32(-1) >> 9;\n uy |= 1 << 23;\n }\n let q = 0;\n do {\n if (ex < ey) {\n if (ex + 1 == ey) break; // goto end\n return x;\n }\n while (ex > ey) {\n if (uxi >= uy) {\n uxi -= uy;\n ++q;\n }\n uxi <<= 1;\n q <<= 1;\n --ex;\n }\n if (uxi >= uy) {\n uxi -= uy;\n ++q;\n }\n if (uxi == 0) ex = -30;\n else {\n let shift = builtin_clz(uxi << 8);\n ex -= shift;\n uxi <<= shift;\n }\n break;\n } while (false);\n // end:\n if (ex > 0) {\n uxi -= 1 << 23;\n uxi |= ex << 23;\n } else {\n uxi >>= -ex + 1;\n }\n x = reinterpret(uxi);\n y = builtin_abs(y);\n let x2 = x + x;\n if (ex == ey || (ex + 1 == ey && (x2 > y || (x2 == y && bool(q & 1))))) {\n x -= y;\n // q++;\n }\n return ux < 0 ? -x : x;\n }\n\n export function sincos(x: f32): void { // see: musl/tree/src/math/sincosf.c\n const\n s1pio2 = reinterpret(0x3FF921FB54442D18), // 1 * M_PI_2\n s2pio2 = reinterpret(0x400921FB54442D18), // 2 * M_PI_2\n s3pio2 = reinterpret(0x4012D97C7F3321D2), // 3 * M_PI_2\n s4pio2 = reinterpret(0x401921FB54442D18); // 4 * M_PI_2\n\n let ux = reinterpret(x);\n let sign = ux >> 31;\n ux &= 0x7FFFFFFF;\n\n if (ux <= 0x3F490FDA) { // |x| ~<= π/4\n if (ux < 0x39800000) { // |x| < 2**-12\n sincos_sin = x;\n sincos_cos = 1;\n return;\n }\n sincos_sin = sin_kernf(x);\n sincos_cos = cos_kernf(x);\n return;\n }\n if (ASC_SHRINK_LEVEL < 1) {\n if (ux <= 0x407B53D1) { // |x| ~<= 5π/4\n if (ux <= 0x4016CBE3) { // |x| ~<= 3π/4\n if (sign) {\n sincos_sin = -cos_kernf(x + s1pio2);\n sincos_cos = sin_kernf(x + s1pio2);\n } else {\n sincos_sin = cos_kernf(s1pio2 - x);\n sincos_cos = sin_kernf(s1pio2 - x);\n }\n return;\n }\n // -sin(x + c) is not correct if x+c could be 0: -0 vs +0\n sincos_sin = -sin_kernf(sign ? x + s2pio2 : x - s2pio2);\n sincos_cos = -cos_kernf(sign ? x + s2pio2 : x - s2pio2);\n return;\n }\n if (ux <= 0x40E231D5) { // |x| ~<= 9π/4\n if (ux <= 0x40AFEDDF) { // |x| ~<= 7π/4\n if (sign) {\n sincos_sin = cos_kernf(x + s3pio2);\n sincos_cos = -sin_kernf(x + s3pio2);\n } else {\n sincos_sin = -cos_kernf(x - s3pio2);\n sincos_cos = sin_kernf(x - s3pio2);\n }\n return;\n }\n sincos_sin = sin_kernf(sign ? x + s4pio2 : x - s4pio2);\n sincos_cos = cos_kernf(sign ? x + s4pio2 : x - s4pio2);\n return;\n }\n }\n // sin(Inf or NaN) is NaN\n if (ux >= 0x7F800000) {\n let xx = x - x;\n sincos_sin = xx;\n sincos_cos = xx;\n return;\n }\n // general argument reduction needed\n let n = rempio2f(x, ux, sign);\n let y = rempio2f_y;\n let s = sin_kernf(y);\n let c = cos_kernf(y);\n let sin = s, cos = c;\n if (n & 1) {\n sin = c;\n cos = -s;\n }\n if (n & 2) {\n sin = -sin;\n cos = -cos;\n }\n sincos_sin = sin;\n sincos_cos = cos;\n }\n}\n\nexport function ipow32(x: i32, e: i32): i32 {\n let out = 1;\n if (ASC_SHRINK_LEVEL < 1) {\n if (x == 2) {\n return select(1 << e, 0, e < 32);\n }\n if (e <= 0) {\n if (x == -1) return select(-1, 1, e & 1);\n return i32(e == 0) | i32(x == 1);\n }\n else if (e == 1) return x;\n else if (e == 2) return x * x;\n else if (e < 32) {\n let log = 32 - clz(e);\n // 32 = 2 ^ 5, so need only five cases.\n // But some extra cases needs for properly overflowing\n switch (log) {\n case 5: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 4: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 3: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 2: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 1: {\n if (e & 1) out *= x;\n }\n }\n return out;\n }\n }\n while (e) {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n return out;\n}\n\nexport function ipow64(x: i64, e: i64): i64 {\n let out: i64 = 1;\n if (ASC_SHRINK_LEVEL < 1) {\n if (x == 2) {\n return select(1 << e, 0, e < 64);\n }\n if (e <= 0) {\n if (x == -1) return select(-1, 1, e & 1);\n return i64(e == 0) | i64(x == 1);\n }\n else if (e == 1) return x;\n else if (e == 2) return x * x;\n else if (e < 64) {\n let log = 64 - clz(e);\n // 64 = 2 ^ 6, so need only six cases.\n // But some extra cases needs for properly overflowing\n switch (log) {\n case 6: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 5: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 4: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 3: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 2: {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n case 1: {\n if (e & 1) out *= x;\n }\n }\n return out;\n }\n }\n while (e) {\n if (e & 1) out *= x;\n e >>>= 1;\n x *= x;\n }\n return out;\n}\n\n/*\nTODO:\nIn compile time if only exponent is constant we could replace ipow32/ipow64 by shortest addition chains\nwhich usually faster than exponentiation by squaring\n\nfor ipow32 and e < 32:\n\nlet b: i32, c: i32, d: i32, h: i32, k: i32, g: i32;\nswitch (e) {\n case 1: return x;\n case 2: return x * x;\n case 3: return x * x * x;\n case 4: return (b = x * x) * b;\n case 5: return (b = x * x) * b * x;\n case 6: return (b = x * x) * b * b;\n case 7: return (b = x * x) * b * b * x;\n case 8: return (d = (b = x * x) * b) * d;\n case 9: return (c = x * x * x) * c * c;\n case 10: return (d = (b = x * x) * b) * d * b;\n case 11: return (d = (b = x * x) * b) * d * b * x;\n case 12: return (d = (b = x * x) * b) * d * d;\n case 13: return (d = (b = x * x) * b) * d * d * x;\n case 14: return (d = (b = x * x) * b) * d * d * b;\n case 15: return (k = (b = x * x) * b * x) * k * k;\n case 16: return (h = (d = (b = x * x) * b) * d) * h;\n case 17: return (h = (d = (b = x * x) * b) * d) * h * x;\n case 18: return (h = (d = (b = x * x) * b) * d * x) * h;\n case 19: return (h = (d = (b = x * x) * b) * d * x) * h * x;\n case 20: return (h = (k = (b = x * x) * b * x) * k) * h;\n case 21: return (h = (k = (b = x * x) * b * x) * k) * h * x;\n case 22: return (g = (h = (k = (b = x * x) * b * x) * k) * x) * g;\n case 23: return (h = (d = (c = (b = x * x) * x) * b) * d) * h * c;\n case 24: return (h = (d = (c = x * x * x) * c) * d) * h;\n case 25: return (h = (d = (c = x * x * x) * c) * d) * h * x;\n case 26: return (g = (h = (d = (c = x * x * x) * c) * d) * x) * g;\n case 27: return (h = (d = (c = x * x * x) * c) * d) * h * c;\n case 28: return (h = (d = (c = x * x * x) * c * x) * d) * h;\n case 29: return (h = (d = (c = x * x * x) * c * x) * d) * h * x;\n case 30: return (h = (d = (c = x * x * x) * c) * d * c) * h;\n case 31: return (h = (d = (c = x * x * x) * c) * d * c) * h * x;\n}\n\nfor ipow64: TODO\nswitch (e) {\n case 32:\n ...\n case 63:\n}\n*/\n","/**\n * @fileoverview The C-like and re-exported public compiler interface.\n *\n * The intended way to consume the compiler sources is to import this\n * file, which again exports all relevant functions, classes and constants\n * as a flat namespace.\n *\n * Note though that the compiler sources are written in \"portable\n * AssemblyScript\" that can be compiled to both JavaScript with tsc and\n * to WebAssembly with asc, and as such require additional glue code\n * depending on the target.\n *\n * When compiling to JavaScript `glue/js/index.js` must be included.\n * When compiling to WebAssembly `glue/wasm/index.ts` must be included.\n */\n\nimport {\n Target,\n Runtime,\n Feature\n} from \"./common\";\n\nimport {\n Compiler,\n Options,\n UncheckedBehavior\n} from \"./compiler\";\n\nimport {\n TSDBuilder,\n JSBuilder\n} from \"./bindings\";\n\nimport {\n Range,\n DiagnosticMessage,\n DiagnosticCategory,\n formatDiagnosticMessage\n} from \"./diagnostics\";\n\nimport { Module } from \"./module\";\nimport { Program } from \"./program\";\nimport { Source } from \"./ast\";\n\n// Options\n\n/** Creates a new set of compiler options. */\nexport function newOptions(): Options {\n return new Options();\n}\n\n/** Sets the `target` option. */\nexport function setTarget(options: Options, target: Target): void {\n options.target = target;\n}\n\nexport function setRuntime(options: Options, runtime: Runtime): void {\n options.runtime = runtime;\n}\n\n/** Sets the `noAssert` option. */\nexport function setNoAssert(options: Options, noAssert: bool): void {\n options.noAssert = noAssert;\n}\n\n/** Sets the `exportMemory` option. */\nexport function setExportMemory(options: Options, exportMemory: bool): void {\n options.exportMemory = exportMemory;\n}\n\n/** Sets the `importMemory` option. */\nexport function setImportMemory(options: Options, importMemory: bool): void {\n options.importMemory = importMemory;\n}\n\n/** Sets the `initialMemory` option. */\nexport function setInitialMemory(options: Options, initialMemory: u32): void {\n options.initialMemory = initialMemory;\n}\n\n/** Sets the `maximumMemory` option. */\nexport function setMaximumMemory(options: Options, maximumMemory: u32): void {\n options.maximumMemory = maximumMemory;\n}\n\n/** Sets the `sharedMemory` option. */\nexport function setSharedMemory(options: Options, sharedMemory: bool): void {\n options.sharedMemory = sharedMemory;\n}\n\n/** Sets the `importTable` option. */\nexport function setImportTable(options: Options, importTable: bool): void {\n options.importTable = importTable;\n}\n\n/** Sets the `exportTable` option. */\nexport function setExportTable(options: Options, exportTable: bool): void {\n options.exportTable = exportTable;\n}\n\n/** Sets the `sourceMap` option. */\nexport function setSourceMap(options: Options, sourceMap: bool): void {\n options.sourceMap = sourceMap;\n}\n\n/** Sets the `uncheckedBehavior` option. */\nexport function setUncheckedBehavior(options: Options, uncheckedBehavior: UncheckedBehavior): void {\n options.uncheckedBehavior = uncheckedBehavior;\n}\n\n/** Sets the `memoryBase` option. */\nexport function setMemoryBase(options: Options, memoryBase: u32): void {\n options.memoryBase = memoryBase;\n}\n\n/** Sets the `tableBase` option. */\nexport function setTableBase(options: Options, tableBase: u32): void {\n options.tableBase = tableBase;\n}\n\n/** Adds a 'globalAliases' value. */\nexport function addGlobalAlias(options: Options, alias: string, name: string): void {\n let globalAliases = options.globalAliases;\n if (!globalAliases) options.globalAliases = globalAliases = new Map();\n globalAliases.set(alias, name);\n}\n\n/** Removes a 'globalAliases' value. */\nexport function removeGlobalAlias(options: Options, alias: string): void {\n let globalAliases = options.globalAliases;\n if (globalAliases) globalAliases.delete(alias);\n}\n\n/** Sets the `exportStart` option. */\nexport function setExportStart(options: Options, exportStart: string | null): void {\n options.exportStart = exportStart;\n}\n\n/** Sets the `noUnsafe` option. */\nexport function setNoUnsafe(options: Options, noUnsafe: bool): void {\n options.noUnsafe = noUnsafe;\n}\n\n/** Sets the `lowMemoryLimit` option. */\nexport function setLowMemoryLimit(options: Options, lowMemoryLimit: i32): void {\n options.lowMemoryLimit = lowMemoryLimit;\n}\n\n/** Sets the `exportRuntime` option. */\nexport function setExportRuntime(options: Options, exportRuntime: bool): void {\n options.exportRuntime = exportRuntime;\n}\n\n/** Default stack size. */\nexport const DEFAULT_STACK_SIZE = 32768;\n\n/** Sets the `stackSize` option. */\nexport function setStackSize(options: Options, stackSize: i32): void {\n options.stackSize = stackSize;\n}\n\n/** Sets the bundle semantic version. */\nexport function setBundleVersion(\n options: Options,\n bundleMajorVersion: i32,\n bundleMinorVersion: i32,\n bundlePatchVersion: i32,\n): void {\n options.bundleMajorVersion = bundleMajorVersion;\n options.bundleMinorVersion = bundleMinorVersion;\n options.bundlePatchVersion = bundlePatchVersion;\n}\n\n/** Sign extension operations. */\nexport const FEATURE_SIGN_EXTENSION = Feature.SignExtension;\n/** Mutable global imports and exports. */\nexport const FEATURE_MUTABLE_GLOBALS = Feature.MutableGlobals;\n/** Non-trapping float to int conversion operations. */\nexport const FEATURE_NONTRAPPING_F2I = Feature.NontrappingF2I;\n/** Bulk memory operations. */\nexport const FEATURE_BULK_MEMORY = Feature.BulkMemory;\n/** SIMD types and operations. */\nexport const FEATURE_SIMD = Feature.Simd;\n/** Threading and atomic operations. */\nexport const FEATURE_THREADS = Feature.Threads;\n/** Exception handling operations. */\nexport const FEATURE_EXCEPTION_HANDLING = Feature.ExceptionHandling;\n/** Tail call operations. */\nexport const FEATURE_TAIL_CALLS = Feature.TailCalls;\n/** Reference types. */\nexport const FEATURE_REFERENCE_TYPES = Feature.ReferenceTypes;\n/** Multi value types. */\nexport const FEATURE_MULTI_VALUE = Feature.MultiValue;\n/** Garbage collection. */\nexport const FEATURE_GC = Feature.GC;\n/** Memory64. */\nexport const FEATURE_MEMORY64 = Feature.Memory64;\n/** Relaxed SIMD. */\nexport const FEATURE_RELAXED_SIMD = Feature.RelaxedSimd;\n/** Extended const expressions. */\nexport const FEATURE_EXTENDED_CONST = Feature.ExtendedConst;\n/** String references. */\nexport const FEATURE_STRINGREF = Feature.Stringref;\n\n/** Enables a specific feature. */\nexport function enableFeature(options: Options, feature: Feature): void {\n options.features |= feature;\n}\n\n/** Disables a specific feature. */\nexport function disableFeature(options: Options, feature: Feature): void {\n options.features &= ~feature;\n}\n\n/** Gives the compiler a hint at the optimize levels that will be used later on. */\nexport function setOptimizeLevelHints(options: Options, optimizeLevel: i32, shrinkLevel: i32): void {\n options.optimizeLevelHint = optimizeLevel;\n options.shrinkLevelHint = shrinkLevel;\n}\n\n/** Gives the compiler a hint of the emitted module's basename. */\nexport function setBasenameHint(options: Options, basename: string): void {\n options.basenameHint = basename;\n}\n\n/** Gives the compiler a hint that bindings will be generated. */\nexport function setBindingsHint(options: Options, bindings: bool): void {\n options.bindingsHint = bindings;\n}\n\n/** Sets the `pedantic` option. */\nexport function setPedantic(options: Options, pedantic: bool): void {\n options.pedantic = pedantic;\n}\n\nexport function setDebugInfo(options: Options, debug: bool): void {\n options.debugInfo = debug;\n}\n\n// Program\n\n/** Creates a new Program. */\nexport function newProgram(options: Options): Program {\n return new Program(options);\n}\n\n/** Obtains the next diagnostic message. Returns `null` once complete. */\nexport function nextDiagnostic(program: Program): DiagnosticMessage | null {\n return program.diagnosticsOffset < program.diagnostics.length\n ? program.diagnostics[program.diagnosticsOffset++]\n : null;\n}\n\n/** Obtains the source of the given file. */\nexport function getSource(program: Program, internalPath: string): string | null {\n return program.getSource(internalPath);\n}\n\n/** Formats a diagnostic message to a string. */\nexport { formatDiagnosticMessage as formatDiagnostic };\n\n/** Gets the code of a diagnostic message. */\nexport function getDiagnosticCode(diagnostic: DiagnosticMessage): i32 {\n return diagnostic.code;\n}\n\n/** Gets the category of a diagnostic message. */\nexport function getDiagnosticCategory(diagnostic: DiagnosticMessage): DiagnosticCategory {\n return diagnostic.category;\n}\n\n/** Gets the textual message of a diagnostic message. */\nexport function getDiagnosticMessage(diagnostic: DiagnosticMessage): string {\n return diagnostic.message;\n}\n\n/** Gets the primary range, if any, of a diagnostic message. */\nexport function getDiagnosticRange(diagnostic: DiagnosticMessage): Range | null {\n return diagnostic.range;\n}\n\n/** Gets the related range, if any, of a diagnostic message. */\nexport function getDiagnosticRelatedRange(diagnostic: DiagnosticMessage): Range | null {\n return diagnostic.relatedRange;\n}\n\n/** Gets a range's start offset. */\nexport function getRangeStart(range: Range): i32 {\n return range.start;\n}\n\n/** Gets a range's end offsset. */\nexport function getRangeEnd(range: Range): i32 {\n return range.end;\n}\n\n/** Gets a range's relevant source. */\nexport function getRangeSource(range: Range): Source {\n return range.source;\n}\n\n/** Gets a source's normalized path. */\nexport function getSourceNormalizedPath(source: Source): string {\n return source.normalizedPath;\n}\n\n/** Tests whether a diagnostic is informatory. */\nexport function isInfo(message: DiagnosticMessage): bool {\n return message.category == DiagnosticCategory.Info;\n}\n\n/** Tests whether a diagnostic is a warning. */\nexport function isWarning(message: DiagnosticMessage): bool {\n return message.category == DiagnosticCategory.Warning;\n}\n\n/** Tests whether a diagnostic is an error. */\nexport function isError(message: DiagnosticMessage): bool {\n return message.category == DiagnosticCategory.Error;\n}\n\n// Parser\n\n/** Parses a source file. If `parser` has been omitted a new one is created. */\nexport function parse(\n /** Program reference. */\n program: Program,\n /** Source text of the file, or `null` to indicate not found. */\n text: string | null,\n /** Normalized path of the file. */\n path: string,\n /** Whether this is an entry file. */\n isEntry: bool = false\n): void {\n program.parser.parseFile(text, path, isEntry);\n}\n\n/** Obtains the next required file's path. Returns `null` once complete. */\nexport function nextFile(program: Program): string | null {\n return program.parser.nextFile();\n}\n\n/** Obtains the path of the dependee of a given imported file. */\nexport function getDependee(program: Program, file: string): string | null {\n return program.parser.getDependee(file);\n}\n\n// Compiler\n\n/** Initializes the program pre-emptively for transform hooks. */\nexport function initializeProgram(program: Program): void {\n program.initialize();\n}\n\n/** Compiles the parsed sources to a module. */\nexport function compile(program: Program): Module {\n program.parser.finish();\n return new Compiler(program).compile();\n}\n\n/** Builds TypeScript definitions for the specified program. */\nexport function buildTSD(program: Program, esm: bool): string {\n return TSDBuilder.build(program, esm);\n}\n\n/** Builds JavaScript glue code for the specified program. */\nexport function buildJS(program: Program, esm: bool): string {\n return JSBuilder.build(program, esm);\n}\n\n/** Gets the Binaryen module reference of a module. */\nexport function getBinaryenModuleRef(module: Module): usize {\n return module.ref;\n}\n\n/** Validates a module. */\nexport function validate(module: Module): bool {\n return module.validate();\n}\n\n/** Optimizes a module. */\nexport function optimize(\n module: Module,\n optimizeLevel: i32,\n shrinkLevel: i32,\n debugInfo: bool = false,\n zeroFilledMemory: bool = false\n): void {\n module.optimize(optimizeLevel, shrinkLevel, debugInfo, zeroFilledMemory);\n}\n","/**\n * @fileoverview A TypeScript parser for the AssemblyScript subset.\n *\n * Takes the tokens produced by the `Tokenizer` and builds an abstract\n * syntax tree composed of `Node`s wrapped in a `Source` out of it.\n *\n * @license Apache-2.0\n */\n\nimport {\n CommonFlags,\n LIBRARY_PREFIX,\n PATH_DELIMITER\n} from \"./common\";\n\nimport {\n Tokenizer,\n Token,\n CommentHandler,\n IdentifierHandling,\n isIllegalVariableIdentifier\n} from \"./tokenizer\";\n\nimport {\n Range,\n DiagnosticCode,\n DiagnosticEmitter,\n DiagnosticMessage\n} from \"./diagnostics\";\n\nimport {\n CharCode,\n normalizePath\n} from \"./util\";\n\nimport {\n Node,\n NodeKind,\n Source,\n SourceKind,\n TypeNode,\n TypeName,\n NamedTypeNode,\n FunctionTypeNode,\n ArrowKind,\n\n Expression,\n AssertionKind,\n CallExpression,\n ClassExpression,\n FunctionExpression,\n IdentifierExpression,\n StringLiteralExpression,\n\n Statement,\n BlockStatement,\n BreakStatement,\n ClassDeclaration,\n ContinueStatement,\n DeclarationStatement,\n DecoratorNode,\n DoStatement,\n EnumDeclaration,\n EnumValueDeclaration,\n ExportImportStatement,\n ExportMember,\n ExportStatement,\n ExpressionStatement,\n ForOfStatement,\n FunctionDeclaration,\n IfStatement,\n ImportDeclaration,\n ImportStatement,\n IndexSignatureNode,\n NamespaceDeclaration,\n ParameterNode,\n ParameterKind,\n ReturnStatement,\n SwitchCase,\n SwitchStatement,\n ThrowStatement,\n TryStatement,\n TypeDeclaration,\n TypeParameterNode,\n VariableStatement,\n VariableDeclaration,\n VoidStatement,\n WhileStatement,\n ModuleDeclaration,\n\n mangleInternalPath\n} from \"./ast\";\n\n/** Represents a dependee. */\nclass Dependee {\n constructor(\n public source: Source,\n public reportNode: Node\n ) {}\n}\n\n/** Parser interface. */\nexport class Parser extends DiagnosticEmitter {\n\n /** Source file names to be requested next. */\n backlog: string[] = new Array();\n /** Source file names already seen, that is processed or backlogged. */\n seenlog: Set = new Set();\n /** Source file names already completely processed. */\n donelog: Set = new Set();\n /** Optional handler to intercept comments while tokenizing. */\n onComment: CommentHandler | null = null;\n /** Current file being parsed. */\n currentSource: Source | null = null;\n /** Map of dependees being depended upon by a source, by path. */\n dependees: Map = new Map();\n /** An array of parsed sources. */\n sources: Source[];\n /** Current overridden module name. */\n currentModuleName: string | null = null;\n\n /** Constructs a new parser. */\n constructor(\n diagnostics: DiagnosticMessage[] | null = null,\n sources: Source[] = []\n ) {\n super(diagnostics);\n this.sources = sources;\n }\n\n /** Parses a file and adds its definitions to the program. */\n parseFile(\n /** Source text of the file, or `null` to indicate not found. */\n text: string | null,\n /** Normalized path of the file. */\n path: string,\n /** Whether this is an entry file. */\n isEntry: bool\n ): void {\n // the frontend gives us paths with file extensions\n let normalizedPath = normalizePath(path);\n let internalPath = mangleInternalPath(normalizedPath);\n\n // check if already processed\n if (this.donelog.has(internalPath)) return;\n this.donelog.add(internalPath); // do not parse again\n this.seenlog.add(internalPath); // do not request again\n\n // check if this is an error\n if (text == null) {\n let dependees = this.dependees;\n let dependee: Dependee | null = null;\n if (dependees.has(internalPath)) dependee = assert(dependees.get(internalPath));\n this.error(\n DiagnosticCode.File_0_not_found,\n dependee\n ? dependee.reportNode.range\n : null,\n path\n );\n return;\n }\n\n // create the source element\n let source = new Source(\n isEntry\n ? SourceKind.UserEntry\n : path.startsWith(LIBRARY_PREFIX)\n ? path.indexOf(PATH_DELIMITER, LIBRARY_PREFIX.length) < 0\n ? SourceKind.LibraryEntry\n : SourceKind.Library\n : SourceKind.User,\n normalizedPath,\n text\n );\n\n this.sources.push(source);\n this.currentSource = source;\n this.currentModuleName = null;\n\n // tokenize and parse\n let tn = new Tokenizer(source, this.diagnostics);\n tn.onComment = this.onComment;\n let statements = source.statements;\n while (!tn.skip(Token.EndOfFile)) {\n let statement = this.parseTopLevelStatement(tn, null);\n if (statement) {\n statements.push(statement);\n } else {\n this.skipStatement(tn);\n }\n }\n }\n\n /** Parses a top-level statement. */\n parseTopLevelStatement(\n tn: Tokenizer,\n namespace: NamespaceDeclaration | null = null\n ): Statement | null {\n let flags = namespace ? namespace.flags & CommonFlags.Ambient : CommonFlags.None;\n let startPos = -1;\n\n // check decorators\n let decorators: DecoratorNode[] | null = null;\n while (tn.skip(Token.At)) {\n if (startPos < 0) startPos = tn.tokenPos;\n let decorator = this.parseDecorator(tn);\n if (!decorator) {\n this.skipStatement(tn);\n continue;\n }\n if (!decorators) decorators = [decorator];\n else decorators.push(decorator);\n }\n\n // check modifiers\n let exportStart = 0;\n let exportEnd = 0;\n let defaultStart = 0;\n let defaultEnd = 0;\n if (tn.skip(Token.Export)) {\n if (startPos < 0) startPos = tn.tokenPos;\n flags |= CommonFlags.Export;\n exportStart = tn.tokenPos;\n exportEnd = tn.pos;\n if (tn.skip(Token.Default)) {\n defaultStart = tn.tokenPos;\n defaultEnd = tn.pos;\n }\n }\n\n let declareStart = 0;\n let declareEnd = 0;\n let contextIsAmbient = namespace != null && namespace.is(CommonFlags.Ambient);\n if (tn.skip(Token.Declare)) {\n if (contextIsAmbient) {\n this.error(\n DiagnosticCode.A_declare_modifier_cannot_be_used_in_an_already_ambient_context,\n tn.range()\n ); // recoverable\n } else {\n if (startPos < 0) startPos = tn.tokenPos;\n declareStart = startPos;\n declareEnd = tn.pos;\n flags |= CommonFlags.Declare | CommonFlags.Ambient;\n }\n } else if (contextIsAmbient) {\n flags |= CommonFlags.Ambient;\n }\n\n // parse the statement\n let statement: Statement | null = null;\n\n // handle declarations\n let first = tn.peek();\n if (startPos < 0) startPos = tn.nextTokenPos;\n switch (first) {\n case Token.Const: {\n tn.next();\n flags |= CommonFlags.Const;\n if (tn.skip(Token.Enum)) {\n statement = this.parseEnum(tn, flags, decorators, startPos);\n } else {\n statement = this.parseVariable(tn, flags, decorators, startPos);\n }\n decorators = null;\n break;\n }\n case Token.Let: flags |= CommonFlags.Let;\n case Token.Var: {\n tn.next();\n statement = this.parseVariable(tn, flags, decorators, startPos);\n decorators = null;\n break;\n }\n case Token.Enum: {\n tn.next();\n statement = this.parseEnum(tn, flags, decorators, startPos);\n decorators = null;\n break;\n }\n case Token.Function: {\n tn.next();\n statement = this.parseFunction(tn, flags, decorators, startPos);\n decorators = null;\n break;\n }\n case Token.Abstract: {\n let state = tn.mark();\n tn.next();\n let abstractStart = tn.tokenPos;\n let abstractEnd = tn.pos;\n if (tn.peekOnNewLine()) {\n tn.reset(state);\n statement = this.parseStatement(tn, true);\n break;\n }\n let next = tn.peek();\n if (next != Token.Class) {\n if (next == Token.Interface) {\n this.error(\n DiagnosticCode._abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration,\n tn.range(abstractStart, abstractEnd)\n );\n }\n tn.reset(state);\n statement = this.parseStatement(tn, true);\n break;\n } else {\n tn.discard(state);\n }\n flags |= CommonFlags.Abstract;\n // fall through\n }\n case Token.Class:\n case Token.Interface: {\n tn.next();\n statement = this.parseClassOrInterface(tn, flags, decorators, startPos);\n decorators = null;\n break;\n }\n case Token.Namespace: {\n let state = tn.mark();\n tn.next();\n if (tn.peek(IdentifierHandling.Prefer) == Token.Identifier) {\n tn.discard(state);\n statement = this.parseNamespace(tn, flags, decorators, startPos);\n decorators = null;\n } else {\n tn.reset(state);\n statement = this.parseStatement(tn, true);\n }\n break;\n }\n case Token.Import: {\n tn.next();\n flags |= CommonFlags.Import;\n if (flags & CommonFlags.Export) {\n statement = this.parseExportImport(tn, startPos);\n } else {\n statement = this.parseImport(tn);\n }\n break;\n }\n case Token.Type: { // also identifier\n let state = tn.mark();\n tn.next();\n if (tn.peek(IdentifierHandling.Prefer) == Token.Identifier) {\n tn.discard(state);\n statement = this.parseTypeDeclaration(tn, flags, decorators, startPos);\n decorators = null;\n } else {\n tn.reset(state);\n statement = this.parseStatement(tn, true);\n }\n break;\n }\n case Token.Module: { // also identifier\n let state = tn.mark();\n tn.next();\n if (tn.peek() == Token.StringLiteral && !tn.peekOnNewLine()) {\n tn.discard(state);\n statement = this.parseModuleDeclaration(tn, flags);\n } else {\n tn.reset(state);\n statement = this.parseStatement(tn, true);\n }\n break;\n }\n default: {\n\n // handle plain exports\n if (flags & CommonFlags.Export) {\n if (defaultEnd && tn.skipIdentifier(IdentifierHandling.Prefer)) {\n if (declareEnd) {\n this.error(\n DiagnosticCode.An_export_assignment_cannot_have_modifiers,\n tn.range(declareStart, declareEnd)\n );\n }\n statement = this.parseExportDefaultAlias(tn, startPos, defaultStart, defaultEnd);\n defaultStart = defaultEnd = 0; // consume\n } else {\n statement = this.parseExport(tn, startPos, (flags & CommonFlags.Declare) != 0);\n }\n\n // handle non-declaration statements\n } else {\n if (exportEnd) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(exportStart, exportEnd), \"export\"\n ); // recoverable\n }\n if (declareEnd) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(declareStart, declareEnd), \"declare\"\n ); // recoverable\n }\n if (!namespace) {\n statement = this.parseStatement(tn, true);\n } // TODO: else?\n }\n break;\n }\n }\n\n // check for decorators that weren't consumed\n if (decorators) {\n for (let i = 0, k = decorators.length; i < k; ++i) {\n this.error(\n DiagnosticCode.Decorators_are_not_valid_here,\n decorators[i].range\n );\n }\n }\n\n // check if this an `export default` declaration\n if (defaultEnd && statement != null) {\n switch (statement.kind) {\n case NodeKind.EnumDeclaration:\n case NodeKind.FunctionDeclaration:\n case NodeKind.ClassDeclaration:\n case NodeKind.InterfaceDeclaration:\n case NodeKind.NamespaceDeclaration: {\n return Node.createExportDefaultStatement(statement, tn.range(startPos, tn.pos));\n }\n default: {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(defaultStart, defaultEnd), \"default\"\n );\n }\n }\n }\n return statement;\n }\n\n /** Obtains the next file to parse. */\n nextFile(): string | null {\n let backlog = this.backlog;\n return backlog.length ? assert(backlog.shift()) : null;\n }\n\n /** Obtains the path of the dependee of the given imported file. */\n getDependee(dependent: string): string | null {\n let dependees = this.dependees;\n if (dependees.has(dependent)) {\n let dependee = assert(dependees.get(dependent));\n return dependee.source.internalPath;\n }\n return null;\n }\n\n /** Finishes parsing. */\n finish(): void {\n if (this.backlog.length) throw new Error(\"backlog is not empty\");\n this.backlog = [];\n this.seenlog.clear();\n this.donelog.clear();\n this.dependees.clear();\n }\n\n // types\n\n /** Parses a type name. */\n parseTypeName(\n tn: Tokenizer\n ): TypeName | null {\n\n // at: Identifier ('.' Identifier)*\n\n let first = Node.createSimpleTypeName(tn.readIdentifier(), tn.range());\n let current = first;\n while (tn.skip(Token.Dot)) {\n if (tn.skip(Token.Identifier)) {\n let next = Node.createSimpleTypeName(tn.readIdentifier(), tn.range());\n current.next = next;\n current = next;\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range(tn.pos)\n );\n return null;\n }\n }\n return first;\n }\n\n /** Parses a type. */\n parseType(\n tn: Tokenizer,\n acceptParenthesized: bool = true,\n suppressErrors: bool = false\n ): TypeNode | null {\n\n // before: Type\n\n // NOTE: this parses our limited subset\n let token = tn.next();\n let startPos = tn.tokenPos;\n\n let type: TypeNode;\n\n // '(' ...\n if (token == Token.OpenParen) {\n\n // '(' FunctionSignature ')'\n let isInnerParenthesized = tn.skip(Token.OpenParen);\n // FunctionSignature?\n let signature = this.tryParseFunctionType(tn);\n if (signature) {\n if (isInnerParenthesized) {\n if (!tn.skip(Token.CloseParen)) {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n }\n return null;\n }\n }\n type = signature;\n } else if (isInnerParenthesized || this.tryParseSignatureIsSignature) {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode.Unexpected_token,\n tn.range()\n );\n }\n return null;\n // Type (',' Type)* ')'\n } else if (acceptParenthesized) {\n let innerType = this.parseType(tn, false, suppressErrors);\n if (!innerType) return null;\n if (!tn.skip(Token.CloseParen)) {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \")\"\n );\n }\n return null;\n }\n type = innerType;\n type.range.start = startPos;\n type.range.end = tn.pos;\n } else {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode.Unexpected_token,\n tn.range()\n );\n }\n return null;\n }\n\n // 'void'\n } else if (token == Token.Void) {\n type = Node.createNamedType(\n Node.createSimpleTypeName(\"void\", tn.range()), [], false, tn.range(startPos, tn.pos)\n );\n\n // 'this'\n } else if (token == Token.This) {\n type = Node.createNamedType(\n Node.createSimpleTypeName(\"this\", tn.range()), [], false, tn.range(startPos, tn.pos)\n );\n\n // 'true'\n } else if (token == Token.True || token == Token.False) {\n type = Node.createNamedType(\n Node.createSimpleTypeName(\"bool\", tn.range()), [], false, tn.range(startPos, tn.pos)\n );\n\n // 'null'\n } else if (token == Token.Null) {\n type = Node.createNamedType(\n Node.createSimpleTypeName(\"null\", tn.range()), [], false, tn.range(startPos, tn.pos)\n );\n\n // StringLiteral\n } else if (token == Token.StringLiteral) {\n tn.readString();\n type = Node.createNamedType(\n Node.createSimpleTypeName(\"string\", tn.range()), [], false, tn.range(startPos, tn.pos)\n );\n\n // Identifier\n } else if (token == Token.Identifier) {\n let name = this.parseTypeName(tn);\n if (!name) return null;\n let parameters: TypeNode[] | null = null;\n\n // Name\n if (tn.skip(Token.LessThan)) {\n do {\n let parameter = this.parseType(tn, true, suppressErrors);\n if (!parameter) return null;\n if (!parameters) parameters = [ parameter ];\n else parameters.push(parameter);\n } while (tn.skip(Token.Comma));\n if (!tn.skip(Token.GreaterThan)) {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \">\"\n );\n }\n return null;\n }\n }\n if (!parameters) parameters = [];\n type = Node.createNamedType(name, parameters, false, tn.range(startPos, tn.pos));\n } else {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode.Type_expected,\n tn.range()\n );\n }\n return null;\n }\n // ... | type\n while (tn.skip(Token.Bar)) {\n let nextType = this.parseType(tn, false, true);\n if (!nextType) return null;\n let typeIsNull = type.kind == NodeKind.NamedType && (type).isNull;\n let nextTypeIsNull = nextType.kind == NodeKind.NamedType && (nextType).isNull;\n if (!typeIsNull && !nextTypeIsNull) {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode.Not_implemented_0, nextType.range, \"union types\"\n );\n }\n return null;\n } else if (nextTypeIsNull) {\n type.isNullable = true;\n type.range.end = nextType.range.end;\n } else if (typeIsNull) {\n nextType.range.start = type.range.start;\n nextType.isNullable = true;\n type = nextType;\n } else {\n // `null | null` still `null`\n type.range.end = nextType.range.end;\n }\n }\n // ... [][]\n while (tn.skip(Token.OpenBracket)) {\n let bracketStart = tn.tokenPos;\n if (!tn.skip(Token.CloseBracket)) {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"]\"\n );\n }\n return null;\n }\n let bracketRange = tn.range(bracketStart, tn.pos);\n\n // ...[] | null\n let nullable = false;\n if (tn.skip(Token.Bar)) {\n if (tn.skip(Token.Null)) {\n nullable = true;\n } else {\n if (!suppressErrors) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n tn.range(), \"union types\"\n );\n }\n return null;\n }\n }\n type = Node.createNamedType(\n Node.createSimpleTypeName(\"Array\", bracketRange),\n [ type ],\n nullable,\n tn.range(startPos, tn.pos)\n );\n if (nullable) break;\n }\n\n return type;\n }\n\n // Indicates whether tryParseSignature determined that it is handling a Signature\n private tryParseSignatureIsSignature: bool = false;\n\n /** Parses a function type, as used in type declarations. */\n tryParseFunctionType(\n tn: Tokenizer\n ): FunctionTypeNode | null {\n\n // at '(': ('...'? Identifier '?'? ':' Type (',' '...'? Identifier '?'? ':' Type)* )? ')' '=>' Type\n\n let state = tn.mark();\n let startPos = tn.tokenPos;\n let parameters: ParameterNode[] | null = null;\n let thisType: NamedTypeNode | null = null;\n let isSignature: bool = false;\n let firstParamNameNoType: IdentifierExpression | null = null;\n let firstParamKind: ParameterKind = ParameterKind.Default;\n\n if (tn.skip(Token.CloseParen)) {\n isSignature = true;\n tn.discard(state);\n parameters = [];\n\n } else {\n isSignature = false; // not yet known\n do {\n let paramStart = -1;\n let kind = ParameterKind.Default;\n if (tn.skip(Token.Dot_Dot_Dot)) {\n paramStart = tn.tokenPos;\n isSignature = true;\n tn.discard(state);\n kind = ParameterKind.Rest;\n }\n if (tn.skip(Token.This)) {\n if (paramStart < 0) paramStart = tn.tokenPos;\n if (tn.skip(Token.Colon)) {\n isSignature = true;\n tn.discard(state);\n let type = this.parseType(tn, false);\n if (!type) return null;\n if (type.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Identifier_expected,\n type.range\n );\n this.tryParseSignatureIsSignature = true;\n return null;\n }\n thisType = type;\n } else {\n tn.reset(state);\n this.tryParseSignatureIsSignature = false;\n return null;\n }\n } else if (tn.skipIdentifier()) {\n if (paramStart < 0) paramStart = tn.tokenPos;\n let name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range(tn.tokenPos, tn.pos));\n if (tn.skip(Token.Question)) {\n isSignature = true;\n tn.discard(state);\n if (kind == ParameterKind.Rest) {\n this.error(\n DiagnosticCode.A_rest_parameter_cannot_be_optional,\n tn.range()\n ); // recoverable\n } else {\n kind = ParameterKind.Optional;\n }\n }\n if (tn.skip(Token.Colon)) {\n isSignature = true;\n tn.discard(state);\n let type = this.parseType(tn); // not suppressing errors because known\n if (!type) {\n this.tryParseSignatureIsSignature = isSignature;\n return null;\n }\n let param = Node.createParameter(kind, name, type, null, tn.range(paramStart, tn.pos));\n if (!parameters) parameters = [ param ];\n else parameters.push(param);\n } else {\n if (!isSignature) {\n if (tn.peek() == Token.Comma) {\n isSignature = true;\n tn.discard(state);\n }\n }\n if (isSignature) {\n let param = Node.createParameter(kind, name, Node.createOmittedType(tn.range(tn.pos)), null, tn.range(paramStart, tn.pos));\n if (!parameters) parameters = [ param ];\n else parameters.push(param);\n this.error(\n DiagnosticCode.Type_expected,\n param.type.range\n ); // recoverable\n } else if (!parameters) {\n // on '(' Identifier ^',' we don't yet know whether this is a\n // parenthesized or a function type, hence we have to delay the\n // respective diagnostic until we know for sure.\n firstParamNameNoType = name;\n firstParamKind = kind;\n }\n }\n } else {\n if (isSignature) {\n if (tn.peek() == Token.CloseParen) break; // allow trailing comma\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n } else {\n tn.reset(state);\n }\n this.tryParseSignatureIsSignature = isSignature;\n return null;\n }\n } while (tn.skip(Token.Comma));\n if (!tn.skip(Token.CloseParen)) {\n if (isSignature) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n } else {\n tn.reset(state);\n }\n this.tryParseSignatureIsSignature = isSignature;\n return null;\n }\n }\n\n let returnType: TypeNode | null;\n if (tn.skip(Token.Equals_GreaterThan)) {\n if (!isSignature) {\n isSignature = true;\n tn.discard(state);\n if (firstParamNameNoType) { // now we know\n let param = Node.createParameter(\n firstParamKind,\n firstParamNameNoType,\n Node.createOmittedType(firstParamNameNoType.range.atEnd),\n null,\n firstParamNameNoType.range\n );\n if (!parameters) parameters = [ param ];\n else parameters.push(param);\n this.error(\n DiagnosticCode.Type_expected,\n param.type.range\n ); // recoverable\n }\n }\n returnType = this.parseType(tn);\n if (!returnType) {\n this.tryParseSignatureIsSignature = isSignature;\n return null;\n }\n } else {\n if (isSignature) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"=>\"\n );\n } else {\n tn.reset(state);\n }\n this.tryParseSignatureIsSignature = isSignature;\n return null;\n }\n this.tryParseSignatureIsSignature = true;\n\n if (!parameters) parameters = [];\n\n return Node.createFunctionType(\n parameters,\n returnType,\n thisType,\n false,\n tn.range(startPos, tn.pos)\n );\n }\n\n // statements\n\n parseDecorator(\n tn: Tokenizer\n ): DecoratorNode | null {\n\n // at '@': Identifier ('.' Identifier)* '(' Arguments\n\n let startPos = tn.tokenPos;\n if (tn.skipIdentifier()) {\n let name = tn.readIdentifier();\n let expression: Expression = Node.createIdentifierExpression(name, tn.range(startPos, tn.pos));\n while (tn.skip(Token.Dot)) {\n if (tn.skipIdentifier(IdentifierHandling.Prefer)) {\n name = tn.readIdentifier();\n expression = Node.createPropertyAccessExpression(\n expression,\n Node.createIdentifierExpression(name, tn.range()),\n tn.range(startPos, tn.pos)\n );\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n }\n let args: Expression[] | null;\n if (tn.skip(Token.OpenParen)) {\n args = this.parseArguments(tn);\n if (args) {\n return Node.createDecorator(expression, args, tn.range(startPos, tn.pos));\n }\n } else {\n return Node.createDecorator(expression, null, tn.range(startPos, tn.pos));\n }\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseVariable(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n startPos: i32,\n isFor: bool = false\n ): VariableStatement | null {\n\n // at ('const' | 'let' | 'var'): VariableDeclaration (',' VariableDeclaration)* ';'?\n\n let declarations = new Array();\n do {\n let declaration = this.parseVariableDeclaration(tn, flags, decorators, isFor);\n if (!declaration) return null;\n declaration.overriddenModuleName = this.currentModuleName;\n declarations.push(declaration);\n } while (tn.skip(Token.Comma));\n\n let ret = Node.createVariableStatement(decorators, declarations, tn.range(startPos, tn.pos));\n if (!tn.skip(Token.Semicolon) && !isFor) this.checkASI(tn);\n return ret;\n }\n\n parseVariableDeclaration(\n tn: Tokenizer,\n parentFlags: CommonFlags,\n parentDecorators: DecoratorNode[] | null,\n isFor: bool = false\n ): VariableDeclaration | null {\n\n // before: Identifier (':' Type)? ('=' Expression)?\n\n if (!tn.skipIdentifier()) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n if (isIllegalVariableIdentifier(identifier.text)) {\n this.error(\n DiagnosticCode.Identifier_expected,\n identifier.range\n );\n }\n let flags = parentFlags;\n if (tn.skip(Token.Exclamation)) {\n flags |= CommonFlags.DefinitelyAssigned;\n }\n\n let type: TypeNode | null = null;\n if (tn.skip(Token.Colon)) {\n type = this.parseType(tn, true);\n }\n\n let initializer: Expression | null = null;\n if (tn.skip(Token.Equals)) {\n if (flags & CommonFlags.Ambient) {\n this.error(\n DiagnosticCode.Initializers_are_not_allowed_in_ambient_contexts,\n tn.range()\n ); // recoverable\n }\n initializer = this.parseExpression(tn, Precedence.Comma + 1);\n if (!initializer) return null;\n if (flags & CommonFlags.DefinitelyAssigned) {\n this.error(\n DiagnosticCode.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions,\n initializer.range\n );\n }\n } else if (!isFor) {\n if (flags & CommonFlags.Const) {\n if (!(flags & CommonFlags.Ambient)) {\n this.error(\n DiagnosticCode._const_declarations_must_be_initialized,\n identifier.range\n ); // recoverable\n }\n } else if (!type) { // neither type nor initializer\n this.error(\n DiagnosticCode.Type_expected,\n tn.range(tn.pos)\n ); // recoverable\n }\n }\n let range = Range.join(identifier.range, tn.range());\n if ((flags & CommonFlags.DefinitelyAssigned) != 0 && (flags & CommonFlags.Ambient) != 0) {\n this.error(\n DiagnosticCode.A_definite_assignment_assertion_is_not_permitted_in_this_context,\n range\n );\n }\n return Node.createVariableDeclaration(\n identifier,\n parentDecorators,\n flags,\n type,\n initializer,\n range\n );\n }\n\n parseEnum(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n startPos: i32\n ): EnumDeclaration | null {\n\n // at 'enum': Identifier '{' (EnumValueDeclaration (',' EnumValueDeclaration )*)? '}' ';'?\n\n if (tn.next() != Token.Identifier) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n if (tn.next() != Token.OpenBrace) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n return null;\n }\n let members = new Array();\n while (!tn.skip(Token.CloseBrace)) {\n let member = this.parseEnumValue(tn, CommonFlags.None);\n if (!member) return null;\n members.push(member);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseBrace)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n }\n let ret = Node.createEnumDeclaration(\n identifier,\n decorators,\n flags,\n members,\n tn.range(startPos, tn.pos)\n );\n ret.overriddenModuleName = this.currentModuleName;\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseEnumValue(\n tn: Tokenizer,\n parentFlags: CommonFlags\n ): EnumValueDeclaration | null {\n\n // before: Identifier ('=' Expression)?\n\n if (!tn.skipIdentifier()) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let value: Expression | null = null;\n if (tn.skip(Token.Equals)) {\n value = this.parseExpression(tn, Precedence.Comma + 1);\n if (!value) return null;\n }\n return Node.createEnumValueDeclaration(\n identifier,\n parentFlags,\n value,\n Range.join(identifier.range, tn.range())\n );\n }\n\n parseReturn(\n tn: Tokenizer\n ): ReturnStatement | null {\n\n // at 'return': Expression | (';' | '}' | ...'\\n')\n\n let startPos = tn.tokenPos;\n let expr: Expression | null = null;\n let nextToken = tn.peek();\n if (\n nextToken != Token.Semicolon &&\n nextToken != Token.CloseBrace &&\n !tn.peekOnNewLine()\n ) {\n if (!(expr = this.parseExpression(tn))) return null;\n }\n\n let ret = Node.createReturnStatement(expr, tn.range(startPos, tn.pos));\n if (!tn.skip(Token.Semicolon)) this.checkASI(tn);\n return ret;\n }\n\n parseTypeParameters(\n tn: Tokenizer\n ): TypeParameterNode[] | null {\n\n // at '<': TypeParameter (',' TypeParameter)* '>'\n\n let typeParameters = new Array();\n let seenOptional = false;\n let start = tn.tokenPos;\n while (!tn.skip(Token.GreaterThan)) {\n let typeParameter = this.parseTypeParameter(tn);\n if (!typeParameter) return null;\n if (typeParameter.defaultType) {\n seenOptional = true;\n } else if (seenOptional) {\n this.error(\n DiagnosticCode.Required_type_parameters_may_not_follow_optional_type_parameters,\n typeParameter.range\n );\n typeParameter.defaultType = null;\n }\n typeParameters.push(typeParameter);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.GreaterThan)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \">\"\n );\n return null;\n }\n }\n }\n if (!typeParameters.length) {\n this.error(\n DiagnosticCode.Type_parameter_list_cannot_be_empty,\n tn.range(start, tn.pos)\n ); // recoverable\n }\n return typeParameters;\n }\n\n parseTypeParameter(\n tn: Tokenizer\n ): TypeParameterNode | null {\n\n // before: Identifier ('extends' Type)? ('=' Type)?\n\n if (tn.next() == Token.Identifier) {\n let identifier = Node.createIdentifierExpression(\n tn.readIdentifier(),\n tn.range()\n );\n let extendsType: NamedTypeNode | null = null;\n if (tn.skip(Token.Extends)) {\n let type = this.parseType(tn);\n if (!type) return null;\n if (type.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Identifier_expected,\n type.range\n );\n return null;\n }\n extendsType = type;\n }\n let defaultType: NamedTypeNode | null = null;\n if (tn.skip(Token.Equals)) {\n let type = this.parseType(tn);\n if (!type) return null;\n if (type.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Identifier_expected,\n type.range\n );\n return null;\n }\n defaultType = type;\n }\n return Node.createTypeParameter(\n identifier,\n extendsType,\n defaultType,\n Range.join(identifier.range, tn.range())\n );\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n private parseParametersThis: NamedTypeNode | null = null;\n\n parseParameters(\n tn: Tokenizer,\n isConstructor: bool = false\n ): ParameterNode[] | null {\n\n // at '(': (Parameter (',' Parameter)*)? ')'\n\n let parameters = new Array();\n let seenRest: ParameterNode | null = null;\n let seenOptional = false;\n let reportedRest = false;\n let thisType: TypeNode | null = null;\n\n // check if there is a leading `this` parameter\n this.parseParametersThis = null;\n if (tn.skip(Token.This)) {\n if (tn.skip(Token.Colon)) {\n thisType = this.parseType(tn); // reports\n if (!thisType) return null;\n if (thisType.kind == NodeKind.NamedType) {\n this.parseParametersThis = thisType;\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n thisType.range\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n return null;\n }\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseParen)) {\n return parameters;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n }\n }\n\n while (!tn.skip(Token.CloseParen)) {\n let param = this.parseParameter(tn, isConstructor); // reports\n if (!param) return null;\n if (seenRest && !reportedRest) {\n this.error(\n DiagnosticCode.A_rest_parameter_must_be_last_in_a_parameter_list,\n seenRest.name.range\n );\n reportedRest = true;\n }\n switch (param.parameterKind) {\n default: {\n if (seenOptional) {\n this.error(\n DiagnosticCode.A_required_parameter_cannot_follow_an_optional_parameter,\n param.name.range\n );\n }\n break;\n }\n case ParameterKind.Optional: {\n seenOptional = true;\n break;\n }\n case ParameterKind.Rest: {\n seenRest = param;\n break;\n }\n }\n parameters.push(param);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseParen)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n }\n }\n return parameters;\n }\n\n parseParameter(\n tn: Tokenizer,\n isConstructor: bool = false\n ): ParameterNode | null {\n\n // before: ('public' | 'private' | 'protected' | '...')? Identifier '?'? (':' Type)? ('=' Expression)?\n\n let isRest = false;\n let isOptional = false;\n let startRange: Range | null = null;\n let accessFlags: CommonFlags = CommonFlags.None;\n if (isConstructor) {\n if (tn.skip(Token.Public)) {\n startRange = tn.range();\n accessFlags |= CommonFlags.Public;\n } else if (tn.skip(Token.Protected)) {\n startRange = tn.range();\n accessFlags |= CommonFlags.Protected;\n } else if (tn.skip(Token.Private)) {\n startRange = tn.range();\n accessFlags |= CommonFlags.Private;\n }\n if (tn.peek() == Token.Readonly) {\n let state = tn.mark();\n tn.next();\n if (tn.peek() != Token.Colon) { // modifier\n tn.discard(state);\n if (!startRange) startRange = tn.range();\n accessFlags |= CommonFlags.Readonly;\n } else { // identifier\n tn.reset(state);\n }\n }\n }\n if (tn.skip(Token.Dot_Dot_Dot)) {\n if (accessFlags) {\n this.error(\n DiagnosticCode.A_parameter_property_cannot_be_declared_using_a_rest_parameter,\n tn.range()\n );\n } else {\n startRange = tn.range();\n }\n isRest = true;\n }\n if (tn.skipIdentifier()) {\n if (!isRest) startRange = tn.range();\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let type: TypeNode | null = null;\n if (isOptional = tn.skip(Token.Question)) {\n if (isRest) {\n this.error(\n DiagnosticCode.A_rest_parameter_cannot_be_optional,\n identifier.range\n );\n }\n }\n if (tn.skip(Token.Colon)) {\n type = this.parseType(tn);\n if (!type) return null;\n } else {\n type = Node.createOmittedType(tn.range(tn.pos));\n }\n let initializer: Expression | null = null;\n if (tn.skip(Token.Equals)) {\n if (isRest) {\n this.error(\n DiagnosticCode.A_rest_parameter_cannot_have_an_initializer,\n identifier.range\n );\n }\n if (isOptional) {\n this.error(\n DiagnosticCode.Parameter_cannot_have_question_mark_and_initializer,\n identifier.range\n );\n } else {\n isOptional = true;\n }\n initializer = this.parseExpression(tn, Precedence.Comma + 1);\n if (!initializer) return null;\n }\n let param = Node.createParameter(\n isRest\n ? ParameterKind.Rest\n : isOptional\n ? ParameterKind.Optional\n : ParameterKind.Default,\n identifier,\n type,\n initializer,\n Range.join(assert(startRange), tn.range())\n );\n param.flags |= accessFlags;\n return param;\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseFunction(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n startPos: i32\n ): FunctionDeclaration | null {\n\n // at 'function':\n // Identifier\n // ('<' TypeParameters)?\n // '(' Parameters (':' Type)?\n // '{' Statement* '}'\n // ';'?\n\n if (!tn.skipIdentifier()) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range(tn.pos)\n );\n return null;\n }\n\n let name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let signatureStart = -1;\n\n let typeParameters: TypeParameterNode[] | null = null;\n if (tn.skip(Token.LessThan)) {\n signatureStart = tn.tokenPos;\n typeParameters = this.parseTypeParameters(tn);\n if (!typeParameters) return null;\n flags |= CommonFlags.Generic;\n }\n\n if (!tn.skip(Token.OpenParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \"(\"\n );\n return null;\n }\n\n if (signatureStart < 0) {\n signatureStart = tn.tokenPos;\n }\n\n let parameters = this.parseParameters(tn);\n if (!parameters) return null;\n let thisType = this.parseParametersThis;\n\n let isSetter = (flags & CommonFlags.Set) != 0;\n if (isSetter) {\n if (parameters.length != 1) {\n this.error(\n DiagnosticCode.A_set_accessor_must_have_exactly_one_parameter,\n name.range\n ); // recoverable\n }\n if (parameters.length > 0 && parameters[0].initializer) {\n this.error(\n DiagnosticCode.A_set_accessor_parameter_cannot_have_an_initializer,\n name.range\n ); // recoverable\n }\n }\n\n if (flags & CommonFlags.Get) {\n if (parameters.length) {\n this.error(\n DiagnosticCode.A_get_accessor_cannot_have_parameters,\n name.range\n ); // recoverable\n }\n }\n\n let returnType: TypeNode | null = null;\n if (tn.skip(Token.Colon)) {\n returnType = this.parseType(tn, true, isSetter);\n if (!returnType) return null;\n }\n\n if (!returnType) {\n returnType = Node.createOmittedType(\n tn.range(tn.pos)\n );\n if (!isSetter) {\n this.error(\n DiagnosticCode.Type_expected,\n returnType.range\n ); // recoverable\n }\n }\n\n let signature = Node.createFunctionType(\n parameters,\n returnType,\n thisType,\n false,\n tn.range(signatureStart, tn.pos)\n );\n\n let body: Statement | null = null;\n if (tn.skip(Token.OpenBrace)) {\n if (flags & CommonFlags.Ambient) {\n this.error(\n DiagnosticCode.An_implementation_cannot_be_declared_in_ambient_contexts,\n tn.range()\n ); // recoverable\n }\n\n body = this.parseBlockStatement(tn, false);\n if (!body) return null;\n } else if (!(flags & CommonFlags.Ambient)) {\n this.error(\n DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration,\n tn.range(tn.pos)\n );\n }\n\n let ret = Node.createFunctionDeclaration(\n name,\n decorators,\n flags,\n typeParameters,\n signature,\n body,\n ArrowKind.None,\n tn.range(startPos, tn.pos)\n );\n ret.overriddenModuleName = this.currentModuleName;\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseFunctionExpression(tn: Tokenizer): FunctionExpression | null {\n let startPos = tn.tokenPos;\n let name: IdentifierExpression;\n let arrowKind = ArrowKind.None;\n\n // either at 'function':\n // Identifier?\n // '(' Parameters (':' Type)?\n // Statement\n\n if (tn.token == Token.Function) {\n if (tn.skipIdentifier()) {\n name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n } else { // empty name\n name = Node.createEmptyIdentifierExpression(tn.range(tn.pos));\n }\n if (!tn.skip(Token.OpenParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \"(\"\n );\n return null;\n }\n\n // or at '(' of arrow function:\n // Parameters (':' Type)?\n // Statement\n\n } else {\n arrowKind = ArrowKind.Parenthesized;\n assert(tn.token == Token.OpenParen);\n name = Node.createEmptyIdentifierExpression(tn.range(tn.tokenPos));\n }\n\n // TODO: type parameters? doesn't seem worth it.\n\n let signatureStart = tn.pos;\n let parameters = this.parseParameters(tn);\n if (!parameters) return null;\n\n return this.parseFunctionExpressionCommon(tn, name, parameters, this.parseParametersThis, arrowKind, startPos, signatureStart);\n }\n\n private parseFunctionExpressionCommon(\n tn: Tokenizer,\n name: IdentifierExpression,\n parameters: ParameterNode[],\n explicitThis: NamedTypeNode | null,\n arrowKind: ArrowKind,\n startPos: i32 = -1,\n signatureStart: i32 = -1\n ): FunctionExpression | null {\n if (startPos < 0) startPos = name.range.start;\n if (signatureStart < 0) signatureStart = startPos;\n\n let returnType: TypeNode | null = null;\n if (arrowKind != ArrowKind.Single && tn.skip(Token.Colon)) {\n returnType = this.parseType(tn);\n if (!returnType) return null;\n } else {\n returnType = Node.createOmittedType(tn.range(tn.pos));\n }\n\n if (arrowKind) {\n if (!tn.skip(Token.Equals_GreaterThan)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \"=>\"\n );\n return null;\n }\n }\n\n let signature = Node.createFunctionType(\n parameters,\n returnType,\n explicitThis,\n false,\n tn.range(signatureStart, tn.pos)\n );\n\n let body: Statement | null = null;\n if (arrowKind) {\n if (tn.skip(Token.OpenBrace)) {\n body = this.parseBlockStatement(tn, false);\n } else {\n let bodyExpression = this.parseExpression(tn, Precedence.Comma + 1);\n if (bodyExpression) body = Node.createExpressionStatement(bodyExpression);\n }\n } else {\n if (!tn.skip(Token.OpenBrace)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \"{\"\n );\n return null;\n }\n body = this.parseBlockStatement(tn, false);\n }\n if (!body) return null;\n\n let declaration = Node.createFunctionDeclaration(\n name,\n null,\n CommonFlags.None,\n null,\n signature,\n body,\n arrowKind,\n tn.range(startPos, tn.pos)\n );\n return Node.createFunctionExpression(declaration);\n }\n\n parseClassOrInterface(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n startPos: i32\n ): ClassDeclaration | null {\n\n // at ('class' | 'interface'):\n // Identifier\n // ('<' TypeParameters)?\n // ('extends' Type)?\n // ('implements' Type (',' Type)*)?\n // '{' ClassMember* '}'\n\n let isInterface = tn.token == Token.Interface;\n\n if (!tn.skipIdentifier()) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n\n let identifier = Node.createIdentifierExpression(\n tn.readIdentifier(),\n tn.range()\n );\n\n let typeParameters: TypeParameterNode[] | null = null;\n if (tn.skip(Token.LessThan)) {\n typeParameters = this.parseTypeParameters(tn);\n if (!typeParameters) return null;\n flags |= CommonFlags.Generic;\n }\n\n let extendsType: NamedTypeNode | null = null;\n if (tn.skip(Token.Extends)) {\n let type = this.parseType(tn);\n if (!type) return null;\n if (type.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Identifier_expected,\n type.range\n );\n return null;\n }\n extendsType = type;\n }\n\n let implementsTypes: NamedTypeNode[] | null = null;\n if (tn.skip(Token.Implements)) {\n if (isInterface) {\n this.error(\n DiagnosticCode.Interface_declaration_cannot_have_implements_clause,\n tn.range()\n ); // recoverable\n }\n do {\n let type = this.parseType(tn);\n if (!type) return null;\n if (type.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Identifier_expected,\n type.range\n );\n return null;\n }\n if (!isInterface) {\n if (!implementsTypes) implementsTypes = [];\n implementsTypes.push(type);\n }\n } while (tn.skip(Token.Comma));\n }\n\n if (!tn.skip(Token.OpenBrace)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n return null;\n }\n\n let members = new Array();\n let declaration: ClassDeclaration;\n if (isInterface) {\n assert(!implementsTypes);\n declaration = Node.createInterfaceDeclaration(\n identifier,\n decorators,\n flags,\n typeParameters,\n extendsType,\n null,\n members,\n tn.range(startPos, tn.pos)\n );\n } else {\n declaration = Node.createClassDeclaration(\n identifier,\n decorators,\n flags,\n typeParameters,\n extendsType,\n implementsTypes,\n members,\n tn.range(startPos, tn.pos)\n );\n }\n if (!tn.skip(Token.CloseBrace)) {\n do {\n let member = this.parseClassMember(tn, declaration);\n if (member) {\n if (member.kind == NodeKind.IndexSignature) {\n declaration.indexSignature = member;\n } else {\n assert(member instanceof DeclarationStatement);\n members.push(member);\n }\n } else {\n this.skipStatement(tn);\n if (tn.skip(Token.EndOfFile)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n } while (!tn.skip(Token.CloseBrace));\n }\n declaration.range.end = tn.pos;\n declaration.overriddenModuleName = this.currentModuleName;\n return declaration;\n }\n\n parseClassExpression(tn: Tokenizer): ClassExpression | null {\n\n // at 'class': Identifier? '{' ... '}'\n\n let startPos = tn.tokenPos;\n let name: IdentifierExpression;\n\n if (tn.skipIdentifier()) {\n name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n } else {\n name = Node.createEmptyIdentifierExpression(tn.range(tn.pos));\n }\n\n if (!tn.skip(Token.OpenBrace)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(tn.pos), \"{\"\n );\n return null;\n }\n\n let members = new Array();\n let declaration = Node.createClassDeclaration(\n name,\n null,\n CommonFlags.None,\n null,\n null,\n null,\n members,\n tn.range(startPos, tn.pos)\n );\n if (!tn.skip(Token.CloseBrace)) {\n do {\n let member = this.parseClassMember(tn, declaration);\n if (member) {\n if (member.kind == NodeKind.IndexSignature) {\n declaration.indexSignature = member;\n } else {\n assert(declaration instanceof DeclarationStatement);\n members.push(member);\n }\n } else {\n this.skipStatement(tn);\n if (tn.skip(Token.EndOfFile)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n } while (!tn.skip(Token.CloseBrace));\n }\n declaration.range.end = tn.pos;\n return Node.createClassExpression(declaration);\n }\n\n parseClassMember(\n tn: Tokenizer,\n parent: ClassDeclaration\n ): Node | null {\n\n // before:\n // 'declare'?\n // ('public' | 'private' | 'protected')?\n // ('static' | 'abstract')?\n // 'override'?\n // 'readonly'?\n // ('get' | 'set')?\n // Identifier ...\n\n let isInterface = parent.kind == NodeKind.InterfaceDeclaration;\n let startPos = 0;\n let decorators: DecoratorNode[] | null = null;\n if (tn.skip(Token.At)) {\n startPos = tn.tokenPos;\n do {\n let decorator = this.parseDecorator(tn);\n if (!decorator) break;\n if (!decorators) decorators = new Array();\n decorators.push(decorator);\n } while (tn.skip(Token.At));\n if (isInterface && decorators) {\n this.error(\n DiagnosticCode.Decorators_are_not_valid_here,\n Range.join(decorators[0].range, decorators[decorators.length - 1].range)\n );\n }\n }\n\n // inherit ambient status\n let flags = parent.flags & CommonFlags.Ambient;\n\n // interface methods are always overridden if used\n if (isInterface) flags |= CommonFlags.Overridden;\n\n let declareStart = 0;\n let declareEnd = 0;\n let contextIsAmbient = parent.is(CommonFlags.Ambient);\n if (tn.skip(Token.Declare)) {\n if (isInterface) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"declare\"\n );\n } else {\n if (contextIsAmbient) {\n this.error(\n DiagnosticCode.A_declare_modifier_cannot_be_used_in_an_already_ambient_context,\n tn.range()\n ); // recoverable\n } else {\n flags |= CommonFlags.Declare | CommonFlags.Ambient;\n declareStart = tn.tokenPos;\n declareEnd = tn.pos;\n }\n }\n if (!startPos) startPos = tn.tokenPos;\n } else if (contextIsAmbient) {\n flags |= CommonFlags.Ambient;\n }\n\n let accessStart = 0;\n let accessEnd = 0;\n if (tn.skip(Token.Public)) {\n if (isInterface) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"public\"\n );\n } else {\n flags |= CommonFlags.Public;\n accessStart = tn.tokenPos;\n accessEnd = tn.pos;\n }\n if (!startPos) startPos = tn.tokenPos;\n } else if (tn.skip(Token.Private)) {\n if (isInterface) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"private\"\n );\n } else {\n flags |= CommonFlags.Private;\n accessStart = tn.tokenPos;\n accessEnd = tn.pos;\n }\n if (!startPos) startPos = tn.tokenPos;\n } else if (tn.skip(Token.Protected)) {\n if (isInterface) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"protected\"\n );\n } else {\n flags |= CommonFlags.Protected;\n accessStart = tn.tokenPos;\n accessEnd = tn.pos;\n }\n if (!startPos) startPos = tn.tokenPos;\n }\n\n let staticStart = 0;\n let staticEnd = 0;\n let abstractStart = 0;\n let abstractEnd = 0;\n if (tn.skip(Token.Static)) {\n if (isInterface) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"static\"\n );\n } else {\n flags |= CommonFlags.Static;\n staticStart = tn.tokenPos;\n staticEnd = tn.pos;\n }\n if (!startPos) startPos = tn.tokenPos;\n } else {\n flags |= CommonFlags.Instance;\n if (tn.skip(Token.Abstract)) {\n if (isInterface || !parent.is(CommonFlags.Abstract)) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"abstract\"\n );\n } else {\n flags |= CommonFlags.Abstract;\n abstractStart = tn.tokenPos;\n abstractEnd = tn.pos;\n }\n if (!startPos) startPos = tn.tokenPos;\n }\n if (parent.flags & CommonFlags.Generic) flags |= CommonFlags.GenericContext;\n }\n\n let overrideStart = 0;\n let overrideEnd = 0;\n if (tn.skip(Token.Override)) {\n if (isInterface || parent.extendsType == null) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(), \"override\"\n );\n } else {\n flags |= CommonFlags.Override;\n overrideStart = tn.tokenPos;\n overrideEnd = tn.pos;\n }\n if (!startPos) startPos = tn.tokenPos;\n }\n\n let readonlyStart = 0;\n let readonlyEnd = 0;\n if (tn.peek() == Token.Readonly) {\n let state = tn.mark();\n tn.next();\n if (tn.peek() != Token.Colon) { // modifier\n tn.discard(state);\n flags |= CommonFlags.Readonly;\n readonlyStart = tn.tokenPos;\n readonlyEnd = tn.pos;\n if (!startPos) startPos = readonlyStart;\n } else { // identifier\n tn.reset(state);\n }\n }\n\n // check if accessor: ('get' | 'set') ^\\n Identifier\n let state = tn.mark();\n let isConstructor = false;\n let isGetter = false;\n let getStart = 0;\n let getEnd = 0;\n let isSetter = false;\n let setStart = 0;\n let setEnd = 0;\n if (!isInterface) {\n if (tn.skip(Token.Get)) {\n if (tn.peek(IdentifierHandling.Prefer) == Token.Identifier && !tn.peekOnNewLine()) {\n flags |= CommonFlags.Get;\n isGetter = true;\n getStart = tn.tokenPos;\n getEnd = tn.pos;\n if (!startPos) startPos = getStart;\n if (flags & CommonFlags.Readonly) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(readonlyStart, readonlyEnd), \"readonly\"\n ); // recoverable\n }\n } else {\n tn.reset(state);\n }\n } else if (tn.skip(Token.Set)) {\n if (tn.peek(IdentifierHandling.Prefer) == Token.Identifier && !tn.peekOnNewLine()) {\n flags |= CommonFlags.Set;\n isSetter = true;\n setStart = tn.tokenPos;\n setEnd = tn.pos;\n if (!startPos) startPos = setStart;\n if (flags & CommonFlags.Readonly) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(readonlyStart, readonlyEnd), \"readonly\"\n ); // recoverable\n }\n } else {\n tn.reset(state);\n }\n } else if (tn.skip(Token.Constructor)) {\n flags |= CommonFlags.Constructor;\n isConstructor = true;\n if (!startPos) startPos = tn.tokenPos;\n if (flags & CommonFlags.Static) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(staticStart, staticEnd), \"static\"\n ); // recoverable\n }\n if (flags & CommonFlags.Abstract) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(abstractStart, abstractEnd), \"abstract\"\n ); // recoverable\n }\n if (flags & CommonFlags.Readonly) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(readonlyStart, readonlyEnd), \"readonly\"\n ); // recoverable\n }\n }\n }\n\n let isGetterOrSetter = isGetter || isSetter;\n let name: IdentifierExpression;\n if (isConstructor) {\n name = Node.createConstructorExpression(tn.range());\n } else {\n if (!isGetterOrSetter && tn.skip(Token.OpenBracket)) {\n if (!startPos) startPos = tn.tokenPos;\n // TODO: also handle symbols, which might have some of these modifiers\n if (flags & CommonFlags.Public) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(accessStart, accessEnd), \"public\"\n ); // recoverable\n } else if (flags & CommonFlags.Protected) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(accessStart, accessEnd), \"protected\"\n ); // recoverable\n } else if (flags & CommonFlags.Private) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(accessStart, accessEnd), \"private\"\n ); // recoverable\n }\n if (flags & CommonFlags.Static) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(staticStart, staticEnd), \"static\"\n ); // recoverable\n }\n if (flags & CommonFlags.Override) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(overrideStart, overrideEnd), \"override\"\n );\n }\n if (flags & CommonFlags.Abstract) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(abstractStart, abstractEnd), \"abstract\"\n ); // recoverable\n }\n let retIndex = this.parseIndexSignature(tn, flags, decorators);\n if (!retIndex) {\n if (flags & CommonFlags.Readonly) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(readonlyStart, readonlyEnd), \"readonly\"\n ); // recoverable\n }\n return null;\n }\n tn.skip(Token.Semicolon);\n return retIndex;\n }\n if (!tn.skipIdentifier(IdentifierHandling.Always)) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n if (!startPos) startPos = tn.tokenPos;\n name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n }\n let typeParameters: TypeParameterNode[] | null = null;\n if (tn.skip(Token.LessThan)) {\n let typeParametersStart = tn.tokenPos;\n typeParameters = this.parseTypeParameters(tn);\n if (!typeParameters) return null;\n if (isConstructor) {\n this.error(\n DiagnosticCode.Type_parameters_cannot_appear_on_a_constructor_declaration,\n tn.range(typeParametersStart, tn.pos)\n ); // recoverable\n } else if (isGetterOrSetter) {\n this.error(\n DiagnosticCode.An_accessor_cannot_have_type_parameters,\n tn.range(typeParametersStart, tn.pos)\n ); // recoverable\n } else {\n flags |= CommonFlags.Generic;\n }\n }\n\n // method: '(' Parameters (':' Type)? '{' Statement* '}' ';'?\n if (tn.skip(Token.OpenParen)) {\n if (flags & CommonFlags.Declare) {\n this.error(\n DiagnosticCode._0_modifier_cannot_appear_on_class_elements_of_this_kind,\n tn.range(declareStart, declareEnd), \"declare\"\n ); // recoverable\n }\n\n let signatureStart = tn.tokenPos;\n let parameters = this.parseParameters(tn, isConstructor);\n if (!parameters) return null;\n let thisType = this.parseParametersThis;\n if (isConstructor) {\n for (let i = 0, k = parameters.length; i < k; ++i) {\n let parameter = parameters[i];\n if (parameter.isAny(\n CommonFlags.Public |\n CommonFlags.Protected |\n CommonFlags.Private |\n CommonFlags.Readonly\n )) {\n let implicitFieldDeclaration = Node.createFieldDeclaration(\n parameter.name,\n null,\n parameter.flags | CommonFlags.Instance,\n parameter.type,\n null, // initialized via parameter\n parameter.range\n );\n implicitFieldDeclaration.parameterIndex = i;\n parameter.implicitFieldDeclaration = implicitFieldDeclaration;\n parent.members.push(implicitFieldDeclaration);\n }\n }\n } else if (isGetter) {\n if (parameters.length) {\n this.error(\n DiagnosticCode.A_get_accessor_cannot_have_parameters,\n name.range\n );\n }\n } else if (isSetter) {\n if (parameters.length != 1) {\n this.error(\n DiagnosticCode.A_set_accessor_must_have_exactly_one_parameter,\n name.range\n );\n }\n if (parameters.length > 0 && parameters[0].initializer) {\n this.error(\n DiagnosticCode.A_set_accessor_parameter_cannot_have_an_initializer,\n name.range\n );\n }\n } else if (name.text == \"constructor\") {\n this.error(\n DiagnosticCode._0_keyword_cannot_be_used_here,\n name.range, \"constructor\"\n );\n }\n\n let returnType: TypeNode | null = null;\n if (tn.skip(Token.Colon)) {\n if (name.kind == NodeKind.Constructor) {\n this.error(\n DiagnosticCode.Type_annotation_cannot_appear_on_a_constructor_declaration,\n tn.range()\n );\n } else if (isSetter) {\n this.error(\n DiagnosticCode.A_set_accessor_cannot_have_a_return_type_annotation,\n tn.range()\n );\n }\n returnType = this.parseType(tn, isSetter || name.kind == NodeKind.Constructor);\n if (!returnType) return null;\n } else {\n returnType = Node.createOmittedType(tn.range(tn.pos));\n if (!isSetter && name.kind != NodeKind.Constructor) {\n this.error(\n DiagnosticCode.Type_expected,\n returnType.range\n ); // recoverable\n }\n }\n\n let signature = Node.createFunctionType(\n parameters,\n returnType,\n thisType,\n false,\n tn.range(signatureStart, tn.pos)\n );\n\n let body: Statement | null = null;\n if (tn.skip(Token.OpenBrace)) {\n if (flags & CommonFlags.Ambient) {\n this.error(\n DiagnosticCode.An_implementation_cannot_be_declared_in_ambient_contexts,\n tn.range()\n ); // recoverable\n } else if (flags & CommonFlags.Abstract) {\n this.error(\n DiagnosticCode.Method_0_cannot_have_an_implementation_because_it_is_marked_abstract,\n tn.range(), name.text\n ); // recoverable\n } else if (isInterface) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \";\"\n ); // recoverable\n }\n body = this.parseBlockStatement(tn, false);\n if (!body) return null;\n } else if (!isInterface && !(flags & (CommonFlags.Ambient | CommonFlags.Abstract))) {\n this.error(\n DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration,\n tn.range()\n ); // recoverable\n }\n\n let retMethod = Node.createMethodDeclaration(\n name,\n decorators,\n flags,\n typeParameters,\n signature,\n body,\n tn.range(startPos, tn.pos)\n );\n if (!(isInterface && tn.skip(Token.Comma))) {\n tn.skip(Token.Semicolon);\n }\n return retMethod;\n\n } else if (isConstructor) {\n this.error(\n DiagnosticCode.Constructor_implementation_is_missing,\n name.range\n );\n\n } else if (isGetterOrSetter) {\n this.error(\n DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration,\n name.range\n );\n\n // field: (':' Type)? ('=' Expression)? ';'?\n } else {\n if (flags & CommonFlags.Declare) {\n this.error(\n DiagnosticCode.Not_implemented_0,\n tn.range(declareStart, declareEnd), \"Ambient fields\"\n ); // recoverable\n }\n\n if (flags & CommonFlags.Abstract) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(abstractStart, abstractEnd), \"abstract\"\n ); // recoverable\n }\n\n if (flags & CommonFlags.Get) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(getStart, getEnd), \"get\"\n ); // recoverable\n }\n\n if (flags & CommonFlags.Set) {\n this.error(\n DiagnosticCode._0_modifier_cannot_be_used_here,\n tn.range(setStart, setEnd), \"set\"\n ); // recoverable\n }\n\n let type: TypeNode | null = null;\n if (tn.skip(Token.Question)) {\n this.error(\n DiagnosticCode.Optional_properties_are_not_supported,\n tn.range(startPos, tn.pos)\n );\n }\n if (tn.skip(Token.Exclamation)) {\n flags |= CommonFlags.DefinitelyAssigned;\n }\n if (tn.skip(Token.Colon)) {\n type = this.parseType(tn);\n if (!type) return null;\n } else {\n this.error(\n DiagnosticCode.Type_expected,\n tn.range()\n ); // recoverable\n }\n let initializer: Expression | null = null;\n if (tn.skip(Token.Equals)) {\n if (flags & CommonFlags.Ambient) {\n this.error(\n DiagnosticCode.Initializers_are_not_allowed_in_ambient_contexts,\n tn.range()\n ); // recoverable\n }\n initializer = this.parseExpression(tn);\n if (!initializer) return null;\n if (flags & CommonFlags.DefinitelyAssigned) {\n this.error(\n DiagnosticCode.Declarations_with_initializers_cannot_also_have_definite_assignment_assertions,\n name.range\n );\n }\n }\n let range = tn.range(startPos, tn.pos);\n if ((flags & CommonFlags.DefinitelyAssigned) != 0 && (isInterface || (flags & CommonFlags.Ambient) != 0)) {\n this.error(\n DiagnosticCode.A_definite_assignment_assertion_is_not_permitted_in_this_context,\n range\n );\n }\n let retField = Node.createFieldDeclaration(\n name,\n decorators,\n flags,\n type,\n initializer,\n range\n );\n if (!(isInterface && tn.skip(Token.Comma))) {\n tn.skip(Token.Semicolon);\n }\n return retField;\n }\n return null;\n }\n\n parseIndexSignature(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n ): IndexSignatureNode | null {\n\n // at: '[': 'key' ':' Type ']' ':' Type\n\n if (decorators && decorators.length > 0) {\n this.error(\n DiagnosticCode.Decorators_are_not_valid_here,\n Range.join(decorators[0].range, decorators[decorators.length - 1].range)\n ); // recoverable\n }\n\n let start = tn.tokenPos;\n if (tn.skipIdentifier()) {\n let id = tn.readIdentifier();\n if (id == \"key\") {\n if (tn.skip(Token.Colon)) {\n let keyType = this.parseType(tn);\n if (!keyType) return null;\n if (keyType.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Type_expected,\n tn.range()\n );\n return null;\n }\n if (tn.skip(Token.CloseBracket)) {\n if (tn.skip(Token.Colon)) {\n let valueType = this.parseType(tn);\n if (!valueType) return null;\n if (valueType.kind != NodeKind.NamedType) {\n this.error(\n DiagnosticCode.Identifier_expected,\n valueType.range\n );\n return null;\n }\n return Node.createIndexSignature(keyType, valueType, flags, tn.range(start, tn.pos));\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"]\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"key\"\n );\n }\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseNamespace(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n startPos: i32\n ): NamespaceDeclaration | null {\n\n // at 'namespace': Identifier '{' (Variable | Function)* '}'\n\n if (tn.skipIdentifier()) {\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n if (tn.skip(Token.OpenBrace)) {\n let members = new Array();\n let declaration = Node.createNamespaceDeclaration(\n identifier,\n decorators,\n flags,\n members,\n tn.range(startPos, tn.pos)\n );\n while (!tn.skip(Token.CloseBrace)) {\n let member = this.parseTopLevelStatement(tn, declaration);\n if (member) {\n if (member.kind == NodeKind.Export) {\n this.error(\n DiagnosticCode.A_default_export_can_only_be_used_in_a_module,\n member.range,\n );\n return null;\n }\n members.push(member);\n } else {\n this.skipStatement(tn);\n if (tn.skip(Token.EndOfFile)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n }\n declaration.range.end = tn.pos;\n declaration.overriddenModuleName = this.currentModuleName;\n tn.skip(Token.Semicolon);\n return declaration;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n }\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseExport(\n tn: Tokenizer,\n startPos: i32,\n isDeclare: bool\n ): ExportStatement | null {\n\n // at 'export': '{' ExportMember (',' ExportMember)* }' ('from' StringLiteral)? ';'?\n\n let path: StringLiteralExpression | null = null;\n let currentSource = assert(this.currentSource);\n if (tn.skip(Token.OpenBrace)) {\n let members = new Array();\n while (!tn.skip(Token.CloseBrace)) {\n let member = this.parseExportMember(tn);\n if (!member) return null;\n members.push(member);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseBrace)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n }\n if (tn.skip(Token.From)) {\n if (tn.skip(Token.StringLiteral)) {\n path = Node.createStringLiteralExpression(tn.readString(), tn.range());\n } else {\n this.error(\n DiagnosticCode.String_literal_expected,\n tn.range()\n );\n return null;\n }\n }\n let ret = Node.createExportStatement(members, path, isDeclare, tn.range(startPos, tn.pos));\n if (path) {\n let internalPath = assert(ret.internalPath);\n if (!this.seenlog.has(internalPath)) {\n this.dependees.set(internalPath, new Dependee(currentSource, path));\n this.backlog.push(internalPath);\n this.seenlog.add(internalPath);\n }\n }\n tn.skip(Token.Semicolon);\n return ret;\n } else if (tn.skip(Token.Asterisk)) {\n if (tn.skip(Token.From)) {\n if (tn.skip(Token.StringLiteral)) {\n path = Node.createStringLiteralExpression(tn.readString(), tn.range());\n let ret = Node.createExportStatement(null, path, isDeclare, tn.range(startPos, tn.pos));\n let internalPath = assert(ret.internalPath);\n let source = tn.source;\n let exportPaths = source.exportPaths;\n if (!exportPaths) source.exportPaths = [ internalPath ];\n else if (!exportPaths.includes(internalPath)) exportPaths.push(internalPath);\n if (!this.seenlog.has(internalPath)) {\n this.dependees.set(internalPath, new Dependee(currentSource, path));\n this.backlog.push(internalPath);\n }\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode.String_literal_expected,\n tn.range()\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"from\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n }\n return null;\n }\n\n parseExportMember(\n tn: Tokenizer\n ): ExportMember | null {\n\n // before: Identifier ('as' Identifier)?\n\n if (tn.skipIdentifier(IdentifierHandling.Always)) {\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let asIdentifier: IdentifierExpression | null = null;\n if (tn.skip(Token.As)) {\n if (tn.skipIdentifier(IdentifierHandling.Always)) {\n asIdentifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n }\n if (asIdentifier) {\n return Node.createExportMember(\n identifier,\n asIdentifier,\n Range.join(identifier.range, asIdentifier.range)\n );\n }\n return Node.createExportMember(\n identifier,\n null,\n identifier.range\n );\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseExportDefaultAlias(\n tn: Tokenizer,\n startPos: i32,\n defaultStart: i32,\n defaultEnd: i32\n ): ExportStatement {\n\n // at 'export' 'default': [Known-To-Be-]Identifier\n\n let name = tn.readIdentifier();\n let range = tn.range();\n let ret = Node.createExportStatement([\n Node.createExportMember(\n Node.createIdentifierExpression(name, range),\n Node.createIdentifierExpression(\"default\", tn.range(defaultStart, defaultEnd)),\n range\n )\n ], null, false, tn.range(startPos, tn.pos));\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseImport(\n tn: Tokenizer\n ): ImportStatement | null {\n\n // at 'import':\n // ('{' (ImportMember (',' ImportMember)* '}') | ('*' 'as' Identifier)?\n // 'from' StringLiteral ';'?\n\n let startPos = tn.tokenPos;\n let members: ImportDeclaration[] | null = null;\n let namespaceName: IdentifierExpression | null = null;\n let skipFrom = false;\n if (tn.skip(Token.OpenBrace)) { // import { ... } from \"file\"\n members = new Array();\n while (!tn.skip(Token.CloseBrace)) {\n let member = this.parseImportDeclaration(tn);\n if (!member) return null;\n members.push(member);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseBrace)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n }\n } else if (tn.skip(Token.Asterisk)) { // import * from \"file\"\n if (tn.skip(Token.As)) {\n if (tn.skipIdentifier()) {\n namespaceName = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"as\"\n );\n return null;\n }\n } else if (tn.skip(Token.Identifier, IdentifierHandling.Prefer)) { // import Name from \"file\"\n let name = tn.readIdentifier();\n let range = tn.range();\n members = [\n Node.createImportDeclaration(\n Node.createIdentifierExpression(\"default\", range),\n Node.createIdentifierExpression(name, range),\n range\n )\n ];\n if (tn.skip(Token.Comma)) {\n // TODO: default + star, default + members\n this.error(\n DiagnosticCode.Not_implemented_0,\n tn.range(),\n \"Mixed default and named imports\"\n );\n return null;\n }\n } else { // import \"file\"\n skipFrom = true;\n }\n\n if (skipFrom || tn.skip(Token.From)) {\n if (tn.skip(Token.StringLiteral)) {\n let path = Node.createStringLiteralExpression(tn.readString(), tn.range());\n let ret: ImportStatement;\n if (namespaceName) {\n assert(!members);\n ret = Node.createWildcardImportStatement(namespaceName, path, tn.range(startPos, tn.pos));\n } else {\n ret = Node.createImportStatement(members, path, tn.range(startPos, tn.pos));\n }\n let internalPath = ret.internalPath;\n if (!this.seenlog.has(internalPath)) {\n this.dependees.set(internalPath, new Dependee(assert(this.currentSource), path));\n this.backlog.push(internalPath);\n }\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode.String_literal_expected,\n tn.range()\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"from\"\n );\n }\n return null;\n }\n\n parseImportDeclaration(\n tn: Tokenizer\n ): ImportDeclaration | null {\n\n // before: Identifier ('as' Identifier)?\n\n if (tn.skipIdentifier(IdentifierHandling.Always)) {\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let asIdentifier: IdentifierExpression | null = null;\n if (tn.skip(Token.As)) {\n if (tn.skipIdentifier()) {\n asIdentifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n }\n if (asIdentifier) {\n return Node.createImportDeclaration(\n identifier,\n asIdentifier,\n Range.join(identifier.range, asIdentifier.range)\n );\n }\n return Node.createImportDeclaration(\n identifier,\n null,\n identifier.range\n );\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseExportImport(\n tn: Tokenizer,\n startPos: i32\n ): ExportImportStatement | null {\n\n // at 'export' 'import': Identifier ('=' Identifier)? ';'?\n\n if (tn.skipIdentifier()) {\n let asIdentifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n if (tn.skip(Token.Equals)) {\n if (tn.skipIdentifier()) {\n let identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let ret = Node.createExportImportStatement(identifier, asIdentifier, tn.range(startPos, tn.pos));\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"=\"\n );\n }\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseStatement(\n tn: Tokenizer,\n topLevel: bool = false\n ): Statement | null {\n\n // at previous token\n\n let state = tn.mark();\n let token = tn.next();\n let statement: Statement | null = null;\n switch (token) {\n case Token.Break: {\n statement = this.parseBreak(tn);\n break;\n }\n case Token.Const: {\n statement = this.parseVariable(tn, CommonFlags.Const, null, tn.tokenPos);\n break;\n }\n case Token.Continue: {\n statement = this.parseContinue(tn);\n break;\n }\n case Token.Do: {\n statement = this.parseDoStatement(tn);\n break;\n }\n case Token.For: {\n statement = this.parseForStatement(tn);\n break;\n }\n case Token.If: {\n statement = this.parseIfStatement(tn);\n break;\n }\n case Token.Let: {\n statement = this.parseVariable(tn, CommonFlags.Let, null, tn.tokenPos);\n break;\n }\n case Token.Var: {\n statement = this.parseVariable(tn, CommonFlags.None, null, tn.tokenPos);\n break;\n }\n case Token.OpenBrace: {\n statement = this.parseBlockStatement(tn, topLevel);\n break;\n }\n case Token.Return: {\n if (topLevel) {\n this.error(\n DiagnosticCode.A_return_statement_can_only_be_used_within_a_function_body,\n tn.range()\n ); // recoverable\n }\n statement = this.parseReturn(tn);\n break;\n }\n case Token.Semicolon: {\n return Node.createEmptyStatement(tn.range(tn.tokenPos));\n }\n case Token.Switch: {\n statement = this.parseSwitchStatement(tn);\n break;\n }\n case Token.Throw: {\n statement = this.parseThrowStatement(tn);\n break;\n }\n case Token.Try: {\n statement = this.parseTryStatement(tn);\n break;\n }\n case Token.Void: {\n statement = this.parseVoidStatement(tn);\n break;\n }\n case Token.While: {\n statement = this.parseWhileStatement(tn);\n break;\n }\n case Token.Type: { // also identifier\n if (tn.peek(IdentifierHandling.Prefer) == Token.Identifier) {\n statement = this.parseTypeDeclaration(tn, CommonFlags.None, null, tn.tokenPos);\n break;\n }\n // fall-through\n }\n default: {\n tn.reset(state);\n statement = this.parseExpressionStatement(tn);\n break;\n }\n }\n if (!statement) { // has been reported\n tn.reset(state);\n this.skipStatement(tn);\n } else {\n tn.discard(state);\n }\n return statement;\n }\n\n parseBlockStatement(\n tn: Tokenizer,\n topLevel: bool\n ): BlockStatement | null {\n\n // at '{': Statement* '}' ';'?\n\n let startPos = tn.tokenPos;\n let statements = new Array();\n while (!tn.skip(Token.CloseBrace)) {\n let state = tn.mark();\n let statement = this.parseStatement(tn, topLevel);\n if (!statement) {\n if (tn.token == Token.EndOfFile) return null;\n tn.reset(state);\n this.skipStatement(tn);\n } else {\n tn.discard(state);\n statements.push(statement);\n }\n }\n let ret = Node.createBlockStatement(statements, tn.range(startPos, tn.pos));\n if (topLevel) tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseBreak(\n tn: Tokenizer\n ): BreakStatement | null {\n\n // at 'break': Identifier? ';'?\n\n let identifier: IdentifierExpression | null = null;\n if (tn.peek() == Token.Identifier && !tn.peekOnNewLine()) {\n tn.next(IdentifierHandling.Prefer);\n identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n }\n let ret = Node.createBreakStatement(identifier, tn.range());\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseContinue(\n tn: Tokenizer\n ): ContinueStatement | null {\n\n // at 'continue': Identifier? ';'?\n\n let identifier: IdentifierExpression | null = null;\n if (tn.peek() == Token.Identifier && !tn.peekOnNewLine()) {\n tn.next(IdentifierHandling.Prefer);\n identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n }\n let ret = Node.createContinueStatement(identifier, tn.range());\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseDoStatement(\n tn: Tokenizer\n ): DoStatement | null {\n\n // at 'do': Statement 'while' '(' Expression ')' ';'?\n\n let startPos = tn.tokenPos;\n let statement = this.parseStatement(tn);\n if (!statement) return null;\n\n if (tn.skip(Token.While)) {\n\n if (tn.skip(Token.OpenParen)) {\n let condition = this.parseExpression(tn);\n if (!condition) return null;\n\n if (tn.skip(Token.CloseParen)) {\n let ret = Node.createDoStatement(statement, condition, tn.range(startPos, tn.pos));\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"(\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"while\"\n );\n }\n return null;\n }\n\n parseExpressionStatement(\n tn: Tokenizer\n ): ExpressionStatement | null {\n\n // at previous token\n\n let expr = this.parseExpression(tn);\n if (!expr) return null;\n\n let ret = Node.createExpressionStatement(expr);\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseForStatement(\n tn: Tokenizer\n ): Statement | null {\n\n // at 'for': '(' Statement? Expression? ';' Expression? ')' Statement\n\n let startPos = tn.tokenPos;\n\n if (tn.skip(Token.OpenParen)) {\n let initializer: Statement | null = null;\n\n if (tn.skip(Token.Const)) {\n initializer = this.parseVariable(tn, CommonFlags.Const, null, tn.tokenPos, true);\n } else if (tn.skip(Token.Let)) {\n initializer = this.parseVariable(tn, CommonFlags.Let, null, tn.tokenPos, true);\n } else if (tn.skip(Token.Var)) {\n initializer = this.parseVariable(tn, CommonFlags.None, null, tn.tokenPos, true);\n\n } else if (!tn.skip(Token.Semicolon)) {\n initializer = this.parseExpressionStatement(tn);\n if (!initializer) return null;\n }\n\n if (initializer) {\n if (tn.skip(Token.Of)) {\n // TODO: for (let [key, val] of ...)\n if (initializer.kind == NodeKind.Expression) {\n if ((initializer).expression.kind != NodeKind.Identifier) {\n this.error(\n DiagnosticCode.Identifier_expected,\n initializer.range\n );\n return null;\n }\n return this.parseForOfStatement(tn, startPos, initializer);\n }\n if (initializer.kind == NodeKind.Variable) {\n let declarations = (initializer).declarations;\n for (let i = 0, k = declarations.length; i < k; ++i) {\n let declaration = declarations[i];\n let initializer = declaration.initializer;\n if (initializer) {\n this.error(\n DiagnosticCode.The_variable_declaration_of_a_for_of_statement_cannot_have_an_initializer,\n initializer.range\n ); // recoverable\n }\n }\n return this.parseForOfStatement(tn, startPos, initializer);\n }\n this.error(\n DiagnosticCode.Identifier_expected,\n initializer.range\n );\n return null;\n }\n // non-for..of needs type or initializer\n if (initializer.kind == NodeKind.Variable) {\n let declarations = (initializer).declarations;\n for (let i = 0, k = declarations.length; i < k; ++i) {\n let declaration = declarations[i];\n if (!declaration.initializer) {\n if (declaration.flags & CommonFlags.Const) {\n this.error(\n DiagnosticCode._const_declarations_must_be_initialized,\n declaration.name.range\n );\n } else if (!declaration.type) {\n this.error(\n DiagnosticCode.Type_expected,\n declaration.name.range.atEnd\n );\n }\n }\n }\n }\n }\n\n if (tn.token == Token.Semicolon) {\n let condition: ExpressionStatement | null = null;\n if (!tn.skip(Token.Semicolon)) {\n condition = this.parseExpressionStatement(tn);\n if (!condition) return null;\n }\n\n if (tn.token == Token.Semicolon) {\n let incrementor: Expression | null = null;\n if (!tn.skip(Token.CloseParen)) {\n incrementor = this.parseExpression(tn);\n if (!incrementor) return null;\n\n if (!tn.skip(Token.CloseParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n }\n\n let statement = this.parseStatement(tn);\n if (!statement) return null;\n\n return Node.createForStatement(\n initializer,\n condition\n ? condition.expression\n : null,\n incrementor,\n statement,\n tn.range(startPos, tn.pos)\n );\n\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \";\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \";\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"(\"\n );\n }\n return null;\n }\n\n parseForOfStatement(\n tn: Tokenizer,\n startPos: i32,\n variable: Statement,\n ): ForOfStatement | null {\n\n // at 'of': Expression ')' Statement\n\n let iterable = this.parseExpression(tn);\n if (!iterable) return null;\n\n if (!tn.skip(Token.CloseParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n\n let statement = this.parseStatement(tn);\n if (!statement) return null;\n\n return Node.createForOfStatement(\n variable,\n iterable,\n statement,\n tn.range(startPos, tn.pos)\n );\n }\n\n parseIfStatement(\n tn: Tokenizer\n ): IfStatement | null {\n\n // at 'if': '(' Expression ')' Statement ('else' Statement)?\n\n let startPos = tn.tokenPos;\n if (tn.skip(Token.OpenParen)) {\n let condition = this.parseExpression(tn);\n if (!condition) return null;\n if (tn.skip(Token.CloseParen)) {\n let statement = this.parseStatement(tn);\n if (!statement) return null;\n let elseStatement: Statement | null = null;\n if (tn.skip(Token.Else)) {\n elseStatement = this.parseStatement(tn);\n if (!elseStatement) return null;\n }\n return Node.createIfStatement(\n condition,\n statement,\n elseStatement,\n tn.range(startPos, tn.pos)\n );\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"(\"\n );\n }\n return null;\n }\n\n parseSwitchStatement(\n tn: Tokenizer\n ): SwitchStatement | null {\n\n // at 'switch': '(' Expression ')' '{' SwitchCase* '}' ';'?\n\n let startPos = tn.tokenPos;\n if (tn.skip(Token.OpenParen)) {\n let condition = this.parseExpression(tn);\n if (!condition) return null;\n if (tn.skip(Token.CloseParen)) {\n if (tn.skip(Token.OpenBrace)) {\n let switchCases = new Array();\n while (!tn.skip(Token.CloseBrace)) {\n let switchCase = this.parseSwitchCase(tn);\n if (!switchCase) return null;\n switchCases.push(switchCase);\n }\n let ret = Node.createSwitchStatement(condition, switchCases, tn.range(startPos, tn.pos));\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"(\"\n );\n }\n return null;\n }\n\n parseSwitchCase(\n tn: Tokenizer\n ): SwitchCase | null {\n\n let startPos = tn.tokenPos;\n let statements: Statement[],\n statement: Statement | null;\n\n // 'case' Expression ':' Statement*\n\n if (tn.skip(Token.Case)) {\n let label = this.parseExpression(tn);\n if (!label) return null;\n if (tn.skip(Token.Colon)) {\n statements = new Array();\n while (\n tn.peek() != Token.Case &&\n tn.nextToken != Token.Default &&\n tn.nextToken != Token.CloseBrace\n ) {\n statement = this.parseStatement(tn);\n if (!statement) return null;\n statements.push(statement);\n }\n return Node.createSwitchCase(label, statements, tn.range(startPos, tn.pos));\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n }\n\n // 'default' ':' Statement*\n\n } else if (tn.skip(Token.Default)) {\n if (tn.skip(Token.Colon)) {\n statements = new Array();\n while (\n tn.peek() != Token.Case &&\n tn.nextToken != Token.Default &&\n tn.nextToken != Token.CloseBrace\n ) {\n statement = this.parseStatement(tn);\n if (!statement) return null;\n statements.push(statement);\n }\n return Node.createSwitchCase(null, statements, tn.range(startPos, tn.pos));\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._case_or_default_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseThrowStatement(\n tn: Tokenizer\n ): ThrowStatement | null {\n\n // at 'throw': Expression ';'?\n\n let startPos = tn.tokenPos;\n let expression = this.parseExpression(tn);\n if (!expression) return null;\n let ret = Node.createThrowStatement(expression, tn.range(startPos, tn.pos));\n if (!tn.skip(Token.Semicolon)) this.checkASI(tn);\n return ret;\n }\n\n parseTryStatement(\n tn: Tokenizer\n ): TryStatement | null {\n\n // at 'try':\n // '{' Statement* '}'\n // ('catch' '(' VariableMember ')' '{' Statement* '}')?\n // ('finally' '{' Statement* '}'? ';'?\n\n let startPos = tn.tokenPos;\n let stmt: Statement | null;\n if (tn.skip(Token.OpenBrace)) {\n let bodyStatements = new Array();\n while (!tn.skip(Token.CloseBrace)) {\n stmt = this.parseStatement(tn);\n if (!stmt) return null;\n bodyStatements.push(stmt);\n }\n let catchVariable: IdentifierExpression | null = null;\n let catchStatements: Statement[] | null = null;\n let finallyStatements: Statement[] | null = null;\n if (tn.skip(Token.Catch)) {\n if (!tn.skip(Token.OpenParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"(\"\n );\n return null;\n }\n if (!tn.skipIdentifier()) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n catchVariable = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n if (!tn.skip(Token.CloseParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n if (!tn.skip(Token.OpenBrace)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n return null;\n }\n catchStatements = [];\n while (!tn.skip(Token.CloseBrace)) {\n stmt = this.parseStatement(tn);\n if (!stmt) return null;\n catchStatements.push(stmt);\n }\n }\n if (tn.skip(Token.Finally)) {\n if (!tn.skip(Token.OpenBrace)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n return null;\n }\n finallyStatements = [];\n while (!tn.skip(Token.CloseBrace)) {\n stmt = this.parseStatement(tn);\n if (!stmt) return null;\n finallyStatements.push(stmt);\n }\n }\n if (!(catchStatements || finallyStatements)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"catch\"\n );\n return null;\n }\n let ret = Node.createTryStatement(\n bodyStatements,\n catchVariable,\n catchStatements,\n finallyStatements,\n tn.range(startPos, tn.pos)\n );\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"{\"\n );\n }\n return null;\n }\n\n parseTypeDeclaration(\n tn: Tokenizer,\n flags: CommonFlags,\n decorators: DecoratorNode[] | null,\n startPos: i32\n ): TypeDeclaration | null {\n\n // at 'type': Identifier ('<' TypeParameters '>')? '=' '|'? Type ';'?\n\n if (tn.skipIdentifier()) {\n let name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n let typeParameters: TypeParameterNode[] | null = null;\n if (tn.skip(Token.LessThan)) {\n typeParameters = this.parseTypeParameters(tn);\n if (!typeParameters) return null;\n flags |= CommonFlags.Generic;\n }\n if (tn.skip(Token.Equals)) {\n tn.skip(Token.Bar);\n let type = this.parseType(tn);\n if (!type) return null;\n if (isCircularTypeAlias(name.text, type)) {\n this.error(\n DiagnosticCode.Type_alias_0_circularly_references_itself,\n name.range, name.text\n );\n return null;\n }\n let ret = Node.createTypeDeclaration(\n name,\n decorators,\n flags,\n typeParameters,\n type,\n tn.range(startPos, tn.pos)\n );\n tn.skip(Token.Semicolon);\n ret.overriddenModuleName = this.currentModuleName;\n return ret;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"=\"\n );\n }\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n }\n return null;\n }\n\n parseModuleDeclaration(\n tn: Tokenizer,\n flags: CommonFlags\n ): ModuleDeclaration | null {\n\n // at 'module': StringLiteral ';'?\n\n let startPos = tn.tokenPos;\n assert(tn.next() == Token.StringLiteral); // checked earlier\n let moduleName = tn.readString();\n let ret = Node.createModuleDeclaration(moduleName, flags, tn.range(startPos, tn.pos));\n this.currentModuleName = moduleName;\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseVoidStatement(\n tn: Tokenizer\n ): VoidStatement | null {\n\n // at 'void': Expression ';'?\n\n let startPos = tn.tokenPos;\n let expression = this.parseExpression(tn, Precedence.Grouping);\n if (!expression) return null;\n let ret = Node.createVoidStatement(expression, tn.range(startPos, tn.pos));\n tn.skip(Token.Semicolon);\n return ret;\n }\n\n parseWhileStatement(\n tn: Tokenizer\n ): WhileStatement | null {\n\n // at 'while': '(' Expression ')' Statement ';'?\n\n let startPos = tn.tokenPos;\n if (tn.skip(Token.OpenParen)) {\n let expression = this.parseExpression(tn);\n if (!expression) return null;\n if (tn.skip(Token.CloseParen)) {\n let statement = this.parseStatement(tn);\n if (!statement) return null;\n let ret = Node.createWhileStatement(expression, statement, tn.range(startPos, tn.pos));\n tn.skip(Token.Semicolon);\n return ret;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n }\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"(\"\n );\n }\n return null;\n }\n\n // expressions\n\n parseExpressionStart(\n tn: Tokenizer\n ): Expression | null {\n let token = tn.next(IdentifierHandling.Prefer);\n let startPos = tn.tokenPos;\n switch (token) {\n\n // TODO: SpreadExpression, YieldExpression\n case Token.Dot_Dot_Dot:\n case Token.Yield: // fallthrough to unsupported UnaryPrefixExpression\n\n // UnaryPrefixExpression\n case Token.Exclamation:\n case Token.Tilde:\n case Token.Plus:\n case Token.Minus:\n case Token.TypeOf:\n case Token.Void:\n case Token.Delete: {\n let operand = this.parseExpression(tn, Precedence.UnaryPrefix);\n if (!operand) return null;\n return Node.createUnaryPrefixExpression(token, operand, tn.range(startPos, tn.pos));\n }\n case Token.Plus_Plus:\n case Token.Minus_Minus: {\n let operand = this.parseExpression(tn, Precedence.UnaryPrefix);\n if (!operand) return null;\n switch (operand.kind) {\n case NodeKind.Identifier:\n case NodeKind.ElementAccess:\n case NodeKind.PropertyAccess: break;\n default: {\n this.error(\n DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access,\n operand.range\n );\n }\n }\n return Node.createUnaryPrefixExpression(token, operand, tn.range(startPos, tn.pos));\n }\n\n // NewExpression\n case Token.New: {\n if (!tn.skipIdentifier()) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range()\n );\n return null;\n }\n let typeName = this.parseTypeName(tn);\n if (!typeName) return null;\n let typeArguments: TypeNode[] | null = null;\n let arguments_: Expression[] | null = null;\n if (\n tn.skip(Token.OpenParen) ||\n (typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn))\n ) {\n arguments_ = this.parseArguments(tn);\n if (!arguments_) return null;\n } else {\n arguments_ = []; // new Type;\n }\n return Node.createNewExpression(\n typeName,\n typeArguments,\n arguments_,\n tn.range(startPos, tn.pos)\n );\n }\n\n // Special IdentifierExpression\n case Token.Null: return Node.createNullExpression(tn.range());\n case Token.True: return Node.createTrueExpression(tn.range());\n case Token.False: return Node.createFalseExpression(tn.range());\n case Token.This: return Node.createThisExpression(tn.range());\n case Token.Constructor: return Node.createConstructorExpression(tn.range());\n\n // ParenthesizedExpression or FunctionExpression\n case Token.OpenParen: {\n\n // determine whether this is a function expression\n if (tn.skip(Token.CloseParen)) { // must be a function expression (fast route)\n return this.parseFunctionExpressionCommon(\n tn,\n Node.createEmptyIdentifierExpression(tn.range(startPos)),\n [],\n null,\n ArrowKind.Parenthesized\n );\n }\n let state = tn.mark();\n let again = true;\n do {\n switch (tn.next(IdentifierHandling.Prefer)) {\n\n // function expression\n case Token.Dot_Dot_Dot: {\n tn.reset(state);\n return this.parseFunctionExpression(tn);\n }\n // can be both\n case Token.Identifier: {\n tn.readIdentifier();\n switch (tn.next()) {\n\n // if we got here, check for arrow\n case Token.CloseParen: {\n // `Identifier):Type =>` is function expression\n if (tn.skip(Token.Colon)) {\n let type = this.parseType(tn, true, true);\n if (type == null) {\n again = false;\n break;\n }\n }\n if (!tn.skip(Token.Equals_GreaterThan)) {\n again = false;\n break;\n }\n // fall-through\n }\n // function expression\n case Token.Colon: { // type annotation\n tn.reset(state);\n return this.parseFunctionExpression(tn);\n }\n // optional parameter or parenthesized\n case Token.Question: {\n if (\n tn.skip(Token.Colon) || // optional parameter with type\n tn.skip(Token.Comma) || // optional parameter without type\n tn.skip(Token.CloseParen) // last optional parameter without type\n ) {\n tn.reset(state);\n return this.parseFunctionExpression(tn);\n }\n again = false; // parenthesized\n break;\n }\n case Token.Comma: {\n break; // continue\n }\n // parenthesized expression\n // case Token.EQUALS: // missing type annotation for simplicity\n default: {\n again = false;\n break;\n }\n }\n break;\n }\n // parenthesized expression\n default: {\n again = false;\n break;\n }\n }\n } while (again);\n tn.reset(state);\n\n // parse parenthesized\n let inner = this.parseExpression(tn);\n if (!inner) return null;\n if (!tn.skip(Token.CloseParen)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n inner = Node.createParenthesizedExpression(inner, tn.range(startPos, tn.pos));\n return this.maybeParseCallExpression(tn, inner);\n }\n // ArrayLiteralExpression\n case Token.OpenBracket: {\n let elementExpressions = new Array();\n while (!tn.skip(Token.CloseBracket)) {\n let expr: Expression | null;\n if (tn.peek() == Token.Comma) {\n expr = Node.createOmittedExpression(tn.range(tn.pos));\n } else {\n expr = this.parseExpression(tn, Precedence.Comma + 1);\n if (!expr) return null;\n }\n elementExpressions.push(expr);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseBracket)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"]\"\n );\n return null;\n }\n }\n }\n return Node.createArrayLiteralExpression(elementExpressions, tn.range(startPos, tn.pos));\n }\n // ObjectLiteralExpression\n case Token.OpenBrace: {\n let startPos = tn.tokenPos;\n let names = new Array();\n let values = new Array();\n let name: IdentifierExpression;\n while (!tn.skip(Token.CloseBrace)) {\n if (!tn.skipIdentifier()) {\n if (!tn.skip(Token.StringLiteral)) {\n this.error(\n DiagnosticCode.Identifier_expected,\n tn.range(),\n );\n return null;\n }\n name = Node.createIdentifierExpression(tn.readString(), tn.range());\n name.isQuoted = true;\n } else {\n name = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n }\n names.push(name);\n if (tn.skip(Token.Colon)) {\n let value = this.parseExpression(tn, Precedence.Comma + 1);\n if (!value) return null;\n values.push(value);\n } else if (!name.isQuoted) {\n values.push(name);\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n return null;\n }\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseBrace)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n }\n }\n return Node.createObjectLiteralExpression(names, values, tn.range(startPos, tn.pos));\n }\n // AssertionExpression (unary prefix)\n case Token.LessThan: {\n let toType = this.parseType(tn);\n if (!toType) return null;\n if (!tn.skip(Token.GreaterThan)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \">\"\n );\n return null;\n }\n let expr = this.parseExpression(tn, Precedence.Call);\n if (!expr) return null;\n return Node.createAssertionExpression(\n AssertionKind.Prefix,\n expr,\n toType,\n tn.range(startPos, tn.pos)\n );\n }\n case Token.Identifier: {\n let identifierText = tn.readIdentifier();\n if (identifierText == \"null\") return Node.createNullExpression(tn.range()); // special\n let identifier = Node.createIdentifierExpression(identifierText, tn.range(startPos, tn.pos));\n if (tn.skip(Token.TemplateLiteral)) {\n return this.parseTemplateLiteral(tn, identifier);\n }\n if (tn.peek() == Token.Equals_GreaterThan && !tn.peekOnNewLine()) {\n return this.parseFunctionExpressionCommon(\n tn,\n Node.createEmptyIdentifierExpression(tn.range(startPos)),\n [\n Node.createParameter(\n ParameterKind.Default,\n identifier,\n Node.createOmittedType(identifier.range.atEnd),\n null,\n identifier.range\n )\n ],\n null,\n ArrowKind.Single,\n startPos\n );\n }\n return this.maybeParseCallExpression(tn, identifier, true);\n }\n case Token.Super: {\n if (tn.peek() != Token.Dot && tn.nextToken != Token.OpenParen) {\n this.error(\n DiagnosticCode._super_must_be_followed_by_an_argument_list_or_member_access,\n tn.range()\n );\n }\n let expr = Node.createSuperExpression(tn.range(startPos, tn.pos));\n return this.maybeParseCallExpression(tn, expr);\n }\n case Token.StringLiteral: {\n return Node.createStringLiteralExpression(tn.readString(), tn.range(startPos, tn.pos));\n }\n case Token.TemplateLiteral: {\n return this.parseTemplateLiteral(tn);\n }\n case Token.IntegerLiteral: {\n let value = tn.readInteger();\n tn.checkForIdentifierStartAfterNumericLiteral();\n return Node.createIntegerLiteralExpression(value, tn.range(startPos, tn.pos));\n }\n case Token.FloatLiteral: {\n let value = tn.readFloat();\n tn.checkForIdentifierStartAfterNumericLiteral();\n return Node.createFloatLiteralExpression(value, tn.range(startPos, tn.pos));\n }\n // RegexpLiteralExpression\n // note that this also continues on invalid ones so the surrounding AST remains intact\n case Token.Slash: {\n let regexpPattern = tn.readRegexpPattern(); // also reports\n if (!tn.skip(Token.Slash)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"/\"\n );\n return null;\n }\n return Node.createRegexpLiteralExpression(\n regexpPattern,\n tn.readRegexpFlags(), // also reports\n tn.range(startPos, tn.pos)\n );\n }\n case Token.Function: {\n let expr = this.parseFunctionExpression(tn);\n if (!expr) return null;\n return this.maybeParseCallExpression(tn, expr);\n }\n case Token.Class: {\n return this.parseClassExpression(tn);\n }\n default: {\n if (token == Token.EndOfFile) {\n this.error(\n DiagnosticCode.Unexpected_end_of_text,\n tn.range(startPos)\n );\n } else {\n this.error(\n DiagnosticCode.Expression_expected,\n tn.range()\n );\n }\n return null;\n }\n }\n }\n\n tryParseTypeArgumentsBeforeArguments(\n tn: Tokenizer\n ): TypeNode[] | null {\n\n // at '<': Type (',' Type)* '>' '('\n\n let state = tn.mark();\n if (!tn.skip(Token.LessThan)) return null;\n let start = tn.tokenPos;\n let typeArguments: TypeNode[] | null = null;\n do {\n if (tn.peek() == Token.GreaterThan) {\n break;\n }\n let type = this.parseType(tn, true, true);\n if (!type) {\n tn.reset(state);\n return null;\n }\n if (!typeArguments) typeArguments = [ type ];\n else typeArguments.push(type);\n } while (tn.skip(Token.Comma));\n if (tn.skip(Token.GreaterThan)) {\n let end = tn.pos;\n if (tn.skip(Token.OpenParen)) {\n if (!typeArguments) {\n this.error(\n DiagnosticCode.Type_argument_list_cannot_be_empty,\n tn.range(start, end)\n );\n }\n return typeArguments;\n }\n }\n tn.reset(state);\n return null;\n }\n\n parseArguments(\n tn: Tokenizer\n ): Expression[] | null {\n\n // at '(': (Expression (',' Expression)*)? ')'\n\n let args = new Array();\n while (!tn.skip(Token.CloseParen)) {\n let expr = this.parseExpression(tn, Precedence.Comma + 1);\n if (!expr) return null;\n args.push(expr);\n if (!tn.skip(Token.Comma)) {\n if (tn.skip(Token.CloseParen)) {\n break;\n } else {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \")\"\n );\n return null;\n }\n }\n }\n return args;\n }\n\n parseExpression(\n tn: Tokenizer,\n precedence: Precedence = Precedence.Comma\n ): Expression | null {\n assert(precedence != Precedence.None);\n let expr = this.parseExpressionStart(tn);\n if (!expr) return null;\n let startPos = expr.range.start;\n\n // precedence climbing\n // see: http://www.engr.mun.ca/~theo/Misc/exp_parsing.htm#climbing\n let nextPrecedence: Precedence;\n while (\n (nextPrecedence = determinePrecedence(tn.peek())) >= precedence\n ) {\n let token = tn.next();\n switch (token) {\n\n // AssertionExpression\n case Token.As: {\n if (tn.skip(Token.Const)) {\n expr = Node.createAssertionExpression(\n AssertionKind.Const,\n expr,\n null,\n tn.range(startPos, tn.pos)\n );\n } else {\n let toType = this.parseType(tn); // reports\n if (!toType) return null;\n expr = Node.createAssertionExpression(\n AssertionKind.As,\n expr,\n toType,\n tn.range(startPos, tn.pos)\n );\n }\n break;\n }\n case Token.Exclamation: {\n expr = Node.createAssertionExpression(\n AssertionKind.NonNull,\n expr,\n null,\n tn.range(startPos, tn.pos)\n );\n expr = this.maybeParseCallExpression(tn, expr);\n break;\n }\n // InstanceOfExpression\n case Token.InstanceOf: {\n let isType = this.parseType(tn); // reports\n if (!isType) return null;\n expr = Node.createInstanceOfExpression(\n expr,\n isType,\n tn.range(startPos, tn.pos)\n );\n break;\n }\n // ElementAccessExpression\n case Token.OpenBracket: {\n let next = this.parseExpression(tn); // reports\n if (!next) return null;\n if (!tn.skip(Token.CloseBracket)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"]\"\n );\n return null;\n }\n expr = Node.createElementAccessExpression(\n expr,\n next,\n tn.range(startPos, tn.pos)\n );\n expr = this.maybeParseCallExpression(tn, expr);\n break;\n }\n // UnaryPostfixExpression\n case Token.Plus_Plus:\n case Token.Minus_Minus: {\n if (\n expr.kind != NodeKind.Identifier &&\n expr.kind != NodeKind.ElementAccess &&\n expr.kind != NodeKind.PropertyAccess\n ) {\n this.error(\n DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access,\n expr.range\n );\n }\n expr = Node.createUnaryPostfixExpression(\n token,\n expr,\n tn.range(startPos, tn.pos)\n );\n break;\n }\n // TernaryExpression\n case Token.Question: {\n let ifThen = this.parseExpression(tn);\n if (!ifThen) return null;\n if (!tn.skip(Token.Colon)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \":\"\n );\n return null;\n }\n let ifElse = this.parseExpression(tn, precedence > Precedence.Comma\n ? Precedence.Comma + 1\n : Precedence.Comma\n );\n if (!ifElse) return null;\n expr = Node.createTernaryExpression(\n expr,\n ifThen,\n ifElse,\n tn.range(startPos, tn.pos)\n );\n break;\n }\n // CommaExpression\n case Token.Comma: {\n let commaExprs: Expression[] = [ expr ];\n do {\n expr = this.parseExpression(tn, Precedence.Comma + 1);\n if (!expr) return null;\n commaExprs.push(expr);\n } while (tn.skip(Token.Comma));\n expr = Node.createCommaExpression(commaExprs, tn.range(startPos, tn.pos));\n break;\n }\n // PropertyAccessExpression\n case Token.Dot: {\n if (tn.skipIdentifier(IdentifierHandling.Always)) { // expr '.' Identifier\n let next = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());\n expr = Node.createPropertyAccessExpression(\n expr,\n next,\n tn.range(startPos, tn.pos)\n );\n } else {\n let next = this.parseExpression(tn, nextPrecedence + 1);\n if (!next) return null;\n if (next.kind == NodeKind.Call) { // expr '.' CallExpression\n expr = this.joinPropertyCall(tn, startPos, expr, next);\n if (!expr) return null;\n } else {\n this.error(\n DiagnosticCode.Identifier_expected,\n next.range\n );\n return null;\n }\n }\n if (tn.skip(Token.TemplateLiteral)) {\n expr = this.parseTemplateLiteral(tn, expr);\n if (!expr) return null;\n } else {\n expr = this.maybeParseCallExpression(tn, expr, true);\n }\n break;\n }\n // BinaryExpression (right associative)\n case Token.Equals:\n case Token.Plus_Equals:\n case Token.Minus_Equals:\n case Token.Asterisk_Asterisk_Equals:\n case Token.Asterisk_Equals:\n case Token.Slash_Equals:\n case Token.Percent_Equals:\n case Token.LessThan_LessThan_Equals:\n case Token.GreaterThan_GreaterThan_Equals:\n case Token.GreaterThan_GreaterThan_GreaterThan_Equals:\n case Token.Ampersand_Equals:\n case Token.Caret_Equals:\n case Token.Bar_Equals:\n case Token.Asterisk_Asterisk: {\n let next = this.parseExpression(tn, nextPrecedence);\n if (!next) return null;\n expr = Node.createBinaryExpression(token, expr, next, tn.range(startPos, tn.pos));\n break;\n }\n // BinaryExpression\n case Token.LessThan:\n case Token.GreaterThan:\n case Token.LessThan_Equals:\n case Token.GreaterThan_Equals:\n case Token.Equals_Equals:\n case Token.Equals_Equals_Equals:\n case Token.Exclamation_Equals_Equals:\n case Token.Exclamation_Equals:\n case Token.Plus:\n case Token.Minus:\n case Token.Asterisk:\n case Token.Slash:\n case Token.Percent:\n case Token.LessThan_LessThan:\n case Token.GreaterThan_GreaterThan:\n case Token.GreaterThan_GreaterThan_GreaterThan:\n case Token.Ampersand:\n case Token.Bar:\n case Token.Caret:\n case Token.Ampersand_Ampersand:\n case Token.Bar_Bar:\n case Token.In: {\n let next = this.parseExpression(tn, nextPrecedence + 1);\n if (!next) return null;\n expr = Node.createBinaryExpression(token, expr, next, tn.range(startPos, tn.pos));\n break;\n }\n default: assert(false); // filtered by determinePrecedence\n }\n }\n return expr;\n }\n\n private parseTemplateLiteral(tn: Tokenizer, tag: Expression | null = null): Expression | null {\n // at '`': ... '`'\n let startPos = tag ? tag.range.start : tn.tokenPos;\n let parts = new Array();\n let rawParts = new Array();\n let exprs = new Array();\n parts.push(tn.readString(0, tag != null));\n rawParts.push(tn.source.text.substring(tn.readStringStart, tn.readStringEnd));\n while (tn.readingTemplateString) {\n let expr = this.parseExpression(tn);\n if (!expr) return null;\n exprs.push(expr);\n if (!tn.skip(Token.CloseBrace)) {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n return null;\n }\n parts.push(tn.readString(CharCode.Backtick, tag != null));\n rawParts.push(tn.source.text.substring(tn.readStringStart, tn.readStringEnd));\n }\n return Node.createTemplateLiteralExpression(tag, parts, rawParts, exprs, tn.range(startPos, tn.pos));\n }\n\n private joinPropertyCall(\n tn: Tokenizer,\n startPos: i32,\n expr: Expression,\n call: CallExpression\n ): Expression | null {\n let callee = call.expression;\n switch (callee.kind) {\n case NodeKind.Identifier: { // join property access and use as call target\n call.expression = Node.createPropertyAccessExpression(\n expr,\n callee,\n tn.range(startPos, tn.pos)\n );\n break;\n }\n case NodeKind.Call: { // join call target und wrap the original call around it\n let inner = this.joinPropertyCall(tn, startPos, expr, callee);\n if (!inner) return null;\n call.expression = inner;\n call.range = tn.range(startPos, tn.pos);\n break;\n }\n default: {\n this.error(\n DiagnosticCode.Identifier_expected,\n call.range\n );\n return null;\n }\n }\n return call;\n }\n\n private maybeParseCallExpression(\n tn: Tokenizer,\n expr: Expression,\n potentiallyGeneric: bool = false\n ): Expression {\n let typeArguments: TypeNode[] | null = null;\n while (\n tn.skip(Token.OpenParen) ||\n potentiallyGeneric &&\n (typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn))\n ) {\n let args = this.parseArguments(tn);\n if (!args) break;\n expr = Node.createCallExpression( // is again callable\n expr,\n typeArguments,\n args,\n tn.range(expr.range.start, tn.pos)\n );\n potentiallyGeneric = false;\n }\n return expr;\n }\n\n private checkASI(\n tn: Tokenizer\n ): void {\n // see: https://tc39.es/ecma262/#sec-automatic-semicolon-insertion\n let nextToken = tn.peek();\n if (nextToken == Token.EndOfFile || nextToken == Token.CloseBrace || tn.peekOnNewLine()) return;\n this.error(\n DiagnosticCode.Unexpected_token,\n tn.range(tn.nextTokenPos)\n );\n }\n\n /** Skips over a statement on errors in an attempt to reduce unnecessary diagnostic noise. */\n skipStatement(tn: Tokenizer): void {\n if (tn.peekOnNewLine()) tn.next(); // if reset() to the previous line\n do {\n let nextToken = tn.peek();\n if (\n nextToken == Token.EndOfFile || // next step should handle this\n nextToken == Token.Semicolon // end of the statement for sure\n ) {\n tn.next();\n break;\n }\n if (tn.peekOnNewLine()) break; // end of the statement maybe\n switch (tn.next()) {\n case Token.Identifier: {\n tn.readIdentifier();\n break;\n }\n case Token.StringLiteral:\n case Token.TemplateLiteral: {\n tn.readString();\n break;\n }\n case Token.IntegerLiteral: {\n tn.readInteger();\n tn.checkForIdentifierStartAfterNumericLiteral();\n break;\n }\n case Token.FloatLiteral: {\n tn.readFloat();\n tn.checkForIdentifierStartAfterNumericLiteral();\n break;\n }\n case Token.OpenBrace: {\n this.skipBlock(tn);\n break;\n }\n }\n } while (true);\n tn.readingTemplateString = false;\n }\n\n /** Skips over a block on errors in an attempt to reduce unnecessary diagnostic noise. */\n skipBlock(tn: Tokenizer): void {\n // at '{': ... '}'\n let depth = 1;\n let again = true;\n do {\n switch (tn.next()) {\n case Token.EndOfFile: {\n this.error(\n DiagnosticCode._0_expected,\n tn.range(), \"}\"\n );\n again = false;\n break;\n }\n case Token.OpenBrace: {\n ++depth;\n break;\n }\n case Token.CloseBrace: {\n --depth;\n if (!depth) again = false;\n break;\n }\n case Token.Identifier: {\n tn.readIdentifier();\n break;\n }\n case Token.StringLiteral:{\n tn.readString();\n break;\n }\n case Token.TemplateLiteral: {\n tn.readString();\n while(tn.readingTemplateString){\n this.skipBlock(tn);\n tn.readString(CharCode.Backtick);\n }\n break;\n }\n case Token.IntegerLiteral: {\n tn.readInteger();\n tn.checkForIdentifierStartAfterNumericLiteral();\n break;\n }\n case Token.FloatLiteral: {\n tn.readFloat();\n tn.checkForIdentifierStartAfterNumericLiteral();\n break;\n }\n }\n } while (again);\n }\n}\n\n/** Operator precedence from least to largest. */\nexport const enum Precedence {\n None,\n Comma,\n Spread,\n Yield,\n Assignment,\n Conditional,\n LogicalOr,\n LogicalAnd,\n BitwiseOr,\n BitwiseXor,\n BitwiseAnd,\n Equality,\n Relational,\n Shift,\n Additive,\n Multiplicative,\n Exponentiated,\n UnaryPrefix,\n UnaryPostfix,\n Call,\n MemberAccess,\n Grouping\n}\n\n/** Determines the precedence of a non-starting token. */\nfunction determinePrecedence(kind: Token): Precedence {\n switch (kind) {\n case Token.Comma: return Precedence.Comma;\n case Token.Equals:\n case Token.Plus_Equals:\n case Token.Minus_Equals:\n case Token.Asterisk_Asterisk_Equals:\n case Token.Asterisk_Equals:\n case Token.Slash_Equals:\n case Token.Percent_Equals:\n case Token.LessThan_LessThan_Equals:\n case Token.GreaterThan_GreaterThan_Equals:\n case Token.GreaterThan_GreaterThan_GreaterThan_Equals:\n case Token.Ampersand_Equals:\n case Token.Caret_Equals:\n case Token.Bar_Equals: return Precedence.Assignment;\n case Token.Question: return Precedence.Conditional;\n case Token.Bar_Bar: return Precedence.LogicalOr;\n case Token.Ampersand_Ampersand: return Precedence.LogicalAnd;\n case Token.Bar: return Precedence.BitwiseOr;\n case Token.Caret: return Precedence.BitwiseXor;\n case Token.Ampersand: return Precedence.BitwiseAnd;\n case Token.Equals_Equals:\n case Token.Exclamation_Equals:\n case Token.Equals_Equals_Equals:\n case Token.Exclamation_Equals_Equals: return Precedence.Equality;\n case Token.As:\n case Token.In:\n case Token.InstanceOf:\n case Token.LessThan:\n case Token.GreaterThan:\n case Token.LessThan_Equals:\n case Token.GreaterThan_Equals: return Precedence.Relational;\n case Token.LessThan_LessThan:\n case Token.GreaterThan_GreaterThan:\n case Token.GreaterThan_GreaterThan_GreaterThan: return Precedence.Shift;\n case Token.Plus:\n case Token.Minus: return Precedence.Additive;\n case Token.Asterisk:\n case Token.Slash:\n case Token.Percent: return Precedence.Multiplicative;\n case Token.Asterisk_Asterisk: return Precedence.Exponentiated;\n case Token.Plus_Plus:\n case Token.Minus_Minus: return Precedence.UnaryPostfix;\n case Token.Dot:\n case Token.OpenBracket:\n case Token.Exclamation: return Precedence.MemberAccess;\n }\n return Precedence.None;\n}\n\n/** Checks if the type alias of the given name and type is circular. */\nfunction isCircularTypeAlias(name: string, type: TypeNode): bool {\n switch (type.kind) {\n case NodeKind.NamedType: {\n if ((type).name.identifier.text == name) {\n return true;\n }\n let typeArguments = (type).typeArguments;\n if (typeArguments) {\n for (let i = 0, k = typeArguments.length; i < k; i++) {\n if (isCircularTypeAlias(name, typeArguments[i])) return true;\n }\n }\n break;\n }\n case NodeKind.FunctionType: {\n let functionType = type;\n if (isCircularTypeAlias(name, functionType.returnType)) return true;\n let parameters = functionType.parameters;\n for (let i = 0, k = parameters.length; i < k; i++) {\n if (isCircularTypeAlias(name, parameters[i].type)) return true;\n }\n break;\n }\n default: assert(false);\n }\n return false;\n}\n","/**\n * @fileoverview Infrastructure for custom Binaryen passes.\n * @license Apache-2.0\n */\n\nimport {\n Module,\n ExpressionId,\n ExpressionRef,\n FunctionRef,\n GlobalRef,\n Index,\n StringRef\n} from \"../module\";\n\nimport {\n _BinaryenExpressionGetId,\n _BinaryenBlockGetNumChildren,\n _BinaryenBlockGetChildAt,\n _BinaryenIfGetCondition,\n _BinaryenIfGetIfTrue,\n _BinaryenIfGetIfFalse,\n _BinaryenLoopGetBody,\n _BinaryenBreakGetCondition,\n _BinaryenBreakGetValue,\n _BinaryenGetNumFunctions,\n _BinaryenGetFunctionByIndex,\n _BinaryenGetNumGlobals,\n _BinaryenGetGlobalByIndex,\n _BinaryenFunctionGetBody,\n _BinaryenSwitchGetCondition,\n _BinaryenSwitchGetValue,\n _BinaryenCallGetNumOperands,\n _BinaryenCallGetOperandAt,\n _BinaryenCallIndirectGetNumOperands,\n _BinaryenCallIndirectGetOperandAt,\n _BinaryenLocalSetGetValue,\n _BinaryenGlobalSetGetValue,\n _BinaryenGlobalGetInitExpr,\n _BinaryenLoadGetPtr,\n _BinaryenStoreGetPtr,\n _BinaryenStoreGetValue,\n _BinaryenUnaryGetValue,\n _BinaryenBinaryGetLeft,\n _BinaryenBinaryGetRight,\n _BinaryenSelectGetIfTrue,\n _BinaryenSelectGetIfFalse,\n _BinaryenSelectGetCondition,\n _BinaryenDropGetValue,\n _BinaryenBlockSetChildAt,\n _BinaryenCallIndirectGetTarget,\n _BinaryenReturnGetValue,\n _BinaryenMemoryGrowGetDelta,\n _BinaryenAtomicRMWGetPtr,\n _BinaryenAtomicRMWGetValue,\n _BinaryenAtomicCmpxchgGetPtr,\n _BinaryenAtomicCmpxchgGetExpected,\n _BinaryenAtomicCmpxchgGetReplacement,\n _BinaryenAtomicWaitGetPtr,\n _BinaryenAtomicWaitGetExpected,\n _BinaryenAtomicWaitGetTimeout,\n _BinaryenAtomicNotifyGetPtr,\n _BinaryenSIMDExtractGetVec,\n _BinaryenSIMDReplaceGetVec,\n _BinaryenSIMDReplaceGetValue,\n _BinaryenSIMDShuffleGetLeft,\n _BinaryenSIMDShuffleGetRight,\n _BinaryenSIMDTernaryGetA,\n _BinaryenSIMDTernaryGetB,\n _BinaryenSIMDTernaryGetC,\n _BinaryenSIMDShiftGetVec,\n _BinaryenSIMDShiftGetShift,\n _BinaryenSIMDLoadGetPtr,\n _BinaryenMemoryInitGetDest,\n _BinaryenMemoryInitGetOffset,\n _BinaryenMemoryInitGetSize,\n _BinaryenMemoryCopyGetDest,\n _BinaryenMemoryCopyGetSource,\n _BinaryenMemoryCopyGetSize,\n _BinaryenMemoryFillGetDest,\n _BinaryenMemoryFillGetValue,\n _BinaryenMemoryFillGetSize,\n _BinaryenRefIsNullGetValue,\n _BinaryenRefAsGetValue,\n _BinaryenTryGetBody,\n _BinaryenTryGetNumCatchBodies,\n _BinaryenTryGetCatchBodyAt,\n _BinaryenThrowGetNumOperands,\n _BinaryenThrowGetOperandAt,\n _BinaryenTupleMakeGetOperandAt,\n _BinaryenTupleMakeGetNumOperands,\n _BinaryenIfSetCondition,\n _BinaryenIfSetIfTrue,\n _BinaryenIfSetIfFalse,\n _BinaryenLoopSetBody,\n _BinaryenBreakSetCondition,\n _BinaryenBreakSetValue,\n _BinaryenSwitchSetCondition,\n _BinaryenSwitchSetValue,\n _BinaryenCallSetOperandAt,\n _BinaryenCallIndirectSetTarget,\n _BinaryenCallIndirectSetOperandAt,\n _BinaryenLocalSetSetValue,\n _BinaryenGlobalSetSetValue,\n _BinaryenLoadSetPtr,\n _BinaryenStoreSetPtr,\n _BinaryenStoreSetValue,\n _BinaryenUnarySetValue,\n _BinaryenExpressionFinalize,\n _BinaryenBinarySetLeft,\n _BinaryenBinarySetRight,\n _BinaryenSelectSetIfTrue,\n _BinaryenSelectSetIfFalse,\n _BinaryenSelectSetCondition,\n _BinaryenDropSetValue,\n _BinaryenReturnSetValue,\n _BinaryenMemoryGrowSetDelta,\n _BinaryenAtomicRMWSetPtr,\n _BinaryenAtomicRMWSetValue,\n _BinaryenAtomicCmpxchgSetPtr,\n _BinaryenAtomicCmpxchgSetExpected,\n _BinaryenAtomicCmpxchgSetReplacement,\n _BinaryenAtomicWaitSetPtr,\n _BinaryenAtomicWaitSetExpected,\n _BinaryenAtomicWaitSetTimeout,\n _BinaryenAtomicNotifySetPtr,\n _BinaryenSIMDExtractSetVec,\n _BinaryenSIMDReplaceSetVec,\n _BinaryenSIMDReplaceSetValue,\n _BinaryenSIMDShuffleSetLeft,\n _BinaryenSIMDShuffleSetRight,\n _BinaryenSIMDTernarySetA,\n _BinaryenSIMDTernarySetB,\n _BinaryenSIMDTernarySetC,\n _BinaryenSIMDShiftSetVec,\n _BinaryenSIMDShiftSetShift,\n _BinaryenSIMDLoadSetPtr,\n _BinaryenSIMDLoadStoreLaneGetPtr,\n _BinaryenSIMDLoadStoreLaneGetVec,\n _BinaryenSIMDLoadStoreLaneSetPtr,\n _BinaryenSIMDLoadStoreLaneSetVec,\n _BinaryenMemoryInitSetDest,\n _BinaryenMemoryInitSetOffset,\n _BinaryenMemoryInitSetSize,\n _BinaryenMemoryCopySetDest,\n _BinaryenMemoryCopySetSource,\n _BinaryenMemoryCopySetSize,\n _BinaryenMemoryFillSetDest,\n _BinaryenMemoryFillSetValue,\n _BinaryenMemoryFillSetSize,\n _BinaryenRefIsNullSetValue,\n _BinaryenTrySetBody,\n _BinaryenTrySetCatchBodyAt,\n _BinaryenThrowSetOperandAt,\n _BinaryenTupleMakeSetOperandAt,\n _BinaryenBlockGetName,\n _BinaryenLoopGetName,\n _BinaryenBreakGetName,\n _BinaryenSwitchGetDefaultName,\n _BinaryenSwitchGetNumNames,\n _BinaryenSwitchGetNameAt,\n _BinaryenCallGetTarget,\n _BinaryenLocalGetGetIndex,\n _BinaryenLocalSetGetIndex,\n _BinaryenGlobalGetGetName,\n _BinaryenGlobalSetGetName,\n _BinaryenAtomicNotifyGetNotifyCount,\n _BinaryenAtomicNotifySetNotifyCount,\n _BinaryenRefFuncGetFunc,\n _BinaryenThrowGetTag,\n _BinaryenTupleExtractGetTuple,\n _BinaryenTupleExtractSetTuple,\n _BinaryenRefEqGetLeft,\n _BinaryenRefEqGetRight,\n _BinaryenRefEqSetLeft,\n _BinaryenRefEqSetRight,\n _BinaryenFunctionSetBody,\n _BinaryenI31NewGetValue,\n _BinaryenI31GetGetI31,\n _BinaryenI31NewSetValue,\n _BinaryenI31GetSetI31,\n _BinaryenCallRefGetNumOperands,\n _BinaryenCallRefGetOperandAt,\n _BinaryenCallRefGetTarget,\n _BinaryenRefTestGetRef,\n _BinaryenRefCastGetRef,\n _BinaryenBrOnGetName,\n _BinaryenBrOnGetRef,\n _BinaryenStructNewGetNumOperands,\n _BinaryenStructNewGetOperandAt,\n _BinaryenStructGetGetRef,\n _BinaryenStructSetGetRef,\n _BinaryenStructSetGetValue,\n _BinaryenStructSetGetIndex,\n _BinaryenStructGetGetIndex,\n _BinaryenArrayNewGetSize,\n _BinaryenArrayNewGetInit,\n _BinaryenArrayInitGetNumValues,\n _BinaryenArrayInitGetValueAt,\n _BinaryenArrayGetGetRef,\n _BinaryenArrayGetGetIndex,\n _BinaryenArraySetGetRef,\n _BinaryenArraySetGetIndex,\n _BinaryenArraySetGetValue,\n _BinaryenArrayLenGetRef,\n _BinaryenArrayCopyGetDestRef,\n _BinaryenArrayCopyGetDestIndex,\n _BinaryenArrayCopyGetSrcRef,\n _BinaryenArrayCopyGetSrcIndex,\n _BinaryenArrayCopyGetLength,\n _BinaryenStringNewGetPtr,\n _BinaryenStringNewGetLength,\n _BinaryenStringNewGetStart,\n _BinaryenStringNewGetEnd,\n _BinaryenStringMeasureGetRef,\n _BinaryenStringEncodeGetPtr,\n _BinaryenStringEncodeGetRef,\n _BinaryenStringEncodeGetStart,\n _BinaryenStringConcatGetLeft,\n _BinaryenStringConcatGetRight,\n _BinaryenStringEqGetLeft,\n _BinaryenStringEqGetRight,\n _BinaryenStringAsGetRef,\n _BinaryenStringWTF8AdvanceGetRef,\n _BinaryenStringWTF8AdvanceGetPos,\n _BinaryenStringWTF8AdvanceGetBytes,\n _BinaryenStringWTF16GetGetRef,\n _BinaryenStringWTF16GetGetPos,\n _BinaryenStringIterNextGetRef,\n _BinaryenStringIterMoveGetRef,\n _BinaryenStringIterMoveGetNum,\n _BinaryenStringSliceWTFGetRef,\n _BinaryenStringSliceWTFGetStart,\n _BinaryenStringSliceWTFGetEnd,\n _BinaryenStringSliceIterGetRef,\n _BinaryenStringSliceIterGetNum,\n _BinaryenCallRefSetOperandAt,\n _BinaryenCallRefSetTarget,\n _BinaryenRefTestSetRef,\n _BinaryenRefCastSetRef,\n _BinaryenBrOnSetRef,\n _BinaryenStructNewSetOperandAt,\n _BinaryenStructGetSetRef,\n _BinaryenStructSetSetRef,\n _BinaryenStructSetSetValue,\n _BinaryenArrayNewSetSize,\n _BinaryenArrayNewSetInit,\n _BinaryenArrayGetSetRef,\n _BinaryenArrayGetSetIndex,\n _BinaryenArraySetSetRef,\n _BinaryenArraySetSetIndex,\n _BinaryenArraySetSetValue,\n _BinaryenArrayLenSetRef,\n _BinaryenArrayCopySetDestRef,\n _BinaryenArrayCopySetDestIndex,\n _BinaryenArrayCopySetSrcRef,\n _BinaryenArrayCopySetSrcIndex,\n _BinaryenArrayCopySetLength,\n _BinaryenRefAsSetValue,\n _BinaryenStringNewSetPtr,\n _BinaryenStringNewSetLength,\n _BinaryenStringNewSetStart,\n _BinaryenStringNewSetEnd,\n _BinaryenStringMeasureSetRef,\n _BinaryenStringEncodeSetRef,\n _BinaryenStringEncodeSetPtr,\n _BinaryenStringEncodeSetStart,\n _BinaryenStringConcatSetLeft,\n _BinaryenStringConcatSetRight,\n _BinaryenStringEqSetLeft,\n _BinaryenStringEqSetRight,\n _BinaryenStringAsSetRef,\n _BinaryenStringWTF8AdvanceSetRef,\n _BinaryenStringWTF8AdvanceSetPos,\n _BinaryenStringWTF8AdvanceSetBytes,\n _BinaryenStringWTF16GetSetRef,\n _BinaryenStringWTF16GetSetPos,\n _BinaryenStringIterNextSetRef,\n _BinaryenStringIterMoveSetRef,\n _BinaryenStringIterMoveSetNum,\n _BinaryenStringSliceWTFSetRef,\n _BinaryenStringSliceWTFSetStart,\n _BinaryenStringSliceWTFSetEnd,\n _BinaryenStringSliceIterSetRef,\n _BinaryenStringSliceIterSetNum,\n _BinaryenArrayInitSetValueAt\n} from \"../glue/binaryen\";\n\n/** Base class of custom Binaryen visitors. */\nexport abstract class Visitor {\n /** Expression stack. */\n private stack: ExpressionRef[] = new Array();\n\n /** Gets the current expression being walked. */\n get currentExpression(): ExpressionRef {\n let currentExpression = this._currentExpression;\n if (!currentExpression) throw new Error(\"not walking expressions\");\n return currentExpression;\n }\n _currentExpression: ExpressionRef = 0;\n\n /** Gets the parent expression of the current expression being walked. Returns zero if already the top-most expression. */\n get parentExpressionOrNull(): ExpressionRef {\n let stack = this.stack;\n let length = stack.length;\n return length ? stack[length - 1] : 0;\n }\n\n // Expressions\n\n visitBlock(expr: ExpressionRef): void {\n // unimp\n }\n\n visitIf(expr: ExpressionRef): void {\n // unimp\n }\n\n visitLoop(expr: ExpressionRef): void {\n // unimp\n }\n\n visitBreak(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSwitch(expr: ExpressionRef): void {\n // unimp\n }\n\n visitCallPre(expr: ExpressionRef): void {\n // unimp\n }\n\n visitCall(expr: ExpressionRef): void {\n // unimp\n }\n\n visitCallIndirectPre(expr: ExpressionRef): void {\n // unimp\n }\n\n visitCallIndirect(expr: ExpressionRef): void {\n // unimp\n }\n\n visitLocalGet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitLocalSet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitGlobalGet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitGlobalSet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitLoad(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStore(expr: ExpressionRef): void {\n // unimp\n }\n\n visitConst(expr: ExpressionRef): void {\n // unimp\n }\n\n visitUnary(expr: ExpressionRef): void {\n // unimp\n }\n\n visitBinary(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSelect(expr: ExpressionRef): void {\n // unimp\n }\n\n visitDrop(expr: ExpressionRef): void {\n // unimp\n }\n\n visitReturn(expr: ExpressionRef): void {\n // unimp\n }\n\n visitMemorySize(expr: ExpressionRef): void {\n // unimp\n }\n\n visitMemoryGrow(expr: ExpressionRef): void {\n // unimp\n }\n\n visitNop(expr: ExpressionRef): void {\n // unimp\n }\n\n visitUnreachable(expr: ExpressionRef): void {\n // unimp\n }\n\n visitAtomicRMW(expr: ExpressionRef): void {\n // unimp\n }\n\n visitAtomicCmpxchg(expr: ExpressionRef): void {\n // unimp\n }\n\n visitAtomicWait(expr: ExpressionRef): void {\n // unimp\n }\n\n visitAtomicNotify(expr: ExpressionRef): void {\n // unimp\n }\n\n visitAtomicFence(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDExtract(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDReplace(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDShuffle(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDTernary(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDShift(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDLoad(expr: ExpressionRef): void {\n // unimp\n }\n\n visitSIMDLoadStoreLane(expr: ExpressionRef): void {\n // unimp\n }\n\n visitMemoryInit(expr: ExpressionRef): void {\n // unimp\n }\n\n visitDataDrop(expr: ExpressionRef): void {\n // unimp\n }\n\n visitMemoryCopy(expr: ExpressionRef): void {\n // unimp\n }\n\n visitMemoryFill(expr: ExpressionRef): void {\n // unimp\n }\n\n visitPop(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefNull(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefIsNull(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefFunc(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefEq(expr: ExpressionRef): void {\n // unimp\n }\n\n visitTry(expr: ExpressionRef): void {\n // unimp\n }\n\n visitThrow(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRethrow(expr: ExpressionRef): void {\n // unimp\n }\n\n visitTupleMake(expr: ExpressionRef): void {\n // unimp\n }\n\n visitTupleExtract(expr: ExpressionRef): void {\n // unimp\n }\n\n visitI31New(expr: ExpressionRef): void {\n // unimp\n }\n\n visitI31Get(expr: ExpressionRef): void {\n // unimp\n }\n\n visitCallRef(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefTest(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefCast(expr: ExpressionRef): void {\n // unimp\n }\n\n visitBrOn(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStructNew(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStructGet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStructSet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitArrayNew(expr: ExpressionRef): void {\n // unimp\n }\n\n visitArrayInit(expr: ExpressionRef): void {\n // unimp\n }\n\n visitArrayGet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitArraySet(expr: ExpressionRef): void {\n // unimp\n }\n\n visitArrayLen(expr: ExpressionRef): void {\n // unimp\n }\n\n visitArrayCopy(expr: ExpressionRef): void {\n // unimp\n }\n\n visitRefAs(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringNew(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringConst(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringMeasure(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringEncode(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringConcat(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringEq(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringAs(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringWTF8Advance(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringWTF16Get(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringIterNext(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringIterMove(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringSliceWTF(expr: ExpressionRef): void {\n // unimp\n }\n\n visitStringSliceIter(expr: ExpressionRef): void {\n // unimp\n }\n\n // Immediates\n\n visitName(name: StringRef): void {\n // unimp\n }\n\n visitLabel(name: StringRef): void {\n // unimp\n }\n\n visitIndex(index: Index): void {\n // unimp\n }\n\n visitTag(name: StringRef): void {\n // unimp\n }\n\n // Delegate\n\n /** Visits any expression, delegating to the respective visitor methods. */\n visit(expr: ExpressionRef): void {\n let previousExpression = this._currentExpression;\n this._currentExpression = assert(expr);\n switch (_BinaryenExpressionGetId(expr)) {\n case ExpressionId.Block: {\n this.stack.push(expr);\n let name = _BinaryenBlockGetName(expr);\n if (name) this.visitLabel(name);\n for (let i: Index = 0, n = _BinaryenBlockGetNumChildren(expr); i < n; ++i) {\n this.visit(_BinaryenBlockGetChildAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n this.visitBlock(expr);\n break;\n }\n case ExpressionId.If: {\n this.stack.push(expr);\n this.visit(_BinaryenIfGetCondition(expr));\n this.visit(_BinaryenIfGetIfTrue(expr));\n let ifFalse = _BinaryenIfGetIfFalse(expr);\n if (ifFalse) this.visit(ifFalse);\n assert(this.stack.pop() == expr);\n this.visitIf(expr);\n break;\n }\n case ExpressionId.Loop: {\n this.stack.push(expr);\n let name = _BinaryenLoopGetName(expr);\n if (name) this.visitLabel(name);\n this.visit(_BinaryenLoopGetBody(expr));\n assert(this.stack.pop() == expr);\n this.visitLoop(expr);\n break;\n }\n case ExpressionId.Break: {\n this.stack.push(expr);\n this.visitLabel(_BinaryenBreakGetName(expr));\n let condition = _BinaryenBreakGetCondition(expr);\n if (condition) this.visit(condition);\n let value = _BinaryenBreakGetValue(expr);\n if (value) this.visit(value);\n assert(this.stack.pop() == expr);\n this.visitBreak(expr);\n break;\n }\n case ExpressionId.Switch: {\n this.stack.push(expr);\n let defaultName = _BinaryenSwitchGetDefaultName(expr);\n if (defaultName) this.visitLabel(defaultName);\n let numNames = _BinaryenSwitchGetNumNames(expr);\n for (let i: Index = 0; i < numNames; ++i) {\n this.visitLabel(_BinaryenSwitchGetNameAt(expr, i));\n }\n this.visit(_BinaryenSwitchGetCondition(expr));\n let value = _BinaryenSwitchGetValue(expr);\n if (value) this.visit(value);\n assert(this.stack.pop() == expr);\n this.visitSwitch(expr);\n break;\n }\n case ExpressionId.Call: {\n this.visitCallPre(expr);\n this.stack.push(expr);\n this.visitName(_BinaryenCallGetTarget(expr));\n let numOperands = _BinaryenCallGetNumOperands(expr);\n for (let i: Index = 0; i < numOperands; ++i) {\n this.visit(_BinaryenCallGetOperandAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n this.visitCall(expr);\n break;\n }\n case ExpressionId.CallIndirect: {\n this.visitCallIndirectPre(expr);\n this.stack.push(expr);\n this.visit(_BinaryenCallIndirectGetTarget(expr));\n for (let i: Index = 0, k = _BinaryenCallIndirectGetNumOperands(expr); i < k; ++i) {\n this.visit(_BinaryenCallIndirectGetOperandAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n this.visitCallIndirect(expr);\n break;\n }\n case ExpressionId.LocalGet: {\n this.stack.push(expr);\n this.visitIndex(_BinaryenLocalGetGetIndex(expr));\n assert(this.stack.pop() == expr);\n this.visitLocalGet(expr);\n break;\n }\n case ExpressionId.LocalSet: {\n this.stack.push(expr);\n this.visitIndex(_BinaryenLocalSetGetIndex(expr));\n this.visit(_BinaryenLocalSetGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitLocalSet(expr);\n break;\n }\n case ExpressionId.GlobalGet: {\n this.stack.push(expr);\n this.visitName(_BinaryenGlobalGetGetName(expr));\n assert(this.stack.pop() == expr);\n this.visitGlobalGet(expr);\n break;\n }\n case ExpressionId.GlobalSet: {\n this.stack.push(expr);\n this.visitName(_BinaryenGlobalSetGetName(expr));\n this.visit(_BinaryenGlobalSetGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitGlobalSet(expr);\n break;\n }\n case ExpressionId.Load: {\n this.stack.push(expr);\n this.visit(_BinaryenLoadGetPtr(expr));\n assert(this.stack.pop() == expr);\n this.visitLoad(expr);\n break;\n }\n case ExpressionId.Store: {\n this.stack.push(expr);\n this.visit(_BinaryenStoreGetPtr(expr));\n this.visit(_BinaryenStoreGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitStore(expr);\n break;\n }\n case ExpressionId.Const: {\n this.visitConst(expr);\n break;\n }\n case ExpressionId.Unary: {\n this.stack.push(expr);\n this.visit(_BinaryenUnaryGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitUnary(expr);\n break;\n }\n case ExpressionId.Binary: {\n this.stack.push(expr);\n this.visit(_BinaryenBinaryGetLeft(expr));\n this.visit(_BinaryenBinaryGetRight(expr));\n assert(this.stack.pop() == expr);\n this.visitBinary(expr);\n break;\n }\n case ExpressionId.Select: {\n this.stack.push(expr);\n this.visit(_BinaryenSelectGetIfTrue(expr));\n this.visit(_BinaryenSelectGetIfFalse(expr));\n this.visit(_BinaryenSelectGetCondition(expr));\n assert(this.stack.pop() == expr);\n this.visitSelect(expr);\n break;\n }\n case ExpressionId.Drop: {\n this.stack.push(expr);\n this.visit(_BinaryenDropGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitDrop(expr);\n break;\n }\n case ExpressionId.Return: {\n let value = _BinaryenReturnGetValue(expr);\n if (value) {\n this.stack.push(expr);\n this.visit(value);\n assert(this.stack.pop() == expr);\n }\n this.visitReturn(expr);\n break;\n }\n case ExpressionId.MemorySize: {\n this.visitMemorySize(expr);\n break;\n }\n case ExpressionId.MemoryGrow: {\n this.stack.push(expr);\n this.visit(_BinaryenMemoryGrowGetDelta(expr));\n assert(this.stack.pop() == expr);\n this.visitMemoryGrow(expr);\n break;\n }\n case ExpressionId.Nop: {\n this.visitNop(expr);\n break;\n }\n case ExpressionId.Unreachable: {\n this.visitUnreachable(expr);\n break;\n }\n case ExpressionId.AtomicRMW: {\n this.stack.push(expr);\n this.visit(_BinaryenAtomicRMWGetPtr(expr));\n this.visit(_BinaryenAtomicRMWGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitAtomicRMW(expr);\n break;\n }\n case ExpressionId.AtomicCmpxchg: {\n this.stack.push(expr);\n this.visit(_BinaryenAtomicCmpxchgGetPtr(expr));\n this.visit(_BinaryenAtomicCmpxchgGetExpected(expr));\n this.visit(_BinaryenAtomicCmpxchgGetReplacement(expr));\n assert(this.stack.pop() == expr);\n this.visitAtomicCmpxchg(expr);\n break;\n }\n case ExpressionId.AtomicWait: {\n this.stack.push(expr);\n this.visit(_BinaryenAtomicWaitGetPtr(expr));\n this.visit(_BinaryenAtomicWaitGetExpected(expr));\n this.visit(_BinaryenAtomicWaitGetTimeout(expr));\n assert(this.stack.pop() == expr);\n this.visitAtomicWait(expr);\n break;\n }\n case ExpressionId.AtomicNotify: {\n this.stack.push(expr);\n this.visit(_BinaryenAtomicNotifyGetPtr(expr));\n this.visit(_BinaryenAtomicNotifyGetNotifyCount(expr));\n assert(this.stack.pop() == expr);\n this.visitAtomicNotify(expr);\n break;\n }\n case ExpressionId.AtomicFence: {\n this.visitAtomicFence(expr);\n break;\n }\n case ExpressionId.SIMDExtract: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDExtractGetVec(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDExtract(expr);\n break;\n }\n case ExpressionId.SIMDReplace: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDReplaceGetVec(expr));\n this.visit(_BinaryenSIMDReplaceGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDReplace(expr);\n break;\n }\n case ExpressionId.SIMDShuffle: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDShuffleGetLeft(expr));\n this.visit(_BinaryenSIMDShuffleGetRight(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDShuffle(expr);\n break;\n }\n case ExpressionId.SIMDTernary: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDTernaryGetA(expr));\n this.visit(_BinaryenSIMDTernaryGetB(expr));\n this.visit(_BinaryenSIMDTernaryGetC(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDTernary(expr);\n break;\n }\n case ExpressionId.SIMDShift: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDShiftGetVec(expr));\n this.visit(_BinaryenSIMDShiftGetShift(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDShift(expr);\n break;\n }\n case ExpressionId.SIMDLoad: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDLoadGetPtr(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDLoad(expr);\n break;\n }\n case ExpressionId.SIMDLoadStoreLane: {\n this.stack.push(expr);\n this.visit(_BinaryenSIMDLoadStoreLaneGetPtr(expr));\n this.visit(_BinaryenSIMDLoadStoreLaneGetVec(expr));\n assert(this.stack.pop() == expr);\n this.visitSIMDLoadStoreLane(expr);\n break;\n }\n case ExpressionId.MemoryInit: {\n this.stack.push(expr);\n this.visit(_BinaryenMemoryInitGetDest(expr));\n this.visit(_BinaryenMemoryInitGetOffset(expr));\n this.visit(_BinaryenMemoryInitGetSize(expr));\n assert(this.stack.pop() == expr);\n this.visitMemoryInit(expr);\n break;\n }\n case ExpressionId.DataDrop: {\n this.visitDataDrop(expr);\n break;\n }\n case ExpressionId.MemoryCopy: {\n this.stack.push(expr);\n this.visit(_BinaryenMemoryCopyGetDest(expr));\n this.visit(_BinaryenMemoryCopyGetSource(expr));\n this.visit(_BinaryenMemoryCopyGetSize(expr));\n assert(this.stack.pop() == expr);\n this.visitMemoryCopy(expr);\n break;\n }\n case ExpressionId.MemoryFill: {\n this.stack.push(expr);\n this.visit(_BinaryenMemoryFillGetDest(expr));\n this.visit(_BinaryenMemoryFillGetValue(expr));\n this.visit(_BinaryenMemoryFillGetSize(expr));\n assert(this.stack.pop() == expr);\n this.visitMemoryFill(expr);\n break;\n }\n case ExpressionId.Pop: {\n this.visitPop(expr);\n break;\n }\n case ExpressionId.RefNull: {\n this.visitRefNull(expr);\n break;\n }\n case ExpressionId.RefIsNull: {\n this.stack.push(expr);\n this.visit(_BinaryenRefIsNullGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitRefIsNull(expr);\n break;\n }\n case ExpressionId.RefFunc: {\n this.stack.push(expr);\n this.visitName(_BinaryenRefFuncGetFunc(expr));\n assert(this.stack.pop() == expr);\n this.visitRefFunc(expr);\n break;\n }\n case ExpressionId.RefEq: {\n this.stack.push(expr);\n this.visit(_BinaryenRefEqGetLeft(expr));\n this.visit(_BinaryenRefEqGetRight(expr));\n assert(this.stack.pop() == expr);\n this.visitRefEq(expr);\n break;\n }\n case ExpressionId.Try: {\n this.stack.push(expr);\n this.visit(_BinaryenTryGetBody(expr));\n let numCatchBodies = _BinaryenTryGetNumCatchBodies(expr);\n for (let i: Index = 0; i < numCatchBodies; ++i) {\n this.visit(_BinaryenTryGetCatchBodyAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n this.visitTry(expr);\n break;\n }\n case ExpressionId.Throw: {\n this.stack.push(expr);\n this.visitTag(_BinaryenThrowGetTag(expr));\n let numOperands = _BinaryenThrowGetNumOperands(expr);\n for (let i: Index = 0; i < numOperands; ++i) {\n this.visit(_BinaryenThrowGetOperandAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n this.visitThrow(expr);\n break;\n }\n case ExpressionId.Rethrow: {\n this.visitRethrow(expr);\n break;\n }\n case ExpressionId.TupleMake: {\n let numOperands = _BinaryenTupleMakeGetNumOperands(expr);\n if (numOperands) {\n this.stack.push(expr);\n for (let i: Index = 0; i < numOperands; ++i) {\n this.visit(_BinaryenTupleMakeGetOperandAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n }\n this.visitTupleMake(expr);\n break;\n }\n case ExpressionId.TupleExtract: {\n this.stack.push(expr);\n this.visit(_BinaryenTupleExtractGetTuple(expr));\n assert(this.stack.pop() == expr);\n this.visitTupleExtract(expr);\n break;\n }\n case ExpressionId.I31New: {\n this.stack.push(expr);\n this.visit(_BinaryenI31NewGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitI31New(expr);\n break;\n }\n case ExpressionId.I31Get: {\n this.stack.push(expr);\n this.visit(_BinaryenI31GetGetI31(expr));\n assert(this.stack.pop() == expr);\n this.visitI31Get(expr);\n break;\n }\n case ExpressionId.CallRef: {\n this.stack.push(expr);\n let numOperands = _BinaryenCallRefGetNumOperands(expr);\n if (numOperands) {\n for (let i: Index = 0; i < numOperands; ++i) {\n this.visit(_BinaryenCallRefGetOperandAt(expr, i));\n }\n }\n this.visit(_BinaryenCallRefGetTarget(expr));\n assert(this.stack.pop() == expr);\n this.visitCallRef(expr);\n break;\n }\n case ExpressionId.RefTest: {\n this.stack.push(expr);\n this.visit(_BinaryenRefTestGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitRefTest(expr);\n break;\n }\n case ExpressionId.RefCast: {\n this.stack.push(expr);\n this.visit(_BinaryenRefCastGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitRefCast(expr);\n break;\n }\n case ExpressionId.BrOn: {\n this.stack.push(expr);\n this.visitLabel(_BinaryenBrOnGetName(expr));\n this.visit(_BinaryenBrOnGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitBrOn(expr);\n break;\n }\n case ExpressionId.StructNew: {\n let numOperands = _BinaryenStructNewGetNumOperands(expr);\n if (numOperands) {\n this.stack.push(expr);\n for (let i: Index = 0; i < numOperands; ++i) {\n this.visit(_BinaryenStructNewGetOperandAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n }\n this.visitStructNew(expr);\n break;\n }\n case ExpressionId.StructGet: {\n this.stack.push(expr);\n this.visit(_BinaryenStructGetGetRef(expr));\n this.visitIndex(_BinaryenStructGetGetIndex(expr));\n assert(this.stack.pop() == expr);\n this.visitStructGet(expr);\n break;\n }\n case ExpressionId.StructSet: {\n this.stack.push(expr);\n this.visit(_BinaryenStructSetGetRef(expr));\n this.visitIndex(_BinaryenStructSetGetIndex(expr));\n this.visit(_BinaryenStructSetGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitStructSet(expr);\n break;\n }\n case ExpressionId.ArrayNew: {\n this.stack.push(expr);\n this.visit(_BinaryenArrayNewGetSize(expr));\n let init = _BinaryenArrayNewGetInit(expr);\n if (init) this.visit(init);\n assert(this.stack.pop() == expr);\n this.visitArrayNew(expr);\n break;\n }\n case ExpressionId.ArrayInit: {\n let numValues = _BinaryenArrayInitGetNumValues(expr);\n if (numValues) {\n this.stack.push(expr);\n for (let i: Index = 0; i < numValues; ++i) {\n this.visit(_BinaryenArrayInitGetValueAt(expr, i));\n }\n assert(this.stack.pop() == expr);\n }\n this.visitArrayInit(expr);\n break;\n }\n case ExpressionId.ArrayGet: {\n this.stack.push(expr);\n this.visit(_BinaryenArrayGetGetRef(expr));\n this.visit(_BinaryenArrayGetGetIndex(expr));\n assert(this.stack.pop() == expr);\n this.visitArrayGet(expr);\n break;\n }\n case ExpressionId.ArraySet: {\n this.stack.push(expr);\n this.visit(_BinaryenArraySetGetRef(expr));\n this.visit(_BinaryenArraySetGetIndex(expr));\n this.visit(_BinaryenArraySetGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitArraySet(expr);\n break;\n }\n case ExpressionId.ArrayLen: {\n this.stack.push(expr);\n this.visit(_BinaryenArrayLenGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitArrayLen(expr);\n break;\n }\n case ExpressionId.ArrayCopy: {\n this.stack.push(expr);\n this.visit(_BinaryenArrayCopyGetDestRef(expr));\n this.visit(_BinaryenArrayCopyGetDestIndex(expr));\n this.visit(_BinaryenArrayCopyGetSrcRef(expr));\n this.visit(_BinaryenArrayCopyGetSrcIndex(expr));\n this.visit(_BinaryenArrayCopyGetLength(expr));\n assert(this.stack.pop() == expr);\n this.visitArrayCopy(expr);\n break;\n }\n case ExpressionId.RefAs: {\n this.stack.push(expr);\n this.visit(_BinaryenRefAsGetValue(expr));\n assert(this.stack.pop() == expr);\n this.visitRefAs(expr);\n break;\n }\n case ExpressionId.StringNew: {\n this.stack.push(expr);\n this.visit(_BinaryenStringNewGetPtr(expr));\n let length = _BinaryenStringNewGetLength(expr); // LM only\n if (length) this.visit(length);\n let start = _BinaryenStringNewGetStart(expr); // GC only\n if (start) this.visit(start);\n let end = _BinaryenStringNewGetEnd(expr); // GC only\n if (end) this.visit(end);\n assert(this.stack.pop() == expr);\n this.visitStringNew(expr);\n break;\n }\n case ExpressionId.StringConst: {\n this.stack.push(expr);\n assert(this.stack.pop() == expr);\n this.visitStringConst(expr);\n break;\n }\n case ExpressionId.StringMeasure: {\n this.stack.push(expr);\n this.visit(_BinaryenStringMeasureGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitStringMeasure(expr);\n break;\n }\n case ExpressionId.StringEncode: {\n this.stack.push(expr);\n this.visit(_BinaryenStringEncodeGetRef(expr));\n this.visit(_BinaryenStringEncodeGetPtr(expr));\n let start = _BinaryenStringEncodeGetStart(expr); // GC only\n if (start) this.visit(start);\n assert(this.stack.pop() == expr);\n this.visitStringEncode(expr);\n break;\n }\n case ExpressionId.StringConcat: {\n this.stack.push(expr);\n this.visit(_BinaryenStringConcatGetLeft(expr));\n this.visit(_BinaryenStringConcatGetRight(expr));\n assert(this.stack.pop() == expr);\n this.visitStringConcat(expr);\n break;\n }\n case ExpressionId.StringEq: {\n this.stack.push(expr);\n this.visit(_BinaryenStringEqGetLeft(expr));\n this.visit(_BinaryenStringEqGetRight(expr));\n assert(this.stack.pop() == expr);\n this.visitStringEq(expr);\n break;\n }\n case ExpressionId.StringAs: {\n this.stack.push(expr);\n this.visit(_BinaryenStringAsGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitStringAs(expr);\n break;\n }\n case ExpressionId.StringWTF8Advance: {\n this.stack.push(expr);\n this.visit(_BinaryenStringWTF8AdvanceGetRef(expr));\n this.visit(_BinaryenStringWTF8AdvanceGetPos(expr));\n this.visit(_BinaryenStringWTF8AdvanceGetBytes(expr));\n assert(this.stack.pop() == expr);\n this.visitStringWTF8Advance(expr);\n break;\n }\n case ExpressionId.StringWTF16Get: {\n this.stack.push(expr);\n this.visit(_BinaryenStringWTF16GetGetRef(expr));\n this.visit(_BinaryenStringWTF16GetGetPos(expr));\n assert(this.stack.pop() == expr);\n this.visitStringWTF16Get(expr);\n break;\n }\n case ExpressionId.StringIterNext: {\n this.stack.push(expr);\n this.visit(_BinaryenStringIterNextGetRef(expr));\n assert(this.stack.pop() == expr);\n this.visitStringIterNext(expr);\n break;\n }\n case ExpressionId.StringIterMove: {\n this.stack.push(expr);\n this.visit(_BinaryenStringIterMoveGetRef(expr));\n this.visit(_BinaryenStringIterMoveGetNum(expr));\n assert(this.stack.pop() == expr);\n this.visitStringIterMove(expr);\n break;\n }\n case ExpressionId.StringSliceWTF: {\n this.stack.push(expr);\n this.visit(_BinaryenStringSliceWTFGetRef(expr));\n this.visit(_BinaryenStringSliceWTFGetStart(expr));\n this.visit(_BinaryenStringSliceWTFGetEnd(expr));\n assert(this.stack.pop() == expr);\n this.visitStringSliceWTF(expr);\n break;\n }\n case ExpressionId.StringSliceIter: {\n this.stack.push(expr);\n this.visit(_BinaryenStringSliceIterGetRef(expr));\n this.visit(_BinaryenStringSliceIterGetNum(expr));\n assert(this.stack.pop() == expr);\n this.visitStringSliceIter(expr);\n break;\n }\n default: throw new Error(\"unexpected expression kind\");\n }\n this._currentExpression = previousExpression;\n }\n}\n\n/** Base class of custom Binaryen passes. */\nexport abstract class Pass extends Visitor {\n\n /** Gets the current function being walked. */\n get currentFunction(): FunctionRef {\n let currentFunction = this._currentFunction;\n if (!currentFunction) throw new Error(\"not walking a function\");\n return currentFunction;\n }\n private _currentFunction: FunctionRef = 0;\n\n /** Gets the current global being walked. */\n get currentGlobal(): GlobalRef {\n let currentGlobal = this._currentGlobal;\n if (!currentGlobal) throw new Error(\"not walking a global\");\n return currentGlobal;\n }\n private _currentGlobal: GlobalRef = 0;\n\n /** Constructs a new Binaryen pass. */\n constructor(readonly module: Module) {\n super();\n }\n\n // Walking\n\n /** Walks the entire module. */\n walkModule(): void {\n this.walkFunctions();\n this.walkGlobals();\n }\n\n /** Walks all functions. */\n walkFunctions(): void {\n let moduleRef = this.module.ref;\n for (let i: Index = 0, k = _BinaryenGetNumFunctions(moduleRef); i < k; ++i) {\n this.walkFunction(_BinaryenGetFunctionByIndex(moduleRef, i));\n }\n }\n\n /** Walks a specific function. */\n walkFunction(func: FunctionRef): void {\n let body = _BinaryenFunctionGetBody(func);\n if (body) {\n this._currentFunction = func;\n this.visit(body);\n this._currentFunction = 0;\n }\n }\n\n /** Walks all global variables. */\n walkGlobals(): void {\n let moduleRef = this.module.ref;\n for (let i: Index = 0, k = _BinaryenGetNumGlobals(moduleRef); i < k; ++i) {\n this.walkGlobal(_BinaryenGetGlobalByIndex(moduleRef, i));\n }\n }\n\n /** Walks a specific global variable. */\n walkGlobal(global: GlobalRef): void {\n this._currentGlobal = global;\n let init = _BinaryenGlobalGetInitExpr(global);\n if (init) this.visit(init);\n this._currentGlobal = 0;\n }\n\n // Utility\n\n /** Replaces the current expression with the specified replacement. */\n replaceCurrent(replacement: ExpressionRef): void {\n let search = this.currentExpression;\n let func = this.currentFunction;\n let body = _BinaryenFunctionGetBody(func);\n if (body == search) {\n _BinaryenFunctionSetBody(func, replacement);\n } else {\n let parent = assert(this.parentExpressionOrNull);\n let replaced = replaceChild(parent, search, replacement);\n if (!replaced) throw Error(\"failed to replace expression\");\n _BinaryenExpressionFinalize(parent);\n }\n }\n}\n\n/** Replaces an expression within a parent expression. Returns the replaced expression on success, otherwise `0`. */\nexport function replaceChild(\n /** Parent expression containing `search`. */\n parent: ExpressionRef,\n /** Expression to replace. */\n search: ExpressionRef,\n /** Expression to replace `search` with. */\n replacement: ExpressionRef\n): ExpressionRef {\n switch (_BinaryenExpressionGetId(parent)) {\n case ExpressionId.Block: {\n let numChildren = _BinaryenBlockGetNumChildren(parent);\n for (let i: Index = 0; i < numChildren; ++i) {\n let child = _BinaryenBlockGetChildAt(parent, i);\n if (child == search) {\n _BinaryenBlockSetChildAt(parent, i, replacement);\n return child;\n }\n }\n break;\n }\n case ExpressionId.If: {\n let condition = _BinaryenIfGetCondition(parent);\n if (condition == search) {\n _BinaryenIfSetCondition(parent, replacement);\n return condition;\n }\n let ifTrue = _BinaryenIfGetIfTrue(parent);\n if (ifTrue == search) {\n _BinaryenIfSetIfTrue(parent, replacement);\n return ifTrue;\n }\n let ifFalse = _BinaryenIfGetIfFalse(parent);\n if (ifFalse == search) {\n _BinaryenIfSetIfFalse(parent, replacement);\n return ifFalse;\n }\n break;\n }\n case ExpressionId.Loop: {\n let body = _BinaryenLoopGetBody(parent);\n if (body == search) {\n _BinaryenLoopSetBody(parent, replacement);\n return body;\n }\n break;\n }\n case ExpressionId.Break: {\n let condition = _BinaryenBreakGetCondition(parent);\n if (condition == search) {\n _BinaryenBreakSetCondition(parent, replacement);\n return condition;\n }\n let value = _BinaryenBreakGetValue(parent);\n if (value == search) {\n _BinaryenBreakSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.Switch: {\n let condition = _BinaryenSwitchGetCondition(parent);\n if (condition == search) {\n _BinaryenSwitchSetCondition(parent, replacement);\n return condition;\n }\n let value = _BinaryenSwitchGetValue(parent);\n if (value == search) {\n _BinaryenSwitchSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.Call: {\n let numOperands = _BinaryenCallGetNumOperands(parent);\n for (let i: Index = 0; i < numOperands; ++i) {\n let operand = _BinaryenCallGetOperandAt(parent, i);\n if (operand == search) {\n _BinaryenCallSetOperandAt(parent, i, replacement);\n return operand;\n }\n }\n break;\n }\n case ExpressionId.CallIndirect: {\n let target = _BinaryenCallIndirectGetTarget(parent);\n if (target == search) {\n _BinaryenCallIndirectSetTarget(parent, replacement);\n return target;\n }\n let numOperands = _BinaryenCallIndirectGetNumOperands(parent);\n for (let i: Index = 0; i < numOperands; ++i) {\n let operand = _BinaryenCallIndirectGetOperandAt(parent, i);\n if (operand == search) {\n _BinaryenCallIndirectSetOperandAt(parent, i, replacement);\n return operand;\n }\n }\n break;\n }\n case ExpressionId.LocalGet: {\n break;\n }\n case ExpressionId.LocalSet: {\n let value = _BinaryenLocalSetGetValue(parent);\n if (value == search) {\n _BinaryenLocalSetSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.GlobalGet: {\n break;\n }\n case ExpressionId.GlobalSet: {\n let value = _BinaryenGlobalSetGetValue(parent);\n if (value == search) {\n _BinaryenGlobalSetSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.Load: {\n let ptr = _BinaryenLoadGetPtr(parent);\n if (ptr == search) {\n _BinaryenLoadSetPtr(parent, replacement);\n return ptr;\n }\n break;\n }\n case ExpressionId.Store: {\n let ptr = _BinaryenStoreGetPtr(parent);\n if (ptr == search) {\n _BinaryenStoreSetPtr(parent, replacement);\n return ptr;\n }\n let value = _BinaryenStoreGetValue(parent);\n if (value == search) {\n _BinaryenStoreSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.Const: {\n break;\n }\n case ExpressionId.Unary: {\n let value = _BinaryenUnaryGetValue(parent);\n if (value == search) {\n _BinaryenUnarySetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.Binary: {\n let left = _BinaryenBinaryGetLeft(parent);\n if (left == search) {\n _BinaryenBinarySetLeft(parent, replacement);\n return left;\n }\n let right = _BinaryenBinaryGetRight(parent);\n if (right == search) {\n _BinaryenBinarySetRight(parent, replacement);\n return right;\n }\n break;\n }\n case ExpressionId.Select: {\n let ifTrue = _BinaryenSelectGetIfTrue(parent);\n if (ifTrue == search) {\n _BinaryenSelectSetIfTrue(parent, replacement);\n return ifTrue;\n }\n let ifFalse = _BinaryenSelectGetIfFalse(parent);\n if (ifFalse == search) {\n _BinaryenSelectSetIfFalse(parent, replacement);\n return ifFalse;\n }\n let condition = _BinaryenSelectGetCondition(parent);\n if (condition == search) {\n _BinaryenSelectSetCondition(parent, replacement);\n return condition;\n }\n break;\n }\n case ExpressionId.Drop: {\n let value = _BinaryenDropGetValue(parent);\n if (value == search) {\n _BinaryenDropSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.Return: {\n let value = _BinaryenReturnGetValue(parent);\n if (value == search) {\n _BinaryenReturnSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.MemorySize: {\n break;\n }\n case ExpressionId.MemoryGrow: {\n let delta = _BinaryenMemoryGrowGetDelta(parent);\n if (delta == search) {\n _BinaryenMemoryGrowSetDelta(parent, replacement);\n return delta;\n }\n break;\n }\n case ExpressionId.Nop: {\n break;\n }\n case ExpressionId.Unreachable: {\n break;\n }\n case ExpressionId.AtomicRMW: {\n let ptr = _BinaryenAtomicRMWGetPtr(parent);\n if (ptr == search) {\n _BinaryenAtomicRMWSetPtr(parent, replacement);\n return ptr;\n }\n let value = _BinaryenAtomicRMWGetValue(parent);\n if (value == search) {\n _BinaryenAtomicRMWSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.AtomicCmpxchg: {\n let ptr = _BinaryenAtomicCmpxchgGetPtr(parent);\n if (ptr == search) {\n _BinaryenAtomicCmpxchgSetPtr(parent, replacement);\n return ptr;\n }\n let expected = _BinaryenAtomicCmpxchgGetExpected(parent);\n if (expected == search) {\n _BinaryenAtomicCmpxchgSetExpected(parent, replacement);\n return expected;\n }\n let repl = _BinaryenAtomicCmpxchgGetReplacement(parent);\n if (repl == search) {\n _BinaryenAtomicCmpxchgSetReplacement(parent, replacement);\n return repl;\n }\n break;\n }\n case ExpressionId.AtomicWait: {\n let ptr = _BinaryenAtomicWaitGetPtr(parent);\n if (ptr == search) {\n _BinaryenAtomicWaitSetPtr(parent, replacement);\n return ptr;\n }\n let expected = _BinaryenAtomicWaitGetExpected(parent);\n if (expected == search) {\n _BinaryenAtomicWaitSetExpected(parent, replacement);\n return expected;\n }\n let timeout = _BinaryenAtomicWaitGetTimeout(parent);\n if (timeout == search) {\n _BinaryenAtomicWaitSetTimeout(parent, replacement);\n return timeout;\n }\n break;\n }\n case ExpressionId.AtomicNotify: {\n let ptr = _BinaryenAtomicNotifyGetPtr(parent);\n if (ptr == search) {\n _BinaryenAtomicNotifySetPtr(parent, replacement);\n return ptr;\n }\n let notifyCount = _BinaryenAtomicNotifyGetNotifyCount(parent);\n if (notifyCount == search) {\n _BinaryenAtomicNotifySetNotifyCount(parent, replacement);\n return notifyCount;\n }\n break;\n }\n case ExpressionId.AtomicFence: {\n break;\n }\n case ExpressionId.SIMDExtract: {\n let vec = _BinaryenSIMDExtractGetVec(parent);\n if (vec == search) {\n _BinaryenSIMDExtractSetVec(parent, replacement);\n return vec;\n }\n break;\n }\n case ExpressionId.SIMDReplace: {\n let vec = _BinaryenSIMDReplaceGetVec(parent);\n if (vec == search) {\n _BinaryenSIMDReplaceSetVec(parent, replacement);\n return vec;\n }\n let value = _BinaryenSIMDReplaceGetValue(parent);\n if (value == search) {\n _BinaryenSIMDReplaceSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.SIMDShuffle: {\n let left = _BinaryenSIMDShuffleGetLeft(parent);\n if (left == search) {\n _BinaryenSIMDShuffleSetLeft(parent, replacement);\n return left;\n }\n let right = _BinaryenSIMDShuffleGetRight(parent);\n if (right == search) {\n _BinaryenSIMDShuffleSetRight(parent, replacement);\n return right;\n }\n break;\n }\n case ExpressionId.SIMDTernary: {\n let a = _BinaryenSIMDTernaryGetA(parent);\n if (a == search) {\n _BinaryenSIMDTernarySetA(parent, replacement);\n return a;\n }\n let b = _BinaryenSIMDTernaryGetB(parent);\n if (b == search) {\n _BinaryenSIMDTernarySetB(parent, replacement);\n return b;\n }\n let c = _BinaryenSIMDTernaryGetC(parent);\n if (c == search) {\n _BinaryenSIMDTernarySetC(parent, replacement);\n return c;\n }\n break;\n }\n case ExpressionId.SIMDShift: {\n let vec = _BinaryenSIMDShiftGetVec(parent);\n if (vec == search) {\n _BinaryenSIMDShiftSetVec(parent, replacement);\n return vec;\n }\n let shift = _BinaryenSIMDShiftGetShift(parent);\n if (shift == search) {\n _BinaryenSIMDShiftSetShift(parent, replacement);\n return shift;\n }\n break;\n }\n case ExpressionId.SIMDLoad: {\n let ptr = _BinaryenSIMDLoadGetPtr(parent);\n if (ptr == search) {\n _BinaryenSIMDLoadSetPtr(parent, replacement);\n return ptr;\n }\n break;\n }\n case ExpressionId.SIMDLoadStoreLane: {\n let ptr = _BinaryenSIMDLoadStoreLaneGetPtr(parent);\n if (ptr == search) {\n _BinaryenSIMDLoadStoreLaneSetPtr(parent, replacement);\n return ptr;\n }\n let vec = _BinaryenSIMDLoadStoreLaneGetVec(parent);\n if (vec == search) {\n _BinaryenSIMDLoadStoreLaneSetVec(parent, replacement);\n return ptr;\n }\n break;\n }\n case ExpressionId.MemoryInit: {\n let dest = _BinaryenMemoryInitGetDest(parent);\n if (dest == search) {\n _BinaryenMemoryInitSetDest(parent, replacement);\n return dest;\n }\n let offset = _BinaryenMemoryInitGetOffset(parent);\n if (offset == search) {\n _BinaryenMemoryInitSetOffset(parent, replacement);\n return offset;\n }\n let size = _BinaryenMemoryInitGetSize(parent);\n if (size == search) {\n _BinaryenMemoryInitSetSize(parent, replacement);\n return size;\n }\n break;\n }\n case ExpressionId.DataDrop: {\n break;\n }\n case ExpressionId.MemoryCopy: {\n let dest = _BinaryenMemoryCopyGetDest(parent);\n if (dest == search) {\n _BinaryenMemoryCopySetDest(parent, replacement);\n return dest;\n }\n let source = _BinaryenMemoryCopyGetSource(parent);\n if (source == search) {\n _BinaryenMemoryCopySetSource(parent, replacement);\n return source;\n }\n let size = _BinaryenMemoryCopyGetSize(parent);\n if (size == search) {\n _BinaryenMemoryCopySetSize(parent, replacement);\n return size;\n }\n break;\n }\n case ExpressionId.MemoryFill: {\n let dest = _BinaryenMemoryFillGetDest(parent);\n if (dest == search) {\n _BinaryenMemoryFillSetDest(parent, replacement);\n return dest;\n }\n let value = _BinaryenMemoryFillGetValue(parent);\n if (value == search) {\n _BinaryenMemoryFillSetValue(parent, replacement);\n return value;\n }\n let size = _BinaryenMemoryFillGetSize(parent);\n if (size == search) {\n _BinaryenMemoryFillSetSize(parent, replacement);\n return size;\n }\n break;\n }\n case ExpressionId.Pop: {\n break;\n }\n case ExpressionId.RefNull: {\n break;\n }\n case ExpressionId.RefIsNull: {\n let value = _BinaryenRefIsNullGetValue(parent);\n if (value == search) {\n _BinaryenRefIsNullSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.RefFunc: {\n break;\n }\n case ExpressionId.RefEq: {\n let left = _BinaryenRefEqGetLeft(parent);\n if (left == search) {\n _BinaryenRefEqSetLeft(parent, replacement);\n return left;\n }\n let right = _BinaryenRefEqGetRight(parent);\n if (right == search) {\n _BinaryenRefEqSetRight(parent, replacement);\n return right;\n }\n break;\n }\n case ExpressionId.Try: {\n let body = _BinaryenTryGetBody(parent);\n if (body == search) {\n _BinaryenTrySetBody(parent, replacement);\n return body;\n }\n let numCatchBodies = _BinaryenTryGetNumCatchBodies(parent);\n for (let i: Index = 0; i < numCatchBodies; ++i) {\n let catchBody = _BinaryenTryGetCatchBodyAt(parent, i);\n if (catchBody == search) {\n _BinaryenTrySetCatchBodyAt(parent, i, replacement);\n return catchBody;\n }\n }\n break;\n }\n case ExpressionId.Throw: {\n let numOperands = _BinaryenThrowGetNumOperands(parent);\n for (let i: Index = 0; i < numOperands; ++i) {\n let operand = _BinaryenThrowGetOperandAt(parent, i);\n if (operand == search) {\n _BinaryenThrowSetOperandAt(parent, i, replacement);\n return operand;\n }\n }\n break;\n }\n case ExpressionId.Rethrow: {\n break;\n }\n case ExpressionId.TupleMake: {\n let numOperands = _BinaryenTupleMakeGetNumOperands(parent);\n for (let i: Index = 0; i < numOperands; ++i) {\n let operand = _BinaryenTupleMakeGetOperandAt(parent, i);\n if (operand == search) {\n _BinaryenTupleMakeSetOperandAt(parent, i, replacement);\n return operand;\n }\n }\n break;\n }\n case ExpressionId.TupleExtract: {\n let tuple = _BinaryenTupleExtractGetTuple(parent);\n if (tuple == search) {\n _BinaryenTupleExtractSetTuple(parent, replacement);\n return tuple;\n }\n break;\n }\n case ExpressionId.I31New: {\n let value = _BinaryenI31NewGetValue(parent);\n if (value == search) {\n _BinaryenI31NewSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.I31Get: {\n let i31Expr = _BinaryenI31GetGetI31(parent);\n if (i31Expr == search) {\n _BinaryenI31GetSetI31(parent, replacement);\n return i31Expr;\n }\n break;\n }\n case ExpressionId.CallRef: {\n let numOperands = _BinaryenCallRefGetNumOperands(parent);\n for (let i: Index = 0; i < numOperands; ++i) {\n let operand = _BinaryenCallRefGetOperandAt(parent, i);\n if (operand == search) {\n _BinaryenCallRefSetOperandAt(parent, i, replacement);\n return operand;\n }\n }\n let target = _BinaryenCallRefGetTarget(parent);\n if (target == search) {\n _BinaryenCallRefSetTarget(parent, replacement);\n return target;\n }\n break;\n }\n case ExpressionId.RefTest: {\n let ref = _BinaryenRefTestGetRef(parent);\n if (ref == search) {\n _BinaryenRefTestSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.RefCast: {\n let ref = _BinaryenRefCastGetRef(parent);\n if (ref == search) {\n _BinaryenRefCastSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.BrOn: {\n let ref = _BinaryenBrOnGetRef(parent);\n if (ref == search) {\n _BinaryenBrOnSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.StructNew: {\n let numOperands = _BinaryenStructNewGetNumOperands(parent);\n for (let i: Index = 0; i < numOperands; ++i) {\n let operand = _BinaryenStructNewGetOperandAt(parent, i);\n if (operand == search) {\n _BinaryenStructNewSetOperandAt(parent, i, replacement);\n return operand;\n }\n }\n break;\n }\n case ExpressionId.StructGet: {\n let ref = _BinaryenStructGetGetRef(parent);\n if (ref == search) {\n _BinaryenStructGetSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.StructSet: {\n let ref = _BinaryenStructSetGetRef(parent);\n if (ref == search) {\n _BinaryenStructSetSetRef(parent, replacement);\n return ref;\n }\n let value = _BinaryenStructSetGetValue(parent);\n if (value == search) {\n _BinaryenStructSetSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.ArrayNew: {\n let size = _BinaryenArrayNewGetSize(parent);\n if (size == search) {\n _BinaryenArrayNewSetSize(parent, replacement);\n return size;\n }\n let init = _BinaryenArrayNewGetInit(parent);\n if (init == search) {\n _BinaryenArrayNewSetInit(parent, replacement);\n return init;\n }\n break;\n }\n case ExpressionId.ArrayInit: {\n let numValues = _BinaryenArrayInitGetNumValues(parent);\n for (let i: Index = 0; i < numValues; ++i) {\n let value = _BinaryenArrayInitGetValueAt(parent, i);\n if (value == search) {\n _BinaryenArrayInitSetValueAt(parent, i, replacement);\n return value;\n }\n }\n break;\n }\n case ExpressionId.ArrayGet: {\n let ref = _BinaryenArrayGetGetRef(parent);\n if (ref == search) {\n _BinaryenArrayGetSetRef(parent, replacement);\n return ref;\n }\n let index = _BinaryenArrayGetGetIndex(parent);\n if (index == search) {\n _BinaryenArrayGetSetIndex(parent, replacement);\n return index;\n }\n break;\n }\n case ExpressionId.ArraySet: {\n let ref = _BinaryenArraySetGetRef(parent);\n if (ref == search) {\n _BinaryenArraySetSetRef(parent, replacement);\n return ref;\n }\n let index = _BinaryenArraySetGetIndex(parent);\n if (index == search) {\n _BinaryenArraySetSetIndex(parent, replacement);\n return index;\n }\n let value = _BinaryenArraySetGetValue(parent);\n if (value == search) {\n _BinaryenArraySetSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.ArrayLen: {\n let ref = _BinaryenArrayLenGetRef(parent);\n if (ref == search) {\n _BinaryenArrayLenSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.ArrayCopy: {\n let destRef = _BinaryenArrayCopyGetDestRef(parent);\n if (destRef == search) {\n _BinaryenArrayCopySetDestRef(parent, replacement);\n return destRef;\n }\n let destIndex = _BinaryenArrayCopyGetDestIndex(parent);\n if (destIndex == search) {\n _BinaryenArrayCopySetDestIndex(parent, replacement);\n return destIndex;\n }\n let srcRef = _BinaryenArrayCopyGetSrcRef(parent);\n if (srcRef == search) {\n _BinaryenArrayCopySetSrcRef(parent, replacement);\n return srcRef;\n }\n let srcIndex = _BinaryenArrayCopyGetSrcIndex(parent);\n if (srcIndex == search) {\n _BinaryenArrayCopySetSrcIndex(parent, replacement);\n return srcIndex;\n }\n let length = _BinaryenArrayCopyGetLength(parent);\n if (length == search) {\n _BinaryenArrayCopySetLength(parent, replacement);\n return length;\n }\n break;\n }\n case ExpressionId.RefAs: {\n let value = _BinaryenRefAsGetValue(parent);\n if (value == search) {\n _BinaryenRefAsSetValue(parent, replacement);\n return value;\n }\n break;\n }\n case ExpressionId.StringNew: {\n let ptr = _BinaryenStringNewGetPtr(parent);\n if (ptr == search) {\n _BinaryenStringNewSetPtr(parent, replacement);\n return ptr;\n }\n let length = _BinaryenStringNewGetLength(parent);\n if (length == search) {\n _BinaryenStringNewSetLength(parent, replacement);\n return length;\n }\n let start = _BinaryenStringNewGetStart(parent);\n if (start == search) {\n _BinaryenStringNewSetStart(parent, replacement);\n return start;\n }\n let end = _BinaryenStringNewGetEnd(parent);\n if (end == search) {\n _BinaryenStringNewSetEnd(parent, replacement);\n return end;\n }\n break;\n }\n case ExpressionId.StringConst: {\n break;\n }\n case ExpressionId.StringMeasure: {\n let ref = _BinaryenStringMeasureGetRef(parent);\n if (ref == search) {\n _BinaryenStringMeasureSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.StringEncode: {\n let ref = _BinaryenStringEncodeGetRef(parent);\n if (ref == search) {\n _BinaryenStringEncodeSetRef(parent, replacement);\n return ref;\n }\n let ptr = _BinaryenStringEncodeGetPtr(parent);\n if (ptr == search) {\n _BinaryenStringEncodeSetPtr(parent, replacement);\n return ptr;\n }\n let start = _BinaryenStringEncodeGetStart(parent);\n if (start == search) {\n _BinaryenStringEncodeSetStart(parent, replacement);\n return start;\n }\n break;\n }\n case ExpressionId.StringConcat: {\n let left = _BinaryenStringConcatGetLeft(parent);\n if (left == search) {\n _BinaryenStringConcatSetLeft(parent, replacement);\n return left;\n }\n let right = _BinaryenStringConcatGetRight(parent);\n if (right == search) {\n _BinaryenStringConcatSetRight(parent, replacement);\n return right;\n }\n break;\n }\n case ExpressionId.StringEq: {\n let left = _BinaryenStringEqGetLeft(parent);\n if (left == search) {\n _BinaryenStringEqSetLeft(parent, replacement);\n return left;\n }\n let right = _BinaryenStringEqGetRight(parent);\n if (right == search) {\n _BinaryenStringEqSetRight(parent, replacement);\n return right;\n }\n break;\n }\n case ExpressionId.StringAs: {\n let ref = _BinaryenStringAsGetRef(parent);\n if (ref == search) {\n _BinaryenStringAsSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.StringWTF8Advance: {\n let ref = _BinaryenStringWTF8AdvanceGetRef(parent);\n if (ref == search) {\n _BinaryenStringWTF8AdvanceSetRef(parent, replacement);\n return ref;\n }\n let pos = _BinaryenStringWTF8AdvanceGetPos(parent);\n if (pos == search) {\n _BinaryenStringWTF8AdvanceSetPos(parent, replacement);\n return pos;\n }\n let bytes = _BinaryenStringWTF8AdvanceGetBytes(parent);\n if (bytes == search) {\n _BinaryenStringWTF8AdvanceSetBytes(parent, replacement);\n return bytes;\n }\n break;\n }\n case ExpressionId.StringWTF16Get: {\n let ref = _BinaryenStringWTF16GetGetRef(parent);\n if (ref == search) {\n _BinaryenStringWTF16GetSetRef(parent, replacement);\n return ref;\n }\n let pos = _BinaryenStringWTF16GetGetPos(parent);\n if (pos == search) {\n _BinaryenStringWTF16GetSetPos(parent, replacement);\n return pos;\n }\n break;\n }\n case ExpressionId.StringIterNext: {\n let ref = _BinaryenStringIterNextGetRef(parent);\n if (ref == search) {\n _BinaryenStringIterNextSetRef(parent, replacement);\n return ref;\n }\n break;\n }\n case ExpressionId.StringIterMove: {\n let ref = _BinaryenStringIterMoveGetRef(parent);\n if (ref == search) {\n _BinaryenStringIterMoveSetRef(parent, replacement);\n return ref;\n }\n let num = _BinaryenStringIterMoveGetNum(parent);\n if (num == search) {\n _BinaryenStringIterMoveSetNum(parent, replacement);\n return num;\n }\n break;\n }\n case ExpressionId.StringSliceWTF: {\n let ref = _BinaryenStringSliceWTFGetRef(parent);\n if (ref == search) {\n _BinaryenStringSliceWTFSetRef(parent, replacement);\n return ref;\n }\n let start = _BinaryenStringSliceWTFGetStart(parent);\n if (start == search) {\n _BinaryenStringSliceWTFSetStart(parent, replacement);\n return start;\n }\n let end = _BinaryenStringSliceWTFGetEnd(parent);\n if (end == search) {\n _BinaryenStringSliceWTFSetEnd(parent, replacement);\n return end;\n }\n break;\n }\n case ExpressionId.StringSliceIter: {\n let ref = _BinaryenStringSliceIterGetRef(parent);\n if (ref == search) {\n _BinaryenStringSliceIterSetRef(parent, replacement);\n return ref;\n }\n let num = _BinaryenStringSliceIterGetNum(parent);\n if (num == search) {\n _BinaryenStringSliceIterSetNum(parent, replacement);\n return num;\n }\n break;\n }\n default: throw new Error(\"unexpected expression id\");\n }\n return 0;\n}\n","/**\n * @fileoverview Shadow stack instrumentation for a precise GC.\n *\n * Instruments function arguments and local assignments marked with a 'tostack'\n * call to also do stores to a shadow stack of managed values only.\n *\n * Consider a simple call to a function looking like the following, taking\n * managed arguments, plus assigning managed values to locals:\n *\n * function foo(a: Obj, b: Obj): Obj {\n * let c = __tostack(a) // slot 2\n * __collect()\n * return b\n * }\n *\n * foo(__tostack(a), __tostack(b)) // slot 0, 1\n *\n * At the call to `__collect()` the 32-bit stack frame of the function is:\n *\n * Offset | Value stored\n * -------|----------------------------\n * 0 | First managed argument 'a'\n * 4 | Second managed argument 'b'\n * -------|----------------------------\n * 8 | First managed local 'c'\n *\n * We are splitting the frame in two halves as annotated since both halves are\n * only known separately for indirect calls, with the first half becoming an\n * extension of the calling function's stack frame by means of treating the\n * arguments as if these were locals beyond the caller's `numLocals`. Function\n * arguments stay a bit longer on the stack than usually, but we also don't have\n * to modify the stack pointer pre-call at all this way. The caller's amended\n * stack frame when assuming one managed local may look like this:\n *\n * Offset | Value stored\n * -------|----------------------------\n * 0 | First managed local '?'\n * 4 | Extended with first managed argument 'a'\n * 8 | Extended with second managed argument 'b'\n *\n * with the callee's stack frame becoming just:\n *\n * Offset | Value stored\n * -------|----------------------------\n * 0 | First managed local 'c'\n *\n * Instrumentation added below looks about like the following, with the stack\n * growing downwards and 't' and 'r' being new temporary locals:\n *\n * // callee frameSize = 1 * sizeof()\n * function foo(a: usize, b: usize): usize {\n * memory.fill(__stack_pointer -= frameSize, 0, frameSize)\n * store(__stack_pointer, c = a, 0 * sizeof())\n * __collect()\n * let r = b\n * __stack_pointer += frameSize\n * return r\n * }\n *\n * // caller frameSize = (numLocalSlots + 2 [by extension]) * sizeof()\n * (\n * r = foo(\n * ( t = a,\n * store(__stack_pointer, t, (numLocalSlots + 0) * sizeof()),\n * t ),\n * ( t = b,\n * store(__stack_pointer, t, (numLocalSlots + 1) * sizeof()),\n * t )\n * ),\n * r\n * )\n *\n * Also note that we have to `memory.fill` the second half because the first\n * assignment to a local may happen at a later point within the function. The\n * invariant we need to maintain for a precise GC is that it only sees zeroes\n * or valid pointers, but never an invalid pointer left on the stack earlier.\n * Since most frames are small, we unroll a sequence of `store`s up to a frame\n * size of 16 bytes, and `memory.fill`, if available, beyond.\n *\n * @license Apache-2.0\n */\n\nimport {\n Pass\n} from \"./pass\";\n\nimport {\n _BinaryenAddFunction,\n _BinaryenAddFunctionExport,\n _BinaryenCallGetNumOperands,\n _BinaryenCallGetOperandAt,\n _BinaryenCallGetTarget,\n _BinaryenCallIndirectGetNumOperands,\n _BinaryenCallIndirectGetOperandAt,\n _BinaryenCallIndirectSetOperandAt,\n _BinaryenCallSetOperandAt,\n _BinaryenExportGetKind,\n _BinaryenExportGetName,\n _BinaryenExportGetValue,\n _BinaryenExpressionGetId,\n _BinaryenExpressionGetType,\n _BinaryenFunctionGetBody,\n _BinaryenFunctionGetName,\n _BinaryenFunctionGetNumLocals,\n _BinaryenFunctionGetNumVars,\n _BinaryenFunctionGetParams,\n _BinaryenFunctionGetResults,\n _BinaryenFunctionGetVar,\n _BinaryenFunctionSetBody,\n _BinaryenGetExport,\n _BinaryenGetFunction,\n _BinaryenLocalSetGetIndex,\n _BinaryenLocalSetGetValue,\n _BinaryenLocalSetIsTee,\n _BinaryenLocalSetSetValue,\n _BinaryenRemoveExport,\n _BinaryenRemoveFunction,\n _BinaryenReturnGetValue,\n _BinaryenReturnSetValue,\n _free\n} from \"../glue/binaryen\";\n\nimport {\n ExpressionId,\n ExpressionRef,\n FunctionRef,\n Index,\n BinaryOp,\n TypeRef,\n allocPtrArray,\n Module,\n ExternalKind,\n ExportRef,\n expandType,\n isConstZero,\n} from \"../module\";\n\nimport {\n Compiler,\n Options\n} from \"../compiler\";\n\nimport {\n Feature\n} from \"../common\";\n\nimport {\n BuiltinNames\n} from \"../builtins\";\n\nimport {\n Source\n} from \"../ast\";\n\ntype LocalIndex = Index;\ntype SlotIndex = Index;\ntype SlotMap = Map;\ntype TempMap = Map;\n\n/** Attempts to match the `__tostack(value)` pattern. Returns `value` if a match, otherwise `0`. */\nfunction matchPattern(module: Module, expr: ExpressionRef): ExpressionRef {\n if (\n _BinaryenExpressionGetId(expr) == ExpressionId.Call &&\n module.readStringCached(_BinaryenCallGetTarget(expr)) == BuiltinNames.tostack\n ) {\n assert(_BinaryenCallGetNumOperands(expr) == 1);\n return _BinaryenCallGetOperandAt(expr, 0);\n }\n return 0;\n}\n\n/** Tests whether a `value` matched by `matchTostack` needs a slot. */\nfunction needsSlot(module: Module, value: ExpressionRef): bool {\n switch (_BinaryenExpressionGetId(value)) {\n // no need to stack null pointers\n case ExpressionId.Const: return !isConstZero(value);\n // note: can't omit a slot when assigning from another local since the other\n // local might have shorter lifetime and become reassigned, say in a loop,\n // then no longer holding on to the previous value in its stack slot.\n }\n return true;\n}\n\n/** Instruments a module with a shadow stack for precise GC. */\nexport class ShadowStackPass extends Pass {\n /** Stack frame slots, per function. */\n slotMaps: Map = new Map();\n /** Temporary locals, per function. */\n tempMaps: Map = new Map();\n /** Exports (with managed operands) map. */\n exportMap: Map = new Map();\n /** Compiler reference. */\n compiler: Compiler;\n\n constructor(compiler: Compiler) {\n super(compiler.module);\n this.compiler = compiler;\n }\n\n /** Compiler options. */\n get options(): Options { return this.compiler.options; }\n /** Target pointer type. */\n get ptrType(): TypeRef { return this.options.sizeTypeRef; }\n /** Target pointer size. */\n get ptrSize(): i32 { return this.ptrType == TypeRef.I64 ? 8 : 4; }\n /** Target pointer addition operation. */\n get ptrBinaryAdd(): BinaryOp { return this.ptrType == TypeRef.I64 ? BinaryOp.AddI64 : BinaryOp.AddI32; }\n /** Target pointer subtraction operation. */\n get ptrBinarySub(): BinaryOp { return this.ptrType == TypeRef.I64 ? BinaryOp.SubI64 : BinaryOp.SubI32; }\n\n /** Gets a constant with the specified value of the target pointer type. */\n ptrConst(value: i32): ExpressionRef {\n return this.ptrType == TypeRef.I64\n ? this.module.i64(value)\n : this.module.i32(value);\n }\n\n /** Notes the presence of a slot for the specified (imaginary) local, returning the slot index. */\n noteSlot(func: FunctionRef, localIndex: Index): i32 {\n let slotMap: SlotMap;\n if (this.slotMaps.has(func)) {\n slotMap = changetype(this.slotMaps.get(func));\n if (slotMap.has(localIndex)) {\n return changetype(slotMap.get(localIndex));\n }\n } else {\n slotMap = new Map();\n this.slotMaps.set(func, slotMap);\n }\n let slotIndex = slotMap.size;\n slotMap.set(localIndex, slotIndex);\n return slotIndex;\n }\n\n /** Notes the presence of an exported function taking managed operands. */\n noteExport(name: string, managedOperandIndices: i32[]): void {\n if (!managedOperandIndices.length) return;\n this.exportMap.set(name, managedOperandIndices);\n }\n\n /** Gets a shared temporary local of the given type in the specified functions. */\n getSharedTemp(func: FunctionRef, type: TypeRef): Index {\n let tempMap: TempMap;\n if (this.tempMaps.has(func)) {\n tempMap = changetype(this.tempMaps.get(func));\n if (tempMap.has(type)) {\n return changetype(tempMap.get(type));\n }\n } else {\n tempMap = new Map();\n this.tempMaps.set(func, tempMap);\n }\n let numLocals = _BinaryenFunctionGetNumLocals(func);\n let localIndex = numLocals + tempMap.size;\n tempMap.set(type, localIndex);\n return localIndex;\n }\n\n /** Makes an expression modifying the stack pointer by the given offset. */\n makeStackOffset(offset: i32): ExpressionRef {\n assert(offset != 0);\n let module = this.module;\n let expr = module.global_set(BuiltinNames.stack_pointer,\n module.binary(offset >= 0 ? this.ptrBinaryAdd : this.ptrBinarySub,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n this.ptrConst(abs(offset))\n )\n );\n if (offset > 0) return expr;\n return module.block(null, [\n expr,\n this.makeStackCheck()\n ], TypeRef.None);\n }\n\n /** Makes a sequence of expressions zeroing the stack frame. */\n makeStackFill(frameSize: i32, stmts: ExpressionRef[]): void {\n assert(frameSize > 0);\n let module = this.module;\n if (this.options.hasFeature(Feature.BulkMemory) && frameSize > 16) {\n stmts.push(\n module.memory_fill(\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.i32(0), // TODO: Wasm64 also i32?\n this.ptrConst(frameSize)\n )\n );\n } else {\n let remain = frameSize;\n while (remain >= 8) {\n // store(__stack_pointer, 0, frameSize - remain)\n stmts.push(\n module.store(8,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.i64(0),\n TypeRef.I64,\n frameSize - remain\n )\n );\n remain -= 8;\n }\n if (remain) {\n assert(remain == 4);\n // store(__stack_pointer, 0, frameSize - remain)\n stmts.push(\n module.store(4,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.i32(0),\n TypeRef.I32,\n frameSize - remain\n )\n );\n }\n }\n }\n\n private hasStackCheckFunction: bool = false;\n\n /** Makes a check that the current stack pointer is valid. */\n makeStackCheck(): ExpressionRef {\n let module = this.module;\n if (!this.hasStackCheckFunction) {\n this.hasStackCheckFunction = true;\n module.addFunction(\"~stack_check\", TypeRef.None, TypeRef.None, null,\n module.if(\n module.binary(BinaryOp.LtI32,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.global_get(BuiltinNames.data_end, this.ptrType)\n ),\n this.compiler.makeStaticAbort(\n this.compiler.ensureStaticString(\"stack overflow\"),\n Source.native\n )\n )\n );\n }\n return module.call(\"~stack_check\", null, TypeRef.None);\n }\n\n private updateCallOperands(operands: ExpressionRef[]): i32 {\n let module = this.module;\n let numSlots = 0;\n for (let i = 0, k = operands.length; i < k; ++i) {\n let operand = operands[i];\n let match = matchPattern(module, operand);\n if (!match) continue;\n if (!needsSlot(module, match)) {\n operands[i] = match;\n continue;\n }\n let currentFunction = this.currentFunction;\n let numLocals = _BinaryenFunctionGetNumLocals(currentFunction);\n let slotIndex = this.noteSlot(currentFunction, numLocals + this.callSlotOffset + i);\n let temp = this.getSharedTemp(currentFunction, this.ptrType);\n let stmts = new Array();\n // t = value\n stmts.push(\n module.local_set(temp, match, false)\n );\n // store(__stack_pointer, t, slotIndex * ptrSize)\n stmts.push(\n module.store(this.ptrSize,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.local_get(temp, this.ptrType),\n this.ptrType, slotIndex * this.ptrSize\n )\n );\n // -> t\n stmts.push(\n module.local_get(temp, this.ptrType)\n );\n operands[i] = module.block(null, stmts, this.ptrType);\n ++numSlots;\n }\n return numSlots;\n }\n\n /** Slot offset accounting for nested calls. */\n private callSlotOffset: i32 = 0;\n /** Slot offset stack in nested calls. */\n private callSlotStack: i32[] = new Array();\n\n /** @override */\n visitCallPre(call: ExpressionRef): void {\n let numOperands = _BinaryenCallGetNumOperands(call);\n let operands = new Array(numOperands);\n for (let i: Index = 0; i < numOperands; ++i) {\n operands[i] = _BinaryenCallGetOperandAt(call, i);\n }\n let numSlots = this.updateCallOperands(operands);\n for (let i = 0, k = operands.length; i < k; ++i) {\n _BinaryenCallSetOperandAt(call, i, operands[i]);\n }\n if (numSlots) {\n // Reserve these slots for us so nested calls use their own\n this.callSlotOffset += numSlots;\n }\n this.callSlotStack.push(numSlots);\n }\n\n /** @override */\n visitCall(call: ExpressionRef): void {\n let numSlots = this.callSlotStack.pop();\n if (numSlots) this.callSlotOffset -= numSlots;\n }\n\n /** @override */\n visitCallIndirectPre(callIndirect: ExpressionRef): void {\n let numOperands = _BinaryenCallIndirectGetNumOperands(callIndirect);\n let operands = new Array(numOperands);\n for (let i: Index = 0; i < numOperands; ++i) {\n operands[i] = _BinaryenCallIndirectGetOperandAt(callIndirect, i);\n }\n let numSlots = this.updateCallOperands(operands);\n for (let i = 0, k = operands.length; i < k; ++i) {\n _BinaryenCallIndirectSetOperandAt(callIndirect, i, operands[i]);\n }\n if (numSlots) {\n // Reserve these slots for us so nested calls use their own\n this.callSlotOffset += numSlots;\n }\n this.callSlotStack.push(numSlots);\n }\n\n /** @override */\n visitCallIndirect(callIndirect: ExpressionRef): void {\n let numSlots = this.callSlotStack.pop();\n if (numSlots) this.callSlotOffset -= numSlots;\n }\n\n /** @override */\n visitLocalSet(localSet: ExpressionRef): void {\n let module = this.module;\n let value = _BinaryenLocalSetGetValue(localSet);\n let match = matchPattern(module, value);\n if (!match) return;\n if (!needsSlot(module, match)) {\n _BinaryenLocalSetSetValue(localSet, match);\n return;\n }\n let index = _BinaryenLocalSetGetIndex(localSet);\n let slotIndex = this.noteSlot(this.currentFunction, index);\n let stmts = new Array();\n // store(__stack_pointer, local = match, slotIndex * ptrSize)\n stmts.push(\n module.store(this.ptrSize,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.local_tee(index, match, false),\n this.ptrType, slotIndex * this.ptrSize\n )\n );\n if (_BinaryenLocalSetIsTee(localSet)) {\n // -> local\n stmts.push(\n module.local_get(index, this.ptrType)\n );\n this.replaceCurrent(module.flatten(stmts, this.ptrType));\n } else {\n this.replaceCurrent(module.flatten(stmts, TypeRef.None));\n }\n }\n\n /** Updates a function with additional locals etc. */\n updateFunction(funcRef: FunctionRef): void {\n let name = _BinaryenFunctionGetName(funcRef);\n let params = _BinaryenFunctionGetParams(funcRef);\n let results = _BinaryenFunctionGetResults(funcRef);\n let body = assert(_BinaryenFunctionGetBody(funcRef));\n let numVars = _BinaryenFunctionGetNumVars(funcRef);\n let vars = new Array();\n for (let i: Index = 0; i < numVars; ++i) {\n vars[i] = _BinaryenFunctionGetVar(funcRef, i);\n }\n let tempMaps = this.tempMaps;\n if (tempMaps.has(funcRef)) {\n let tempMap = changetype(tempMaps.get(funcRef));\n for (let _keys = Map_keys(tempMap), i = 0, k = _keys.length; i < k; ++i) {\n vars.push(_keys[i]);\n }\n }\n let moduleRef = this.module.ref;\n _BinaryenRemoveFunction(moduleRef, name);\n let cArr = allocPtrArray(vars);\n let newFuncRef = _BinaryenAddFunction(moduleRef, name, params, results, cArr, vars.length, body);\n if (this.options.sourceMap || this.options.debugInfo) {\n let func = this.compiler.program.searchFunctionByRef(newFuncRef);\n if (func) func.addDebugInfo(this.module, newFuncRef);\n }\n _free(cArr);\n }\n\n /** Updates a function export taking managed arguments. */\n updateExport(exportRef: ExportRef, managedOperandIndices: i32[]): void {\n let module = this.module;\n let moduleRef = module.ref;\n assert(_BinaryenExportGetKind(exportRef) == ExternalKind.Function);\n\n let internalNameRef = _BinaryenExportGetValue(exportRef);\n let internalName = module.readStringCached(internalNameRef)!;\n let externalNameRef = _BinaryenExportGetName(exportRef);\n let funcRef = _BinaryenGetFunction(moduleRef, internalNameRef);\n let params = _BinaryenFunctionGetParams(funcRef);\n let paramTypes = expandType(params);\n let numParams = paramTypes.length;\n let results = _BinaryenFunctionGetResults(funcRef);\n let numLocals = numParams;\n let vars = new Array();\n let numSlots = assert(managedOperandIndices.length);\n let frameSize = numSlots * this.ptrSize;\n let wrapperName = \"export:\" + internalName;\n let wrapperNameRef = module.allocStringCached(wrapperName);\n\n if (_BinaryenGetFunction(moduleRef, wrapperNameRef) == 0) {\n let stmts = new Array();\n // __stack_pointer -= frameSize\n stmts.push(\n this.makeStackOffset(-frameSize)\n );\n for (let slotIndex = 0; slotIndex < numSlots; ++slotIndex) {\n // store(__stack_pointer, $local, slotIndex * ptrSize)\n stmts.push(\n module.store(this.ptrSize,\n module.global_get(BuiltinNames.stack_pointer, this.ptrType),\n module.local_get(managedOperandIndices[slotIndex], this.ptrType),\n this.ptrType, slotIndex * this.ptrSize\n )\n );\n }\n let forwardedOperands = new Array(numParams);\n for (let i = 0; i < numParams; ++i) {\n forwardedOperands[i] = module.local_get(i, paramTypes[i]);\n }\n if (results != TypeRef.None) {\n let tempIndex = numLocals++;\n vars.push(results);\n // t = original(...)\n stmts.push(\n module.local_set(tempIndex,\n module.call(internalName, forwardedOperands, results),\n false // internal\n )\n );\n // __stack_pointer += frameSize\n stmts.push(\n this.makeStackOffset(+frameSize)\n );\n // -> t\n stmts.push(\n module.local_get(tempIndex, results)\n );\n } else {\n // original(...)\n stmts.push(\n module.call(internalName, forwardedOperands, results)\n );\n // __stack_pointer += frameSize\n stmts.push(\n this.makeStackOffset(+frameSize)\n );\n }\n let cArr = allocPtrArray(vars);\n _BinaryenAddFunction(moduleRef, wrapperNameRef, params, results, cArr, vars.length,\n module.block(null, stmts, results)\n );\n _free(cArr);\n }\n _BinaryenRemoveExport(moduleRef, externalNameRef);\n _BinaryenAddFunctionExport(moduleRef, wrapperNameRef, externalNameRef);\n }\n\n /** @override */\n walkModule(): void {\n // Run the pass normally\n super.walkModule();\n\n // Instrument returns in functions utilizing stack slots\n let module = this.module;\n let instrumentReturns = new InstrumentReturns(this);\n for (let _keys = Map_keys(this.slotMaps), i = 0, k = _keys.length; i < k; ++i) {\n let func = _keys[i];\n let slotMap = changetype(this.slotMaps.get(func));\n let frameSize = slotMap.size * this.ptrSize;\n\n // Instrument function returns\n instrumentReturns.frameSize = frameSize;\n instrumentReturns.walkFunction(func);\n\n // Instrument function entry\n let stmts = new Array();\n // __stack_pointer -= frameSize\n stmts.push(\n this.makeStackOffset(-frameSize)\n );\n // memory.fill(__stack_pointer, 0, frameSize)\n this.makeStackFill(frameSize, stmts);\n\n // Handle implicit return\n let body = _BinaryenFunctionGetBody(func);\n let bodyType = _BinaryenExpressionGetType(body);\n if (bodyType == TypeRef.Unreachable) {\n // body\n stmts.push(\n body\n );\n } else if (bodyType == TypeRef.None) {\n // body\n stmts.push(\n body\n );\n // __stack_pointer += frameSize\n stmts.push(\n this.makeStackOffset(+frameSize)\n );\n } else {\n let temp = this.getSharedTemp(func, bodyType);\n // t = body\n stmts.push(\n module.local_set(temp, body, false)\n );\n // __stack_pointer += frameSize\n stmts.push(\n this.makeStackOffset(+frameSize)\n );\n // -> t\n stmts.push(\n module.local_get(temp, bodyType)\n );\n }\n _BinaryenFunctionSetBody(func, module.flatten(stmts, bodyType));\n }\n\n // Update functions we added more locals to\n // TODO: _BinaryenFunctionAddVar ?\n for (let _keys = Map_keys(this.tempMaps), i = 0, k = _keys.length; i < k; ++i) {\n this.updateFunction(_keys[i]);\n }\n\n // Update exports taking managed arguments\n let exportMap = this.exportMap;\n for (let _keys = Map_keys(exportMap), i = 0, k = _keys.length; i < k; ++i) {\n let exportName = _keys[i];\n let exportRef = _BinaryenGetExport(module.ref, module.allocStringCached(exportName));\n let managedOperandIndices = changetype(exportMap.get(exportName));\n this.updateExport(exportRef, managedOperandIndices);\n }\n }\n}\n\n/** Companion pass instrumenting `return` statements to restore the stack frame. */\nclass InstrumentReturns extends Pass {\n /** Parent pass. */\n parentPass: ShadowStackPass;\n /** Frame size of the current function being processed. */\n frameSize: i32 = 0;\n\n constructor(shadowStack: ShadowStackPass) {\n super(shadowStack.module);\n this.parentPass = shadowStack;\n }\n\n /** @override */\n visitReturn(ret: ExpressionRef): void {\n assert(this.frameSize);\n let module = this.module;\n let value = _BinaryenReturnGetValue(ret);\n let stmts = new Array();\n if (value) {\n let returnType = _BinaryenExpressionGetType(value);\n if (returnType == TypeRef.Unreachable) return;\n let temp = this.parentPass.getSharedTemp(this.currentFunction, returnType);\n // t = value\n stmts.push(\n module.local_set(temp, value, false)\n );\n // __stack_pointer += frameSize\n stmts.push(\n this.parentPass.makeStackOffset(+this.frameSize)\n );\n // return t\n _BinaryenReturnSetValue(ret, module.local_get(temp, returnType));\n } else {\n // __stack_pointer += frameSize\n stmts.push(\n this.parentPass.makeStackOffset(+this.frameSize)\n );\n // return\n }\n stmts.push(\n ret\n );\n this.replaceCurrent(module.flatten(stmts, TypeRef.Unreachable));\n }\n}\n","/**\n * @fileoverview A lightweight store instrumentation pass.\n * \n * Can be used to find rogue stores to protected memory addresses like object\n * headers or similar, without going overboard with instrumentation. Also\n * passes a flag whether a store originates within the runtime or other code.\n * \n * @license Apache-2.0\n */\n\nimport {\n Pass\n} from \"./pass\";\n\nimport {\n Compiler\n} from \"../compiler\";\n\nimport {\n createType,\n ExpressionRef,\n TypeRef\n} from \"../module\";\n\nimport {\n _BinaryenFunctionGetName,\n _BinaryenStoreGetBytes,\n _BinaryenStoreGetOffset,\n _BinaryenStoreGetPtr,\n _BinaryenStoreSetPtr\n} from \"../glue/binaryen\";\n\n/** Instruments stores to also call an import. */\nexport class RtraceMemory extends Pass {\n /** Whether we've seen any stores. */\n seenStores: bool = false;\n /** Target pointer type. */\n ptrType: TypeRef;\n\n constructor(compiler: Compiler) {\n super(compiler.module);\n this.ptrType = compiler.options.sizeTypeRef;\n }\n\n checkRT(): bool {\n let functionName = this.module.readStringCached(_BinaryenFunctionGetName(this.currentFunction))!;\n return functionName.startsWith(\"~lib/rt/\");\n }\n\n /** @override */\n visitStore(store: ExpressionRef): void {\n let module = this.module;\n let ptr = _BinaryenStoreGetPtr(store);\n let offset = _BinaryenStoreGetOffset(store);\n let bytes = _BinaryenStoreGetBytes(store);\n // onstore(ptr: usize, offset: i32, bytes: i32, isRT: bool) -> ptr\n _BinaryenStoreSetPtr(store,\n module.call(\"~onstore\", [\n ptr,\n module.i32(offset),\n module.i32(bytes),\n module.i32(i32(this.checkRT()))\n ], this.ptrType)\n );\n this.seenStores = true;\n }\n\n // TODO: MemoryFill, Atomics\n\n /** @override */\n walkModule(): void {\n super.walkModule();\n if (this.seenStores) {\n this.module.addFunctionImport(\"~onstore\", \"rtrace\", \"onstore\",\n createType([ this.ptrType, TypeRef.I32, TypeRef.I32, TypeRef.I32 ]),\n this.ptrType\n );\n }\n }\n}\n","import {\n SourceKind\n} from \"../ast\";\n\nimport {\n CommonFlags\n} from \"../common\";\n\nimport {\n ClassPrototype,\n Element,\n ElementKind,\n Function,\n Enum,\n Class,\n Interface,\n File,\n FunctionPrototype,\n Global,\n Program,\n Property,\n PropertyPrototype,\n InterfacePrototype\n} from \"../program\";\n\n/** Walker base class. */\nexport abstract class ExportsWalker {\n\n /** Program reference. */\n program: Program;\n /** Whether to include private members */\n includePrivate: bool;\n /** Already seen elements. */\n seen: Map = new Map();\n\n /** Constructs a new Element walker. */\n constructor(program: Program, includePrivate: bool = false) {\n this.program = program;\n this.includePrivate = includePrivate;\n }\n\n /** Walks all elements and calls the respective handlers. */\n walk(): void {\n // TODO: for (let file of this.program.filesByName.values()) {\n for (let _values = Map_values(this.program.filesByName), i = 0, k = _values.length; i < k; ++i) {\n let file = unchecked(_values[i]);\n if (file.source.sourceKind == SourceKind.UserEntry) this.visitFile(file);\n }\n }\n\n /** Visits all exported elements of a file. */\n visitFile(file: File): void {\n let exports = file.exports;\n if (exports) {\n // TODO: for (let [memberName, member] of exports) {\n for (let _keys = Map_keys(exports), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let member = assert(exports.get(memberName));\n this.visitElement(memberName, member);\n }\n }\n let exportsStar = file.exportsStar;\n if (exportsStar) {\n for (let i = 0, k = exportsStar.length; i < k; ++i) {\n let exportStar = unchecked(exportsStar[i]);\n this.visitFile(exportStar);\n }\n }\n }\n\n /** Visits an element.*/\n visitElement(name: string, element: Element): void {\n if (element.is(CommonFlags.Private) && !this.includePrivate) return;\n let seen = this.seen;\n if (!element.is(CommonFlags.Instance) && seen.has(element)) {\n this.visitAlias(name, element, assert(seen.get(element)));\n return;\n }\n seen.set(element, name);\n switch (element.kind) {\n case ElementKind.Global: {\n if (element.is(CommonFlags.Compiled)) this.visitGlobal(name, element);\n break;\n }\n case ElementKind.Enum: {\n if (element.is(CommonFlags.Compiled)) this.visitEnum(name, element);\n break;\n }\n case ElementKind.EnumValue: break; // handled by visitEnum\n case ElementKind.FunctionPrototype: {\n this.visitFunctionInstances(name, element);\n break;\n }\n case ElementKind.ClassPrototype: {\n this.visitClassInstances(name, element);\n break;\n }\n case ElementKind.InterfacePrototype: {\n this.visitInterfaceInstances(name, element);\n break;\n }\n case ElementKind.PropertyPrototype: {\n let propertyInstance = (element).instance;\n if (!propertyInstance) break;\n element = propertyInstance;\n // fall-through\n }\n case ElementKind.Property: {\n let propertyInstance = element;\n let getterInstance = propertyInstance.getterInstance;\n if (getterInstance) this.visitFunction(name, getterInstance);\n let setterInstance = propertyInstance.setterInstance;\n if (setterInstance) this.visitFunction(name, setterInstance);\n break;\n }\n case ElementKind.Namespace: {\n if (hasCompiledMember(element)) this.visitNamespace(name, element);\n break;\n }\n case ElementKind.TypeDefinition:\n case ElementKind.IndexSignature: break;\n default: {\n // Not (directly) reachable exports:\n // File, Local, Function, Class, Interface\n assert(false);\n }\n }\n }\n\n private visitFunctionInstances(name: string, element: FunctionPrototype): void {\n let instances = element.instances;\n if (instances) {\n // TODO: for (let instance of instances.values()) {\n for (let _values = Map_values(instances), i = 0, k = _values.length; i < k; ++i) {\n let instance = unchecked(_values[i]);\n if (instance.is(CommonFlags.Compiled)) this.visitFunction(name, instance);\n }\n }\n }\n\n private visitClassInstances(name: string, element: ClassPrototype): void {\n let instances = element.instances;\n if (instances) {\n // TODO: for (let instance of instances.values()) {\n for (let _values = Map_values(instances), i = 0, k = _values.length; i < k; ++i) {\n let instance = unchecked(_values[i]);\n assert(instance.kind == ElementKind.Class);\n if (instance.is(CommonFlags.Compiled)) this.visitClass(name, instance);\n }\n }\n }\n\n private visitInterfaceInstances(name: string, element: InterfacePrototype): void {\n let instances = element.instances;\n if (instances) {\n // TODO: for (let instance of instances.values()) {\n for (let _values = Map_values(instances), i = 0, k = _values.length; i < k; ++i) {\n let instance = unchecked(_values[i]);\n assert(instance.kind == ElementKind.Interface);\n if (instance.is(CommonFlags.Compiled)) this.visitInterface(name, instance);\n }\n }\n }\n\n abstract visitGlobal(name: string, element: Global): void;\n abstract visitEnum(name: string, element: Enum): void;\n abstract visitFunction(name: string, element: Function): void;\n abstract visitClass(name: string, element: Class): void;\n abstract visitInterface(name: string, element: Interface): void;\n abstract visitNamespace(name: string, element: Element): void;\n abstract visitAlias(name: string, element: Element, originalName: string): void;\n}\n\n// Helpers\n\n/** Tests if a namespace-like element has at least one compiled member. */\nexport function hasCompiledMember(element: Element): bool {\n let members = element.members;\n if (members) {\n // TODO: for (let member of members.values()) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = unchecked(_values[i]);\n switch (member.kind) {\n case ElementKind.FunctionPrototype: {\n let instances = (member).instances;\n if (instances) {\n // TODO: for (let instance of instances.values()) {\n for (let _values = Map_values(instances), j = 0, l = _values.length; j < l; ++j) {\n let instance = unchecked(_values[j]);\n if (instance.is(CommonFlags.Compiled)) return true;\n }\n }\n break;\n }\n case ElementKind.ClassPrototype: {\n let instances = (member).instances;\n if (instances) {\n // TODO: for (let instance of instances.values()) {\n for (let _values = Map_values(instances), j = 0, l = _values.length; j < l; ++j) {\n let instance = unchecked(_values[j]);\n if (instance.is(CommonFlags.Compiled)) return true;\n }\n }\n break;\n }\n default: {\n if (member.is(CommonFlags.Compiled) || hasCompiledMember(member)) return true;\n break;\n }\n }\n }\n }\n return false;\n}\n","import {\n Source\n} from \"../ast\";\n\nimport {\n CommonFlags\n} from \"../common\";\n\nimport {\n Global,\n Program,\n Function,\n Class,\n Interface,\n Enum,\n ElementKind,\n Element,\n PropertyPrototype\n} from \"../program\";\n\nimport {\n Type,\n TypeFlags\n} from \"../types\";\n\nimport {\n CharCode,\n escapeString,\n indent, isIdentifier\n} from \"../util\";\n\nimport {\n ExportsWalker\n} from \"./util\";\n\n/** A TypeScript definitions builder. */\nexport class TSDBuilder extends ExportsWalker {\n\n /** Builds TypeScript definitions for the specified program. */\n static build(program: Program, esm: bool = true): string {\n return new TSDBuilder(program, esm).build();\n }\n\n private esm: bool;\n private sb: string[] = [];\n private indentLevel: i32 = 0;\n private seenObjectTypes: Map = new Map();\n private deferredTypings: string[] = new Array();\n\n /** Constructs a new TypeScript definitions builder. */\n constructor(program: Program, esm: bool, includePrivate: bool = false) {\n super(program, includePrivate);\n this.esm = esm;\n }\n\n visitGlobal(name: string, element: Global): void {\n let sb = this.sb;\n let type = element.type;\n let tsType = this.toTypeScriptType(type, Mode.EXPORT);\n indent(sb, this.indentLevel);\n sb.push(\"/** \");\n sb.push(element.internalName);\n sb.push(\" */\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"export \");\n if (this.esm) sb.push(\"declare \");\n sb.push(\"const \");\n sb.push(name);\n sb.push(\": {\\n\");\n indent(sb, ++this.indentLevel);\n sb.push(\"/** @type `\");\n sb.push(type.toString());\n sb.push(\"` */\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"get value(): \");\n sb.push(tsType);\n if (!element.is(CommonFlags.Const)) {\n sb.push(\";\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"set value(value: \");\n sb.push(tsType);\n sb.push(\");\\n\");\n } else {\n sb.push(\"\\n\");\n }\n indent(sb, --this.indentLevel);\n sb.push(\"};\\n\");\n }\n\n visitEnum(name: string, element: Enum): void {\n let sb = this.sb;\n indent(sb, this.indentLevel);\n sb.push(\"/** \");\n sb.push(element.internalName);\n sb.push(\" */\\n\");\n indent(sb, this.indentLevel++);\n sb.push(\"export \");\n if (this.esm) sb.push(\"declare \");\n sb.push(\"enum \");\n sb.push(name);\n sb.push(\" {\\n\");\n let members = element.members;\n if (members) {\n // TODO: for (let [memberName, member] of members) {\n for (let _keys = Map_keys(members), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = unchecked(_keys[i]);\n let member = assert(members.get(memberName));\n if (member.kind != ElementKind.EnumValue) continue;\n indent(sb, this.indentLevel);\n sb.push(\"/** @type `i32` */\\n\");\n indent(sb, this.indentLevel);\n sb.push(memberName);\n sb.push(\",\\n\");\n }\n }\n indent(sb, --this.indentLevel);\n sb.push(\"}\\n\");\n }\n\n visitFunction(name: string, element: Function): void {\n let sb = this.sb;\n let signature = element.signature;\n indent(sb, this.indentLevel);\n sb.push(\"/**\\n\");\n indent(sb, this.indentLevel);\n sb.push(\" * \");\n sb.push(element.internalName);\n sb.push(\"\\n\");\n let parameterTypes = signature.parameterTypes;\n let numParameters = parameterTypes.length;\n for (let i = 0; i < numParameters; ++i) {\n indent(sb, this.indentLevel);\n sb.push(\" * @param \");\n sb.push(element.getParameterName(i));\n sb.push(\" `\");\n sb.push(parameterTypes[i].toString());\n sb.push(\"`\\n\");\n }\n let returnType = signature.returnType;\n if (returnType != Type.void) {\n indent(sb, this.indentLevel);\n sb.push(\" * @returns `\");\n sb.push(returnType.toString());\n sb.push(\"`\\n\");\n }\n indent(sb, this.indentLevel);\n sb.push(\" */\\n\");\n indent(sb, this.indentLevel);\n sb.push(\"export \");\n if (this.esm) sb.push(\"declare \");\n sb.push(\"function \");\n sb.push(name);\n sb.push(\"(\");\n let requiredParameters = signature.requiredParameters;\n for (let i = 0; i < numParameters; ++i) {\n if (i) sb.push(\", \");\n sb.push(element.getParameterName(i));\n if (i >= requiredParameters) sb.push(\"?\");\n sb.push(\": \");\n sb.push(this.toTypeScriptType(parameterTypes[i], Mode.IMPORT));\n }\n sb.push(\"): \");\n sb.push(this.toTypeScriptType(returnType, Mode.EXPORT));\n sb.push(\";\\n\");\n }\n\n visitClass(name: string, element: Class): void {\n // not implemented\n }\n\n visitInterface(name: string, element: Interface): void {\n // not implemented\n }\n\n visitNamespace(name: string, element: Element): void {\n // not implemented\n }\n\n visitAlias(name: string, element: Element, originalName: string): void {\n // not implemented\n }\n\n build(): string {\n let sb = this.sb;\n if (!this.esm) {\n sb.push(\"declare namespace __AdaptedExports {\\n\");\n ++this.indentLevel;\n }\n if (this.program.options.exportMemory) {\n indent(sb, this.indentLevel);\n sb.push(\"/** Exported memory */\\n\");\n indent(sb, this.indentLevel);\n sb.push(`export ${this.esm ? \"declare \" : \"\"}const memory: WebAssembly.Memory;\\n`);\n }\n if (this.program.options.exportTable) {\n indent(sb, this.indentLevel);\n sb.push(\"/** Exported table */\\n\");\n indent(sb, this.indentLevel);\n sb.push(`export ${this.esm ? \"declare \" : \"\"}const table: WebAssembly.Table;\\n`);\n }\n this.walk();\n if (!this.esm) {\n --this.indentLevel;\n sb.push(\"}\\n\");\n }\n let deferredTypes = this.deferredTypings;\n for (let i = 0, k = deferredTypes.length; i < k; ++i) {\n sb.push(deferredTypes[i]);\n }\n if (!this.esm) {\n sb.push(\"/** Instantiates the compiled WebAssembly module with the given imports. */\\n\");\n sb.push(\"export declare function instantiate(module: WebAssembly.Module, imports: {\\n\");\n let moduleImports = this.program.moduleImports;\n for (let _keys = Map_keys(moduleImports), i = 0, k = _keys.length; i < k; ++i) {\n let moduleName = _keys[i];\n sb.push(\" \");\n if (isIdentifier(moduleName)) {\n sb.push(moduleName);\n } else {\n sb.push(\"\\\"\");\n sb.push(escapeString(moduleName, CharCode.DoubleQuote));\n sb.push(\"\\\"\");\n }\n sb.push(\": unknown,\\n\");\n }\n sb.push(\"}): Promise;\\n\");\n }\n return sb.join(\"\");\n }\n\n isPlainObject(clazz: Class): bool {\n // A plain object does not inherit and does not have a constructor or private properties\n if (clazz.base && !clazz.prototype.implicitlyExtendsObject) return false;\n let members = clazz.members;\n if (members) {\n for (let _values = Map_values(members), i = 0, k = _values.length; i < k; ++i) {\n let member = _values[i];\n if (member.isAny(CommonFlags.Private | CommonFlags.Protected)) return false;\n if (member.is(CommonFlags.Constructor)) {\n // a generated constructor is ok\n if (member.declaration.range != Source.native.range) return false;\n }\n }\n }\n return true;\n }\n\n toTypeScriptType(type: Type, mode: Mode): string {\n if (type.isInternalReference) {\n const sb = new Array();\n const clazz = assert(type.getClassOrWrapper(this.program));\n if (clazz.extendsPrototype(this.program.arrayBufferInstance.prototype)) {\n sb.push(\"ArrayBuffer\");\n } else if (clazz.extendsPrototype(this.program.stringInstance.prototype)) {\n sb.push(\"string\");\n } else if (clazz.extendsPrototype(this.program.arrayPrototype)) {\n const valueType = clazz.getArrayValueType();\n sb.push(\"Array<\");\n sb.push(this.toTypeScriptType(valueType, mode));\n sb.push(\">\");\n } else if (clazz.extendsPrototype(this.program.staticArrayPrototype)) {\n const valueType = clazz.getArrayValueType();\n sb.push(\"ArrayLike<\");\n sb.push(this.toTypeScriptType(valueType, mode));\n sb.push(\">\");\n } else if (clazz.extendsPrototype(this.program.arrayBufferViewInstance.prototype)) {\n const valueType = clazz.getArrayValueType();\n if (valueType == Type.i8) {\n sb.push(\"Int8Array\");\n } else if (valueType == Type.u8) {\n if (clazz.extendsPrototype(this.program.uint8ClampedArrayPrototype)) {\n sb.push(\"Uint8ClampedArray\");\n } else {\n sb.push(\"Uint8Array\");\n }\n } else if (valueType == Type.i16) {\n sb.push(\"Int16Array\");\n } else if (valueType == Type.u16) {\n sb.push(\"Uint16Array\");\n } else if (valueType == Type.i32) {\n sb.push(\"Int32Array\");\n } else if (valueType == Type.u32) {\n sb.push(\"Uint32Array\");\n } else if (valueType == Type.i64) {\n sb.push(\"BigInt64Array\");\n } else if (valueType == Type.u64) {\n sb.push(\"BigUint64Array\");\n } else if (valueType == Type.f32) {\n sb.push(\"Float32Array\");\n } else if (valueType == Type.f64) {\n sb.push(\"Float64Array\");\n } else {\n sb.push(\"unknown\");\n }\n } else {\n let seenObjectTypes = this.seenObjectTypes;\n let typeName: string;\n if (seenObjectTypes.has(clazz)) {\n typeName = assert(seenObjectTypes.get(clazz));\n sb.push(typeName);\n if (this.isPlainObject(clazz)) {\n sb.push(mode == Mode.EXPORT ? \"\" : \"\");\n }\n } else {\n let isPlain = this.isPlainObject(clazz);\n typeName = `${isPlain ? \"__Record\" : \"__Internref\"}${clazz.id}`;\n sb.push(typeName);\n seenObjectTypes.set(clazz, typeName);\n if (isPlain) {\n sb.push(mode == Mode.EXPORT ? \"\" : \"\");\n this.deferredTypings.push(this.makeRecordType(clazz, mode));\n } else {\n this.deferredTypings.push(this.makeInternrefType(clazz));\n }\n }\n }\n if (type.is(TypeFlags.Nullable)) {\n sb.push(\" | null\");\n }\n return sb.join(\"\");\n } else {\n if (type == Type.bool) {\n return \"boolean\";\n }\n if (type == Type.void) {\n return \"void\";\n }\n if (type.isNumericValue) {\n if (type.isLongIntegerValue) {\n return \"bigint\";\n }\n return \"number\";\n }\n }\n return \"unknown\";\n }\n\n makeRecordType(clazz: Class, mode: Mode): string {\n let sb = new Array();\n let members = clazz.members;\n sb.push(\"/** \");\n sb.push(clazz.internalName);\n sb.push(\" */\\ndeclare interface __Record\");\n sb.push(clazz.id.toString());\n sb.push(\" {\\n\");\n if (members) {\n for (let _keys = Map_keys(members), i = 0, k = _keys.length; i < k; ++i) {\n let memberName = _keys[i];\n let member = assert(members.get(memberName));\n if (member.kind != ElementKind.PropertyPrototype) continue;\n let property = (member).instance; // resolved during class finalization\n if (!property || !property.isField) continue;\n sb.push(\" /** @type `\");\n sb.push(property.type.toString());\n sb.push(\"` */\\n \");\n sb.push(property.name);\n sb.push(\": \");\n sb.push(this.toTypeScriptType(property.type, mode));\n if (this.fieldAcceptsUndefined(property.type)) {\n sb.push(\" | TOmittable\");\n }\n sb.push(\";\\n\");\n }\n }\n sb.push(\"}\\n\");\n return sb.join(\"\");\n }\n\n fieldAcceptsUndefined(type: Type): bool {\n if (type.isInternalReference) {\n return type.is(TypeFlags.Nullable);\n }\n return true;\n }\n\n makeInternrefType(clazz: Class): string {\n let sb = new Array();\n sb.push(\"/** \");\n sb.push(clazz.internalName);\n sb.push(\" */\\n\");\n sb.push(\"declare class __Internref\");\n sb.push(clazz.id.toString());\n sb.push(\" extends Number {\\n\");\n let base: Class | null = clazz;\n do {\n sb.push(\" private __nominal\");\n sb.push(base.id.toString());\n sb.push(\": symbol;\\n\");\n base = base.base;\n } while (base);\n sb.push(\"}\\n\");\n return sb.join(\"\");\n }\n}\n\n// Helpers\n\nenum Mode {\n IMPORT,\n EXPORT\n}\n","import { memcmp, memmove, memset } from \"./util/memory\";\nimport { E_NOTIMPLEMENTED } from \"./util/error\";\n\n/** Memory manager interface. */\nexport namespace memory {\n\n /** Gets the size of the memory in pages. */\n // @ts-ignore: decorator\n @builtin\n export declare function size(): i32;\n\n /** Grows the memory by the given size in pages and returns the previous size in pages. */\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function grow(pages: i32): i32;\n\n /** Fills a section in memory with the specified byte value. */\n // @ts-ignore: decorator\n @unsafe @builtin\n export function fill(dst: usize, c: u8, n: usize): void {\n memset(dst, c, n); // fallback if \"bulk-memory\" isn't enabled\n }\n\n /** Copies a section of memory to another. Has move semantics. */\n // @ts-ignore: decorator\n @unsafe @builtin\n export function copy(dst: usize, src: usize, n: usize): void {\n memmove(dst, src, n); // fallback if \"bulk-memory\" isn't enabled\n }\n\n export namespace atomic {\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function wait32(ptr: usize, expected: i32, timeout: i64): AtomicWaitResult;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function wait64(ptr: usize, expected: i64, timeout: i64): AtomicWaitResult;\n }\n\n /** Initializes a memory segment. */\n // @ts-ignore: decorator\n @unsafe\n export function init(segmentIndex: u32, srcOffset: usize, dstOffset: usize, n: usize): void {\n throw new Error(E_NOTIMPLEMENTED);\n }\n\n /** Drops a memory segment. */\n // @ts-ignore: decorator\n @unsafe\n export function drop(segmentIndex: u32): void {\n throw new Error(E_NOTIMPLEMENTED);\n }\n\n /** Repeats a section of memory at a specific address. */\n // @ts-ignore: decorator\n @unsafe\n export function repeat(dst: usize, src: usize, srcLength: usize, count: usize): void {\n let index: usize = 0;\n let total = srcLength * count;\n while (index < total) {\n memory.copy(dst + index, src, srcLength);\n index += srcLength;\n }\n }\n\n /** Compares a section of memory to another. */\n // @ts-ignore: decorator\n @inline\n export function compare(vl: usize, vr: usize, n: usize): i32 {\n return memcmp(vl, vr, n);\n }\n\n /** Gets a pointer to a static chunk of memory of the given size. */\n // @ts-ignore: decorator\n @builtin\n export declare function data(size: T, align?: i32): usize;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare const __data_end: usize;\n\n// @ts-ignore: decorator\n@builtin\nexport declare let __stack_pointer: usize;\n\n// @ts-ignore: decorator\n@builtin\nexport declare const __heap_base: usize;\n\n/** Heap memory interface. */\nexport namespace heap {\n\n /** Allocates a chunk of memory of at least the specified size. */\n // @ts-ignore: decorator\n @unsafe export function alloc(size: usize): usize {\n return __alloc(size);\n }\n\n /** Reallocates a chunk of memory to have at least the specified size. */\n // @ts-ignore: decorator\n @unsafe export function realloc(ptr: usize, size: usize): usize {\n return __realloc(ptr, size);\n }\n\n /** Frees a chunk of memory. Does hardly anything (most recent block only) with the stub runtime. */\n // @ts-ignore: decorator\n @unsafe export function free(ptr: usize): void {\n __free(ptr);\n }\n\n /** Dangerously resets the entire heap. Specific to the stub runtime. */\n // @ts-ignore: decorator\n @unsafe export function reset(): void {\n if (isDefined(__reset)) {\n __reset();\n } else {\n throw new Error(E_NOTIMPLEMENTED);\n }\n }\n}\n","type auto = i32;\n\n@final export abstract class Function {\n private _index: u32;\n private _env: usize;\n\n // @ts-ignore: this on getter\n get index(this: T): u32 {\n return load(changetype(this), offsetof>(\"_index\"));\n }\n\n // @ts-ignore: this on getter\n get name(this: T): string {\n return \"\";\n }\n\n // @ts-ignore: this on getter\n get length(this: T): i32 {\n // @ts-ignore: T is function\n return lengthof();\n }\n\n // @ts-ignore: T is function\n @builtin call(thisArg: thisof | null, ...args: auto[]): returnof {\n return unreachable();\n }\n\n toString(this: T): string {\n return \"function() { [native code] }\";\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n // Env is either `null` (nop) or compiler-generated\n __visit(this._env, cookie);\n }\n}\n"]} \ No newline at end of file diff --git a/tests/cpp/lit.cpp b/tests/cpp/lit.cpp new file mode 100644 index 0000000..27aff00 --- /dev/null +++ b/tests/cpp/lit.cpp @@ -0,0 +1,121 @@ +#include "json/reader.h" +#include "json/value.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include "../../instrumentation/CoverageInstru.hpp" +#include "../../instrumentation/InstrumentResponse.hpp" +#include "utils/utils.h" + +TEST(lit, coverageInstrumentation) { + // step 1, prepare + const std::filesystem::path projectPath = testUtils::getProjectPath(); + const std::filesystem::path wasmOptPath = + projectPath / "build" / "thirdparty" / "binaryen" / "bin" / "wasm-opt"; + const std::filesystem::path fixtureFolder = projectPath / "test" / "lit" / "covInstrument"; + const std::filesystem::path tmpDir = projectPath / "test" / "lit" / "build"; + const std::filesystem::path executor = projectPath / "test" / "lit" / "run.cjs"; + const std::filesystem::path checkPy = projectPath / "test" / "check.py"; + + if (!exists(tmpDir)) { + create_directory(tmpDir); + } + + // step 2, build + + const std::string separator(" "); + std::vector wastFiles; + for (const auto &entity : std::filesystem::recursive_directory_iterator(fixtureFolder)) { + if (entity.is_regular_file() && entity.path().extension() == ".wast") { + std::stringstream cmd; + cmd << wasmOptPath; + wastFiles.push_back(entity.path().filename()); + cmd << separator << entity << separator << "-o" << separator << tmpDir << "/" + << entity.path().filename() << ".out.wasm" << separator << "-osm" << separator << tmpDir + << "/" << entity.path().filename() << ".out.wasm.map" << separator << "-g" << separator + << "-q"; + ASSERT_EQ(system(cmd.str().c_str()), 0); + } + } + const char *include = "[\"main\",\"assembly/.*\"]"; + Json::Reader jsonReader; + // step 3, instrument , run and check; + for (Json::String const &wast : wastFiles) { + const std::filesystem::path wasmFile = tmpDir / (wast + ".out.wasm"); + const std::filesystem::path wasmFileMap = tmpDir / (wast + ".out.wasm.map"); + const std::filesystem::path wasmTarget = tmpDir / (wast + ".instrumented.wasm"); + const std::filesystem::path debugTarget = tmpDir / (wast + ".debug.json"); + const std::filesystem::path expectTarget = tmpDir / (wast + ".expect.json"); + const char *traceFunName = "assembly/env/traceExpression"; + wasmInstrumentation::InstrumentationConfig config; + std::cout << "running lit - " << fixtureFolder << "/" << wast << std::endl; + config.fileName = wasmFile.c_str(); + config.debugInfoOutputFilePath = debugTarget.c_str(); + config.expectInfoOutputFilePath = expectTarget.c_str(); + config.sourceMap = wasmFileMap.c_str(); + config.targetName = wasmTarget.c_str(); + config.reportFunction = traceFunName; + config.includes = include; + config.excludes = ""; + wasmInstrumentation::CoverageInstru instrumentor(&config); + ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::NORMAL); + std::stringstream cmd; + cmd << "node " << executor << " " << wasmTarget << " >" << tmpDir << "/" << wast << ".run.log"; + const std::filesystem::path fixtureFilePath = fixtureFolder / (wast + ".debug.json"); + std::ifstream fixtureStream(fixtureFilePath); + std::ifstream debugInfoStream(debugTarget); + Json::Value fixtureJson; + Json::Value debugInfoJson; + jsonReader.parse(fixtureStream, fixtureJson, false); + jsonReader.parse(debugInfoStream, debugInfoJson, false); + + ASSERT_TRUE(testUtils::compareDebugInfoJson(fixtureJson, debugInfoJson)); + std::stringstream runLogCmpCmd; + runLogCmpCmd << "python3 " << checkPy << separator << fixtureFolder << "/" << wast << ".run.log" + << separator << tmpDir << "/" << wast << ".run.log"; + ASSERT_EQ(system(cmd.str().c_str()), 0); + ASSERT_EQ(system(runLogCmpCmd.str().c_str()), 0); + } +} + +TEST(lit, expectInstrumentation) { + const std::filesystem::path projectPath = testUtils::getProjectPath(); + const std::filesystem::path fixtureFolder = projectPath / "test" / "lit" / "expectInstrument"; + const std::filesystem::path tmpDir = projectPath / "test" / "lit" / "build"; + const std::filesystem::path checkPy = projectPath / "test" / "check.py"; + + if (!exists(tmpDir)) { + create_directory(tmpDir); + } + + wasmInstrumentation::InstrumentationConfig config; + const std::filesystem::path wasmFile = fixtureFolder / "expect.test.wasm"; + const std::filesystem::path wasmFileMap = fixtureFolder / "expect.test.wasm.map"; + const std::filesystem::path debugTarget = tmpDir / "expect.test.debug.json"; + const std::filesystem::path expectTarget = tmpDir / "expect.test.expect.json"; + const std::filesystem::path wasmTarget = tmpDir / "expect.test.instrumented.wasm"; + const char *traceFunName = "assembly/env/traceExpression"; + const char *include = "[\"tests-as\",\"assembly/.*\"]"; + config.fileName = wasmFile.c_str(); + config.sourceMap = wasmFileMap.c_str(); + config.debugInfoOutputFilePath = debugTarget.c_str(); + config.expectInfoOutputFilePath = expectTarget.c_str(); + config.targetName = wasmTarget.c_str(); + config.reportFunction = traceFunName; + config.includes = include; + config.excludes = ""; + wasmInstrumentation::CoverageInstru instrumentor(&config); + ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::NORMAL); + + std::stringstream assertExpectInfoCmd; + assertExpectInfoCmd << "python3 " << checkPy << " " << fixtureFolder << "/" + << "expect.test.expect.json" + << " " << tmpDir << "/" + << "expect.test.expect.json"; + ASSERT_EQ(system(assertExpectInfoCmd.str().c_str()), 0); +} diff --git a/tests/cpp/lit/build/do_while.wast.debug.json b/tests/cpp/lit/build/do_while.wast.debug.json new file mode 100644 index 0000000..d214a55 --- /dev/null +++ b/tests/cpp/lit/build/do_while.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/do-while.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,1]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,5,4],[0,6,10],[0,6,18]],[[0,4,2]],[[0,7,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/do_while.wast.expect.json b/tests/cpp/lit/build/do_while.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/do_while.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/do_while.wast.instrumented.wasm b/tests/cpp/lit/build/do_while.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..38ed12aa5e3c1a64bfe5798fb48a5b8b05dc6a6e GIT binary patch literal 183 zcmYMqK?=e!6olbjz%ySnL0X7lqg=u#j6v{x-i zS|uWAS%icST)FXciD{nR!N<9tr_TA)_ci&H`Z0obVRXa)uyGIXhFdnUV#2zhRp|N% v-rng-N-V5cYG4Zk3qzI+XUl7#j+!k!4QtjoXQM?clsWUMfzDvnQg!(Qu)-#4 literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/do_while.wast.out.wasm b/tests/cpp/lit/build/do_while.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..18a2d7c953a85a7ad05a6fa1fff994c42c95e37e GIT binary patch literal 111 zcmW;Du?|Hr7zWVq`>P>D?rLlk5s#sp$I!S2qBW?*=G7(6e&EkQ0MwkoM+uP^%z|Gd zPd6SUOr!gAvEgiV=gcMrHV`&}Y$yg*ov}X$S>9A6HD&=}3MTy~h7?zd6qm A7ytkO literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/do_while.wast.out.wasm.map b/tests/cpp/lit/build/do_while.wast.out.wasm.map new file mode 100644 index 0000000..b698350 --- /dev/null +++ b/tests/cpp/lit/build/do_while.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/do-while.ts"],"names":[],"mappings":"oCACc,IACA,IAAW,IACvB,EACE,OACM,EAAQ,MACT"} \ No newline at end of file diff --git a/tests/cpp/lit/build/do_while.wast.run.log b/tests/cpp/lit/build/do_while.wast.run.log new file mode 100644 index 0000000..0877ba8 --- /dev/null +++ b/tests/cpp/lit/build/do_while.wast.run.log @@ -0,0 +1,11 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/build/do_while_break.wast.debug.json b/tests/cpp/lit/build/do_while_break.wast.debug.json new file mode 100644 index 0000000..168ce35 --- /dev/null +++ b/tests/cpp/lit/build/do_while_break.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/do-while-break.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3],[3,4],[3,1]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,5,4],[0,6,8],[0,6,16]],[[0,6,19]],[[0,7,10],[0,7,18]],[[0,4,2]],[[0,4,2]],[[0,8,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/do_while_break.wast.expect.json b/tests/cpp/lit/build/do_while_break.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/do_while_break.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/do_while_break.wast.instrumented.wasm b/tests/cpp/lit/build/do_while_break.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..b9ec1c5d91e137342d2765965367eb584b8ddeb0 GIT binary patch literal 223 zcmYL=K@NgI3`KuCpeQ1E1Gt9^W?`Zx-T^Wp5eZ-biMw9i&dPMr_g{Ze&piR4lc_*b z84*FnA|!m~#Et81n3w6(H^Y)HQ|+3|_dPZ9+>Qh2*pIIJ7k2L1xbC42Y?!c(DCp~U z0Pj~?$cTj%OBrlbz@i{a1*_A^z$KTa%-PbbU|r!|J^4#eDrqmn!NfV|xN0^&Cx{gT PkFlrFQ?5^T<0*}QMmj3& literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/do_while_break.wast.out.wasm b/tests/cpp/lit/build/do_while_break.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ef72f081db3513c5cd8946b5caf4d18b7fd2524d GIT binary patch literal 124 zcmW;Eu@1r@6a~;_(Fw$ukC1SSTNXrhs=BxbCVBY?!cGQ`Fb( z0N#3fk`W6lmNHmVz@i{a1*_A`U`j4?wsbF8gGaR#d{ipwD#MQASlI;5ImcN`6iR~N M7eB8*b{Qy*zsAcdv;Y7A literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/do_while_continue.wast.out.wasm b/tests/cpp/lit/build/do_while_continue.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..2bd00c51ee16aefc6e977fd60558d0d29a989dfe GIT binary patch literal 124 zcmW;Eu@1r@6a~Xn6xy6=K-Y zl)O}6Kk-6clLjONCI-L2iRU3`M^^w1iL^dVvV8kaZW#B8x=o9Y77B7&MlNcf#IH~t)kd6_PKJ1m=JYFxX&eoyT@pT+_7+K;aL7ZUf` zy6!_euwg>HqNs0919<&M^h?BIVZ~AoyDMS0C27{l!4+3VUjfTsC3M~5qn=dA5mid; u=_N|_L|rhpUN8?K3IYY;T>5{Xe3L4`K6}hUh(qh^m8Sv)oi!vrY|=X(j4+J9`;{`U$6+8iy>Lnz`!gXN_vEJ)?43TPPUNK1TOaL^zfvXb2 zZm4s57GQhjnX<-{M;tsQs32iPl-Z-j*IsnkDc34rU4}of!{p&2_Hb>DoDL3Nmy{p0 SM8B6KAu#vlQz}heYMOs`gB9oi literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/do_while_once.wast.out.wasm.map b/tests/cpp/lit/build/do_while_once.wast.out.wasm.map new file mode 100644 index 0000000..7ed6737 --- /dev/null +++ b/tests/cpp/lit/build/do_while_once.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/do-while-once.ts"],"names":[],"mappings":"oCACc,IACA,IACZ,MACE,EAAS,KACL,EAAQ,MAAM,GAClB,OACI,EAAQ,KAAI,GAChB,QACO,MACF,EAAQ"} \ No newline at end of file diff --git a/tests/cpp/lit/build/do_while_once.wast.run.log b/tests/cpp/lit/build/do_while_once.wast.run.log new file mode 100644 index 0000000..25482e7 --- /dev/null +++ b/tests/cpp/lit/build/do_while_once.wast.run.log @@ -0,0 +1,9 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 +basic block entry trace to: function=0, basic block=8 +basic block entry trace to: function=0, basic block=9 diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.debug.json b/tests/cpp/lit/build/exit_basicBlock.wast.debug.json new file mode 100644 index 0000000..3cea1a8 --- /dev/null +++ b/tests/cpp/lit/build/exit_basicBlock.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/exit-basicBlock.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[3,4],[3,5]],"index":0,"lineInfo":[[[0,4,6],[0,4,14]],[[0,4,14]],[[0,4,19],[0,4,27]],[],[[0,5,17]],[]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.expect.json b/tests/cpp/lit/build/exit_basicBlock.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/exit_basicBlock.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.instrumented.wasm b/tests/cpp/lit/build/exit_basicBlock.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ec384441175e8e71a5f776ebcbc99c8a14dd1692 GIT binary patch literal 207 zcmYj}K?=e!5Jmqasnr%WR}in^!YmYAcmt7^P_UG=(o}Ibm-Qe{+$h5^e;$vIItBtj zR#!l!nHiO0CRRJO^uzPi$7y_ork~c+So`Mix{pna?a+f(Ves8gSomAxyR$GTtq8N6 z819WSpOXo7+d~ysx)8C0V@DQSxa=s8jD-;-N!BK!)6K*vlA-=-Y4%dPNtQ{xl#qSH E2f$}4-T(jq literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.out.wasm b/tests/cpp/lit/build/exit_basicBlock.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..30db66fd61f64027f75d9ee99ddb7c1e2dfd5a9f GIT binary patch literal 131 zcmW-ZK@Ng200eiTSVO-+G{&>x10JXc-eJX>G*C!rNx1d1KE%e`9A*Y4cmkl{6DSMf zAeo@QQ1VFOjhlh`#D+{)=&BbU$#oNmSH$0|g7+b%*?GI~W8!G?+ literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.out.wasm.map b/tests/cpp/lit/build/exit_basicBlock.wast.out.wasm.map new file mode 100644 index 0000000..5298920 --- /dev/null +++ b/tests/cpp/lit/build/exit_basicBlock.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/exit-basicBlock.ts"],"names":[],"mappings":"4CAGM,EAAQ,QAAK,EAAQ,MACV,MADU"} \ No newline at end of file diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.run.log b/tests/cpp/lit/build/exit_basicBlock.wast.run.log new file mode 100644 index 0000000..6ef1c53 --- /dev/null +++ b/tests/cpp/lit/build/exit_basicBlock.wast.run.log @@ -0,0 +1,5 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=5 diff --git a/tests/cpp/lit/build/expect.test.debug.json b/tests/cpp/lit/build/expect.test.debug.json new file mode 100644 index 0000000..399cd82 --- /dev/null +++ b/tests/cpp/lit/build/expect.test.debug.json @@ -0,0 +1 @@ +{"debugFiles":["~lib/rt/common.ts","~lib/rt/tlsf.ts","~lib/shared/typeinfo.ts","~lib/rt/itcms.ts","~lib/util/error.ts","~lib/shared/runtime.ts","~lib/util/number.ts","~lib/util/math.ts","~lib/util/string.ts","~lib/rt.ts","assembly/assertCollector.ts","~lib/arraybuffer.ts","~lib/util/hash.ts","~lib/map.ts","assembly/expect.ts","~lib/@assemblyscript/wasi-shim/assembly/bindings/wasi_snapshot_preview1.ts","tests-as/expect.test.ts","assembly/index.ts","assembly/comparison.ts","assembly/formatPrint.ts","~lib/number.ts","~lib/util/sort.ts","~lib/string.ts","~lib/array.ts","assembly/implement.ts","assembly/output.ts","~lib/staticarray.ts","~lib/builtins.ts","~lib/function.ts"],"debugInfos":{"assembly/assertCollector/AssertResultCollector#addDescription":{"branchInfo":[],"index":19,"lineInfo":[[[10,10,4],[10,10,38]]]},"assembly/assertCollector/AssertResultCollector#clear":{"branchInfo":[],"index":38,"lineInfo":[[[10,39,4],[10,39,23],[10,40,4],[10,40,35],[10,41,4]]]},"assembly/assertCollector/AssertResultCollector#collectCheckResult":{"branchInfo":[[0,1],[0,5],[1,2],[1,3]],"index":10,"lineInfo":[[[10,21,4],[10,22,8],[10,22,9]],[[10,23,6],[10,24,31],[10,24,65],[10,25,28],[10,26,8],[10,27,8],[10,28,8],[10,30,10],[10,30,31],[20,187,35]],[[10,31,8],[10,31,29],[10,31,52]],[[10,33,8],[10,33,29],[10,33,47],[10,33,48]],[],[]]},"assembly/assertCollector/AssertResultCollector#constructor":{"branchInfo":[[0,1],[0,2]],"index":8,"lineInfo":[[],[],[[10,4,15],[10,5,14],[10,6,41],[10,7,38]]]},"assembly/assertCollector/AssertResultCollector#failInfoString":{"branchInfo":[],"index":37,"lineInfo":[[[10,51,4],[10,51,11],[10,51,30],[10,51,37]]]},"assembly/assertCollector/AssertResultCollector#failString":{"branchInfo":[],"index":32,"lineInfo":[[[10,48,4],[10,48,11],[10,48,23],[20,187,35]]]},"assembly/assertCollector/AssertResultCollector#removeDescription":{"branchInfo":[],"index":20,"lineInfo":[[[10,13,4]]]},"assembly/assertCollector/AssertResultCollector#totalString":{"branchInfo":[],"index":31,"lineInfo":[[[10,45,4],[10,45,11],[10,45,24],[20,187,35]]]},"assembly/comparison/equal":{"branchInfo":[],"index":1,"lineInfo":[[[18,94,6],[18,94,7],[18,94,42],[18,95,11],[18,95,16]]]},"assembly/comparison/isNull<~lib/string/String|null>":{"branchInfo":[],"index":25,"lineInfo":[[[18,2,2],[18,2,6],[18,2,7],[18,5,2],[18,5,6],[18,5,7],[18,8,2],[18,8,9],[18,8,14]]]},"assembly/expect/Value#closeTo":{"branchInfo":[],"index":14,"lineInfo":[[[14,100,4],[14,100,17],[14,101,8],[14,101,52],[14,102,6],[14,103,8],[14,103,12],[14,103,19],[14,103,33],[14,104,8],[14,105,8],[14,105,15],[14,106,8],[14,106,22],[14,106,29],[14,111,4],[14,111,11]]]},"assembly/expect/Value#constructor":{"branchInfo":[[0,1],[0,2]],"index":13,"lineInfo":[[],[],[[14,12,4],[14,12,16]]]},"assembly/expect/Value#constructor":{"branchInfo":[[0,1],[0,2]],"index":9,"lineInfo":[[],[],[[14,12,4],[14,12,16]]]},"assembly/expect/Value#equal":{"branchInfo":[],"index":11,"lineInfo":[[[14,34,4],[14,35,6],[14,35,15],[14,35,26],[14,36,6],[14,37,6],[14,37,13],[14,38,6],[14,38,13],[14,38,20],[14,40,4],[14,40,11]]]},"assembly/expect/Value#equal@varargs":{"branchInfo":[[0,1],[0,2],[0,3]],"index":43,"lineInfo":[[],[],[[14,33,44]],[]]},"assembly/expect/Value#greaterThan":{"branchInfo":[],"index":15,"lineInfo":[[[14,53,4],[14,54,6],[14,54,18],[14,55,6],[14,56,6],[14,56,13],[14,57,6],[14,57,14],[14,57,21],[14,59,4],[14,59,11]]]},"assembly/expect/Value#greaterThanOrEqual":{"branchInfo":[],"index":16,"lineInfo":[[[14,65,4],[14,66,6],[14,66,19],[14,67,6],[14,68,6],[14,68,13],[14,69,6],[14,69,15],[14,69,22],[14,71,4],[14,71,11]]]},"assembly/expect/Value#lessThan":{"branchInfo":[],"index":17,"lineInfo":[[[14,74,4],[14,75,6],[14,75,18],[14,76,6],[14,77,6],[14,77,13],[14,78,6],[14,78,14],[14,78,21],[14,80,4],[14,80,11]]]},"assembly/expect/Value#lessThanOrEqual":{"branchInfo":[],"index":18,"lineInfo":[[[14,86,4],[14,87,6],[14,87,19],[14,88,6],[14,89,6],[14,89,13],[14,90,6],[14,90,15],[14,90,22],[14,92,4],[14,92,11]]]},"assembly/expect/Value#notEqual":{"branchInfo":[],"index":12,"lineInfo":[[[14,43,4],[14,44,6],[14,44,7],[14,44,16],[14,44,27],[14,45,6],[14,46,6],[14,46,13],[14,47,6],[14,47,15],[14,47,22],[14,49,4],[14,49,11]]]},"assembly/expect/Value<~lib/string/String|null>#constructor":{"branchInfo":[[0,1],[0,2]],"index":23,"lineInfo":[[],[],[[14,12,4],[14,12,16]]]},"assembly/expect/Value<~lib/string/String|null>#isNull":{"branchInfo":[],"index":27,"lineInfo":[[[14,15,4],[14,16,6],[14,16,16],[14,17,6],[14,18,6],[14,18,13],[14,19,6],[14,21,4],[14,21,11]]]},"assembly/expect/Value<~lib/string/String|null>#notNull":{"branchInfo":[],"index":28,"lineInfo":[[[14,24,4],[14,25,6],[14,25,7],[14,25,17],[14,26,6],[14,27,6],[14,27,13],[14,28,6],[14,30,4],[14,30,11]]]},"assembly/formatPrint/toJson":{"branchInfo":[],"index":4,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,6],[19,8,60],[19,9,11],[20,383,35]]]},"assembly/formatPrint/toJson":{"branchInfo":[],"index":2,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,6],[19,8,60],[19,9,11],[20,78,35]]]},"assembly/formatPrint/toJson<~lib/array/Array<~lib/array/Array<~lib/string/String>>>":{"branchInfo":[[1,2],[1,3]],"index":35,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,2],[19,11,6],[19,68,2],[19,68,6],[19,76,6],[19,76,42],[19,77,25],[19,77,43],[19,78,17],[19,78,24]],[[19,78,34],[19,78,38]],[[19,78,41],[19,79,6],[19,79,19],[19,79,24],[19,79,31],[19,79,33]],[],[[19,81,4],[19,81,11],[19,81,15],[19,81,33]]]},"assembly/formatPrint/toJson<~lib/array/Array<~lib/string/String>>":{"branchInfo":[[1,2],[1,3]],"index":34,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,2],[19,11,6],[19,68,2],[19,68,6],[19,76,6],[19,76,42],[19,77,25],[19,77,43],[19,78,17],[19,78,24]],[[19,78,34],[19,78,38]],[[19,78,41],[19,79,6],[19,79,19],[19,79,24],[19,79,31],[19,79,33]],[],[[19,81,4],[19,81,11],[19,81,15],[19,81,33]]]},"assembly/formatPrint/toJson<~lib/map/Map<~lib/string/String\\2c~lib/array/Array<~lib/array/Array<~lib/string/String>>>>":{"branchInfo":[[1,2],[1,3]],"index":36,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,2],[19,11,6],[19,68,2],[19,68,6],[19,76,2],[19,76,6],[19,83,2],[19,83,6],[19,86,6],[19,86,24],[19,87,16],[19,88,18],[19,89,25],[19,90,9],[19,90,17],[23,69,28]],[[19,90,20],[19,90,24]],[[19,90,36],[19,91,6],[19,91,19],[19,91,24],[19,91,31],[19,91,35],[19,91,41],[19,91,49],[19,91,56],[19,91,62]],[],[[19,93,4],[19,93,11],[19,93,16],[19,93,34]]]},"assembly/formatPrint/toJson<~lib/string/String>":{"branchInfo":[[1,2],[1,44],[2,3],[2,4],[5,6],[5,7],[7,8],[7,9],[10,11],[10,12],[12,13],[12,14],[15,16],[15,17],[17,18],[17,28],[18,19],[18,29],[19,20],[19,30],[20,21],[20,31],[21,22],[21,32],[22,23],[22,33],[23,24],[23,34],[24,25],[24,35],[25,26],[25,36],[26,27],[26,37],[39,40],[39,41]],"index":33,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,6],[19,11,22],[19,12,24],[19,13,32],[19,14,9],[19,14,17]],[[19,14,20],[19,14,24]],[[19,15,6],[19,15,23],[19,15,38],[19,17,9],[19,17,21]],[[19,17,29],[19,17,41]],[],[],[],[[19,18,9],[19,18,21]],[[19,18,29],[19,18,41]],[],[],[],[[19,19,9],[19,19,21]],[[19,19,29],[19,19,41]],[],[],[[19,21,8],[19,21,23],[19,21,34]],[[19,23,16],[19,24,15]],[[19,27,15]],[[19,30,15]],[[19,33,15]],[[19,36,15]],[[19,39,15]],[[19,42,15]],[[19,45,15]],[[19,48,15]],[[19,51,15]],[],[[19,25,12],[19,25,27],[19,26,12]],[[19,28,12],[19,28,27],[19,29,12]],[[19,31,12],[19,31,27],[19,32,12]],[[19,34,12],[19,34,27],[19,35,12]],[[19,37,12],[19,37,27],[19,38,12]],[[19,40,12],[19,40,27],[19,41,12]],[[19,43,12],[19,43,27],[19,44,12]],[[19,46,12],[19,46,27],[19,47,12]],[[19,49,12],[19,49,27],[19,50,12]],[[19,52,12],[19,52,27],[19,53,12]],[[19,54,19],[19,56,32],[19,57,12],[19,57,27],[19,58,17],[19,58,25],[20,78,35]],[[19,58,45],[19,58,49]],[[19,58,52],[19,59,14],[19,59,29]],[],[[19,23,8],[19,61,12],[19,61,27]],[[19,14,36]],[],[[19,66,4],[19,66,11],[19,66,17],[19,66,32],[19,66,38]]]},"assembly/formatPrint/toJson<~lib/string/String|null>":{"branchInfo":[[0,1],[0,2],[3,4],[3,46],[4,5],[4,6],[7,8],[7,9],[9,10],[9,11],[12,13],[12,14],[14,15],[14,16],[17,18],[17,19],[19,20],[19,30],[20,21],[20,31],[21,22],[21,32],[22,23],[22,33],[23,24],[23,34],[24,25],[24,35],[25,26],[25,36],[26,27],[26,37],[27,28],[27,38],[28,29],[28,39],[41,42],[41,43]],"index":26,"lineInfo":[[[19,2,6],[19,2,23],[19,2,28]],[[19,3,4],[19,3,11]],[[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,6],[19,11,22],[19,12,24],[19,13,32],[19,14,9],[19,14,17]],[[19,14,20],[19,14,24]],[[19,15,6],[19,15,23],[19,15,38],[19,17,9],[19,17,21]],[[19,17,29],[19,17,41]],[],[],[],[[19,18,9],[19,18,21]],[[19,18,29],[19,18,41]],[],[],[],[[19,19,9],[19,19,21]],[[19,19,29],[19,19,41]],[],[],[[19,21,8],[19,21,23],[19,21,34]],[[19,23,16],[19,24,15]],[[19,27,15]],[[19,30,15]],[[19,33,15]],[[19,36,15]],[[19,39,15]],[[19,42,15]],[[19,45,15]],[[19,48,15]],[[19,51,15]],[],[[19,25,12],[19,25,27],[19,26,12]],[[19,28,12],[19,28,27],[19,29,12]],[[19,31,12],[19,31,27],[19,32,12]],[[19,34,12],[19,34,27],[19,35,12]],[[19,37,12],[19,37,27],[19,38,12]],[[19,40,12],[19,40,27],[19,41,12]],[[19,43,12],[19,43,27],[19,44,12]],[[19,46,12],[19,46,27],[19,47,12]],[[19,49,12],[19,49,27],[19,50,12]],[[19,52,12],[19,52,27],[19,53,12]],[[19,54,19],[19,56,32],[19,57,12],[19,57,27],[19,58,17],[19,58,25],[20,78,35]],[[19,58,45],[19,58,49]],[[19,58,52],[19,59,14],[19,59,29]],[],[[19,23,8],[19,61,12],[19,61,27]],[[19,14,36]],[],[[19,66,4],[19,66,11],[19,66,17],[19,66,32],[19,66,38]]]},"assembly/implement/describeImpl":{"branchInfo":[],"index":29,"lineInfo":[[[24,8,2],[24,8,30],[24,9,2],[24,10,2]]]},"assembly/implement/testImpl":{"branchInfo":[],"index":21,"lineInfo":[[[24,13,2],[24,13,30],[24,14,2],[24,15,2],[24,16,2]]]},"assembly/index/describe":{"branchInfo":[],"index":30,"lineInfo":[[[17,19,2],[17,19,15],[17,19,28]]]},"assembly/index/endTest":{"branchInfo":[],"index":7,"lineInfo":[[[17,61,2]]]},"assembly/index/expect":{"branchInfo":[],"index":3,"lineInfo":[[[17,57,2],[17,57,9],[17,57,22]]]},"assembly/index/expect":{"branchInfo":[],"index":0,"lineInfo":[[[17,57,2],[17,57,9],[17,57,22]]]},"assembly/index/expect<~lib/string/String|null>":{"branchInfo":[],"index":24,"lineInfo":[[[17,57,2],[17,57,9],[17,57,22]]]},"assembly/index/test":{"branchInfo":[],"index":22,"lineInfo":[[[17,28,2],[17,28,11],[17,28,24]]]},"assembly/output/checkMemory":{"branchInfo":[[0,1],[0,2]],"index":5,"lineInfo":[[[25,45,9],[25,45,18]],[[25,45,40]],[]]},"assembly/output/fromCString":{"branchInfo":[[1,2],[1,3]],"index":6,"lineInfo":[[[25,49,2],[25,49,13]],[[25,50,9],[25,50,18],[25,50,28],[25,50,38]],[[25,51,4]],[],[[22,767,80],[25,50,2],[25,53,2],[25,53,9],[25,53,34],[25,53,43]]]},"assembly/output/getArgs":{"branchInfo":[[1,2],[1,3]],"index":40,"lineInfo":[[[25,57,25],[25,60,2],[25,60,14],[25,60,31],[25,60,49],[25,61,2],[25,61,8],[25,61,23],[25,61,39],[25,61,56],[25,62,2],[25,62,9],[25,63,2],[25,63,15],[25,63,27],[25,64,2],[25,64,26],[25,64,38],[25,66,25],[25,66,41],[25,66,46],[25,66,53],[25,66,58],[25,67,28],[25,67,44],[25,68,2],[25,68,14],[25,68,50],[25,68,51],[25,68,58],[25,68,63],[25,69,2],[25,69,14],[25,69,53],[25,70,2],[25,70,8],[25,71,4],[25,72,4],[25,74,2],[25,74,9],[25,75,7],[25,75,22]],[[25,75,25],[25,75,29]],[[25,75,35],[25,76,4],[25,76,21],[25,77,6],[25,77,42],[25,77,46],[25,79,16],[25,79,28],[25,80,4],[25,80,14]],[],[[25,83,2],[25,83,9]]]},"assembly/output/output":{"branchInfo":[],"index":42,"lineInfo":[[[25,21,27],[25,22,2],[25,22,14],[25,23,2],[25,23,14],[25,24,2],[25,24,14],[25,25,2],[25,27,2],[25,29,23],[25,29,29],[25,29,41],[25,29,48],[25,31,25],[25,31,35],[25,31,44],[25,31,47],[25,31,53],[25,32,2],[25,32,12],[25,32,28]]]},"assembly/output/perror":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":39,"lineInfo":[[[25,38,6],[25,38,13]],[[25,39,4]],[[25,41,9]],[[25,41,16],[25,41,30],[25,41,37],[25,41,43]],[]]},"assembly/output/writeFile":{"branchInfo":[[0,1],[0,2],[3,4],[3,3]],"index":41,"lineInfo":[[[25,87,6],[25,87,21]],[[25,87,24]],[[22,697,63],[25,89,19],[25,89,38],[25,91,2],[25,91,14],[25,91,44],[25,92,2],[25,92,8],[25,93,4],[25,94,4],[25,95,4],[25,96,4],[25,97,4],[25,97,19],[25,98,4],[25,99,6],[25,100,6],[25,101,6],[25,102,6],[25,103,4],[25,104,6],[25,105,6],[25,106,6],[25,107,6],[25,108,4],[25,109,4],[25,111,2],[25,111,9],[25,112,2],[25,112,29],[25,112,38],[25,115,14],[25,115,33],[25,117,2],[25,117,12],[25,118,2],[25,118,16],[25,120,2],[25,120,14],[25,120,39]],[[25,122,4],[25,122,10],[25,122,19],[25,122,35],[25,122,59],[25,122,62],[25,123,4],[25,123,11],[25,124,4],[25,124,19],[25,124,31],[25,125,4],[25,125,15],[25,125,27],[25,126,11],[25,126,25]],[[25,121,2]],[[25,127,2],[25,127,11]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/expect.test.expect.json b/tests/cpp/lit/build/expect.test.expect.json new file mode 100644 index 0000000..57f50bf --- /dev/null +++ b/tests/cpp/lit/build/expect.test.expect.json @@ -0,0 +1 @@ +{"0":"tests-as/expect.test.ts:8:4","1":"tests-as/expect.test.ts:9:4","10":"tests-as/expect.test.ts:20:4","2":"tests-as/expect.test.ts:10:4","3":"tests-as/expect.test.ts:11:4","4":"tests-as/expect.test.ts:12:4","5":"tests-as/expect.test.ts:13:4","6":"tests-as/expect.test.ts:14:4","7":"tests-as/expect.test.ts:15:4","8":"tests-as/expect.test.ts:16:4","9":"tests-as/expect.test.ts:19:4"} \ No newline at end of file diff --git a/tests/cpp/lit/build/expect.test.instrumented.wasm b/tests/cpp/lit/build/expect.test.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5d1083ab037bbcb4c641d4bbb5d495290bee7f96 GIT binary patch literal 41011 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 J8&+@r{{Tjn^zr}z literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/for_loop.wast.debug.json b/tests/cpp/lit/build/for_loop.wast.debug.json new file mode 100644 index 0000000..d66f010 --- /dev/null +++ b/tests/cpp/lit/build/for_loop.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/for-loop.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,4,19]],[[0,4,22],[0,4,30]],[[0,4,37],[0,5,4],[0,5,13]],[[0,4,19]],[[0,7,2],[0,7,11],[0,8,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/for_loop.wast.expect.json b/tests/cpp/lit/build/for_loop.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/for_loop.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/for_loop.wast.instrumented.wasm b/tests/cpp/lit/build/for_loop.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..77f83b296f6c7d8f89c5cf96424ae608a80f6477 GIT binary patch literal 210 zcmYL>O%8%U4254i7=KW~8w~ew!7NO4;T<3oqCgl7pmEpBdJu~n)1-O*^1Y%QI|4ul zQ-Gu}B7%ZNNchM*-@h(loQ7vtg(;ba(pRVVW2nZl?gMDw^}hWJYk#kNdsPNDOjxcc z>dHERH#ObJh=UVHDcmB1`yeBSj1}snFu7%mvmT05M7br)O{U9H^V3vKv86ax$IRK1 Newh_*xM(Ix`~_L$D@OnT literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/for_loop.wast.out.wasm b/tests/cpp/lit/build/for_loop.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0527b630110bd55b5c05e9992ae2f545f2cb9e6e GIT binary patch literal 130 zcmW-ZF%H5o5CnJ6wt_GcE#+Ou4-j44@eC|TkqA2lMxx7Sc?f}KiqUA0pM?Mzcm)?H zM7NU24Km5QWdojg1;x(;eLG!-vd6!3y0&!X;3ZB$7n&Z5{>J*@ZYaFJ)l(&JPFm z*b)HxbQMS|r>dw}m6Uh<9{SsNH%`N~ZMtbY4RvU~?w6q%$7A1tKH5H<{|l?|+l2Fv zd0@wcbV*5DA3N~+N%SCcDi9UQA!z~mLqURq&9uwGC6})B?6Eh)q8y1ySsYASD@r35 hX_I80Jf8}CLZ^8onFGo)D=i|=^cKn6nxv7o*$Y5@E${#U literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/for_loop_break.wast.out.wasm b/tests/cpp/lit/build/for_loop_break.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..54232248fcbce4b6b2b54fdc52641cc348eec0b5 GIT binary patch literal 135 zcmW-ZF%AMD6b0Y=Krph2ttE7O2xFi#o_*r^Ozifu9zO>V+K3`ReDLMenc=?y0LV1XA@Wx*X1jUw@*Bq#}potH?QlY`(vm5?{j&re1* zGz5TtTnWLxhp|65bvtHbUxj*oJ@xf4?7J59-E`sj4rXCjhvU{9 z*fC-HNl8=fTk!l&bR%*q5EaTHTtFTuNKmjzn;dTC+2hX^(>anAn-J~wwBO&3;B)l7!uuLHv+|CVz-y|AQG#YOfg7nCIC9#!OaLU z>}YeE3$RySXf~Aq{UT5i#6&M1HyfpkN>yBKJaF{%vV=}iETZ+O^5Jao{CgUSBW8A^bKK!sh1Qliv373Eml1LIoMCi@B5IgZ>XlUvbheFX+ z1b~(<2Wjq96*;St@``^#bKBKj-(IV-?iYPqgmQDgv}M;Fn;P_6HR1d(%)+4z=RfPf zjtP?~MOAUE!Sg3Q$f-b7D1}Tj$O{<>GPcq#g literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/for_loop_return.wast.out.wasm b/tests/cpp/lit/build/for_loop_return.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..55348e3a3898f86155a3f5b53b0806e7aecdb73b GIT binary patch literal 133 zcmW-Zu?oU46h-fSNoX-bSI1=Y8^ob+6TiZs9a>B}7{RSS>xURz&Ve%=q*o>YI^Mv| z2+{SlIn4#woq3|!w2#m)A{9~07$o3go77$Hs2F@;kR>)KmneJsRtArwEh$gzi2qLx Ugn_%S?^5aNTGLb9TprWs2h>v)mH+?% literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/for_loop_return.wast.out.wasm.map b/tests/cpp/lit/build/for_loop_return.wast.out.wasm.map new file mode 100644 index 0000000..ad6d958 --- /dev/null +++ b/tests/cpp/lit/build/for_loop_return.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/for-loop-return.ts"],"names":[],"mappings":"oCACc,IACA,KACK,MAAG,EAAQ,KACtB,EAAQ,KAAU,IACtB,EAAS,KAFwB,WAI5B"} \ No newline at end of file diff --git a/tests/cpp/lit/build/for_loop_return.wast.run.log b/tests/cpp/lit/build/for_loop_return.wast.run.log new file mode 100644 index 0000000..622bd5f --- /dev/null +++ b/tests/cpp/lit/build/for_loop_return.wast.run.log @@ -0,0 +1,23 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/build/if_else.wast.debug.json b/tests/cpp/lit/build/if_else.wast.debug.json new file mode 100644 index 0000000..2bdea0a --- /dev/null +++ b/tests/cpp/lit/build/if_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6]],[[0,5,13]],[[0,7,13]],[[0,9,2]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_else.wast.expect.json b/tests/cpp/lit/build/if_else.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/if_else.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/if_else.wast.instrumented.wasm b/tests/cpp/lit/build/if_else.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..eaa51ba3b3b05c5dc80663a7f6e8cc81de5df596 GIT binary patch literal 175 zcmYL8+z#>Vdsp4*~=RrJ(sT&#I<9#24E(HQW z*0extR240&lJbGKZg`$!n#M=)ajK@VbG~`qN1swZM9?k_?)HCJyQ_D%OLkzxgyo8g r(Df0#IZ;Eb0#P9gp&Ejk_POV?D30>UB14YFLf-Tvo~g{*%%dv5Zm=d^ literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/if_else.wast.out.wasm b/tests/cpp/lit/build/if_else.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..52ad28cc37b747f55074ca3c78c27b3556c1c195 GIT binary patch literal 96 zcmW;D!3{t#00q$ht5ozL1`xW5ZlZ}EBwC4bww^%@qH%kd2bTf?P;v$eL8zKCxHSUJ oz@Fl^G_WunAt(E0l=h*aZZ(XIE_f>9FQOwv=Dv7Vhfmjbes=c{)c^nh literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/if_else.wast.out.wasm.map b/tests/cpp/lit/build/if_else.wast.out.wasm.map new file mode 100644 index 0000000..f8f58ef --- /dev/null +++ b/tests/cpp/lit/build/if_else.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/if-else.ts"],"names":[],"mappings":"mCACa,IACE,IACT,IACO,MAEA,MAEX"} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_else.wast.run.log b/tests/cpp/lit/build/if_else.wast.run.log new file mode 100644 index 0000000..7712ed2 --- /dev/null +++ b/tests/cpp/lit/build/if_else.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/build/if_elseif_else.wast.debug.json b/tests/cpp/lit/build/if_elseif_else.wast.debug.json new file mode 100644 index 0000000..9d85273 --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-elseif-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,4],[0,9,14]],[[0,11,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_elseif_else.wast.expect.json b/tests/cpp/lit/build/if_elseif_else.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_else.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/if_elseif_else.wast.instrumented.wasm b/tests/cpp/lit/build/if_elseif_else.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..23ed17964d1f4477f013c1251087b153ff244665 GIT binary patch literal 220 zcmYL=O%8%U429bc#2=#I4d5OuoP~*+cn8R25|PZH3>tU6tOv2cf;9bk?|X$hI0OJZ zs0xrP#mrC};PS!fmXqX1C+P_Xw*;HXxO7o>) literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/if_elseif_else.wast.out.wasm.map b/tests/cpp/lit/build/if_elseif_else.wast.out.wasm.map new file mode 100644 index 0000000..f91b248 --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_else.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/if-elseif-else.ts"],"names":[],"mappings":"oCACa,KACE,KACT,EAAO,MACT,EAAU,MACD,EAAO,KAChB,EAAU,MAEV,EAAU,OAEL"} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_elseif_else.wast.run.log b/tests/cpp/lit/build/if_elseif_else.wast.run.log new file mode 100644 index 0000000..850cbf5 --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_else.wast.run.log @@ -0,0 +1,5 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=5 diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json b/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json new file mode 100644 index 0000000..2f6aa47 --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-elseif-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,20],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json b/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.instrumented.wasm b/tests/cpp/lit/build/if_elseif_empty_else.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..f1766af2ad8fa23f1279efb35f6ade1fdec5299f GIT binary patch literal 205 zcmYL{7>#5;hsiAX4hqVa7n>p^UJF`M1l`DRf2jsVbB zRUoO9h@fH-65jFJ^zW1NCoWMJoDWXVm;%wu5SGGR1gWU6<3!l1|iA{Z4wloyMG z0+5xZ$jA!jdqDWvij3Uc3XJ^R42mpyiMgqa?2HUxbC?7f8JK{~{FGEiwxZPH(wq_i DWF-{a literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.out.wasm.map b/tests/cpp/lit/build/if_elseif_empty_else.wast.out.wasm.map new file mode 100644 index 0000000..6c053bd --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_empty_else.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/if-elseif-empty-else.ts"],"names":[],"mappings":"oCACa,KACO,KACd,EAAO,MACT,EAAU,MACD,EAAO,MAChB,EAAU,OAEL"} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.run.log b/tests/cpp/lit/build/if_elseif_empty_else.wast.run.log new file mode 100644 index 0000000..0265d9f --- /dev/null +++ b/tests/cpp/lit/build/if_elseif_empty_else.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 diff --git a/tests/cpp/lit/build/if_empty_else.wast.debug.json b/tests/cpp/lit/build/if_empty_else.wast.debug.json new file mode 100644 index 0000000..a72518d --- /dev/null +++ b/tests/cpp/lit/build/if_empty_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,16],[0,4,6]],[[0,5,13]],[[0,7,2]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_empty_else.wast.expect.json b/tests/cpp/lit/build/if_empty_else.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/if_empty_else.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/if_empty_else.wast.instrumented.wasm b/tests/cpp/lit/build/if_empty_else.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..bdad5cfedc7d020f19907456f5e8ea535d5614b1 GIT binary patch literal 162 zcmYL9gPd=r7jNmqmZulQo?&jTa%??rsu~@PU nT^}Lq1NRiQuxe>w*}#6#aEGjN49b&zvtb^&22}?6L0x?TkzFMQ literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/if_empty_else.wast.out.wasm b/tests/cpp/lit/build/if_empty_else.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..92c73c1da175f99ec676c6d165c6ad0584285004 GIT binary patch literal 91 zcmW;CF%Cd57zWVqt42i!v5Col6TOKhI!LqBR zA^OSq;+!dSasV%y$Y--T7YTWTBjNPGd$GtId zz=Yw5!YVIoaC|4a5wQwHg=Ua=3Bi&UkZ5brYKG8Gwpp713H*%Ah`qu8H2J9E2M)e! e>ec9ST6h+bZe(Zqk0%k#uPXJ literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/if_multi_condition.wast.out.wasm.map b/tests/cpp/lit/build/if_multi_condition.wast.out.wasm.map new file mode 100644 index 0000000..2ff9984 --- /dev/null +++ b/tests/cpp/lit/build/if_multi_condition.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/if-multi-condition.ts"],"names":[],"mappings":"oCACa,IACE,IACT,EAAQ,QAAK,EAAQ,MAAb,GAAmB,EAAQ,MAC5B,MAEA,MAEJ"} \ No newline at end of file diff --git a/tests/cpp/lit/build/if_multi_condition.wast.run.log b/tests/cpp/lit/build/if_multi_condition.wast.run.log new file mode 100644 index 0000000..877e64e --- /dev/null +++ b/tests/cpp/lit/build/if_multi_condition.wast.run.log @@ -0,0 +1,8 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 +basic block entry trace to: function=0, basic block=9 diff --git a/tests/cpp/lit/build/include_exclude.wast.debug.json b/tests/cpp/lit/build/include_exclude.wast.debug.json new file mode 100644 index 0000000..5791c54 --- /dev/null +++ b/tests/cpp/lit/build/include_exclude.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["index.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,1,1],[0,2,1],[0,3,1]],[[0,4,1],[0,5,1]],[[0,6,1],[0,7,1]],[[0,8,1]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/include_exclude.wast.expect.json b/tests/cpp/lit/build/include_exclude.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/include_exclude.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/include_exclude.wast.instrumented.wasm b/tests/cpp/lit/build/include_exclude.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..14ddde82b24763de0d4900b4acd003c45e4fd8fe GIT binary patch literal 206 zcmYL=%?^Sv5QKMIj6X!}$%9_-Jv`V0MiYGpNNEB>TSKYg)>n7oVm7;(Z)O%sZx8_R zkQ5l9V37`w(i_cE+jpUs$VJtM)}6aLyUv z^28ETHq;cpcA=~CQFWoxw_t&9o=gHwlqeu0b)OLgBv%RNDMCrKkT?Ui1*GIL!6~C9 LT+wHS?_>G{`qVAy literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/include_exclude.wast.out.wasm b/tests/cpp/lit/build/include_exclude.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..285897213490a0b1ce7ca91d887f787a7f5af79c GIT binary patch literal 142 zcmZXNF$%&!6hvo!RumT`ZL~?i19${~p?HjZO~6QYEy9A`UfspkYKr%G16u+Ca4S7C zddV48CE)rXF4z=-dU?LnJX}7HISu1A#UdZ2K?}vrofREc$_`$sQqyk=Y5CfFoLsap SvJw1J{42?>Jb}hCM&7?(z#8ZP literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/include_exclude.wast.out.wasm.map b/tests/cpp/lit/build/include_exclude.wast.out.wasm.map new file mode 100644 index 0000000..dc10d01 --- /dev/null +++ b/tests/cpp/lit/build/include_exclude.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["index.ts"],"names":[],"mappings":"2DACC,EACA,EAFA,GAIA,EADA,GAGA,EADA,GAEA,SAEA,KADA"} \ No newline at end of file diff --git a/tests/cpp/lit/build/include_exclude.wast.run.log b/tests/cpp/lit/build/include_exclude.wast.run.log new file mode 100644 index 0000000..a0ba415 --- /dev/null +++ b/tests/cpp/lit/build/include_exclude.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/build/multi_func.wast.debug.json b/tests/cpp/lit/build/multi_func.wast.debug.json new file mode 100644 index 0000000..ca8f1ae --- /dev/null +++ b/tests/cpp/lit/build/multi_func.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["assembly/add.ts"],"debugInfos":{"assembly/add/add":{"branchInfo":[],"index":2,"lineInfo":[[[0,3,11]]]},"assembly/add/genA":{"branchInfo":[],"index":0,"lineInfo":[[[0,11,11]]]},"assembly/add/main":{"branchInfo":[[0,1],[0,2]],"index":3,"lineInfo":[[[0,15,12],[0,16,8],[0,16,12]],[[0,17,12]],[[0,19,12]],[]]},"assembly/add/min":{"branchInfo":[],"index":1,"lineInfo":[[[0,7,11]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/multi_func.wast.expect.json b/tests/cpp/lit/build/multi_func.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/multi_func.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/multi_func.wast.instrumented.wasm b/tests/cpp/lit/build/multi_func.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..3418e753a734f79e61979cf195a84901fa055ec2 GIT binary patch literal 327 zcmY+7O-{ow5QX3Pr&Sw4&7zC43Oxr4ykG$mCt#DvvP2s>sgi(TQ*D$2qS6 literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/multi_func.wast.out.wasm b/tests/cpp/lit/build/multi_func.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e209a3e9668f90614a0477782a465da91592c437 GIT binary patch literal 309 zcmY+Ay-ou$5QJye_61@PmnKDME>v{krv`BaP4WJBX`N-P`b-?1fNVu`@fL zb|rfe+C%`nG#hs8Hs}k+S*2nfzeqZxVKfn&LX%;N6x06uAUH3GnjYg<>$JJ@CD~QD zVa?qf)c}0_foq*8p*?CW?MsD{Gp8yu@9{&MLyBBkOhVhn^!9mJgza|m9&^odfKroX zNOaH)*ZSwm)KI`c-pk4LHw^aHVB9=Dte>9OYV>)Z<0;6+f9SnG1@DTZo*nfUQc^k; literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/multi_func.wast.out.wasm.map b/tests/cpp/lit/build/multi_func.wast.out.wasm.map new file mode 100644 index 0000000..5447e40 --- /dev/null +++ b/tests/cpp/lit/build/multi_func.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["assembly/add.ts"],"names":[],"mappings":"0EAUW,QAJA,iBAJA,iBAYC,IACJ,EAAI,KACA,MAEA,MAHA"} \ No newline at end of file diff --git a/tests/cpp/lit/build/multi_func.wast.run.log b/tests/cpp/lit/build/multi_func.wast.run.log new file mode 100644 index 0000000..09144f3 --- /dev/null +++ b/tests/cpp/lit/build/multi_func.wast.run.log @@ -0,0 +1,10 @@ +make directly call to function index=3 +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +exit from function call index=0 +basic block entry trace to: function=3, basic block=0 +make directly call to function index=1 +basic block entry trace to: function=1, basic block=0 +exit from function call index=1 +basic block entry trace to: function=3, basic block=1 +basic block entry trace to: function=3, basic block=3 diff --git a/tests/cpp/lit/build/multi_if_else.wast.debug.json b/tests/cpp/lit/build/multi_if_else.wast.debug.json new file mode 100644 index 0000000..6c1c53c --- /dev/null +++ b/tests/cpp/lit/build/multi_if_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/multi-if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4],[4,5],[4,6]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,7,8],[0,7,15]],[[0,8,6],[0,8,16]],[[0,9,15],[0,9,22]],[[0,10,6],[0,10,16]],[]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/multi_if_else.wast.expect.json b/tests/cpp/lit/build/multi_if_else.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/multi_if_else.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/multi_if_else.wast.instrumented.wasm b/tests/cpp/lit/build/multi_if_else.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..675e91a9df1a58d0b3f56fd0517aa71d5761774f GIT binary patch literal 236 zcmZ9DOA5k342J(?T3SJ3FX-B}2Qe*(AR({sOOUq} z0U)h1AXDCZWb8e8Uh&-2*PUy-=2BVLExRT+c5^#7wrz{rffiM5%HP4%9IYu2!oZ3N z;|T>-UO4dVL3Af#pCa`sX{2u?L!r2Dd*Koq!8#UlN=Q~ojZpk^@ci%9*T1lp^Wf*p O;Xmv_6h-1j!}tM@FEAVc literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/multi_if_else.wast.out.wasm b/tests/cpp/lit/build/multi_if_else.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..ee9c5c455711d70a4ec95cce14c00bd07d45156b GIT binary patch literal 131 zcmZQbEY4+QU|?WmVN76PU}j=uVCP_D$xY16V_@KNVsv0+s&{v#$O`0NK;z$H@PNo?D>8Be0fQn-USe)4BReAl*iQA)#55Jm5uSKDf=jXOwi8-6$+3VyhUgh#-(B#|VFf3qDy7ve%(i1Sjk3|!{i zISlHtB>-NB3bZPi87eWO$*pW+|Mu98)9~6h-L##CIyU$3FGDkqyS@Xj+CCmm!g+jd z;^E0VNDyL~2ZJ*6kQ5Z!*An`Jl5+Pq1xhL81`qD|6g^YS2Y3L>Hwie{IBwQ81Bqm!+5KK|F{D>5rvL zc`!3?-Y^d)O9_BgF2O$;z<{w z3rh@LT9VL}hSDBwc40F+}_C}p{zW7#;oRt-0XyX w=R={rPQLTgG45qwNxs@VtxOj8UTo|+oJR8nJ9qE%@$hvvlKTaV$ut`M0*@CwkpKVy literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/switch_case.wast.out.wasm.map b/tests/cpp/lit/build/switch_case.wast.out.wasm.map new file mode 100644 index 0000000..ed0d0f9 --- /dev/null +++ b/tests/cpp/lit/build/switch_case.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/switch-case.ts"],"names":[],"mappings":"sDAOa,IACC,KACZ,UAAQ,MACD,OAIA,OAGA,QANH,EAAS,MACT,GAGO,EAAQ,MAGf,EAAS,MACT,GAGO,IAGJ"} \ No newline at end of file diff --git a/tests/cpp/lit/build/switch_case.wast.run.log b/tests/cpp/lit/build/switch_case.wast.run.log new file mode 100644 index 0000000..cf1e9f2 --- /dev/null +++ b/tests/cpp/lit/build/switch_case.wast.run.log @@ -0,0 +1,6 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=8 diff --git a/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json b/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json new file mode 100644 index 0000000..725d2c8 --- /dev/null +++ b/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/switch-case-fallthrough.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,4],[1,2],[1,5],[2,3],[2,6]],"index":0,"lineInfo":[[[0,8,13],[0,9,14],[0,10,10],[0,11,9]],[[0,11,9],[0,15,9]],[[0,15,9],[0,16,9]],[[0,16,9]],[[0,12,6],[0,12,15],[0,13,6]],[[0,10,2]],[[0,17,6],[0,17,15],[0,18,6]],[[0,21,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json b/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/switch_case_fallthrough.wast.instrumented.wasm b/tests/cpp/lit/build/switch_case_fallthrough.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..38737d3a63525309de63fb6b82370810ae465760 GIT binary patch literal 277 zcmYL>QA)%>5Janb;;!zvZoEN)*Vqr|L%|R4kT3*Xmn4$J#lODAf_Ly(9>kszk%ppP zRnchYo&b338c-Xjs%S)&Dtp<+@$@vz%k zi^pfnAWn!?=@fz9M3OkazGTt2hXJzrB+sPNfS`e;O=^U1)RgiG17rvrBd#!C3iX1ub&0i#+$}jmXSGmj)!aBju{{XiHGO+*v literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/switch_case_fallthrough.wast.out.wasm b/tests/cpp/lit/build/switch_case_fallthrough.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..0dc4f3a8cdcbc6ecd1d2ba28e14ff619f5722dba GIT binary patch literal 301 zcma)#QEI|K7=&m3Ra0DpLNAcew~7^df`;0l6cyA1bg{9CBnHe%eal-<0&Op_OsGUh;N_%%~6(&0X-8tW>>PSLFzX&NW{|XRFAP1b=JWVADRZqs9V`bx)hck>j_R_hIiH+9!O-{o=429qGl(saKh8rZ}8Z0^skXUesM59RkQ4*A-6+2(3LgE%2qzA#12vwG? z`98lf%DyH5KDh$a!l^0>QKia@tV4T#Z~CD-)m1ZWhOP|N>(^&j_5HqWz{k1`$6Me& z?5c45Fb8o$%u}cEOl(LTE?F!&tIK@@S^bdTq*D*Co~cE0_$zYC_P;XZlF2jPEMt{o zO+!ZHh;b_sWkhE$>l6=2GWylQcoumR@rpxk-~8Q}kf?q+srjfF)kP+?xZQzYPDlO# D-@Z0u literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/switch_case_rdefault.wast.out.wasm b/tests/cpp/lit/build/switch_case_rdefault.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5c58d0e3b6900aec9254d866b3ec13d221187729 GIT binary patch literal 310 zcma)#L2ANK6h-fSUz=hK7P^6i4%&$oT!BFwbYKN_T>R*lMvQ{_qLY%nICddjhzn`H z;JEVO-t*w_9(0}&0IQsVg%aZ7Nfn6cmmw~c?>(}T>2w3sX8fWmVu=u65K%g}2@y#s zFGvEG#UyZ>B!Q~K4;j~14ObVeBG$#>FCEh1SsXgA;p4>0MrVc|aeXS!geq~nFs$0G z)oWqf`%!pZrboNqnO1&C?fknr*STr#7G|mUYug%@{(CYQPo{kPUz~h&N1r{pdpCWqJ}mQlZ2giibK~0c_cga6bdv`i#>ox;VB?;x8*b5o6%$r#%EqSi z;O&F%q{PCCr2=+c!lEQgB}W%mfGe(4W!T^n1tpcmYpE~Ukl{Y&urV*NBdsH=#9Eu= Iv&6an0gN3fDF6Tf literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/while.wast.out.wasm b/tests/cpp/lit/build/while.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..5a6d564619f422ebb4cd8a49ea65b6f934ddc053 GIT binary patch literal 124 zcmW;EF%H5o5Cp*8v#mrJiI(!Nqeb~Z-0=)7NRbFT1xBLF*Mq308{~H(00!Q{%?Z)< z^d-*~I1IefZK*dT7!yrobfb#m=6@tECQ6mXcw~%Gd5XCBn#;tF_&0JU9KvJ$)W*=( LmR}O)`kcNy_GJ^D literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/while.wast.out.wasm.map b/tests/cpp/lit/build/while.wast.out.wasm.map new file mode 100644 index 0000000..8ac3deb --- /dev/null +++ b/tests/cpp/lit/build/while.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/while.ts"],"names":[],"mappings":"oCACc,IACA,IAAW,IACvB,IAAO,EAAQ,KACb,OACA,EAAS,UAEJ"} \ No newline at end of file diff --git a/tests/cpp/lit/build/while.wast.run.log b/tests/cpp/lit/build/while.wast.run.log new file mode 100644 index 0000000..f048875 --- /dev/null +++ b/tests/cpp/lit/build/while.wast.run.log @@ -0,0 +1,19 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 diff --git a/tests/cpp/lit/build/while_break.wast.debug.json b/tests/cpp/lit/build/while_break.wast.debug.json new file mode 100644 index 0000000..eacf70a --- /dev/null +++ b/tests/cpp/lit/build/while_break.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/while-break.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,5],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,4,9],[0,4,17]],[[0,5,4],[0,6,8],[0,6,16]],[[0,6,19]],[[0,7,4],[0,7,13]],[[0,4,2]],[[0,4,2]],[[0,9,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/build/while_break.wast.expect.json b/tests/cpp/lit/build/while_break.wast.expect.json new file mode 100644 index 0000000..ec747fa --- /dev/null +++ b/tests/cpp/lit/build/while_break.wast.expect.json @@ -0,0 +1 @@ +null \ No newline at end of file diff --git a/tests/cpp/lit/build/while_break.wast.instrumented.wasm b/tests/cpp/lit/build/while_break.wast.instrumented.wasm new file mode 100644 index 0000000000000000000000000000000000000000..15cd5808ee8997cd8dfe3a3993df755cb63a744b GIT binary patch literal 243 zcmYL>OKQVF5Janbr1+yGc5X1bhZmYfAPM9S5`!SNkz^#!Q(2 z9Rcvo)u7f+RZ)v7RSxnJhuddA&EvIe`*}ByO>E!qm$99u>-s@uJYpXVS-6z76VVE*vh}mS~*!G em*_bwJiVOk5kj^Y7KL%1c%i36KHXP|cEumNmn{qc literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/while_break.wast.out.wasm b/tests/cpp/lit/build/while_break.wast.out.wasm new file mode 100644 index 0000000000000000000000000000000000000000..194912e14ee145823bdb9a345fc1f3e7c972492c GIT binary patch literal 134 zcmW;Eu@1r@7)9ZGe;{q7iK`=QeFtL#oAD_m+M$imL7H^yt4o}|GaaOFCIA{f!9xkr z_0&1d1vuS!r8;8o5#br>MS==W9PYXixp--qhYo|Xj!qWOf!4M@Ta3D-Jh3DGL%9$N S=Cy96($ux4kC?fO%8%U42AnT_&X|k1Gt9^W?`ZW?*N&Q2m~;I#+CKxcHEdQ`t|F}qhf49L^zn7 zAh{6{%2@=$N8bAWdFjS!c(i3V#nVvu^7Oh7kZsv|ZGS}YN@ zMb#0nKfoJC9652=lZ#Svl)@opbvk?Ej5CuZoX}YXf{OHXs8iO(y;=BhaGrRlI->T7@Qm~#K?Nrc58a7ey>z7NFp70_vU-lRw)e&2rc25*2jV}JE1_Us Q^;;TEt1W%REag4#Kb(ma-T(jq literal 0 HcmV?d00001 diff --git a/tests/cpp/lit/build/while_continue.wast.out.wasm.map b/tests/cpp/lit/build/while_continue.wast.out.wasm.map new file mode 100644 index 0000000..c458658 --- /dev/null +++ b/tests/cpp/lit/build/while_continue.wast.out.wasm.map @@ -0,0 +1 @@ +{"version":3,"sources":["fixture/while-continue.ts"],"names":[],"mappings":"oCACc,IACA,IAAW,IACvB,IAAO,EAAQ,KACb,OACI,EAAQ,KAAG,GACf,EAAS,UAEJ"} \ No newline at end of file diff --git a/tests/cpp/lit/build/while_continue.wast.run.log b/tests/cpp/lit/build/while_continue.wast.run.log new file mode 100644 index 0000000..37a9eeb --- /dev/null +++ b/tests/cpp/lit/build/while_continue.wast.run.log @@ -0,0 +1,14 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=6 diff --git a/tests/cpp/lit/covInstrument/do_while.wast b/tests/cpp/lit/covInstrument/do_while.wast new file mode 100644 index 0000000..d335d40 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while.wast @@ -0,0 +1,42 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/do-while.ts:2:14 + (local.set $count + (i32.const 8) + ) + ;;@ fixture/do-while.ts:3:14 + (local.set $total + (i32.const 0) + ) + ;;@ fixture/do-while.ts:3:25 + (local.set $index + (i32.const 1) + ) + ;;@ fixture/do-while.ts:4:2 + (loop $label$1 + ;;@ fixture/do-while.ts:5:4 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + ;;@ fixture/do-while.ts:6:18 + (br_if $label$1 + (i32.lt_s + ;;@ fixture/do-while.ts:6:10 + (local.get $index) + ;;@ fixture/do-while.ts:6:18 + (local.get $count) + ) + ) + ) + ;;@ fixture/do-while.ts:7:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while.wast.debug.json b/tests/cpp/lit/covInstrument/do_while.wast.debug.json new file mode 100644 index 0000000..2be21a6 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while.wast.debug.json @@ -0,0 +1,70 @@ +{ + "debugFiles": [ + "fixture/do-while.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 1 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 3, + 25 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 6, + 10 + ], + [ + 0, + 6, + 18 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 7, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while.wast.run.log b/tests/cpp/lit/covInstrument/do_while.wast.run.log new file mode 100644 index 0000000..0877ba8 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while.wast.run.log @@ -0,0 +1,11 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/covInstrument/do_while_break.wast b/tests/cpp/lit/covInstrument/do_while_break.wast new file mode 100644 index 0000000..a41cb88 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_break.wast @@ -0,0 +1,55 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/do-while-break.ts:2:14 + (local.set $count + (i32.const 8) + ) + ;;@ fixture/do-while-break.ts:3:14 + (local.set $total + (i32.const 0) + ) + ;;@ fixture/do-while-break.ts:3:25 + (local.set $index + (i32.const 1) + ) + ;;@ fixture/do-while-break.ts:4:2 + (block $label$1 + (loop $label$2 + ;;@ fixture/do-while-break.ts:5:4 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + ;;@ fixture/do-while-break.ts:6:16 + (if + (i32.gt_s + ;;@ fixture/do-while-break.ts:6:8 + (local.get $index) + ;;@ fixture/do-while-break.ts:6:16 + (i32.const 5) + ) + ;;@ fixture/do-while-break.ts:6:19 + (br $label$1) + ) + ;;@ fixture/do-while-break.ts:7:18 + (br_if $label$2 + (i32.lt_s + ;;@ fixture/do-while-break.ts:7:10 + (local.get $index) + ;;@ fixture/do-while-break.ts:7:18 + (local.get $count) + ) + ) + ) + ) + ;;@ fixture/do-while-break.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json b/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json new file mode 100644 index 0000000..e89c871 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json @@ -0,0 +1,104 @@ +{ + "debugFiles": [ + "fixture/do-while-break.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 3 + ], + [ + 3, + 4 + ], + [ + 3, + 1 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 3, + 25 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 6, + 8 + ], + [ + 0, + 6, + 16 + ] + ], + [ + [ + 0, + 6, + 19 + ] + ], + [ + [ + 0, + 7, + 10 + ], + [ + 0, + 7, + 18 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while_break.wast.run.log b/tests/cpp/lit/covInstrument/do_while_break.wast.run.log new file mode 100644 index 0000000..2a3bbe6 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_break.wast.run.log @@ -0,0 +1,14 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=6 diff --git a/tests/cpp/lit/covInstrument/do_while_continue.wast b/tests/cpp/lit/covInstrument/do_while_continue.wast new file mode 100644 index 0000000..1e76a0d --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_continue.wast @@ -0,0 +1,55 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/do-while-continue.ts:2:14 + (local.set $count + (i32.const 3) + ) + ;;@ fixture/do-while-continue.ts:3:14 + (local.set $total + (i32.const 0) + ) + ;;@ fixture/do-while-continue.ts:3:25 + (local.set $index + (i32.const 1) + ) + ;;@ fixture/do-while-continue.ts:4:2 + (loop $label$1 + (block $label$2 + ;;@ fixture/do-while-continue.ts:5:4 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + ;;@ fixture/do-while-continue.ts:6:16 + (if + (i32.rem_s + ;;@ fixture/do-while-continue.ts:6:8 + (local.get $index) + ;;@ fixture/do-while-continue.ts:6:16 + (i32.const 2) + ) + ;;@ fixture/do-while-continue.ts:6:19 + (br $label$2) + ) + ) + ;;@ fixture/do-while-continue.ts:7:18 + (br_if $label$1 + (i32.lt_s + ;;@ fixture/do-while-continue.ts:7:10 + (local.get $index) + ;;@ fixture/do-while-continue.ts:7:18 + (local.get $count) + ) + ) + ) + ;;@ fixture/do-while-continue.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json b/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json new file mode 100644 index 0000000..a66211a --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json @@ -0,0 +1,104 @@ +{ + "debugFiles": [ + "fixture/do-while-continue.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 3 + ], + [ + 4, + 5 + ], + [ + 4, + 1 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 3, + 25 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 6, + 8 + ], + [ + 0, + 6, + 16 + ] + ], + [ + [ + 0, + 6, + 19 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 7, + 10 + ], + [ + 0, + 7, + 18 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while_continue.wast.run.log b/tests/cpp/lit/covInstrument/do_while_continue.wast.run.log new file mode 100644 index 0000000..407dc41 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_continue.wast.run.log @@ -0,0 +1,11 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=6 diff --git a/tests/cpp/lit/covInstrument/do_while_once.wast b/tests/cpp/lit/covInstrument/do_while_once.wast new file mode 100644 index 0000000..d5d7f48 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_once.wast @@ -0,0 +1,79 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + ;;@ fixture/do-while-once.ts:2:14 + (local.set $count + (i32.const 50) + ) + ;;@ fixture/do-while-once.ts:3:14 + (local.set $total + (i32.const 30) + ) + ;;@ fixture/do-while-once.ts:4:2 + (block $label$1 + (loop $label$2 + (block $label$3 + ;;@ fixture/do-while-once.ts:5:13 + (local.set $count + (i32.mul + ;;@ fixture/do-while-once.ts:5:4 + (local.get $count) + ;;@ fixture/do-while-once.ts:5:13 + (i32.const 2) + ) + ) + ;;@ fixture/do-while-once.ts:6:16 + (if + (i32.gt_s + ;;@ fixture/do-while-once.ts:6:8 + (local.get $count) + ;;@ fixture/do-while-once.ts:6:16 + (i32.const 1000) + ) + ;;@ fixture/do-while-once.ts:6:22 + (br $label$1) + ) + ;;@ fixture/do-while-once.ts:7:4 + (local.set $count + (i32.sub + (local.get $count) + (i32.const 1) + ) + ) + ;;@ fixture/do-while-once.ts:8:16 + (if + (i32.gt_s + ;;@ fixture/do-while-once.ts:8:8 + (local.get $count) + ;;@ fixture/do-while-once.ts:8:16 + (i32.const 30) + ) + ;;@ fixture/do-while-once.ts:8:20 + (br $label$3) + ) + ;;@ fixture/do-while-once.ts:9:4 + (local.set $count + (i32.add + (local.get $count) + (i32.const 1) + ) + ) + ) + ;;@ fixture/do-while-once.ts:10:11 + (br_if $label$2 + (i32.const 0) + ) + ) + ) + ;;@ fixture/do-while-once.ts:11:17 + (return + (i32.add + ;;@ fixture/do-while-once.ts:11:9 + (local.get $count) + ;;@ fixture/do-while-once.ts:11:17 + (local.get $total) + ) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json b/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json new file mode 100644 index 0000000..4df6bb5 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json @@ -0,0 +1,148 @@ +{ + "debugFiles": [ + "fixture/do-while-once.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 3 + ], + [ + 3, + 4 + ], + [ + 3, + 5 + ], + [ + 6, + 7 + ], + [ + 6, + 1 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 5, + 13 + ], + [ + 0, + 6, + 8 + ], + [ + 0, + 6, + 16 + ] + ], + [ + [ + 0, + 6, + 22 + ] + ], + [ + [ + 0, + 7, + 4 + ], + [ + 0, + 8, + 8 + ], + [ + 0, + 8, + 16 + ] + ], + [ + [ + 0, + 8, + 20 + ] + ], + [ + [ + 0, + 4, + 2 + ], + [ + 0, + 9, + 4 + ] + ], + [ + [ + 0, + 10, + 11 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 11, + 9 + ], + [ + 0, + 11, + 17 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/do_while_once.wast.run.log b/tests/cpp/lit/covInstrument/do_while_once.wast.run.log new file mode 100644 index 0000000..25482e7 --- /dev/null +++ b/tests/cpp/lit/covInstrument/do_while_once.wast.run.log @@ -0,0 +1,9 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 +basic block entry trace to: function=0, basic block=8 +basic block entry trace to: function=0, basic block=9 diff --git a/tests/cpp/lit/covInstrument/exit_basicBlock.wast b/tests/cpp/lit/covInstrument/exit_basicBlock.wast new file mode 100644 index 0000000..1c2671c --- /dev/null +++ b/tests/cpp/lit/covInstrument/exit_basicBlock.wast @@ -0,0 +1,30 @@ +(module + (global $fixture/exit-basicBlock/mode i32 (i32.const 100)) + (func $main (export "main") + (local $result i32) + ;;@ fixture/exit-basicBlock.ts:4:27 + (if + ;;@ fixture/exit-basicBlock.ts:4:14 + (if (result i32) + (i32.eq + ;;@ fixture/exit-basicBlock.ts:4:6 + (global.get $fixture/exit-basicBlock/mode) + ;;@ fixture/exit-basicBlock.ts:4:14 + (i32.const 5) + ) + (i32.const 1) + ;;@ fixture/exit-basicBlock.ts:4:27 + (i32.eq + ;;@ fixture/exit-basicBlock.ts:4:19 + (global.get $fixture/exit-basicBlock/mode) + ;;@ fixture/exit-basicBlock.ts:4:27 + (i32.const 10) + ) + ) + ;;@ fixture/exit-basicBlock.ts:5:17 + (local.set $result + (i32.const 100) + ) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json b/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json new file mode 100644 index 0000000..ce50b83 --- /dev/null +++ b/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json @@ -0,0 +1,70 @@ +{ + "debugFiles": [ + "fixture/exit-basicBlock.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 0, + 1 + ], + [ + 0, + 2 + ], + [ + 3, + 4 + ], + [ + 3, + 5 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 4, + 6 + ], + [ + 0, + 4, + 14 + ] + ], + [ + [ + 0, + 4, + 14 + ] + ], + [ + [ + 0, + 4, + 19 + ], + [ + 0, + 4, + 27 + ] + ], + [], + [ + [ + 0, + 5, + 17 + ] + ], + [] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/exit_basicBlock.wast.run.log b/tests/cpp/lit/covInstrument/exit_basicBlock.wast.run.log new file mode 100644 index 0000000..6ef1c53 --- /dev/null +++ b/tests/cpp/lit/covInstrument/exit_basicBlock.wast.run.log @@ -0,0 +1,5 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=5 diff --git a/tests/cpp/lit/covInstrument/for_loop.wast b/tests/cpp/lit/covInstrument/for_loop.wast new file mode 100644 index 0000000..a10730b --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop.wast @@ -0,0 +1,62 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/for-loop.ts:2:14 + (local.set $count + (i32.const 5) + ) + ;;@ fixture/for-loop.ts:3:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/for-loop.ts:4:19 + (local.set $index + (i32.const 0) + ) + (loop $label$1 + ;;@ fixture/for-loop.ts:4:30 + (if + (i32.lt_s + ;;@ fixture/for-loop.ts:4:22 + (local.get $index) + ;;@ fixture/for-loop.ts:4:30 + (local.get $count) + ) + (block + ;;@ fixture/for-loop.ts:5:13 + (local.set $total + (i32.add + ;;@ fixture/for-loop.ts:5:4 + (local.get $total) + ;;@ fixture/for-loop.ts:5:13 + (local.get $index) + ) + ) + ;;@ fixture/for-loop.ts:4:37 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + (br $label$1) + ) + ) + ) + ;;@ fixture/for-loop.ts:7:11 + (local.set $total + (i32.add + ;;@ fixture/for-loop.ts:7:2 + (local.get $total) + ;;@ fixture/for-loop.ts:7:11 + (i32.const 100) + ) + ) + ;;@ fixture/for-loop.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop.wast.debug.json new file mode 100644 index 0000000..3e7a717 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop.wast.debug.json @@ -0,0 +1,92 @@ +{ + "debugFiles": [ + "fixture/for-loop.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 3 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 4, + 22 + ], + [ + 0, + 4, + 30 + ] + ], + [ + [ + 0, + 4, + 37 + ], + [ + 0, + 5, + 4 + ], + [ + 0, + 5, + 13 + ] + ], + [ + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 7, + 2 + ], + [ + 0, + 7, + 11 + ], + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop.wast.run.log b/tests/cpp/lit/covInstrument/for_loop.wast.run.log new file mode 100644 index 0000000..8a55338 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop.wast.run.log @@ -0,0 +1,15 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 diff --git a/tests/cpp/lit/covInstrument/for_loop_break.wast b/tests/cpp/lit/covInstrument/for_loop_break.wast new file mode 100644 index 0000000..6dbfef2 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_break.wast @@ -0,0 +1,66 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/for-loop-break.ts:2:14 + (local.set $count + (i32.const 7) + ) + ;;@ fixture/for-loop-break.ts:3:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/for-loop-break.ts:4:19 + (local.set $index + (i32.const 0) + ) + (block $label$1 + (loop $label$2 + ;;@ fixture/for-loop-break.ts:4:30 + (if + (i32.lt_s + ;;@ fixture/for-loop-break.ts:4:22 + (local.get $index) + ;;@ fixture/for-loop-break.ts:4:30 + (local.get $count) + ) + (block + ;;@ fixture/for-loop-break.ts:5:16 + (if + (i32.gt_s + ;;@ fixture/for-loop-break.ts:5:8 + (local.get $index) + ;;@ fixture/for-loop-break.ts:5:16 + (i32.const 5) + ) + ;;@ fixture/for-loop-break.ts:5:19 + (br $label$1) + ) + ;;@ fixture/for-loop-break.ts:6:13 + (local.set $total + (i32.add + ;;@ fixture/for-loop-break.ts:6:4 + (local.get $total) + ;;@ fixture/for-loop-break.ts:6:13 + (local.get $index) + ) + ) + ;;@ fixture/for-loop-break.ts:4:37 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + (br $label$2) + ) + ) + ) + ) + ;;@ fixture/for-loop-break.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json new file mode 100644 index 0000000..b5ec18b --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json @@ -0,0 +1,116 @@ +{ + "debugFiles": [ + "fixture/for-loop-break.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 5 + ], + [ + 2, + 3 + ], + [ + 2, + 4 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 4, + 22 + ], + [ + 0, + 4, + 30 + ] + ], + [ + [ + 0, + 5, + 8 + ], + [ + 0, + 5, + 16 + ] + ], + [ + [ + 0, + 5, + 19 + ] + ], + [ + [ + 0, + 4, + 37 + ], + [ + 0, + 6, + 4 + ], + [ + 0, + 6, + 13 + ] + ], + [ + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop_break.wast.run.log b/tests/cpp/lit/covInstrument/for_loop_break.wast.run.log new file mode 100644 index 0000000..1868300 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_break.wast.run.log @@ -0,0 +1,25 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 diff --git a/tests/cpp/lit/covInstrument/for_loop_continue.wast b/tests/cpp/lit/covInstrument/for_loop_continue.wast new file mode 100644 index 0000000..e921a6a --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_continue.wast @@ -0,0 +1,71 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/for-loop-continue.ts:2:14 + (local.set $count + (i32.const 2) + ) + ;;@ fixture/for-loop-continue.ts:3:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/for-loop-continue.ts:4:19 + (local.set $index + (i32.const 0) + ) + (loop $label$1 + ;;@ fixture/for-loop-continue.ts:4:30 + (if + (i32.lt_s + ;;@ fixture/for-loop-continue.ts:4:22 + (local.get $index) + ;;@ fixture/for-loop-continue.ts:4:30 + (local.get $count) + ) + (block + (block $label$3 + ;;@ fixture/for-loop-continue.ts:5:21 + (if + (i32.eq + ;;@ fixture/for-loop-continue.ts:5:16 + (i32.rem_s + ;;@ fixture/for-loop-continue.ts:5:8 + (local.get $index) + ;;@ fixture/for-loop-continue.ts:5:16 + (i32.const 2) + ) + ;;@ fixture/for-loop-continue.ts:5:21 + (i32.const 0) + ) + ;;@ fixture/for-loop-continue.ts:5:24 + (br $label$3) + ) + ;;@ fixture/for-loop-continue.ts:6:13 + (local.set $total + (i32.add + ;;@ fixture/for-loop-continue.ts:6:4 + (local.get $total) + ;;@ fixture/for-loop-continue.ts:6:13 + (local.get $index) + ) + ) + ) + ;;@ fixture/for-loop-continue.ts:4:37 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + (br $label$1) + ) + ) + ) + ;;@ fixture/for-loop-continue.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json new file mode 100644 index 0000000..ae9e642 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json @@ -0,0 +1,121 @@ +{ + "debugFiles": [ + "fixture/for-loop-continue.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 6 + ], + [ + 2, + 3 + ], + [ + 2, + 4 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 4, + 22 + ], + [ + 0, + 4, + 30 + ] + ], + [ + [ + 0, + 5, + 8 + ], + [ + 0, + 5, + 16 + ], + [ + 0, + 5, + 21 + ] + ], + [ + [ + 0, + 5, + 24 + ] + ], + [ + [ + 0, + 4, + 30 + ], + [ + 0, + 6, + 4 + ], + [ + 0, + 6, + 13 + ] + ], + [ + [ + 0, + 4, + 37 + ] + ], + [ + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop_continue.wast.run.log b/tests/cpp/lit/covInstrument/for_loop_continue.wast.run.log new file mode 100644 index 0000000..3f8c240 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_continue.wast.run.log @@ -0,0 +1,13 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 diff --git a/tests/cpp/lit/covInstrument/for_loop_return.wast b/tests/cpp/lit/covInstrument/for_loop_return.wast new file mode 100644 index 0000000..827e140 --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_return.wast @@ -0,0 +1,66 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/for-loop-return.ts:2:14 + (local.set $count + (i32.const 8) + ) + ;;@ fixture/for-loop-return.ts:3:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/for-loop-return.ts:4:19 + (local.set $index + (i32.const 0) + ) + (loop $label$1 + ;;@ fixture/for-loop-return.ts:4:30 + (if + (i32.lt_s + ;;@ fixture/for-loop-return.ts:4:22 + (local.get $index) + ;;@ fixture/for-loop-return.ts:4:30 + (local.get $count) + ) + (block + ;;@ fixture/for-loop-return.ts:5:16 + (if + (i32.gt_s + ;;@ fixture/for-loop-return.ts:5:8 + (local.get $index) + ;;@ fixture/for-loop-return.ts:5:16 + (i32.const 5) + ) + ;;@ fixture/for-loop-return.ts:5:26 + (return + (i32.const 0) + ) + ) + ;;@ fixture/for-loop-return.ts:6:13 + (local.set $total + (i32.add + ;;@ fixture/for-loop-return.ts:6:4 + (local.get $total) + ;;@ fixture/for-loop-return.ts:6:13 + (local.get $index) + ) + ) + ;;@ fixture/for-loop-return.ts:4:37 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + (br $label$1) + ) + ) + ) + ;;@ fixture/for-loop-return.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json new file mode 100644 index 0000000..65489db --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json @@ -0,0 +1,109 @@ +{ + "debugFiles": [ + "fixture/for-loop-return.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 5 + ], + [ + 2, + 3 + ], + [ + 2, + 4 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 4, + 22 + ], + [ + 0, + 4, + 30 + ] + ], + [ + [ + 0, + 5, + 8 + ], + [ + 0, + 5, + 16 + ] + ], + [ + [ + 0, + 5, + 26 + ] + ], + [ + [ + 0, + 4, + 37 + ], + [ + 0, + 6, + 4 + ], + [ + 0, + 6, + 13 + ] + ], + [ + [ + 0, + 4, + 19 + ] + ], + [ + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/for_loop_return.wast.run.log b/tests/cpp/lit/covInstrument/for_loop_return.wast.run.log new file mode 100644 index 0000000..622bd5f --- /dev/null +++ b/tests/cpp/lit/covInstrument/for_loop_return.wast.run.log @@ -0,0 +1,23 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/covInstrument/if_else.wast b/tests/cpp/lit/covInstrument/if_else.wast new file mode 100644 index 0000000..f51ca74 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_else.wast @@ -0,0 +1,28 @@ +(module + (func $main (export "main") + (local $mode i32) + (local $result i32) + ;;@ fixture/if-else.ts:2:13 + (local.set $mode + (i32.const 1) + ) + ;;@ fixture/if-else.ts:3:15 + (local.set $result + (i32.const 0) + ) + ;;@ fixture/if-else.ts:4:6 + (if + (local.get $mode) + ;;@ fixture/if-else.ts:5:13 + (local.set $result + (i32.const 100) + ) + ;;@ fixture/if-else.ts:7:13 + (local.set $result + (i32.const 200) + ) + ) + ;;@ fixture/if-else.ts:9:2 + (return) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_else.wast.debug.json new file mode 100644 index 0000000..2bdea0a --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6]],[[0,5,13]],[[0,7,13]],[[0,9,2]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_else.wast.run.log b/tests/cpp/lit/covInstrument/if_else.wast.run.log new file mode 100644 index 0000000..7712ed2 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_else.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/covInstrument/if_elseif_else.wast b/tests/cpp/lit/covInstrument/if_elseif_else.wast new file mode 100644 index 0000000..c178ae1 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_elseif_else.wast @@ -0,0 +1,63 @@ +(module + (func $main (export "main") (result i32) + (local $mode i32) + (local $result i32) + ;;@ fixture/if-elseif-else.ts:2:13 + (local.set $mode + (i32.const 100) + ) + ;;@ fixture/if-elseif-else.ts:3:15 + (local.set $result + (i32.const 100) + ) + ;;@ fixture/if-elseif-else.ts:4:13 + (if + (i32.gt_s + ;;@ fixture/if-elseif-else.ts:4:6 + (local.get $mode) + ;;@ fixture/if-elseif-else.ts:4:13 + (i32.const 100) + ) + ;;@ fixture/if-elseif-else.ts:5:14 + (local.set $result + (i32.add + ;;@ fixture/if-elseif-else.ts:5:4 + (local.get $result) + ;;@ fixture/if-elseif-else.ts:5:14 + (local.get $mode) + ) + ) + ;;@ fixture/if-elseif-else.ts:6:20 + (if + (i32.lt_s + ;;@ fixture/if-elseif-else.ts:6:13 + (local.get $mode) + ;;@ fixture/if-elseif-else.ts:6:20 + (i32.const 60) + ) + ;;@ fixture/if-elseif-else.ts:7:14 + (local.set $result + (i32.sub + ;;@ fixture/if-elseif-else.ts:7:4 + (local.get $result) + ;;@ fixture/if-elseif-else.ts:7:14 + (local.get $mode) + ) + ) + ;;@ fixture/if-elseif-else.ts:9:14 + (local.set $result + (i32.add + ;;@ fixture/if-elseif-else.ts:9:4 + (local.get $result) + ;;@ fixture/if-elseif-else.ts:9:14 + (i32.const 60) + ) + ) + ) + ) + ;;@ fixture/if-elseif-else.ts:11:9 + (return + (local.get $result) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json new file mode 100644 index 0000000..9d85273 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-elseif-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,4],[0,9,14]],[[0,11,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_elseif_else.wast.run.log b/tests/cpp/lit/covInstrument/if_elseif_else.wast.run.log new file mode 100644 index 0000000..850cbf5 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_elseif_else.wast.run.log @@ -0,0 +1,5 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=5 diff --git a/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast new file mode 100644 index 0000000..f3e712a --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast @@ -0,0 +1,54 @@ +(module + (func $main (export "main") (result i32) + (local $mode i32) + (local $result i32) + ;;@ fixture/if-elseif-empty-else.ts:2:13 + (local.set $mode + (i32.const 100) + ) + ;;@ fixture/if-elseif-empty-else.ts:3:20 + (local.set $result + (i32.const 100) + ) + ;;@ fixture/if-elseif-empty-else.ts:4:13 + (if + (i32.gt_s + ;;@ fixture/if-elseif-empty-else.ts:4:6 + (local.get $mode) + ;;@ fixture/if-elseif-empty-else.ts:4:13 + (i32.const 100) + ) + ;;@ fixture/if-elseif-empty-else.ts:5:14 + (local.set $result + (i32.add + ;;@ fixture/if-elseif-empty-else.ts:5:4 + (local.get $result) + ;;@ fixture/if-elseif-empty-else.ts:5:14 + (local.get $mode) + ) + ) + ;;@ fixture/if-elseif-empty-else.ts:6:20 + (if + (i32.lt_s + ;;@ fixture/if-elseif-empty-else.ts:6:13 + (local.get $mode) + ;;@ fixture/if-elseif-empty-else.ts:6:20 + (i32.const 100) + ) + ;;@ fixture/if-elseif-empty-else.ts:7:14 + (local.set $result + (i32.sub + ;;@ fixture/if-elseif-empty-else.ts:7:4 + (local.get $result) + ;;@ fixture/if-elseif-empty-else.ts:7:14 + (local.get $mode) + ) + ) + ) + ) + ;;@ fixture/if-elseif-empty-else.ts:9:9 + (return + (local.get $result) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json new file mode 100644 index 0000000..2f6aa47 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-elseif-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,20],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.run.log b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.run.log new file mode 100644 index 0000000..0265d9f --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 diff --git a/tests/cpp/lit/covInstrument/if_empty_else.wast b/tests/cpp/lit/covInstrument/if_empty_else.wast new file mode 100644 index 0000000..bf87129 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_empty_else.wast @@ -0,0 +1,24 @@ +(module + (func $main (export "main") + (local $mode i32) + (local $result i32) + ;;@ fixture/if-empty-else.ts:2:13 + (local.set $mode + (i32.const 1) + ) + ;;@ fixture/if-empty-else.ts:3:16 + (local.set $result + (i32.const 100) + ) + ;;@ fixture/if-empty-else.ts:4:6 + (if + (local.get $mode) + ;;@ fixture/if-empty-else.ts:5:13 + (local.set $result + (i32.const 200) + ) + ) + ;;@ fixture/if-empty-else.ts:7:2 + (return) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json new file mode 100644 index 0000000..a72518d --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/if-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,16],[0,4,6]],[[0,5,13]],[[0,7,2]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_empty_else.wast.run.log b/tests/cpp/lit/covInstrument/if_empty_else.wast.run.log new file mode 100644 index 0000000..e33ce62 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_empty_else.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 diff --git a/tests/cpp/lit/covInstrument/if_multi_condition.wast b/tests/cpp/lit/covInstrument/if_multi_condition.wast new file mode 100644 index 0000000..7c53337 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_multi_condition.wast @@ -0,0 +1,57 @@ +(module + (func $main (export "main") (result i32) + (local $mode i32) + (local $result i32) + ;;@ fixture/if-multi-condition.ts:2:13 + (local.set $mode + (i32.const 10) + ) + ;;@ fixture/if-multi-condition.ts:3:15 + (local.set $result + (i32.const 0) + ) + ;;@ fixture/if-multi-condition.ts:4:41 + (if + ;;@ fixture/if-multi-condition.ts:4:27 + (if (result i32) + ;;@ fixture/if-multi-condition.ts:4:14 + (if (result i32) + (i32.eq + ;;@ fixture/if-multi-condition.ts:4:6 + (local.get $mode) + ;;@ fixture/if-multi-condition.ts:4:14 + (i32.const 5) + ) + (i32.const 1) + ;;@ fixture/if-multi-condition.ts:4:27 + (i32.eq + ;;@ fixture/if-multi-condition.ts:4:19 + (local.get $mode) + ;;@ fixture/if-multi-condition.ts:4:27 + (i32.const 10) + ) + ) + (i32.const 1) + ;;@ fixture/if-multi-condition.ts:4:41 + (i32.eq + ;;@ fixture/if-multi-condition.ts:4:33 + (local.get $mode) + ;;@ fixture/if-multi-condition.ts:4:41 + (i32.const 15) + ) + ) + ;;@ fixture/if-multi-condition.ts:5:13 + (local.set $result + (i32.const 100) + ) + ;;@ fixture/if-multi-condition.ts:7:13 + (local.set $result + (i32.const 300) + ) + ) + ;;@ fixture/if-multi-condition.ts:9:9 + (return + (local.get $result) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json b/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json new file mode 100644 index 0000000..72079a5 --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json @@ -0,0 +1,121 @@ +{ + "debugFiles": [ + "fixture/if-multi-condition.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 0, + 1 + ], + [ + 0, + 2 + ], + [ + 3, + 4 + ], + [ + 3, + 5 + ], + [ + 6, + 7 + ], + [ + 6, + 8 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 13 + ], + [ + 0, + 3, + 15 + ], + [ + 0, + 4, + 6 + ], + [ + 0, + 4, + 14 + ] + ], + [ + [ + 0, + 4, + 14 + ] + ], + [ + [ + 0, + 4, + 19 + ], + [ + 0, + 4, + 27 + ] + ], + [], + [ + [ + 0, + 4, + 14 + ] + ], + [ + [ + 0, + 4, + 33 + ], + [ + 0, + 4, + 41 + ] + ], + [], + [ + [ + 0, + 5, + 13 + ] + ], + [ + [ + 0, + 7, + 13 + ] + ], + [ + [ + 0, + 9, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/if_multi_condition.wast.run.log b/tests/cpp/lit/covInstrument/if_multi_condition.wast.run.log new file mode 100644 index 0000000..877e64e --- /dev/null +++ b/tests/cpp/lit/covInstrument/if_multi_condition.wast.run.log @@ -0,0 +1,8 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 +basic block entry trace to: function=0, basic block=9 diff --git a/tests/cpp/lit/covInstrument/include_exclude.wast b/tests/cpp/lit/covInstrument/include_exclude.wast new file mode 100644 index 0000000..60f6f4e --- /dev/null +++ b/tests/cpp/lit/covInstrument/include_exclude.wast @@ -0,0 +1,42 @@ +(module + (export "main" (func $main)) + (export "shouldExcludeFun" (func $shouldExcludeFun)) + (func $main (param $a i32) + ;;@ index.ts:1:1 + (if + ;;@ index.ts:1:1 + (i32.lt_s + ;;@ index.ts:2:1 + (local.get $a) + ;;@ index.ts:3:1 + (i32.const 0) + ) + ;;@ index.ts:4:1 + (local.set $a + ;;@ index.ts:5:1 + (i32.const 0) + ) + ;;@ index.ts:6:1 + (local.set $a + ;;@ index.ts:7:1 + (i32.const 1) + ) + ) + ;;@ index.ts:8:1 + (call $shouldExcludeFun + (i32.const 1) + (i32.const 2) + ) + ) + (func $shouldExcludeFun (param $a i32)(param $b i32) + ;;@ index.ts:9:1 + (drop + ;;@ index.ts:10:1 + (i32.add + (local.get $a) + (local.get $b) + ) + ) + ) + ;; custom section "sourceMappingURL", size 17 +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json b/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json new file mode 100644 index 0000000..5791c54 --- /dev/null +++ b/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["index.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,1,1],[0,2,1],[0,3,1]],[[0,4,1],[0,5,1]],[[0,6,1],[0,7,1]],[[0,8,1]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/include_exclude.wast.run.log b/tests/cpp/lit/covInstrument/include_exclude.wast.run.log new file mode 100644 index 0000000..a0ba415 --- /dev/null +++ b/tests/cpp/lit/covInstrument/include_exclude.wast.run.log @@ -0,0 +1,4 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 diff --git a/tests/cpp/lit/covInstrument/multi_func.wast b/tests/cpp/lit/covInstrument/multi_func.wast new file mode 100644 index 0000000..e8fdc41 --- /dev/null +++ b/tests/cpp/lit/covInstrument/multi_func.wast @@ -0,0 +1,75 @@ +(module + (type $i32_=>_i32 (func (param i32) (result i32))) + (type $none_=>_i32 (func (result i32))) + (type $none_=>_none (func)) + (memory $0 0) + (table $0 1 1 funcref) + (elem $0 (i32.const 1)) + (export "main" (func $assembly/add/main)) + (export "memory" (memory $0)) + (func $assembly/add/genA (result i32) + ;;@ assembly/add.ts:11:11 + (return + (i32.const 1) + ) + ) + (func $assembly/add/min (param $a i32) (result i32) + (local $1 i32) + ;;@ assembly/add.ts:7:11 + (local.set $a + (i32.sub + (local.tee $1 + (local.get $a) + ) + (i32.const 1) + ) + ) + (return + (local.get $1) + ) + ) + (func $assembly/add/add (param $a i32) (result i32) + (local $1 i32) + ;;@ assembly/add.ts:3:11 + (local.set $a + (i32.add + (local.tee $1 + (local.get $a) + ) + (i32.const 1) + ) + ) + (return + (local.get $1) + ) + ) + (func $assembly/add/main + (local $a i32) + ;;@ assembly/add.ts:15:12 + (local.set $a + (call $assembly/add/genA) + ) + ;;@ assembly/add.ts:16:12 + (if + (i32.gt_s + ;;@ assembly/add.ts:16:8 + (local.get $a) + ;;@ assembly/add.ts:16:12 + (i32.const 0) + ) + ;;@ assembly/add.ts:17:12 + (drop + (call $assembly/add/min + (local.get $a) + ) + ) + ;;@ assembly/add.ts:19:12 + (drop + (call $assembly/add/add + (local.get $a) + ) + ) + ) + ) + ;; custom section "sourceMappingURL", size 17 +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/multi_func.wast.debug.json b/tests/cpp/lit/covInstrument/multi_func.wast.debug.json new file mode 100644 index 0000000..ca8f1ae --- /dev/null +++ b/tests/cpp/lit/covInstrument/multi_func.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["assembly/add.ts"],"debugInfos":{"assembly/add/add":{"branchInfo":[],"index":2,"lineInfo":[[[0,3,11]]]},"assembly/add/genA":{"branchInfo":[],"index":0,"lineInfo":[[[0,11,11]]]},"assembly/add/main":{"branchInfo":[[0,1],[0,2]],"index":3,"lineInfo":[[[0,15,12],[0,16,8],[0,16,12]],[[0,17,12]],[[0,19,12]],[]]},"assembly/add/min":{"branchInfo":[],"index":1,"lineInfo":[[[0,7,11]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/multi_func.wast.run.log b/tests/cpp/lit/covInstrument/multi_func.wast.run.log new file mode 100644 index 0000000..09144f3 --- /dev/null +++ b/tests/cpp/lit/covInstrument/multi_func.wast.run.log @@ -0,0 +1,10 @@ +make directly call to function index=3 +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +exit from function call index=0 +basic block entry trace to: function=3, basic block=0 +make directly call to function index=1 +basic block entry trace to: function=1, basic block=0 +exit from function call index=1 +basic block entry trace to: function=3, basic block=1 +basic block entry trace to: function=3, basic block=3 diff --git a/tests/cpp/lit/covInstrument/multi_if_else.wast b/tests/cpp/lit/covInstrument/multi_if_else.wast new file mode 100644 index 0000000..36d1963 --- /dev/null +++ b/tests/cpp/lit/covInstrument/multi_if_else.wast @@ -0,0 +1,68 @@ +(module + (func $main (export "main") + (local $mode i32) + (local $result i32) + ;;@ fixture/multi-if-else.ts:2:13 + (local.set $mode + (i32.const 100) + ) + ;;@ fixture/multi-if-else.ts:3:15 + (local.set $result + (i32.const 100) + ) + ;;@ fixture/multi-if-else.ts:4:13 + (if + (i32.gt_s + ;;@ fixture/multi-if-else.ts:4:6 + (local.get $mode) + ;;@ fixture/multi-if-else.ts:4:13 + (i32.const 100) + ) + ;;@ fixture/multi-if-else.ts:5:14 + (local.set $result + (i32.add + ;;@ fixture/multi-if-else.ts:5:4 + (local.get $result) + ;;@ fixture/multi-if-else.ts:5:14 + (local.get $mode) + ) + ) + ;;@ fixture/multi-if-else.ts:7:15 + (if + (i32.gt_s + ;;@ fixture/multi-if-else.ts:7:8 + (local.get $mode) + ;;@ fixture/multi-if-else.ts:7:15 + (i32.const 80) + ) + ;;@ fixture/multi-if-else.ts:8:16 + (local.set $result + (i32.add + ;;@ fixture/multi-if-else.ts:8:6 + (local.get $result) + ;;@ fixture/multi-if-else.ts:8:16 + (local.get $mode) + ) + ) + ;;@ fixture/multi-if-else.ts:9:22 + (if + (i32.lt_s + ;;@ fixture/multi-if-else.ts:9:15 + (local.get $mode) + ;;@ fixture/multi-if-else.ts:9:22 + (i32.const 90) + ) + ;;@ fixture/multi-if-else.ts:10:16 + (local.set $result + (i32.sub + ;;@ fixture/multi-if-else.ts:10:6 + (local.get $result) + ;;@ fixture/multi-if-else.ts:10:16 + (local.get $mode) + ) + ) + ) + ) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json b/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json new file mode 100644 index 0000000..6c1c53c --- /dev/null +++ b/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/multi-if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4],[4,5],[4,6]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,7,8],[0,7,15]],[[0,8,6],[0,8,16]],[[0,9,15],[0,9,22]],[[0,10,6],[0,10,16]],[]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/multi_if_else.wast.run.log b/tests/cpp/lit/covInstrument/multi_if_else.wast.run.log new file mode 100644 index 0000000..89ab5d9 --- /dev/null +++ b/tests/cpp/lit/covInstrument/multi_if_else.wast.run.log @@ -0,0 +1,5 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=6 diff --git a/tests/cpp/lit/covInstrument/switch_case.wast b/tests/cpp/lit/covInstrument/switch_case.wast new file mode 100644 index 0000000..faf54b9 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case.wast @@ -0,0 +1,100 @@ +(module + (global $fixture/switch-case/Mode.FIRST i32 (i32.const 1)) + (global $fixture/switch-case/Mode.SECOND i32 (i32.const 2)) + (global $fixture/switch-case/Mode.THIRD i32 (i32.const 3)) + (func $main (export "main") (result i32) + (local $mode i32) + (local $total i32) + (local $2 i32) + ;;@ fixture/switch-case.ts:8:13 + (local.set $mode + (i32.const 3) + ) + ;;@ fixture/switch-case.ts:9:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/switch-case.ts:10:2 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + ;;@ fixture/switch-case.ts:10:10 + (local.set $2 + (local.get $mode) + ) + ;;@ fixture/switch-case.ts:11:9 + (br_if $label$5 + (i32.eq + ;;@ fixture/switch-case.ts:10:10 + (local.get $2) + ;;@ fixture/switch-case.ts:11:9 + (global.get $fixture/switch-case/Mode.FIRST) + ) + ) + ;;@ fixture/switch-case.ts:15:9 + (br_if $label$4 + (i32.eq + ;;@ fixture/switch-case.ts:11:9 + (local.get $2) + ;;@ fixture/switch-case.ts:15:9 + (global.get $fixture/switch-case/Mode.SECOND) + ) + ) + ;;@ fixture/switch-case.ts:18:9 + (br_if $label$3 + (i32.eq + ;;@ fixture/switch-case.ts:15:9 + (local.get $2) + ;;@ fixture/switch-case.ts:18:9 + (global.get $fixture/switch-case/Mode.THIRD) + ) + ) + (br $label$2) + ) + ;;@ fixture/switch-case.ts:12:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case.ts:12:6 + (local.get $total) + ;;@ fixture/switch-case.ts:12:15 + (i32.const 100) + ) + ) + ;;@ fixture/switch-case.ts:13:6 + (br $label$1) + ) + ;;@ fixture/switch-case.ts:16:21 + (return + (i32.add + ;;@ fixture/switch-case.ts:16:13 + (local.get $total) + ;;@ fixture/switch-case.ts:16:21 + (i32.const 200) + ) + ) + ) + ;;@ fixture/switch-case.ts:19:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case.ts:19:6 + (local.get $total) + ;;@ fixture/switch-case.ts:19:15 + (i32.const 300) + ) + ) + ;;@ fixture/switch-case.ts:20:6 + (br $label$1) + ) + ;;@ fixture/switch-case.ts:23:13 + (return + (i32.const 0) + ) + ) + ;;@ fixture/switch-case.ts:26:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/switch_case.wast.debug.json b/tests/cpp/lit/covInstrument/switch_case.wast.debug.json new file mode 100644 index 0000000..8dd5688 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case.wast.debug.json @@ -0,0 +1,151 @@ +{ + "debugFiles": [ + "fixture/switch-case.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 0, + 1 + ], + [ + 0, + 4 + ], + [ + 1, + 2 + ], + [ + 1, + 5 + ], + [ + 2, + 3 + ], + [ + 2, + 6 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 8, + 13 + ], + [ + 0, + 9, + 14 + ], + [ + 0, + 10, + 10 + ], + [ + 0, + 11, + 9 + ] + ], + [ + [ + 0, + 11, + 9 + ], + [ + 0, + 15, + 9 + ] + ], + [ + [ + 0, + 15, + 9 + ], + [ + 0, + 18, + 9 + ] + ], + [ + [ + 0, + 18, + 9 + ] + ], + [ + [ + 0, + 12, + 6 + ], + [ + 0, + 12, + 15 + ], + [ + 0, + 13, + 6 + ] + ], + [ + [ + 0, + 16, + 13 + ], + [ + 0, + 16, + 21 + ] + ], + [ + [ + 0, + 19, + 6 + ], + [ + 0, + 19, + 15 + ], + [ + 0, + 20, + 6 + ] + ], + [ + [ + 0, + 23, + 13 + ] + ], + [ + [ + 0, + 26, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/switch_case.wast.run.log b/tests/cpp/lit/covInstrument/switch_case.wast.run.log new file mode 100644 index 0000000..cf1e9f2 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case.wast.run.log @@ -0,0 +1,6 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=8 diff --git a/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast new file mode 100644 index 0000000..2147e48 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast @@ -0,0 +1,85 @@ +(module + (global $fixture/switch-case-fallthrough/Mode.FIRST i32 (i32.const 1)) + (global $fixture/switch-case-fallthrough/Mode.SECOND i32 (i32.const 2)) + (global $fixture/switch-case-fallthrough/Mode.THIRD i32 (i32.const 3)) + (func $main (export "main") (result i32) + (local $mode i32) + (local $total i32) + (local $2 i32) + ;;@ fixture/switch-case-fallthrough.ts:8:13 + (local.set $mode + (i32.const 2) + ) + ;;@ fixture/switch-case-fallthrough.ts:9:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/switch-case-fallthrough.ts:10:2 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + ;;@ fixture/switch-case-fallthrough.ts:10:10 + (local.set $2 + (local.get $mode) + ) + ;;@ fixture/switch-case-fallthrough.ts:11:9 + (br_if $label$4 + (i32.eq + ;;@ fixture/switch-case-fallthrough.ts:10:10 + (local.get $2) + ;;@ fixture/switch-case-fallthrough.ts:11:9 + (global.get $fixture/switch-case-fallthrough/Mode.FIRST) + ) + ) + ;;@ fixture/switch-case-fallthrough.ts:15:9 + (br_if $label$3 + (i32.eq + ;;@ fixture/switch-case-fallthrough.ts:11:9 + (local.get $2) + ;;@ fixture/switch-case-fallthrough.ts:15:9 + (global.get $fixture/switch-case-fallthrough/Mode.SECOND) + ) + ) + ;;@ fixture/switch-case-fallthrough.ts:16:9 + (br_if $label$2 + (i32.eq + ;;@ fixture/switch-case-fallthrough.ts:15:9 + (local.get $2) + ;;@ fixture/switch-case-fallthrough.ts:16:9 + (global.get $fixture/switch-case-fallthrough/Mode.THIRD) + ) + ) + (br $label$1) + ) + ;;@ fixture/switch-case-fallthrough.ts:12:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case-fallthrough.ts:12:6 + (local.get $total) + ;;@ fixture/switch-case-fallthrough.ts:12:15 + (i32.const 100) + ) + ) + ;;@ fixture/switch-case-fallthrough.ts:13:6 + (br $label$1) + ) + ) + ;;@ fixture/switch-case-fallthrough.ts:17:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case-fallthrough.ts:17:6 + (local.get $total) + ;;@ fixture/switch-case-fallthrough.ts:17:15 + (i32.const 300) + ) + ) + ;;@ fixture/switch-case-fallthrough.ts:18:6 + (br $label$1) + ) + ;;@ fixture/switch-case-fallthrough.ts:21:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json new file mode 100644 index 0000000..389aa97 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json @@ -0,0 +1,139 @@ +{ + "debugFiles": [ + "fixture/switch-case-fallthrough.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 0, + 1 + ], + [ + 0, + 4 + ], + [ + 1, + 2 + ], + [ + 1, + 5 + ], + [ + 2, + 3 + ], + [ + 2, + 6 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 8, + 13 + ], + [ + 0, + 9, + 14 + ], + [ + 0, + 10, + 10 + ], + [ + 0, + 11, + 9 + ] + ], + [ + [ + 0, + 11, + 9 + ], + [ + 0, + 15, + 9 + ] + ], + [ + [ + 0, + 15, + 9 + ], + [ + 0, + 16, + 9 + ] + ], + [ + [ + 0, + 16, + 9 + ] + ], + [ + [ + 0, + 12, + 6 + ], + [ + 0, + 12, + 15 + ], + [ + 0, + 13, + 6 + ] + ], + [ + [ + 0, + 10, + 2 + ] + ], + [ + [ + 0, + 17, + 6 + ], + [ + 0, + 17, + 15 + ], + [ + 0, + 18, + 6 + ] + ], + [ + [ + 0, + 21, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.run.log b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.run.log new file mode 100644 index 0000000..c70390b --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.run.log @@ -0,0 +1,6 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 diff --git a/tests/cpp/lit/covInstrument/switch_case_rdefault.wast b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast new file mode 100644 index 0000000..346cca6 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast @@ -0,0 +1,107 @@ +(module + (global $fixture/switch-case-rdefault/Mode.FIRST i32 (i32.const 1)) + (global $fixture/switch-case-rdefault/Mode.SECOND i32 (i32.const 2)) + (global $fixture/switch-case-rdefault/Mode.THIRD i32 (i32.const 3)) + (func $main (export "main") (result i32) + (local $mode i32) + (local $total i32) + (local $2 i32) + ;;@ fixture/switch-case-rdefault.ts:8:13 + (local.set $mode + (i32.const 2) + ) + ;;@ fixture/switch-case-rdefault.ts:9:14 + (local.set $total + (i32.const 100) + ) + ;;@ fixture/switch-case-rdefault.ts:10:2 + (block $label$1 + (block $label$2 + (block $label$3 + (block $label$4 + (block $label$5 + ;;@ fixture/switch-case-rdefault.ts:10:10 + (local.set $2 + (local.get $mode) + ) + ;;@ fixture/switch-case-rdefault.ts:14:9 + (br_if $label$4 + (i32.eq + ;;@ fixture/switch-case-rdefault.ts:10:10 + (local.get $2) + ;;@ fixture/switch-case-rdefault.ts:14:9 + (global.get $fixture/switch-case-rdefault/Mode.FIRST) + ) + ) + ;;@ fixture/switch-case-rdefault.ts:18:9 + (br_if $label$3 + (i32.eq + ;;@ fixture/switch-case-rdefault.ts:14:9 + (local.get $2) + ;;@ fixture/switch-case-rdefault.ts:18:9 + (global.get $fixture/switch-case-rdefault/Mode.SECOND) + ) + ) + ;;@ fixture/switch-case-rdefault.ts:22:9 + (br_if $label$2 + (i32.eq + ;;@ fixture/switch-case-rdefault.ts:18:9 + (local.get $2) + ;;@ fixture/switch-case-rdefault.ts:22:9 + (global.get $fixture/switch-case-rdefault/Mode.THIRD) + ) + ) + (br $label$5) + ) + ;;@ fixture/switch-case-rdefault.ts:12:21 + (return + (i32.add + ;;@ fixture/switch-case-rdefault.ts:12:13 + (local.get $total) + ;;@ fixture/switch-case-rdefault.ts:12:21 + (i32.const 10) + ) + ) + ) + ;;@ fixture/switch-case-rdefault.ts:15:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case-rdefault.ts:15:6 + (local.get $total) + ;;@ fixture/switch-case-rdefault.ts:15:15 + (i32.const 100) + ) + ) + ;;@ fixture/switch-case-rdefault.ts:16:6 + (br $label$1) + ) + ;;@ fixture/switch-case-rdefault.ts:19:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case-rdefault.ts:19:6 + (local.get $total) + ;;@ fixture/switch-case-rdefault.ts:19:15 + (i32.const 200) + ) + ) + ;;@ fixture/switch-case-rdefault.ts:20:6 + (br $label$1) + ) + ;;@ fixture/switch-case-rdefault.ts:23:15 + (local.set $total + (i32.add + ;;@ fixture/switch-case-rdefault.ts:23:6 + (local.get $total) + ;;@ fixture/switch-case-rdefault.ts:23:15 + (i32.const 300) + ) + ) + ;;@ fixture/switch-case-rdefault.ts:24:6 + (br $label$1) + ) + ;;@ fixture/switch-case-rdefault.ts:27:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json new file mode 100644 index 0000000..9d9927f --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json @@ -0,0 +1 @@ +{"debugFiles":["fixture/switch-case-rdefault.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,5],[1,2],[1,6],[2,3],[2,7]],"index":0,"lineInfo":[[[0,8,13],[0,9,14],[0,10,10],[0,14,9]],[[0,14,9],[0,18,9]],[[0,18,9],[0,22,9]],[[0,22,9]],[[0,12,13],[0,12,21]],[[0,15,6],[0,15,15],[0,16,6]],[[0,19,6],[0,19,15],[0,20,6]],[[0,23,6],[0,23,15],[0,24,6]],[[0,27,9]]]}}} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.run.log b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.run.log new file mode 100644 index 0000000..ec1fbe6 --- /dev/null +++ b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.run.log @@ -0,0 +1,5 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=8 diff --git a/tests/cpp/lit/covInstrument/while.wast b/tests/cpp/lit/covInstrument/while.wast new file mode 100644 index 0000000..3d3c711 --- /dev/null +++ b/tests/cpp/lit/covInstrument/while.wast @@ -0,0 +1,56 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/while.ts:2:14 + (local.set $count + (i32.const 8) + ) + ;;@ fixture/while.ts:3:14 + (local.set $total + (i32.const 0) + ) + ;;@ fixture/while.ts:3:25 + (local.set $index + (i32.const 1) + ) + ;;@ fixture/while.ts:4:2 + (block $label$1 + (loop $label$2 + ;;@ fixture/while.ts:4:17 + (if + (i32.lt_s + ;;@ fixture/while.ts:4:9 + (local.get $index) + ;;@ fixture/while.ts:4:17 + (local.get $count) + ) + (block + ;;@ fixture/while.ts:5:4 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + ;;@ fixture/while.ts:6:13 + (local.set $total + (i32.add + ;;@ fixture/while.ts:6:4 + (local.get $total) + ;;@ fixture/while.ts:6:13 + (local.get $index) + ) + ) + (br $label$2) + ) + ) + ) + ) + ;;@ fixture/while.ts:8:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/while.wast.debug.json b/tests/cpp/lit/covInstrument/while.wast.debug.json new file mode 100644 index 0000000..0052e2c --- /dev/null +++ b/tests/cpp/lit/covInstrument/while.wast.debug.json @@ -0,0 +1,87 @@ +{ + "debugFiles": [ + "fixture/while.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 3 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 3, + 25 + ] + ], + [ + [ + 0, + 4, + 9 + ], + [ + 0, + 4, + 17 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 6, + 4 + ], + [ + 0, + 6, + 13 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 4, + 2 + ], + [ + 0, + 8, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/while.wast.run.log b/tests/cpp/lit/covInstrument/while.wast.run.log new file mode 100644 index 0000000..f048875 --- /dev/null +++ b/tests/cpp/lit/covInstrument/while.wast.run.log @@ -0,0 +1,19 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=4 diff --git a/tests/cpp/lit/covInstrument/while_break.wast b/tests/cpp/lit/covInstrument/while_break.wast new file mode 100644 index 0000000..4e821bd --- /dev/null +++ b/tests/cpp/lit/covInstrument/while_break.wast @@ -0,0 +1,67 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/while-break.ts:2:14 + (local.set $count + (i32.const 8) + ) + ;;@ fixture/while-break.ts:3:14 + (local.set $total + (i32.const 0) + ) + ;;@ fixture/while-break.ts:3:25 + (local.set $index + (i32.const 1) + ) + ;;@ fixture/while-break.ts:4:2 + (block $label$1 + (loop $label$2 + ;;@ fixture/while-break.ts:4:17 + (if + (i32.lt_s + ;;@ fixture/while-break.ts:4:9 + (local.get $index) + ;;@ fixture/while-break.ts:4:17 + (local.get $count) + ) + (block + ;;@ fixture/while-break.ts:5:4 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + ;;@ fixture/while-break.ts:6:16 + (if + (i32.gt_s + ;;@ fixture/while-break.ts:6:8 + (local.get $index) + ;;@ fixture/while-break.ts:6:16 + (i32.const 5) + ) + ;;@ fixture/while-break.ts:6:19 + (br $label$1) + ) + ;;@ fixture/while-break.ts:7:13 + (local.set $total + (i32.add + ;;@ fixture/while-break.ts:7:4 + (local.get $total) + ;;@ fixture/while-break.ts:7:13 + (local.get $index) + ) + ) + (br $label$2) + ) + ) + ) + ) + ;;@ fixture/while-break.ts:9:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/while_break.wast.debug.json b/tests/cpp/lit/covInstrument/while_break.wast.debug.json new file mode 100644 index 0000000..20bc3dc --- /dev/null +++ b/tests/cpp/lit/covInstrument/while_break.wast.debug.json @@ -0,0 +1,116 @@ +{ + "debugFiles": [ + "fixture/while-break.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 5 + ], + [ + 2, + 3 + ], + [ + 2, + 4 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 3, + 25 + ] + ], + [ + [ + 0, + 4, + 9 + ], + [ + 0, + 4, + 17 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 6, + 8 + ], + [ + 0, + 6, + 16 + ] + ], + [ + [ + 0, + 6, + 19 + ] + ], + [ + [ + 0, + 7, + 4 + ], + [ + 0, + 7, + 13 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 9, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/while_break.wast.run.log b/tests/cpp/lit/covInstrument/while_break.wast.run.log new file mode 100644 index 0000000..8deec4e --- /dev/null +++ b/tests/cpp/lit/covInstrument/while_break.wast.run.log @@ -0,0 +1,19 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=6 +basic block entry trace to: function=0, basic block=7 diff --git a/tests/cpp/lit/covInstrument/while_continue.wast b/tests/cpp/lit/covInstrument/while_continue.wast new file mode 100644 index 0000000..ffec087 --- /dev/null +++ b/tests/cpp/lit/covInstrument/while_continue.wast @@ -0,0 +1,67 @@ +(module + (func $main (export "main") (result i32) + (local $count i32) + (local $total i32) + (local $index i32) + ;;@ fixture/while-continue.ts:2:14 + (local.set $count + (i32.const 4) + ) + ;;@ fixture/while-continue.ts:3:14 + (local.set $total + (i32.const 0) + ) + ;;@ fixture/while-continue.ts:3:25 + (local.set $index + (i32.const 1) + ) + ;;@ fixture/while-continue.ts:4:2 + (block $label$1 + (loop $label$2 + ;;@ fixture/while-continue.ts:4:17 + (if + (i32.lt_s + ;;@ fixture/while-continue.ts:4:9 + (local.get $index) + ;;@ fixture/while-continue.ts:4:17 + (local.get $count) + ) + (block + ;;@ fixture/while-continue.ts:5:4 + (local.set $index + (i32.add + (local.get $index) + (i32.const 1) + ) + ) + ;;@ fixture/while-continue.ts:6:16 + (if + (i32.rem_s + ;;@ fixture/while-continue.ts:6:8 + (local.get $index) + ;;@ fixture/while-continue.ts:6:16 + (i32.const 2) + ) + ;;@ fixture/while-continue.ts:6:19 + (br $label$2) + ) + ;;@ fixture/while-continue.ts:7:13 + (local.set $total + (i32.add + ;;@ fixture/while-continue.ts:7:4 + (local.get $total) + ;;@ fixture/while-continue.ts:7:13 + (local.get $index) + ) + ) + (br $label$2) + ) + ) + ) + ) + ;;@ fixture/while-continue.ts:9:9 + (return + (local.get $total) + ) + ) +) \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/while_continue.wast.debug.json b/tests/cpp/lit/covInstrument/while_continue.wast.debug.json new file mode 100644 index 0000000..418a833 --- /dev/null +++ b/tests/cpp/lit/covInstrument/while_continue.wast.debug.json @@ -0,0 +1,114 @@ +{ + "debugFiles": [ + "fixture/while-continue.ts" + ], + "debugInfos": { + "main": { + "branchInfo": [ + [ + 1, + 2 + ], + [ + 1, + 5 + ], + [ + 2, + 3 + ], + [ + 2, + 4 + ] + ], + "index": 0, + "lineInfo": [ + [ + [ + 0, + 2, + 14 + ], + [ + 0, + 3, + 14 + ], + [ + 0, + 3, + 25 + ] + ], + [ + [ + 0, + 4, + 9 + ], + [ + 0, + 4, + 17 + ] + ], + [ + [ + 0, + 5, + 4 + ], + [ + 0, + 6, + 8 + ], + [ + 0, + 6, + 16 + ] + ], + [ + [ + 0, + 6, + 19 + ] + ], + [ + [ + 0, + 7, + 4 + ], + [ + 0, + 7, + 13 + ] + ], + [ + [ + 0, + 4, + 2 + ] + ], + [ + [ + 0, + 4, + 2 + ], + [ + 0, + 9, + 9 + ] + ] + ] + } + } +} \ No newline at end of file diff --git a/tests/cpp/lit/covInstrument/while_continue.wast.run.log b/tests/cpp/lit/covInstrument/while_continue.wast.run.log new file mode 100644 index 0000000..37a9eeb --- /dev/null +++ b/tests/cpp/lit/covInstrument/while_continue.wast.run.log @@ -0,0 +1,14 @@ +make directly call to function index=0 +basic block entry trace to: function=0, basic block=0 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=3 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=2 +basic block entry trace to: function=0, basic block=4 +basic block entry trace to: function=0, basic block=1 +basic block entry trace to: function=0, basic block=5 +basic block entry trace to: function=0, basic block=6 diff --git a/tests/cpp/lit/expectInstrument/expect.test.expect.json b/tests/cpp/lit/expectInstrument/expect.test.expect.json new file mode 100644 index 0000000..57f50bf --- /dev/null +++ b/tests/cpp/lit/expectInstrument/expect.test.expect.json @@ -0,0 +1 @@ +{"0":"tests-as/expect.test.ts:8:4","1":"tests-as/expect.test.ts:9:4","10":"tests-as/expect.test.ts:20:4","2":"tests-as/expect.test.ts:10:4","3":"tests-as/expect.test.ts:11:4","4":"tests-as/expect.test.ts:12:4","5":"tests-as/expect.test.ts:13:4","6":"tests-as/expect.test.ts:14:4","7":"tests-as/expect.test.ts:15:4","8":"tests-as/expect.test.ts:16:4","9":"tests-as/expect.test.ts:19:4"} \ No newline at end of file diff --git a/tests/cpp/lit/expectInstrument/expect.test.wasm b/tests/cpp/lit/expectInstrument/expect.test.wasm new file mode 100644 index 0000000000000000000000000000000000000000..e596983100ca590a0e8b1c4d25cf9004df5b188c GIT binary patch literal 59010 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\n// @ts-ignore: decorator\n@inline export const AL_MASK: usize = AL_SIZE - 1;\n\n// Extra debugging\n\n// @ts-ignore: decorator\n@inline export const DEBUG = true;\n// @ts-ignore: decorator\n@inline export const TRACE = false;\n// @ts-ignore: decorator\n@inline export const RTRACE = isDefined(ASC_RTRACE);\n// @ts-ignore: decorator\n@inline export const PROFILE = isDefined(ASC_PROFILE);\n\n// Memory manager\n\n// ╒════════════ Memory manager block layout (32-bit) ═════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤\n// │ MM info │ -4\n// ╞>ptr═══════════════════════════════════════════════════════════╡\n// │ ... │\n@unmanaged export class BLOCK {\n /** Memory manager info. */\n mmInfo: usize;\n}\n\n/** Overhead of a memory manager block. */\n// @ts-ignore: decorator\n@inline export const BLOCK_OVERHEAD: usize = offsetof();\n\n/** Maximum size of a memory manager block's payload. */\n// @ts-ignore: decorator\n@inline export const BLOCK_MAXSIZE: usize = (1 << 30) - BLOCK_OVERHEAD;\n\n// Garbage collector\n\n// ╒══════════ Garbage collector object layout (32-bit) ═══════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤\n// │ Memory manager block │ -20\n// ╞═══════════════════════════════════════════════════════════════╡\n// │ GC info │ -16\n// ├───────────────────────────────────────────────────────────────┤\n// │ GC info │ -12\n// ├───────────────────────────────────────────────────────────────┤\n// │ RT id │ -8\n// ├───────────────────────────────────────────────────────────────┤\n// │ RT size │ -4\n// ╞>ptr═══════════════════════════════════════════════════════════╡\n// │ ... │\n@unmanaged export class OBJECT extends BLOCK {\n /** Garbage collector info. */\n gcInfo: u32;\n /** Garbage collector info. */\n gcInfo2: u32;\n /** Runtime class id. */\n rtId: u32;\n /** Runtime object size. */\n rtSize: u32;\n}\n\n/** Overhead of a garbage collector object. Excludes memory manager block overhead. */\n// @ts-ignore: decorator\n@inline export const OBJECT_OVERHEAD: usize = (offsetof() - BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK;\n\n/** Maximum size of a garbage collector object's payload. */\n// @ts-ignore: decorator\n@inline export const OBJECT_MAXSIZE: usize = BLOCK_MAXSIZE - OBJECT_OVERHEAD;\n\n/** Total of memory manager and garbage collector overhead. */\n// @ts-ignore: decorator\n@inline export const TOTAL_OVERHEAD: usize = BLOCK_OVERHEAD + OBJECT_OVERHEAD;\n","import { AL_BITS, AL_SIZE, AL_MASK, DEBUG, BLOCK, BLOCK_OVERHEAD, BLOCK_MAXSIZE } from \"./common\";\nimport { oninit, onalloc, onresize, onmove, onfree } from \"./rtrace\";\nimport { E_ALLOCATION_TOO_LARGE } from \"../util/error\";\n\n// === The TLSF (Two-Level Segregate Fit) memory allocator ===\n// see: http://www.gii.upv.es/tlsf/\n\n// - `ffs(x)` is equivalent to `ctz(x)` with x != 0\n// - `fls(x)` is equivalent to `sizeof(x) * 8 - clz(x) - 1`\n\n// ╒══════════════ Block size interpretation (32-bit) ═════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┼─┴─┴─┴─╫─┴─┴─┴─┤\n// │ | FL │ SB = SL + AL │ ◄─ usize\n// └───────────────────────────────────────────────┴───────╨───────┘\n// FL: first level, SL: second level, AL: alignment, SB: small block\n\n// @ts-ignore: decorator\n@inline const SL_BITS: u32 = 4;\n// @ts-ignore: decorator\n@inline const SL_SIZE: u32 = 1 << SL_BITS;\n\n// @ts-ignore: decorator\n@inline const SB_BITS: u32 = SL_BITS + AL_BITS;\n// @ts-ignore: decorator\n@inline const SB_SIZE: u32 = 1 << SB_BITS;\n\n// @ts-ignore: decorator\n@inline const FL_BITS: u32 = 31 - SB_BITS;\n\n// [00]: < 256B (SB) [12]: < 1M\n// [01]: < 512B [13]: < 2M\n// [02]: < 1K [14]: < 4M\n// [03]: < 2K [15]: < 8M\n// [04]: < 4K [16]: < 16M\n// [05]: < 8K [17]: < 32M\n// [06]: < 16K [18]: < 64M\n// [07]: < 32K [19]: < 128M\n// [08]: < 64K [20]: < 256M\n// [09]: < 128K [21]: < 512M\n// [10]: < 256K [22]: <= 1G - OVERHEAD\n// [11]: < 512K\n// VMs limit to 2GB total (currently), making one 1G block max (or three 512M etc.) due to block overhead\n\n// Tags stored in otherwise unused alignment bits\n\n// @ts-ignore: decorator\n@inline const FREE: usize = 1 << 0;\n// @ts-ignore: decorator\n@inline const LEFTFREE: usize = 1 << 1;\n// @ts-ignore: decorator\n@inline const TAGS_MASK: usize = FREE | LEFTFREE; // <= AL_MASK\n\n// ╒════════════════════ Block layout (32-bit) ════════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┼─┼─┤ ┐\n// │ size │L│F│ ◄─┐ info overhead\n// ╞>ptr═══════════════════════════════════════════════════════╧═╧═╡ │ ┘\n// │ if free: ◄ prev │ ◄─┤ usize\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ if free: next ► │ ◄─┤\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ ... │ │ >= 0\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ if free: back ▲ │ ◄─┘\n// └───────────────────────────────────────────────────────────────┘ >= MIN SIZE\n// F: FREE, L: LEFTFREE\n@unmanaged export class Block extends BLOCK {\n\n /** Previous free block, if any. Only valid if free, otherwise part of payload. */\n prev: Block | null;\n /** Next free block, if any. Only valid if free, otherwise part of payload. */\n next: Block | null;\n\n // If the block is free, there is a 'back'reference at its end pointing at its start.\n}\n\n// Block constants. A block must have a minimum size of three pointers so it can hold `prev`,\n// `next` and `back` if free.\n\n// @ts-ignore: decorator\n@inline const BLOCK_MINSIZE: usize = ((3 * sizeof() + BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK) - BLOCK_OVERHEAD; // prev + next + back\n// @ts-ignore: decorator\n// @inline const BLOCK_MAXSIZE: usize = 1 << (FL_BITS + SB_BITS - 1); // exclusive, lives in common.ts\n\n/** Gets the left block of a block. Only valid if the left block is free. */\n// @ts-ignore: decorator\n@inline function GETFREELEFT(block: Block): Block {\n return load(changetype(block) - sizeof());\n}\n\n/** Gets the right block of a block by advancing to the right by its size. */\n// @ts-ignore: decorator\n@inline function GETRIGHT(block: Block): Block {\n return changetype(changetype(block) + BLOCK_OVERHEAD + (block.mmInfo & ~TAGS_MASK));\n}\n\n// ╒═════════════════════ Root layout (32-bit) ════════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤ ┐\n// │ 0 | flMap S│ ◄────┐\n// ╞═══════════════════════════════════════════════════════════════╡ │\n// │ slMap[0] S │ ◄─┐ │\n// ├───────────────────────────────────────────────────────────────┤ │ │\n// │ slMap[1] │ ◄─┤ │\n// ├───────────────────────────────────────────────────────────────┤ u32 │\n// │ slMap[22] │ ◄─┘ │\n// ╞═══════════════════════════════════════════════════════════════╡ usize\n// │ head[0] │ ◄────┤\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ ... │ ◄────┤\n// ├───────────────────────────────────────────────────────────────┤ │\n// │ head[367] │ ◄────┤\n// ╞═══════════════════════════════════════════════════════════════╡ │\n// │ tail │ ◄────┘\n// └───────────────────────────────────────────────────────────────┘ SIZE ┘\n// S: Small blocks map\n@unmanaged class Root {\n /** First level bitmap. */\n flMap: usize;\n}\n\n// Root constants. Where stuff is stored inside of the root structure.\n\n// @ts-ignore: decorator\n@inline const SL_START: usize = sizeof();\n// @ts-ignore: decorator\n@inline const SL_END: usize = SL_START + (FL_BITS << alignof());\n// @ts-ignore: decorator\n@inline const HL_START: usize = (SL_END + AL_MASK) & ~AL_MASK;\n// @ts-ignore: decorator\n@inline const HL_END: usize = HL_START + FL_BITS * SL_SIZE * sizeof();\n// @ts-ignore: decorator\n@inline const ROOT_SIZE: usize = HL_END + sizeof();\n\n// @ts-ignore: decorator\n@lazy export let ROOT: Root = changetype(0); // unsafe initializion below\n\n/** Gets the second level map of the specified first level. */\n// @ts-ignore: decorator\n@inline function GETSL(root: Root, fl: usize): u32 {\n return load(\n changetype(root) + (fl << alignof()),\n SL_START\n );\n}\n\n/** Sets the second level map of the specified first level. */\n// @ts-ignore: decorator\n@inline function SETSL(root: Root, fl: usize, slMap: u32): void {\n store(\n changetype(root) + (fl << alignof()),\n slMap,\n SL_START\n );\n}\n\n/** Gets the head of the free list for the specified combination of first and second level. */\n// @ts-ignore: decorator\n@inline function GETHEAD(root: Root, fl: usize, sl: u32): Block | null {\n return load(\n changetype(root) + (((fl << SL_BITS) + sl) << alignof()),\n HL_START\n );\n}\n\n/** Sets the head of the free list for the specified combination of first and second level. */\n// @ts-ignore: decorator\n@inline function SETHEAD(root: Root, fl: usize, sl: u32, head: Block | null): void {\n store(\n changetype(root) + (((fl << SL_BITS) + sl) << alignof()),\n head,\n HL_START\n );\n}\n\n/** Gets the tail block.. */\n// @ts-ignore: decorator\n@inline function GETTAIL(root: Root): Block {\n return load(\n changetype(root),\n HL_END\n );\n}\n\n/** Sets the tail block. */\n// @ts-ignore: decorator\n@inline function SETTAIL(root: Root, tail: Block): void {\n store(\n changetype(root),\n tail,\n HL_END\n );\n}\n\n/** Inserts a previously used block back into the free list. */\nfunction insertBlock(root: Root, block: Block): void {\n if (DEBUG) assert(block); // cannot be null\n let blockInfo = block.mmInfo;\n if (DEBUG) assert(blockInfo & FREE); // must be free\n\n let right = GETRIGHT(block);\n let rightInfo = right.mmInfo;\n\n // merge with right block if also free\n if (rightInfo & FREE) {\n removeBlock(root, right);\n block.mmInfo = blockInfo = blockInfo + BLOCK_OVERHEAD + (rightInfo & ~TAGS_MASK); // keep block tags\n right = GETRIGHT(block);\n rightInfo = right.mmInfo;\n // 'back' is set below\n }\n\n // merge with left block if also free\n if (blockInfo & LEFTFREE) {\n let left = GETFREELEFT(block);\n let leftInfo = left.mmInfo;\n if (DEBUG) assert(leftInfo & FREE); // must be free according to right tags\n removeBlock(root, left);\n block = left;\n block.mmInfo = blockInfo = leftInfo + BLOCK_OVERHEAD + (blockInfo & ~TAGS_MASK); // keep left tags\n // 'back' is set below\n }\n\n right.mmInfo = rightInfo | LEFTFREE;\n // reference to right is no longer used now, hence rightInfo is not synced\n\n // we now know the size of the block\n let size = blockInfo & ~TAGS_MASK;\n if (DEBUG) assert(size >= BLOCK_MINSIZE); // must be a valid size\n if (DEBUG) assert(changetype(block) + BLOCK_OVERHEAD + size == changetype(right)); // must match\n\n // set 'back' to itself at the end of block\n store(changetype(right) - sizeof(), block);\n\n // mapping_insert\n let fl: usize, sl: u32;\n if (size < SB_SIZE) {\n fl = 0;\n sl = (size >> AL_BITS);\n } else {\n const inv: usize = sizeof() * 8 - 1;\n let boundedSize = min(size, BLOCK_MAXSIZE);\n fl = inv - clz(boundedSize);\n sl = ((boundedSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));\n fl -= SB_BITS - 1;\n }\n if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range\n\n // perform insertion\n let head = GETHEAD(root, fl, sl);\n block.prev = null;\n block.next = head;\n if (head) head.prev = block;\n SETHEAD(root, fl, sl, block);\n\n // update first and second level maps\n root.flMap |= (1 << fl);\n SETSL(root, fl, GETSL(root, fl) | (1 << sl));\n}\n\n/** Removes a free block from internal lists. */\nfunction removeBlock(root: Root, block: Block): void {\n let blockInfo = block.mmInfo;\n if (DEBUG) assert(blockInfo & FREE); // must be free\n let size = blockInfo & ~TAGS_MASK;\n if (DEBUG) assert(size >= BLOCK_MINSIZE); // must be valid\n\n // mapping_insert\n let fl: usize, sl: u32;\n if (size < SB_SIZE) {\n fl = 0;\n sl = (size >> AL_BITS);\n } else {\n const inv: usize = sizeof() * 8 - 1;\n let boundedSize = min(size, BLOCK_MAXSIZE);\n fl = inv - clz(boundedSize);\n sl = ((boundedSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));\n fl -= SB_BITS - 1;\n }\n if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range\n\n // link previous and next free block\n let prev = block.prev;\n let next = block.next;\n if (prev) prev.next = next;\n if (next) next.prev = prev;\n\n // update head if we are removing it\n if (block == GETHEAD(root, fl, sl)) {\n SETHEAD(root, fl, sl, next);\n\n // clear second level map if head is empty now\n if (!next) {\n let slMap = GETSL(root, fl);\n SETSL(root, fl, slMap &= ~(1 << sl));\n\n // clear first level map if second level is empty now\n if (!slMap) root.flMap &= ~(1 << fl);\n }\n }\n // note: does not alter left/back because it is likely that splitting\n // is performed afterwards, invalidating those changes. so, the caller\n // must perform those updates.\n}\n\nfunction roundSize(size: usize): usize {\n const halfMaxSize = BLOCK_MAXSIZE >> 1; // don't round last fl\n const inv: usize = sizeof() * 8 - 1;\n const invRound = inv - SL_BITS;\n return size < halfMaxSize\n ? size + (1 << (invRound - clz(size))) - 1\n : size;\n}\n\n/** Searches for a free block of at least the specified size. */\nfunction searchBlock(root: Root, size: usize): Block | null {\n // size was already asserted by caller\n\n // mapping_search\n let fl: usize, sl: u32;\n if (size < SB_SIZE) {\n fl = 0;\n sl = (size >> AL_BITS);\n } else {\n const requestSize = roundSize(size);\n fl = sizeof() * 8 - 1 - clz(requestSize);\n sl = ((requestSize >> (fl - SL_BITS)) ^ (1 << SL_BITS));\n fl -= SB_BITS - 1;\n }\n if (DEBUG) assert(fl < FL_BITS && sl < SL_SIZE); // fl/sl out of range\n\n // search second level\n let slMap = GETSL(root, fl) & (~0 << sl);\n let head: Block | null = null;\n if (!slMap) {\n // search next larger first level\n let flMap = root.flMap & (~0 << (fl + 1));\n if (!flMap) {\n head = null;\n } else {\n fl = ctz(flMap);\n slMap = GETSL(root, fl);\n if (DEBUG) assert(slMap); // can't be zero if fl points here\n head = GETHEAD(root, fl, ctz(slMap));\n }\n } else {\n head = GETHEAD(root, fl, ctz(slMap));\n }\n return head;\n}\n\n/** Prepares the specified block before (re-)use, possibly splitting it. */\nfunction prepareBlock(root: Root, block: Block, size: usize): void {\n // size was already asserted by caller\n\n let blockInfo = block.mmInfo;\n if (DEBUG) assert(!((size + BLOCK_OVERHEAD) & AL_MASK)); // size must be aligned so the new block is\n\n // split if the block can hold another MINSIZE block incl. overhead\n let remaining = (blockInfo & ~TAGS_MASK) - size;\n if (remaining >= BLOCK_OVERHEAD + BLOCK_MINSIZE) {\n block.mmInfo = size | (blockInfo & LEFTFREE); // also discards FREE\n\n let spare = changetype(changetype(block) + BLOCK_OVERHEAD + size);\n spare.mmInfo = (remaining - BLOCK_OVERHEAD) | FREE; // not LEFTFREE\n insertBlock(root, spare); // also sets 'back'\n\n // otherwise tag block as no longer FREE and right as no longer LEFTFREE\n } else {\n block.mmInfo = blockInfo & ~FREE;\n GETRIGHT(block).mmInfo &= ~LEFTFREE;\n }\n}\n\n/** Adds more memory to the pool. */\nfunction addMemory(root: Root, start: usize, endU64: u64): bool {\n let end = endU64;\n if (DEBUG) assert(start <= endU64); // must be valid\n start = ((start + BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK) - BLOCK_OVERHEAD;\n end &= ~AL_MASK;\n\n let tail = GETTAIL(root);\n let tailInfo: usize = 0;\n if (tail) { // more memory\n if (DEBUG) assert(start >= changetype(tail) + BLOCK_OVERHEAD);\n\n // merge with current tail if adjacent\n const offsetToTail = AL_SIZE;\n if (start - offsetToTail == changetype(tail)) {\n start -= offsetToTail;\n tailInfo = tail.mmInfo;\n } else {\n // We don't do this, but a user might `memory.grow` manually\n // leading to non-adjacent pages managed by TLSF.\n }\n\n } else if (DEBUG) { // first memory\n assert(start >= changetype(root) + ROOT_SIZE); // starts after root\n }\n\n // check if size is large enough for a free block and the tail block\n let size = end - start;\n if (size < BLOCK_OVERHEAD + BLOCK_MINSIZE + BLOCK_OVERHEAD) {\n return false;\n }\n\n // left size is total minus its own and the zero-length tail's header\n let leftSize = size - 2 * BLOCK_OVERHEAD;\n let left = changetype(start);\n left.mmInfo = leftSize | FREE | (tailInfo & LEFTFREE);\n left.prev = null;\n left.next = null;\n\n // tail is a zero-length used block\n tail = changetype(start + BLOCK_OVERHEAD + leftSize);\n tail.mmInfo = 0 | LEFTFREE;\n SETTAIL(root, tail);\n\n insertBlock(root, left); // also merges with free left before tail / sets 'back'\n\n return true;\n}\n\n/** Grows memory to fit at least another block of the specified size. */\nfunction growMemory(root: Root, size: usize): void {\n if (ASC_LOW_MEMORY_LIMIT) {\n unreachable();\n return;\n }\n // Here, both rounding performed in searchBlock ...\n if (size >= SB_SIZE) {\n size = roundSize(size);\n }\n // and additional BLOCK_OVERHEAD must be taken into account. If we are going\n // to merge with the tail block, that's one time, otherwise it's two times.\n let pagesBefore = memory.size();\n size += BLOCK_OVERHEAD << usize((pagesBefore << 16) - BLOCK_OVERHEAD != changetype(GETTAIL(root)));\n let pagesNeeded = (((size + 0xffff) & ~0xffff) >>> 16);\n let pagesWanted = max(pagesBefore, pagesNeeded); // double memory\n if (memory.grow(pagesWanted) < 0) {\n if (memory.grow(pagesNeeded) < 0) unreachable();\n }\n let pagesAfter = memory.size();\n addMemory(root, pagesBefore << 16, pagesAfter << 16);\n}\n\n/** Computes the size (excl. header) of a block. */\nfunction computeSize(size: usize): usize {\n // Size must be large enough and aligned minus preceeding overhead\n return size <= BLOCK_MINSIZE\n ? BLOCK_MINSIZE\n : ((size + BLOCK_OVERHEAD + AL_MASK) & ~AL_MASK) - BLOCK_OVERHEAD;\n}\n\n/** Prepares and checks an allocation size. */\nfunction prepareSize(size: usize): usize {\n if (size > BLOCK_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);\n return computeSize(size);\n}\n\n/** Initializes the root structure. */\nfunction initialize(): void {\n if (isDefined(ASC_RTRACE)) oninit(__heap_base);\n let rootOffset = (__heap_base + AL_MASK) & ~AL_MASK;\n let pagesBefore = memory.size();\n let pagesNeeded = ((((rootOffset + ROOT_SIZE) + 0xffff) & ~0xffff) >>> 16);\n if (pagesNeeded > pagesBefore && memory.grow(pagesNeeded - pagesBefore) < 0) unreachable();\n let root = changetype(rootOffset);\n root.flMap = 0;\n SETTAIL(root, changetype(0));\n for (let fl: usize = 0; fl < FL_BITS; ++fl) {\n SETSL(root, fl, 0);\n for (let sl: u32 = 0; sl < SL_SIZE; ++sl) {\n SETHEAD(root, fl, sl, null);\n }\n }\n let memStart = rootOffset + ROOT_SIZE;\n if (ASC_LOW_MEMORY_LIMIT) {\n const memEnd = ASC_LOW_MEMORY_LIMIT & ~AL_MASK;\n if (memStart <= memEnd) addMemory(root, memStart, memEnd);\n else unreachable(); // low memory limit already exceeded\n } else {\n addMemory(root, memStart, memory.size() << 16);\n }\n ROOT = root;\n}\n\n/** Allocates a block of the specified size. */\nexport function allocateBlock(root: Root, size: usize): Block {\n let payloadSize = prepareSize(size);\n let block = searchBlock(root, payloadSize);\n if (!block) {\n growMemory(root, payloadSize);\n block = changetype(searchBlock(root, payloadSize));\n if (DEBUG) assert(block); // must be found now\n }\n if (DEBUG) assert((block.mmInfo & ~TAGS_MASK) >= payloadSize); // must fit\n removeBlock(root, block);\n prepareBlock(root, block, payloadSize);\n if (isDefined(ASC_RTRACE)) onalloc(block);\n return block;\n}\n\n/** Reallocates a block to the specified size. */\nexport function reallocateBlock(root: Root, block: Block, size: usize): Block {\n let payloadSize = prepareSize(size);\n let blockInfo = block.mmInfo;\n let blockSize = blockInfo & ~TAGS_MASK;\n\n // possibly split and update runtime size if it still fits\n if (payloadSize <= blockSize) {\n prepareBlock(root, block, payloadSize);\n if (isDefined(ASC_RTRACE)) {\n if (payloadSize != blockSize) onresize(block, BLOCK_OVERHEAD + blockSize);\n }\n return block;\n }\n\n // merge with right free block if merger is large enough\n let right = GETRIGHT(block);\n let rightInfo = right.mmInfo;\n if (rightInfo & FREE) {\n let mergeSize = blockSize + BLOCK_OVERHEAD + (rightInfo & ~TAGS_MASK);\n if (mergeSize >= payloadSize) {\n removeBlock(root, right);\n block.mmInfo = (blockInfo & TAGS_MASK) | mergeSize;\n prepareBlock(root, block, payloadSize);\n if (isDefined(ASC_RTRACE)) onresize(block, BLOCK_OVERHEAD + blockSize);\n return block;\n }\n }\n\n // otherwise move the block\n return moveBlock(root, block, size);\n}\n\n/** Moves a block to a new one of the specified size. */\nfunction moveBlock(root: Root, block: Block, newSize: usize): Block {\n let newBlock = allocateBlock(root, newSize);\n memory.copy(changetype(newBlock) + BLOCK_OVERHEAD, changetype(block) + BLOCK_OVERHEAD, block.mmInfo & ~TAGS_MASK);\n if (changetype(block) >= __heap_base) {\n if (isDefined(ASC_RTRACE)) onmove(block, newBlock);\n freeBlock(root, block);\n }\n return newBlock;\n}\n\n/** Frees a block. */\nexport function freeBlock(root: Root, block: Block): void {\n if (isDefined(ASC_RTRACE)) onfree(block);\n block.mmInfo = block.mmInfo | FREE;\n insertBlock(root, block);\n}\n\n/** Checks that a used block is valid to be freed or reallocated. */\nfunction checkUsedBlock(ptr: usize): Block {\n let block = changetype(ptr - BLOCK_OVERHEAD);\n assert(\n ptr != 0 && !(ptr & AL_MASK) && // must exist and be aligned\n !(block.mmInfo & FREE) // must be used\n );\n return block;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __alloc(size: usize): usize {\n if (!ROOT) initialize();\n return changetype(allocateBlock(ROOT, size)) + BLOCK_OVERHEAD;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __realloc(ptr: usize, size: usize): usize {\n if (!ROOT) initialize();\n return (ptr < __heap_base\n ? changetype(moveBlock(ROOT, checkUsedBlock(ptr), size))\n : changetype(reallocateBlock(ROOT, checkUsedBlock(ptr), size))\n ) + BLOCK_OVERHEAD;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __free(ptr: usize): void {\n if (ptr < __heap_base) return;\n if (!ROOT) initialize();\n freeBlock(ROOT, checkUsedBlock(ptr));\n}\n","// This file is shared with the compiler and must remain portable\n\n// ╒═══════════════════ Typeinfo interpretation ═══════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤ ◄─ __rtti_base\n// │ count │\n// ╞═══════════════════════════════════════════════════════════════╡ ┐\n// │ Typeinfo#flags [id=0] │ id < count\n// ├───────────────────────────────────────────────────────────────┤\n// │ ... │\n\n/** Runtime type information data structure. */\n@unmanaged\nexport class Typeinfo {\n /** Flags describing the shape of this class type. */\n flags: TypeinfoFlags = TypeinfoFlags.NONE;\n}\n\n/** Runtime type information flags. */\nexport const enum TypeinfoFlags {\n /** No specific flags. */\n NONE = 0,\n /** Type is an `ArrayBufferView`. */\n ARRAYBUFFERVIEW = 1 << 0,\n /** Type is an `Array`. */\n ARRAY = 1 << 1,\n /** Type is a `StaticArray`. */\n STATICARRAY = 1 << 2,\n /** Type is a `Set`. */\n SET = 1 << 3,\n /** Type is a `Map`. */\n MAP = 1 << 4,\n /** Type has no outgoing pointers. */\n POINTERFREE = 1 << 5,\n /** Value alignment of 1 byte. */\n VALUE_ALIGN_0 = 1 << 6,\n /** Value alignment of 2 bytes. */\n VALUE_ALIGN_1 = 1 << 7,\n /** Value alignment of 4 bytes. */\n VALUE_ALIGN_2 = 1 << 8,\n /** Value alignment of 8 bytes. */\n VALUE_ALIGN_3 = 1 << 9,\n /** Value alignment of 16 bytes. */\n VALUE_ALIGN_4 = 1 << 10,\n /** Value is a signed type. */\n VALUE_SIGNED = 1 << 11,\n /** Value is a float type. */\n VALUE_FLOAT = 1 << 12,\n /** Value type is nullable. */\n VALUE_NULLABLE = 1 << 13,\n /** Value type is managed. */\n VALUE_MANAGED = 1 << 14,\n /** Key alignment of 1 byte. */\n KEY_ALIGN_0 = 1 << 15,\n /** Key alignment of 2 bytes. */\n KEY_ALIGN_1 = 1 << 16,\n /** Key alignment of 4 bytes. */\n KEY_ALIGN_2 = 1 << 17,\n /** Key alignment of 8 bytes. */\n KEY_ALIGN_3 = 1 << 18,\n /** Key alignment of 16 bytes. */\n KEY_ALIGN_4 = 1 << 19,\n /** Key is a signed type. */\n KEY_SIGNED = 1 << 20,\n /** Key is a float type. */\n KEY_FLOAT = 1 << 21,\n /** Key type is nullable. */\n KEY_NULLABLE = 1 << 22,\n /** Key type is managed. */\n KEY_MANAGED = 1 << 23\n}\n","import { BLOCK, BLOCK_OVERHEAD, OBJECT_OVERHEAD, OBJECT_MAXSIZE, TOTAL_OVERHEAD, DEBUG, TRACE, RTRACE, PROFILE } from \"./common\";\nimport { onvisit, oncollect, oninterrupt, onyield } from \"./rtrace\";\nimport { TypeinfoFlags } from \"../shared/typeinfo\";\nimport { E_ALLOCATION_TOO_LARGE, E_ALREADY_PINNED, E_NOT_PINNED } from \"../util/error\";\n\n// === ITCMS: An incremental Tri-Color Mark & Sweep garbage collector ===\n// Adapted from Bach Le's μgc, see: https://github.com/bullno1/ugc\n\n// ╒═════════════╤══════════════ Colors ═══════════════════════════╕\n// │ Color │ Meaning │\n// ├─────────────┼─────────────────────────────────────────────────┤\n// │ WHITE* │ Unprocessed │\n// │ BLACK* │ Processed │\n// │ GRAY │ Processed with unprocessed children │\n// │ TRANSPARENT │ Manually pinned (always reachable) │\n// └─────────────┴─────────────────────────────────────────────────┘\n// * flipped between cycles\n\n// @ts-ignore: decorator\n@lazy let white = 0;\n// @ts-ignore: decorator\n@inline const gray = 2;\n// @ts-ignore: decorator\n@inline const transparent = 3;\n// @ts-ignore: decorator\n@inline const COLOR_MASK = 3;\n\n/** Size in memory of all objects currently managed by the GC. */\n// @ts-ignore: decorator\n@lazy let total: usize = 0;\n\n/** Currently transitioning from SWEEP to MARK state. */\n// @ts-ignore: decorator\n@inline const STATE_IDLE = 0;\n/** Currently marking reachable objects. */\n// @ts-ignore: decorator\n@inline const STATE_MARK = 1;\n/** Currently sweeping unreachable objects. */\n// @ts-ignore: decorator\n@inline const STATE_SWEEP = 2;\n/** Current collector state. */\n// @ts-ignore: decorator\n@lazy let state = STATE_IDLE;\n\n// @ts-ignore: decorator\n@lazy let fromSpace = initLazy(changetype(memory.data(offsetof())));\n// @ts-ignore: decorator\n@lazy let toSpace = initLazy(changetype(memory.data(offsetof())));\n// @ts-ignore: decorator\n@lazy let pinSpace = initLazy(changetype(memory.data(offsetof())));\n// @ts-ignore: decorator\n@lazy let iter: Object = changetype(0); // unsafe initializion below\n\nfunction initLazy(space: Object): Object {\n space.nextWithColor = changetype(space);\n space.prev = space;\n return space;\n}\n\n/** Visit cookie indicating scanning of an object. */\n// @ts-ignore: decorator\n@inline const VISIT_SCAN = 0;\n\n// ╒═══════════════ Managed object layout (32-bit) ════════════════╕\n// 3 2 1\n// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 bits\n// ├─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┴─┤\n// │ Memory manager block │\n// ╞═══════════════════════════════════════════════════════════╤═══╡\n// │ next │ C │ = nextWithColor\n// ├───────────────────────────────────────────────────────────┴───┤\n// │ prev │\n// ├───────────────────────────────────────────────────────────────┤\n// │ rtId │\n// ├───────────────────────────────────────────────────────────────┤\n// │ rtSize │\n// ╞>ptr═══════════════════════════════════════════════════════════╡\n// │ ... │\n// C: color\n\n/** Represents a managed object in memory, consisting of a header followed by the object's data. */\n@unmanaged class Object extends BLOCK {\n /** Pointer to the next object with color flags stored in the alignment bits. */\n nextWithColor: usize; // *u32\n /** Pointer to the previous object. */\n prev: Object; // *u32\n /** Runtime id. */\n rtId: u32;\n /** Runtime size. */\n rtSize: u32;\n\n /** Gets the pointer to the next object. */\n get next(): Object {\n return changetype(this.nextWithColor & ~COLOR_MASK);\n }\n\n /** Sets the pointer to the next object. */\n set next(obj: Object) {\n this.nextWithColor = changetype(obj) | (this.nextWithColor & COLOR_MASK);\n }\n\n /** Gets this object's color. */\n get color(): i32 {\n return i32(this.nextWithColor & COLOR_MASK);\n }\n\n /** Sets this object's color. */\n set color(color: i32) {\n this.nextWithColor = (this.nextWithColor & ~COLOR_MASK) | color;\n }\n\n /** Gets the size of this object in memory. */\n get size(): usize {\n return BLOCK_OVERHEAD + (this.mmInfo & ~3);\n }\n\n /** Tests if this object is pointerfree. */\n get isPointerfree(): bool {\n let rtId = this.rtId;\n // 0: Object, 1: ArrayBuffer, 2: String\n return rtId <= idof() || (__typeinfo(rtId) & TypeinfoFlags.POINTERFREE) != 0;\n }\n\n /** Unlinks this object from its list. */\n unlink(): void {\n let next = this.next;\n if (next == null) {\n if (DEBUG) assert(this.prev == null && changetype(this) < __heap_base);\n return; // static data not yet linked\n }\n let prev = this.prev;\n if (DEBUG) assert(prev);\n next.prev = prev;\n prev.next = next;\n }\n\n /** Links this object to the specified list, with the given color. */\n linkTo(list: Object, withColor: i32): void {\n let prev = list.prev;\n this.nextWithColor = changetype(list) | withColor;\n this.prev = prev;\n prev.next = this;\n list.prev = this;\n }\n\n /** Marks this object as gray, that is reachable with unscanned children. */\n makeGray(): void {\n if (this == iter) iter = assert(this.prev);\n this.unlink();\n this.linkTo(toSpace, this.isPointerfree ? i32(!white) : gray);\n }\n}\n\n/** Visits all objects considered to be program roots. */\nfunction visitRoots(cookie: u32): void {\n __visit_globals(cookie);\n let pn = pinSpace;\n let iter = pn.next;\n while (iter != pn) {\n if (DEBUG) assert(iter.color == transparent);\n __visit_members(changetype(iter) + TOTAL_OVERHEAD, cookie);\n iter = iter.next;\n }\n}\n\n/** Visits all objects on the stack. */\nfunction visitStack(cookie: u32): void {\n let ptr = __stack_pointer;\n while (ptr < __heap_base) {\n __visit(load(ptr), cookie);\n ptr += sizeof();\n }\n}\n\n/** Performs a single step according to the current state. */\nfunction step(): usize {\n // Magic constants responsible for pause times. Obtained experimentally\n // using the compiler compiling itself. 2048 budget pro run by default.\n const MARKCOST = isDefined(ASC_GC_MARKCOST) ? ASC_GC_MARKCOST : 1;\n const SWEEPCOST = isDefined(ASC_GC_SWEEPCOST) ? ASC_GC_SWEEPCOST : 10;\n let obj: Object;\n switch (state) {\n case STATE_IDLE: {\n state = STATE_MARK;\n visitCount = 0;\n visitRoots(VISIT_SCAN);\n iter = toSpace;\n return visitCount * MARKCOST;\n }\n case STATE_MARK: {\n let black = i32(!white);\n obj = iter.next;\n while (obj != toSpace) {\n iter = obj;\n if (obj.color != black) { // skip already-blacks (pointerfree)\n obj.color = black;\n visitCount = 0;\n __visit_members(changetype(obj) + TOTAL_OVERHEAD, VISIT_SCAN);\n return visitCount * MARKCOST;\n }\n obj = obj.next;\n }\n visitCount = 0;\n visitRoots(VISIT_SCAN);\n obj = iter.next;\n if (obj == toSpace) {\n visitStack(VISIT_SCAN);\n obj = iter.next;\n while (obj != toSpace) {\n if (obj.color != black) {\n obj.color = black;\n __visit_members(changetype(obj) + TOTAL_OVERHEAD, VISIT_SCAN);\n }\n obj = obj.next;\n }\n let from = fromSpace;\n fromSpace = toSpace;\n toSpace = from;\n white = black;\n iter = from.next;\n state = STATE_SWEEP;\n }\n return visitCount * MARKCOST;\n }\n case STATE_SWEEP: {\n obj = iter;\n if (obj != toSpace) {\n iter = obj.next;\n if (DEBUG) assert(obj.color == i32(!white)); // old white\n free(obj);\n return SWEEPCOST;\n }\n toSpace.nextWithColor = changetype(toSpace);\n toSpace.prev = toSpace;\n state = STATE_IDLE;\n break;\n }\n }\n return 0;\n}\n\n/** Frees an object. */\nfunction free(obj: Object): void {\n if (changetype(obj) < __heap_base) {\n obj.nextWithColor = 0; // may become linked again\n obj.prev = changetype(0);\n } else {\n total -= obj.size;\n if (isDefined(__finalize)) {\n __finalize(changetype(obj) + TOTAL_OVERHEAD);\n }\n __free(changetype(obj) + BLOCK_OVERHEAD);\n }\n}\n\n// Garbage collector interface\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __new(size: usize, id: i32): usize {\n if (size >= OBJECT_MAXSIZE) throw new Error(E_ALLOCATION_TOO_LARGE);\n if (total >= threshold) interrupt();\n let obj = changetype(__alloc(OBJECT_OVERHEAD + size) - BLOCK_OVERHEAD);\n obj.rtId = id;\n obj.rtSize = size;\n obj.linkTo(fromSpace, white); // inits next/prev\n total += obj.size;\n let ptr = changetype(obj) + TOTAL_OVERHEAD;\n // may be visited before being fully initialized, so must fill\n memory.fill(ptr, 0, size);\n return ptr;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __renew(oldPtr: usize, size: usize): usize {\n let oldObj = changetype(oldPtr - TOTAL_OVERHEAD);\n // Update object size if its block is large enough\n if (size <= (oldObj.mmInfo & ~3) - OBJECT_OVERHEAD) {\n oldObj.rtSize = size;\n return oldPtr;\n }\n // If not the same object anymore, we have to move it move it due to the\n // shadow stack potentially still referencing the old object\n let newPtr = __new(size, oldObj.rtId);\n memory.copy(newPtr, oldPtr, min(size, oldObj.rtSize));\n return newPtr;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void {\n // Write barrier is unnecessary if non-incremental\n if (!childPtr) return;\n if (DEBUG) assert(parentPtr);\n let child = changetype(childPtr - TOTAL_OVERHEAD);\n if (child.color == white) {\n let parent = changetype(parentPtr - TOTAL_OVERHEAD);\n let parentColor = parent.color;\n if (parentColor == i32(!white)) {\n // Maintain the invariant that no black object may point to a white object.\n if (expectMultiple) {\n // Move the barrier \"backward\". Suitable for containers receiving multiple stores.\n // Avoids a barrier for subsequent objects stored into the same container.\n parent.makeGray();\n } else {\n // Move the barrier \"forward\". Suitable for objects receiving isolated stores.\n child.makeGray();\n }\n } else if (parentColor == transparent && state == STATE_MARK) {\n // Pinned objects are considered 'black' during the mark phase.\n child.makeGray();\n }\n }\n}\n\n// @ts-ignore: decorator\n@lazy let visitCount = 0;\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __visit(ptr: usize, cookie: i32): void {\n if (!ptr) return;\n let obj = changetype(ptr - TOTAL_OVERHEAD);\n if (RTRACE) if (!onvisit(obj)) return;\n if (obj.color == white) {\n obj.makeGray();\n ++visitCount;\n }\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __pin(ptr: usize): usize {\n if (ptr) {\n let obj = changetype(ptr - TOTAL_OVERHEAD);\n if (obj.color == transparent) {\n throw new Error(E_ALREADY_PINNED);\n }\n obj.unlink(); // from fromSpace\n obj.linkTo(pinSpace, transparent);\n }\n return ptr;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __unpin(ptr: usize): void {\n if (!ptr) return;\n let obj = changetype(ptr - TOTAL_OVERHEAD);\n if (obj.color != transparent) {\n throw new Error(E_NOT_PINNED);\n }\n if (state == STATE_MARK) {\n // We may be right at the point after marking roots for the second time and\n // entering the sweep phase, in which case the object would be missed if it\n // is not only pinned but also a root. Make sure it isn't missed.\n obj.makeGray();\n } else {\n obj.unlink();\n obj.linkTo(fromSpace, white);\n }\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nexport function __collect(): void {\n if (TRACE) trace(\"GC (full) at\", 1, total);\n if (state > STATE_IDLE) {\n // finish current cycle\n while (state != STATE_IDLE) step();\n }\n // perform a full cycle\n step();\n while (state != STATE_IDLE) step();\n threshold = (total * IDLEFACTOR / 100) + GRANULARITY;\n if (TRACE) trace(\"GC (full) done at cur/max\", 2, total, memory.size() << 16);\n if (RTRACE || PROFILE) oncollect(total);\n}\n\n// Garbage collector automation\n\n/** How often to interrupt. The default of 1024 means \"interrupt each 1024 bytes allocated\". */\n// @ts-ignore: decorator\n@inline const GRANULARITY: usize = isDefined(ASC_GC_GRANULARITY) ? ASC_GC_GRANULARITY : 1024;\n/** How long to interrupt. The default of 200% means \"run at double the speed of allocations\". */\n// @ts-ignore: decorator\n@inline const STEPFACTOR: usize = isDefined(ASC_GC_SWEEPFACTOR) ? ASC_GC_SWEEPFACTOR : 200;\n/** How long to idle. The default of 200% means \"wait for memory to double before kicking in again\". */\n// @ts-ignore: decorator\n@inline const IDLEFACTOR: usize = isDefined(ASC_GC_IDLEFACTOR) ? ASC_GC_IDLEFACTOR : 200;\n\n/** Threshold of memory used by objects to exceed before interrupting again. */\n// @ts-ignore: decorator\n@lazy let threshold: usize = ((memory.size() << 16) - __heap_base) >> 1;\n\n/** Performs a reasonable amount of incremental GC steps. */\nfunction interrupt(): void {\n if (PROFILE) oninterrupt(total);\n if (TRACE) trace(\"GC (auto) at\", 1, total);\n let budget: isize = GRANULARITY * STEPFACTOR / 100;\n do {\n budget -= step();\n if (state == STATE_IDLE) {\n if (TRACE) trace(\"└ GC (auto) done at cur/max\", 2, total, memory.size() << 16);\n threshold = (total * IDLEFACTOR / 100) + GRANULARITY;\n if (PROFILE) onyield(total);\n return;\n }\n } while (budget > 0);\n if (TRACE) trace(\"└ GC (auto) ongoing at\", 1, total);\n threshold = total + GRANULARITY * usize(total - threshold < GRANULARITY);\n if (PROFILE) onyield(total);\n}\n","// Common error messages for use across the standard library. Keeping error messages compact\n// and reusing them where possible ensures minimal static data in binaries.\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_INDEXOUTOFRANGE: string = \"Index out of range\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_VALUEOUTOFRANGE: string = \"Value out of range\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_INVALIDLENGTH: string = \"Invalid length\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_EMPTYARRAY: string = \"Array is empty\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_HOLEYARRAY: string = \"Element type must be nullable if array is holey\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_NOTIMPLEMENTED: string = \"Not implemented\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_KEYNOTFOUND: string = \"Key does not exist\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_ALLOCATION_TOO_LARGE: string = \"Allocation too large\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_ALREADY_PINNED: string = \"Object already pinned\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_NOT_PINNED: string = \"Object is not pinned\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_URI_MALFORMED: string = \"URI malformed\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_INVALIDDATE: string = \"Invalid Date\";\n\n// @ts-ignore: decorator\n@lazy @inline\nexport const E_UNPAIRED_SURROGATE: string = \"Unpaired surrogate\";\n","// This file is shared with the compiler and must remain portable\n\n/** Runtime types. */\nexport enum Runtime {\n /** Simple bump allocator without GC. */\n Stub = 0,\n /** Stop the world semi-automatic GC. */\n Minimal = 1,\n /** incremental GC. */\n Incremental = 2,\n}\n","/// \n\nimport { idof } from \"../builtins\";\nimport { CharCode } from \"./string\";\n\n// @ts-ignore: decorator\n@inline\nexport const MAX_DOUBLE_LENGTH = 28;\n\n// @ts-ignore: decorator\n@lazy @inline const POWERS10 = memory.data([\n 1,\n 10,\n 100,\n 1000,\n 10000,\n 100000,\n 1000000,\n 10000000,\n 100000000,\n 1000000000\n]);\n\n/*\n Lookup table for pairwise char codes in range [0-99]\n\n \"00\", \"01\", \"02\", \"03\", \"04\", \"05\", \"06\", \"07\", \"08\", \"09\",\n \"10\", \"11\", \"12\", \"13\", \"14\", \"15\", \"16\", \"17\", \"18\", \"19\",\n \"20\", \"21\", \"22\", \"23\", \"24\", \"25\", \"26\", \"27\", \"28\", \"29\",\n \"30\", \"31\", \"32\", \"33\", \"34\", \"35\", \"36\", \"37\", \"38\", \"39\",\n \"40\", \"41\", \"42\", \"43\", \"44\", \"45\", \"46\", \"47\", \"48\", \"49\",\n \"50\", \"51\", \"52\", \"53\", \"54\", \"55\", \"56\", \"57\", \"58\", \"59\",\n \"60\", \"61\", \"62\", \"63\", \"64\", \"65\", \"66\", \"67\", \"68\", \"69\",\n \"70\", \"71\", \"72\", \"73\", \"74\", \"75\", \"76\", \"77\", \"78\", \"79\",\n \"80\", \"81\", \"82\", \"83\", \"84\", \"85\", \"86\", \"87\", \"88\", \"89\",\n \"90\", \"91\", \"92\", \"93\", \"94\", \"95\", \"96\", \"97\", \"98\", \"99\"\n*/\n// @ts-ignore: decorator\n@lazy @inline const DIGITS = memory.data([\n 0x00300030, 0x00310030, 0x00320030, 0x00330030, 0x00340030,\n 0x00350030, 0x00360030, 0x00370030, 0x00380030, 0x00390030,\n 0x00300031, 0x00310031, 0x00320031, 0x00330031, 0x00340031,\n 0x00350031, 0x00360031, 0x00370031, 0x00380031, 0x00390031,\n 0x00300032, 0x00310032, 0x00320032, 0x00330032, 0x00340032,\n 0x00350032, 0x00360032, 0x00370032, 0x00380032, 0x00390032,\n 0x00300033, 0x00310033, 0x00320033, 0x00330033, 0x00340033,\n 0x00350033, 0x00360033, 0x00370033, 0x00380033, 0x00390033,\n 0x00300034, 0x00310034, 0x00320034, 0x00330034, 0x00340034,\n 0x00350034, 0x00360034, 0x00370034, 0x00380034, 0x00390034,\n 0x00300035, 0x00310035, 0x00320035, 0x00330035, 0x00340035,\n 0x00350035, 0x00360035, 0x00370035, 0x00380035, 0x00390035,\n 0x00300036, 0x00310036, 0x00320036, 0x00330036, 0x00340036,\n 0x00350036, 0x00360036, 0x00370036, 0x00380036, 0x00390036,\n 0x00300037, 0x00310037, 0x00320037, 0x00330037, 0x00340037,\n 0x00350037, 0x00360037, 0x00370037, 0x00380037, 0x00390037,\n 0x00300038, 0x00310038, 0x00320038, 0x00330038, 0x00340038,\n 0x00350038, 0x00360038, 0x00370038, 0x00380038, 0x00390038,\n 0x00300039, 0x00310039, 0x00320039, 0x00330039, 0x00340039,\n 0x00350039, 0x00360039, 0x00370039, 0x00380039, 0x00390039\n]);\n\n// Lookup table for pairwise char codes in range [0x00-0xFF]\n// @ts-ignore: decorator\n@lazy @inline const HEX_DIGITS =\n\"000102030405060708090a0b0c0d0e0f\\\n101112131415161718191a1b1c1d1e1f\\\n202122232425262728292a2b2c2d2e2f\\\n303132333435363738393a3b3c3d3e3f\\\n404142434445464748494a4b4c4d4e4f\\\n505152535455565758595a5b5c5d5e5f\\\n606162636465666768696a6b6c6d6e6f\\\n707172737475767778797a7b7c7d7e7f\\\n808182838485868788898a8b8c8d8e8f\\\n909192939495969798999a9b9c9d9e9f\\\na0a1a2a3a4a5a6a7a8a9aaabacadaeaf\\\nb0b1b2b3b4b5b6b7b8b9babbbcbdbebf\\\nc0c1c2c3c4c5c6c7c8c9cacbcccdcecf\\\nd0d1d2d3d4d5d6d7d8d9dadbdcdddedf\\\ne0e1e2e3e4e5e6e7e8e9eaebecedeeef\\\nf0f1f2f3f4f5f6f7f8f9fafbfcfdfeff\";\n\n// @ts-ignore: decorator\n@lazy @inline const ANY_DIGITS = \"0123456789abcdefghijklmnopqrstuvwxyz\";\n\n// @ts-ignore: decorator\n@lazy @inline const EXP_POWERS = memory.data([/* eslint-disable indent */\n -1220, -1193, -1166, -1140, -1113, -1087, -1060, -1034, -1007, -980,\n -954, -927, -901, -874, -847, -821, -794, -768, -741, -715,\n -688, -661, -635, -608, -582, -555, -529, -502, -475, -449,\n -422, -396, -369, -343, -316, -289, -263, -236, -210, -183,\n -157, -130, -103, -77, -50, -24, 3, 30, 56, 83,\n 109, 136, 162, 189, 216, 242, 269, 295, 322, 348,\n 375, 402, 428, 455, 481, 508, 534, 561, 588, 614,\n 641, 667, 694, 720, 747, 774, 800, 827, 853, 880,\n 907, 933, 960, 986, 1013, 1039, 1066\n/* eslint-enable indent */]);\n\n// 1e-348, 1e-340, ..., 1e340\n// @ts-ignore: decorator\n@lazy @inline const FRC_POWERS = memory.data([\n 0xFA8FD5A0081C0288, 0xBAAEE17FA23EBF76, 0x8B16FB203055AC76, 0xCF42894A5DCE35EA,\n 0x9A6BB0AA55653B2D, 0xE61ACF033D1A45DF, 0xAB70FE17C79AC6CA, 0xFF77B1FCBEBCDC4F,\n 0xBE5691EF416BD60C, 0x8DD01FAD907FFC3C, 0xD3515C2831559A83, 0x9D71AC8FADA6C9B5,\n 0xEA9C227723EE8BCB, 0xAECC49914078536D, 0x823C12795DB6CE57, 0xC21094364DFB5637,\n 0x9096EA6F3848984F, 0xD77485CB25823AC7, 0xA086CFCD97BF97F4, 0xEF340A98172AACE5,\n 0xB23867FB2A35B28E, 0x84C8D4DFD2C63F3B, 0xC5DD44271AD3CDBA, 0x936B9FCEBB25C996,\n 0xDBAC6C247D62A584, 0xA3AB66580D5FDAF6, 0xF3E2F893DEC3F126, 0xB5B5ADA8AAFF80B8,\n 0x87625F056C7C4A8B, 0xC9BCFF6034C13053, 0x964E858C91BA2655, 0xDFF9772470297EBD,\n 0xA6DFBD9FB8E5B88F, 0xF8A95FCF88747D94, 0xB94470938FA89BCF, 0x8A08F0F8BF0F156B,\n 0xCDB02555653131B6, 0x993FE2C6D07B7FAC, 0xE45C10C42A2B3B06, 0xAA242499697392D3,\n 0xFD87B5F28300CA0E, 0xBCE5086492111AEB, 0x8CBCCC096F5088CC, 0xD1B71758E219652C,\n 0x9C40000000000000, 0xE8D4A51000000000, 0xAD78EBC5AC620000, 0x813F3978F8940984,\n 0xC097CE7BC90715B3, 0x8F7E32CE7BEA5C70, 0xD5D238A4ABE98068, 0x9F4F2726179A2245,\n 0xED63A231D4C4FB27, 0xB0DE65388CC8ADA8, 0x83C7088E1AAB65DB, 0xC45D1DF942711D9A,\n 0x924D692CA61BE758, 0xDA01EE641A708DEA, 0xA26DA3999AEF774A, 0xF209787BB47D6B85,\n 0xB454E4A179DD1877, 0x865B86925B9BC5C2, 0xC83553C5C8965D3D, 0x952AB45CFA97A0B3,\n 0xDE469FBD99A05FE3, 0xA59BC234DB398C25, 0xF6C69A72A3989F5C, 0xB7DCBF5354E9BECE,\n 0x88FCF317F22241E2, 0xCC20CE9BD35C78A5, 0x98165AF37B2153DF, 0xE2A0B5DC971F303A,\n 0xA8D9D1535CE3B396, 0xFB9B7CD9A4A7443C, 0xBB764C4CA7A44410, 0x8BAB8EEFB6409C1A,\n 0xD01FEF10A657842C, 0x9B10A4E5E9913129, 0xE7109BFBA19C0C9D, 0xAC2820D9623BF429,\n 0x80444B5E7AA7CF85, 0xBF21E44003ACDD2D, 0x8E679C2F5E44FF8F, 0xD433179D9C8CB841,\n 0x9E19DB92B4E31BA9, 0xEB96BF6EBADF77D9, 0xAF87023B9BF0EE6B\n]);\n\n// @ts-ignore: decorator\n@inline\nexport function isPowerOf2(value: T): bool {\n return popcnt(value) == 1;\n}\n\n// Count number of decimals for u32 values\n// In our case input value always non-zero so we can simplify some parts\nexport function decimalCount32(value: u32): u32 {\n if (value < 100000) {\n if (value < 100) {\n return 1 + u32(value >= 10);\n } else {\n return 3 + u32(value >= 10000) + u32(value >= 1000);\n }\n } else {\n if (value < 10000000) {\n return 6 + u32(value >= 1000000);\n } else {\n return 8 + u32(value >= 1000000000) + u32(value >= 100000000);\n }\n }\n}\n\n// Count number of decimals for u64 values\n// In our case input value always greater than 2^32-1 so we can skip some parts\nexport function decimalCount64High(value: u64): u32 {\n if (value < 1000000000000000) {\n if (value < 1000000000000) {\n return 10 + u32(value >= 100000000000) + u32(value >= 10000000000);\n } else {\n return 13 + u32(value >= 100000000000000) + u32(value >= 10000000000000);\n }\n } else {\n if (value < 100000000000000000) {\n return 16 + u32(value >= 10000000000000000);\n } else {\n return 18 + u32(value >= 10000000000000000000) + u32(value >= 1000000000000000000);\n }\n }\n}\n\nfunction ulog_base(num: u64, base: i32): u32 {\n if (isPowerOf2(base)) {\n return (63 - clz(num)) / (31 - clz(base)) + 1;\n }\n let b64 = u64(base), b = b64, e: u32 = 1;\n while (num >= b) {\n num /= b;\n b *= b;\n e <<= 1;\n }\n while (num >= 1) {\n num /= b64;\n e++;\n }\n return e - 1;\n}\n\nfunction utoa32_dec_lut(buffer: usize, num: u32, offset: usize): void {\n while (num >= 10000) {\n // in most VMs i32/u32 div and modulo by constant can be shared and simplificate\n let t = num / 10000;\n let r = num % 10000;\n num = t;\n\n let d1 = r / 100;\n let d2 = r % 100;\n\n let digits1 = load(DIGITS + (d1 << alignof()));\n let digits2 = load(DIGITS + (d2 << alignof()));\n\n offset -= 4;\n store(buffer + (offset << 1), digits1 | (digits2 << 32));\n }\n\n if (num >= 100) {\n let t = num / 100;\n let d1 = num % 100;\n num = t;\n offset -= 2;\n let digits = load(DIGITS + (d1 << alignof()));\n store(buffer + (offset << 1), digits);\n }\n\n if (num >= 10) {\n offset -= 2;\n let digits = load(DIGITS + (num << alignof()));\n store(buffer + (offset << 1), digits);\n } else {\n offset -= 1;\n let digit = CharCode._0 + num;\n store(buffer + (offset << 1), digit);\n }\n}\n\nfunction utoa64_dec_lut(buffer: usize, num: u64, offset: usize): void {\n while (num >= 100000000) {\n let t = num / 100000000;\n let r = (num - t * 100000000);\n num = t;\n\n let b = r / 10000;\n let c = r % 10000;\n\n let b1 = b / 100;\n let b2 = b % 100;\n let c1 = c / 100;\n let c2 = c % 100;\n\n let digits1 = load(DIGITS + (c1 << alignof()));\n let digits2 = load(DIGITS + (c2 << alignof()));\n\n offset -= 4;\n store(buffer + (offset << 1), digits1 | (digits2 << 32));\n\n digits1 = load(DIGITS + (b1 << alignof()));\n digits2 = load(DIGITS + (b2 << alignof()));\n\n offset -= 4;\n store(buffer + (offset << 1), digits1 | (digits2 << 32));\n }\n\n utoa32_dec_lut(buffer, num, offset);\n}\n\nfunction utoa_hex_lut(buffer: usize, num: u64, offset: usize): void {\n const lut = changetype(HEX_DIGITS);\n while (offset >= 2) {\n offset -= 2;\n store(\n buffer + (offset << 1),\n load(lut + ((num & 0xFF) << alignof()))\n );\n num >>= 8;\n }\n if (offset & 1) {\n store(buffer, load(lut + (num << 6)));\n }\n}\n\nfunction utoa_dec_simple(buffer: usize, num: T, offset: usize): void {\n do {\n let t = num / 10;\n let r = (num % 10);\n num = changetype(t);\n offset--;\n store(buffer + (offset << 1), CharCode._0 + r);\n } while (num);\n}\n\nfunction utoa_hex_simple(buffer: usize, num: T, offset: usize): void {\n do {\n let d = num & 0x0F | CharCode._0;\n d += select(0x27, 0, d > CharCode._9);\n offset--;\n store(buffer + (offset << 1), d);\n // @ts-ignore: type\n num >>= 4;\n } while (num);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function utoa32_dec_core(buffer: usize, num: u32, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_dec_simple(buffer, num, offset);\n } else {\n utoa32_dec_lut(buffer, num, offset);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction utoa32_hex_core(buffer: usize, num: u32, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_hex_simple(buffer, num, offset);\n } else {\n utoa_hex_lut(buffer, num, offset);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction utoa64_dec_core(buffer: usize, num: u64, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_dec_simple(buffer, num, offset);\n } else {\n utoa64_dec_lut(buffer, num, offset);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction utoa64_hex_core(buffer: usize, num: u64, offset: usize): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n utoa_hex_simple(buffer, num, offset);\n } else {\n utoa_hex_lut(buffer, num, offset);\n }\n}\n\nfunction utoa64_any_core(buffer: usize, num: u64, offset: usize, radix: i32): void {\n const lut = changetype(ANY_DIGITS);\n let base = u64(radix);\n if ((radix & (radix - 1)) == 0) { // for radix which pow of two\n let shift = u64(ctz(radix) & 7);\n let mask = base - 1;\n do {\n offset--;\n store(buffer + (offset << 1), load(lut + (usize(num & mask) << 1)));\n num >>= shift;\n } while (num);\n } else {\n do {\n offset--;\n let q = num / base;\n store(buffer + (offset << 1), load(lut + (usize(num - q * base) << 1)));\n num = q;\n } while (num);\n }\n}\n\nexport function utoa32(value: u32, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n let out: String;\n\n if (radix == 10) {\n let decimals = decimalCount32(value);\n out = changetype(__new(decimals << 1, idof()));\n utoa32_dec_core(changetype(out), value, decimals);\n } else if (radix == 16) {\n let decimals = (31 - clz(value) >> 2) + 1;\n out = changetype(__new(decimals << 1, idof()));\n utoa32_hex_core(changetype(out), value, decimals);\n } else {\n let decimals = ulog_base(value, radix);\n out = changetype(__new(decimals << 1, idof()));\n utoa64_any_core(changetype(out), value, decimals, radix);\n }\n return out;\n}\n\nexport function itoa32(value: i32, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n\n let sign = (value >>> 31) << 1;\n if (sign) value = -value;\n let out: String;\n\n if (radix == 10) {\n let decimals = decimalCount32(value);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa32_dec_core(changetype(out) + sign, value, decimals);\n } else if (radix == 16) {\n let decimals = (31 - clz(value) >> 2) + 1;\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa32_hex_core(changetype(out) + sign, value, decimals);\n } else {\n let val32 = u32(value);\n let decimals = ulog_base(val32, radix);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_any_core(changetype(out) + sign, val32, decimals, radix);\n }\n if (sign) store(changetype(out), CharCode.MINUS);\n return out;\n}\n\nexport function utoa64(value: u64, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n let out: String;\n\n if (radix == 10) {\n if (value <= u32.MAX_VALUE) {\n let val32 = value;\n let decimals = decimalCount32(val32);\n out = changetype(__new(decimals << 1, idof()));\n utoa32_dec_core(changetype(out), val32, decimals);\n } else {\n let decimals = decimalCount64High(value);\n out = changetype(__new(decimals << 1, idof()));\n utoa64_dec_core(changetype(out), value, decimals);\n }\n } else if (radix == 16) {\n let decimals = (63 - u32(clz(value)) >> 2) + 1;\n out = changetype(__new(decimals << 1, idof()));\n utoa64_hex_core(changetype(out), value, decimals);\n } else {\n let decimals = ulog_base(value, radix);\n out = changetype(__new(decimals << 1, idof()));\n utoa64_any_core(changetype(out), value, decimals, radix);\n }\n return out;\n}\n\nexport function itoa64(value: i64, radix: i32): String {\n if (radix < 2 || radix > 36) {\n throw new RangeError(\"toString() radix argument must be between 2 and 36\");\n }\n if (!value) return \"0\";\n\n let sign = u32(value >>> 63) << 1;\n if (sign) value = -value;\n let out: String;\n\n if (radix == 10) {\n if (value <= u32.MAX_VALUE) {\n let val32 = value;\n let decimals = decimalCount32(val32);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa32_dec_core(changetype(out) + sign, val32, decimals);\n } else {\n let decimals = decimalCount64High(value);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_dec_core(changetype(out) + sign, value, decimals);\n }\n } else if (radix == 16) {\n let decimals = (63 - u32(clz(value)) >> 2) + 1;\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_hex_core(changetype(out) + sign, value, decimals);\n } else {\n let decimals = ulog_base(value, radix);\n out = changetype(__new((decimals << 1) + sign, idof()));\n utoa64_any_core(changetype(out) + sign, value, decimals, radix);\n }\n if (sign) store(changetype(out), CharCode.MINUS);\n return out;\n}\n\n// @ts-ignore: decorator\n@lazy let _K: i32 = 0;\n\n// // @ts-ignore: decorator\n// @lazy\n// let _frc: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _exp: i32 = 0;\n\n// @ts-ignore: decorator\n@lazy let _frc_minus: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _frc_plus: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _frc_pow: u64 = 0;\n\n// @ts-ignore: decorator\n@lazy let _exp_pow: i32 = 0;\n\n// @ts-ignore: decorator\n@inline\nfunction umul64f(u: u64, v: u64): u64 {\n let u0 = u & 0xFFFFFFFF;\n let v0 = v & 0xFFFFFFFF;\n\n let u1 = u >> 32;\n let v1 = v >> 32;\n\n let l = u0 * v0;\n let t = u1 * v0 + (l >> 32);\n let w = u0 * v1 + (t & 0xFFFFFFFF);\n\n w += 0x7FFFFFFF; // rounding\n\n t >>= 32;\n w >>= 32;\n\n return u1 * v1 + t + w;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction umul64e(e1: i32, e2: i32): i32 {\n return e1 + e2 + 64; // where 64 is significand size\n}\n\n// @ts-ignore: decorator\n@inline\nfunction normalizedBoundaries(f: u64, e: i32): void {\n let frc = (f << 1) + 1;\n let exp = e - 1;\n let off = clz(frc);\n frc <<= off;\n exp -= off;\n\n let m = 1 + i32(f == 0x0010000000000000);\n\n _frc_plus = frc;\n _frc_minus = ((f << m) - 1) << e - m - exp;\n _exp = exp;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction grisuRound(buffer: usize, len: i32, delta: u64, rest: u64, ten_kappa: u64, wp_w: u64): void {\n let lastp = buffer + ((len - 1) << 1);\n let digit = load(lastp);\n while (\n rest < wp_w &&\n delta - rest >= ten_kappa && (\n rest + ten_kappa < wp_w ||\n wp_w - rest > rest + ten_kappa - wp_w\n )\n ) {\n --digit;\n rest += ten_kappa;\n }\n store(lastp, digit);\n}\n\n// @ts-ignore: decorator\n@inline\nfunction getCachedPower(minExp: i32): void {\n const c = reinterpret(0x3FD34413509F79FE); // 1 / lg(10) = 0.30102999566398114\n let dk = (-61 - minExp) * c + 347;\t // dk must be positive, so can do ceiling in positive\n let k = dk;\n k += i32(k != dk); // conversion with ceil\n\n let index = (k >> 3) + 1;\n _K = 348 - (index << 3);\t// decimal exponent no need lookup table\n _frc_pow = load(FRC_POWERS + (index << alignof()));\n _exp_pow = load(EXP_POWERS + (index << alignof()));\n}\n\n// @ts-ignore: decorator\n@inline\nfunction grisu2(value: f64, buffer: usize, sign: i32): i32 {\n\n // frexp routine\n let uv = reinterpret(value);\n let exp = i32((uv & 0x7FF0000000000000) >>> 52);\n let sid = uv & 0x000FFFFFFFFFFFFF;\n let frc = (u64(exp != 0) << 52) + sid;\n exp = select(exp, 1, exp) - (0x3FF + 52);\n\n normalizedBoundaries(frc, exp);\n getCachedPower(_exp);\n\n // normalize\n let off = clz(frc);\n frc <<= off;\n exp -= off;\n\n let frc_pow = _frc_pow;\n let exp_pow = _exp_pow;\n\n let w_frc = umul64f(frc, frc_pow);\n let w_exp = umul64e(exp, exp_pow);\n\n let wp_frc = umul64f(_frc_plus, frc_pow) - 1;\n let wp_exp = umul64e(_exp, exp_pow);\n\n let wm_frc = umul64f(_frc_minus, frc_pow) + 1;\n let delta = wp_frc - wm_frc;\n\n return genDigits(buffer, w_frc, w_exp, wp_frc, wp_exp, delta, sign);\n}\n\nfunction genDigits(buffer: usize, w_frc: u64, w_exp: i32, mp_frc: u64, mp_exp: i32, delta: u64, sign: i32): i32 {\n let one_exp = -mp_exp;\n let one_frc = (1) << one_exp;\n let mask = one_frc - 1;\n\n let wp_w_frc = mp_frc - w_frc;\n\n let p1 = u32(mp_frc >> one_exp);\n let p2 = mp_frc & mask;\n\n let kappa = decimalCount32(p1);\n let len = sign;\n\n while (kappa > 0) {\n let d: u32;\n switch (kappa) {\n case 10: { d = p1 / 1000000000; p1 %= 1000000000; break; }\n case 9: { d = p1 / 100000000; p1 %= 100000000; break; }\n case 8: { d = p1 / 10000000; p1 %= 10000000; break; }\n case 7: { d = p1 / 1000000; p1 %= 1000000; break; }\n case 6: { d = p1 / 100000; p1 %= 100000; break; }\n case 5: { d = p1 / 10000; p1 %= 10000; break; }\n case 4: { d = p1 / 1000; p1 %= 1000; break; }\n case 3: { d = p1 / 100; p1 %= 100; break; }\n case 2: { d = p1 / 10; p1 %= 10; break; }\n case 1: { d = p1; p1 = 0; break; }\n default: { d = 0; break; }\n }\n\n if (d | len) store(buffer + (len++ << 1), CharCode._0 + d);\n\n --kappa;\n let tmp = ((p1) << one_exp) + p2;\n if (tmp <= delta) {\n _K += kappa;\n grisuRound(buffer, len, delta, tmp, load(POWERS10 + (kappa << alignof())) << one_exp, wp_w_frc);\n return len;\n }\n }\n\n while (true) {\n p2 *= 10;\n delta *= 10;\n\n let d = p2 >> one_exp;\n if (d | len) store(buffer + (len++ << 1), CharCode._0 + d);\n\n p2 &= mask;\n --kappa;\n if (p2 < delta) {\n _K += kappa;\n wp_w_frc *= load(POWERS10 + (-kappa << alignof()));\n grisuRound(buffer, len, delta, p2, one_frc, wp_w_frc);\n return len;\n }\n }\n}\n\n// @ts-ignore: decorator\n@inline\nfunction genExponent(buffer: usize, k: i32): i32 {\n let sign = k < 0;\n if (sign) k = -k;\n let decimals = decimalCount32(k) + 1;\n utoa32_dec_core(buffer, k, decimals);\n store(buffer, select(CharCode.MINUS, CharCode.PLUS, sign));\n return decimals;\n}\n\nfunction prettify(buffer: usize, length: i32, k: i32): i32 {\n if (!k) {\n store(buffer + (length << 1), CharCode.DOT | (CharCode._0 << 16));\n return length + 2;\n }\n\n let kk = length + k;\n if (length <= kk && kk <= 21) {\n // 1234e7 -> 12340000000\n for (let i = length; i < kk; ++i) {\n store(buffer + (i << 1), CharCode._0);\n }\n store(buffer + (kk << 1), CharCode.DOT | (CharCode._0 << 16));\n return kk + 2;\n } else if (kk > 0 && kk <= 21) {\n // 1234e-2 -> 12.34\n let ptr = buffer + (kk << 1);\n memory.copy(\n ptr + 2,\n ptr,\n -k << 1\n );\n store(buffer + (kk << 1), CharCode.DOT);\n return length + 1;\n } else if (-6 < kk && kk <= 0) {\n // 1234e-6 -> 0.001234\n let offset = 2 - kk;\n memory.copy(\n buffer + (offset << 1),\n buffer,\n length << 1\n );\n store(buffer, CharCode._0 | (CharCode.DOT << 16));\n for (let i = 2; i < offset; ++i) {\n store(buffer + (i << 1), CharCode._0);\n }\n return length + offset;\n } else if (length == 1) {\n // 1e30\n store(buffer, CharCode.e, 2);\n length = genExponent(buffer + 4, kk - 1);\n return length + 2;\n } else {\n let len = length << 1;\n memory.copy(\n buffer + 4,\n buffer + 2,\n len - 2\n );\n store(buffer, CharCode.DOT, 2);\n store(buffer + len, CharCode.e, 2);\n length += genExponent(buffer + len + 4, kk - 1);\n return length + 2;\n }\n}\n\nfunction dtoa_core(buffer: usize, value: f64): i32 {\n let sign = i32(value < 0);\n if (sign) {\n value = -value;\n store(buffer, CharCode.MINUS);\n }\n // assert(value > 0 && value <= 1.7976931348623157e308);\n let len = grisu2(value, buffer, sign);\n len = prettify(buffer + (sign << 1), len - sign, _K);\n return len + sign;\n}\n\n// @ts-ignore: decorator\n@lazy @inline const dtoa_buf = memory.data(MAX_DOUBLE_LENGTH << 1);\n\nexport function dtoa(value: f64): String {\n if (value == 0) return \"0.0\";\n if (!isFinite(value)) {\n if (isNaN(value)) return \"NaN\";\n return select(\"-Infinity\", \"Infinity\", value < 0);\n }\n let size = dtoa_core(dtoa_buf, value) << 1;\n let result = changetype(__new(size, idof()));\n memory.copy(changetype(result), dtoa_buf, size);\n return result;\n}\n\nexport function itoa_buffered(buffer: usize, value: T): u32 {\n let sign: u32 = 0;\n if (isSigned()) {\n sign = u32(value < 0);\n if (sign) {\n if (sizeof() == 1) {\n if (value == -0x80) {\n // -0x80 -> -128\n store(buffer,\n CharCode.MINUS |\n (CharCode._0 + 1) << 16 |\n (CharCode._0 + 2) << 32 |\n (CharCode._0 + 8) << 48\n );\n return 4;\n }\n }\n if (sizeof() == 2) {\n if (value == -0x8000) {\n // -0x8000 -> -32768\n store(buffer,\n CharCode.MINUS |\n (CharCode._0 + 3) << 16 |\n (CharCode._0 + 2) << 32 |\n (CharCode._0 + 7) << 48\n ); // -327\n store(buffer + 8,\n (CharCode._0 + 6) << 0 |\n (CharCode._0 + 8) << 16\n ); // 68\n return 6;\n }\n }\n store(buffer, CharCode.MINUS);\n // @ts-ignore\n value = -value;\n }\n }\n let dest = buffer + (sign << 1);\n if (ASC_SHRINK_LEVEL <= 1) {\n if (isSigned()) {\n if (sizeof() <= 4) {\n if (value < 10) {\n store(dest, value | CharCode._0);\n return 1 + sign;\n }\n } else {\n if (value < 10) {\n store(dest, value | CharCode._0);\n return 1 + sign;\n }\n }\n } else {\n if (value < 10) {\n store(buffer, value | CharCode._0);\n return 1;\n }\n }\n }\n let decimals: u32 = 0;\n if (sizeof() <= 4) {\n let val32 = value;\n decimals = decimalCount32(val32);\n utoa32_dec_core(dest, val32, decimals);\n } else {\n if (value <= u32.MAX_VALUE) {\n let val32 = value;\n decimals = decimalCount32(val32);\n utoa32_dec_core(dest, val32, decimals);\n } else {\n let val64 = value;\n decimals = decimalCount64High(val64);\n utoa64_dec_core(dest, val64, decimals);\n }\n }\n return sign + decimals;\n}\n\nexport function dtoa_buffered(buffer: usize, value: f64): u32 {\n if (value == 0) {\n store(buffer, CharCode._0);\n store(buffer, CharCode.DOT, 2);\n store(buffer, CharCode._0, 4);\n return 3;\n }\n if (!isFinite(value)) {\n if (isNaN(value)) {\n store(buffer, CharCode.N);\n store(buffer, CharCode.a, 2);\n store(buffer, CharCode.N, 4);\n return 3;\n } else {\n let sign = value < 0;\n if (sign) {\n store(buffer, CharCode.MINUS); // -\n buffer += 2;\n }\n store(buffer, 0x690066006E0049, 0); // ifnI\n store(buffer, 0x7900740069006E, 8); // ytin\n return 8 + u32(sign);\n }\n }\n return dtoa_core(buffer, value);\n}\n","//\n// Lookup data for exp2f\n//\n\n// @ts-ignore: decorator\n@inline const EXP2F_TABLE_BITS = 5;\n\n// @ts-ignore: decorator\n@lazy @inline const EXP2F_DATA_TAB = memory.data([\n // exp2f_data_tab[i] = uint(2^(i/N)) - (i << 52-BITS)\n // used for computing 2^(k/N) for an int |k| < 150 N as\n // double(tab[k%N] + (k << 52-BITS))\n 0x3FF0000000000000, 0x3FEFD9B0D3158574, 0x3FEFB5586CF9890F, 0x3FEF9301D0125B51,\n 0x3FEF72B83C7D517B, 0x3FEF54873168B9AA, 0x3FEF387A6E756238, 0x3FEF1E9DF51FDEE1,\n 0x3FEF06FE0A31B715, 0x3FEEF1A7373AA9CB, 0x3FEEDEA64C123422, 0x3FEECE086061892D,\n 0x3FEEBFDAD5362A27, 0x3FEEB42B569D4F82, 0x3FEEAB07DD485429, 0x3FEEA47EB03A5585,\n 0x3FEEA09E667F3BCD, 0x3FEE9F75E8EC5F74, 0x3FEEA11473EB0187, 0x3FEEA589994CCE13,\n 0x3FEEACE5422AA0DB, 0x3FEEB737B0CDC5E5, 0x3FEEC49182A3F090, 0x3FEED503B23E255D,\n 0x3FEEE89F995AD3AD, 0x3FEEFF76F2FB5E47, 0x3FEF199BDD85529C, 0x3FEF3720DCEF9069,\n 0x3FEF5818DCFBA487, 0x3FEF7C97337B9B5F, 0x3FEFA4AFA2A490DA, 0x3FEFD0765B6E4540\n]);\n\n// ULP error: 0.502 (nearest rounding.)\n// Relative error: 1.69 * 2^-34 in [-1/64, 1/64] (before rounding.)\n// Wrong count: 168353 (all nearest rounding wrong results with fma.)\n// @ts-ignore: decorator\n@inline\nexport function exp2f_lut(x: f32): f32 {\n const\n N = 1 << EXP2F_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000) / N, // 0x1.8p+52\n Ox127f = reinterpret(0x7F000000);\n\n const\n C0 = reinterpret(0x3FAC6AF84B912394), // 0x1.c6af84b912394p-5\n C1 = reinterpret(0x3FCEBFCE50FAC4F3), // 0x1.ebfce50fac4f3p-3\n C2 = reinterpret(0x3FE62E42FF0C52D6); // 0x1.62e42ff0c52d6p-1\n\n let xd = x;\n let ix = reinterpret(x);\n let ux = ix >> 20 & 0x7FF;\n if (ux >= 0x430) {\n // |x| >= 128 or x is nan.\n if (ix == 0xFF800000) return 0; // x == -Inf -> 0\n if (ux >= 0x7F8) return x + x; // x == Inf/NaN -> Inf/NaN\n if (x > 0) return x * Ox127f; // x > 0 -> HugeVal (Owerflow)\n if (x <= -150) return 0; // x <= -150 -> 0 (Underflow)\n }\n\n // x = k/N + r with r in [-1/(2N), 1/(2N)] and int k.\n let kd = xd + shift;\n let ki = reinterpret(kd);\n let r = xd - (kd - shift);\n let t: u64, y: f64, s: f64;\n\n // exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1)\n t = load(EXP2F_DATA_TAB + ((ki & N_MASK) << alignof()));\n t += ki << (52 - EXP2F_TABLE_BITS);\n s = reinterpret(t);\n y = C2 * r + 1;\n y += (C0 * r + C1) * (r * r);\n y *= s;\n\n return y;\n}\n\n// ULP error: 0.502 (nearest rounding.)\n// Relative error: 1.69 * 2^-34 in [-ln2/64, ln2/64] (before rounding.)\n// Wrong count: 170635 (all nearest rounding wrong results with fma.)\n// @ts-ignore: decorator\n@inline\nexport function expf_lut(x: f32): f32 {\n const\n N = 1 << EXP2F_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000), // 0x1.8p+52\n InvLn2N = reinterpret(0x3FF71547652B82FE) * N, // 0x1.71547652b82fep+0\n Ox1p127f = reinterpret(0x7F000000);\n\n const\n C0 = reinterpret(0x3FAC6AF84B912394) / N / N / N, // 0x1.c6af84b912394p-5\n C1 = reinterpret(0x3FCEBFCE50FAC4F3) / N / N, // 0x1.ebfce50fac4f3p-3\n C2 = reinterpret(0x3FE62E42FF0C52D6) / N; // 0x1.62e42ff0c52d6p-1\n\n let xd = x;\n let ix = reinterpret(x);\n let ux = ix >> 20 & 0x7FF;\n if (ux >= 0x42B) {\n // |x| >= 88 or x is nan.\n if (ix == 0xFF800000) return 0; // x == -Inf -> 0\n if (ux >= 0x7F8) return x + x; // x == Inf/NaN -> Inf/NaN\n if (x > reinterpret(0x42B17217)) return x * Ox1p127f; // x > log(0x1p128) ~= 88.72 -> HugeVal (Owerflow)\n if (x < reinterpret(0xC2CFF1B4)) return 0; // x < log(0x1p-150) ~= -103.97 -> 0 (Underflow)\n }\n\n // x*N/Ln2 = k + r with r in [-1/2, 1/2] and int k.\n let z = InvLn2N * xd;\n\n // Round and convert z to int, the result is in [-150*N, 128*N] and\n // ideally ties-to-even rule is used, otherwise the magnitude of r\n // can be bigger which gives larger approximation error.\n let kd = (z + shift);\n let ki = reinterpret(kd);\n let r = z - (kd - shift);\n let s: f64, y: f64, t: u64;\n\n // exp(x) = 2^(k/N) * 2^(r/N) ~= s * (C0*r^3 + C1*r^2 + C2*r + 1)\n t = load(EXP2F_DATA_TAB + ((ki & N_MASK) << alignof()));\n t += ki << (52 - EXP2F_TABLE_BITS);\n s = reinterpret(t);\n z = C0 * r + C1;\n y = C2 * r + 1;\n y += z * (r * r);\n y *= s;\n\n return y;\n}\n\n//\n// Lookup data for log2f\n//\n\n// @ts-ignore: decorator\n@inline const LOG2F_TABLE_BITS = 4;\n\n// @ts-ignore: decorator\n@lazy @inline const LOG2F_DATA_TAB = memory.data([\n 0x3FF661EC79F8F3BE, 0xBFDEFEC65B963019, // 0x1.661ec79f8f3bep+0, -0x1.efec65b963019p-2,\n 0x3FF571ED4AAF883D, 0xBFDB0B6832D4FCA4, // 0x1.571ed4aaf883dp+0, -0x1.b0b6832d4fca4p-2,\n 0x3FF49539F0F010B0, 0xBFD7418B0A1FB77B, // 0x1.49539f0f010bp+0 , -0x1.7418b0a1fb77bp-2,\n 0x3FF3C995B0B80385, 0xBFD39DE91A6DCF7B, // 0x1.3c995b0b80385p+0, -0x1.39de91a6dcf7bp-2,\n 0x3FF30D190C8864A5, 0xBFD01D9BF3F2B631, // 0x1.30d190c8864a5p+0, -0x1.01d9bf3f2b631p-2,\n 0x3FF25E227B0B8EA0, 0xBFC97C1D1B3B7AF0, // 0x1.25e227b0b8eap+0 , -0x1.97c1d1b3b7afp-3 ,\n 0x3FF1BB4A4A1A343F, 0xBFC2F9E393AF3C9F, // 0x1.1bb4a4a1a343fp+0, -0x1.2f9e393af3c9fp-3,\n 0x3FF12358F08AE5BA, 0xBFB960CBBF788D5C, // 0x1.12358f08ae5bap+0, -0x1.960cbbf788d5cp-4,\n 0x3FF0953F419900A7, 0xBFAA6F9DB6475FCE, // 0x1.0953f419900a7p+0, -0x1.a6f9db6475fcep-5,\n 0x3FF0000000000000, 0, // 0x1p+0, 0x0,\n 0x3FEE608CFD9A47AC, 0x3FB338CA9F24F53D, // 0x1.e608cfd9a47acp-1, 0x1.338ca9f24f53dp-4,\n 0x3FECA4B31F026AA0, 0x3FC476A9543891BA, // 0x1.ca4b31f026aap-1 , 0x1.476a9543891bap-3,\n 0x3FEB2036576AFCE6, 0x3FCE840B4AC4E4D2, // 0x1.b2036576afce6p-1, 0x1.e840b4ac4e4d2p-3,\n 0x3FE9C2D163A1AA2D, 0x3FD40645F0C6651C, // 0x1.9c2d163a1aa2dp-1, 0x1.40645f0c6651cp-2,\n 0x3FE886E6037841ED, 0x3FD88E9C2C1B9FF8, // 0x1.886e6037841edp-1, 0x1.88e9c2c1b9ff8p-2,\n 0x3FE767DCF5534862, 0x3FDCE0A44EB17BCC // 0x1.767dcf5534862p-1, 0x1.ce0a44eb17bccp-2\n]);\n\n// ULP error: 0.752 (nearest rounding.)\n// Relative error: 1.9 * 2^-26 (before rounding.)\n// @ts-ignore: decorator\n@inline\nexport function log2f_lut(x: f32): f32 {\n const\n N_MASK = (1 << LOG2F_TABLE_BITS) - 1,\n Ox1p23f = reinterpret(0x4B000000); // 0x1p23f\n\n const\n A0 = reinterpret(0xBFD712B6F70A7E4D), // -0x1.712b6f70a7e4dp-2\n A1 = reinterpret(0x3FDECABF496832E0), // 0x1.ecabf496832ep-2\n A2 = reinterpret(0xBFE715479FFAE3DE), // -0x1.715479ffae3dep-1\n A3 = reinterpret(0x3FF715475F35C8B8); // 0x1.715475f35c8b8p0\n\n let ux = reinterpret(x);\n // Fix sign of zero with downward rounding when x==1.\n // if (WANT_ROUNDING && predict_false(ix == 0x3f800000)) return 0;\n if (ux - 0x00800000 >= 0x7F800000 - 0x00800000) {\n // x < 0x1p-126 or inf or nan.\n if (ux * 2 == 0) return -Infinity;\n if (ux == 0x7F800000) return x; // log2(inf) == inf.\n if ((ux >> 31) || ux * 2 >= 0xFF000000) return (x - x) / (x - x);\n // x is subnormal, normalize it.\n ux = reinterpret(x * Ox1p23f);\n ux -= 23 << 23;\n }\n // x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ux - 0x3F330000;\n let i = (tmp >> (23 - LOG2F_TABLE_BITS)) & N_MASK;\n let top = tmp & 0xFF800000;\n let iz = ux - top;\n let k = tmp >> 23;\n\n let invc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 0 << alignof());\n let logc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 1 << alignof());\n let z = reinterpret(iz);\n\n // log2(x) = log1p(z/c-1)/ln2 + log2(c) + k\n let r = z * invc - 1;\n let y0 = logc + k;\n\n // Pipelined polynomial evaluation to approximate log1p(r)/ln2.\n let y = A1 * r + A2;\n let p = A3 * r + y0;\n let r2 = r * r;\n y += A0 * r2;\n y = y * r2 + p;\n\n return y;\n}\n\n//\n// Lookup data for logf. See: https://git.musl-libc.org/cgit/musl/tree/src/math/logf.c\n//\n\n// @ts-ignore: decorator\n@inline const LOGF_TABLE_BITS = 4;\n\n// @ts-ignore: decorator\n@lazy @inline const LOGF_DATA_TAB = memory.data([\n 0x3FF661EC79F8F3BE, 0xBFD57BF7808CAADE, // 0x1.661ec79f8f3bep+0, -0x1.57bf7808caadep-2,\n 0x3FF571ED4AAF883D, 0xBFD2BEF0A7C06DDB, // 0x1.571ed4aaf883dp+0, -0x1.2bef0a7c06ddbp-2,\n 0x3FF49539F0F010B0, 0xBFD01EAE7F513A67, // 0x1.49539f0f010bp+0 , -0x1.01eae7f513a67p-2,\n 0x3FF3C995B0B80385, 0xBFCB31D8A68224E9, // 0x1.3c995b0b80385p+0, -0x1.b31d8a68224e9p-3,\n 0x3FF30D190C8864A5, 0xBFC6574F0AC07758, // 0x1.30d190c8864a5p+0, -0x1.6574f0ac07758p-3,\n 0x3FF25E227B0B8EA0, 0xBFC1AA2BC79C8100, // 0x1.25e227b0b8eap+0 , -0x1.1aa2bc79c81p-3 ,\n 0x3FF1BB4A4A1A343F, 0xBFBA4E76CE8C0E5E, // 0x1.1bb4a4a1a343fp+0, -0x1.a4e76ce8c0e5ep-4,\n 0x3FF12358F08AE5BA, 0xBFB1973C5A611CCC, // 0x1.12358f08ae5bap+0, -0x1.1973c5a611cccp-4,\n 0x3FF0953F419900A7, 0xBFA252F438E10C1E, // 0x1.0953f419900a7p+0, -0x1.252f438e10c1ep-5,\n 0x3FF0000000000000, 0, // 0x1p+0, 0,\n 0x3FEE608CFD9A47AC, 0x3FAAA5AA5DF25984, // 0x1.e608cfd9a47acp-1, 0x1.aa5aa5df25984p-5,\n 0x3FECA4B31F026AA0, 0x3FBC5E53AA362EB4, // 0x1.ca4b31f026aap-1 , 0x1.c5e53aa362eb4p-4,\n 0x3FEB2036576AFCE6, 0x3FC526E57720DB08, // 0x1.b2036576afce6p-1, 0x1.526e57720db08p-3,\n 0x3FE9C2D163A1AA2D, 0x3FCBC2860D224770, // 0x1.9c2d163a1aa2dp-1, 0x1.bc2860d22477p-3 ,\n 0x3FE886E6037841ED, 0x3FD1058BC8A07EE1, // 0x1.886e6037841edp-1, 0x1.1058bc8a07ee1p-2,\n 0x3FE767DCF5534862, 0x3FD4043057B6EE09 // 0x1.767dcf5534862p-1, 0x1.4043057b6ee09p-2\n]);\n\n// ULP error: 0.818 (nearest rounding.)\n// Relative error: 1.957 * 2^-26 (before rounding.)\n// @ts-ignore: decorator\n@inline\nexport function logf_lut(x: f32): f32 {\n const\n N_MASK = (1 << LOGF_TABLE_BITS) - 1,\n Ox1p23f = reinterpret(0x4B000000); // 0x1p23f\n\n const\n Ln2 = reinterpret(0x3FE62E42FEFA39EF), // 0x1.62e42fefa39efp-1;\n A0 = reinterpret(0xBFD00EA348B88334), // -0x1.00ea348b88334p-2\n A1 = reinterpret(0x3FD5575B0BE00B6A), // 0x1.5575b0be00b6ap-2\n A2 = reinterpret(0xBFDFFFFEF20A4123); // -0x1.ffffef20a4123p-2\n\n let ux = reinterpret(x);\n // Fix sign of zero with downward rounding when x==1.\n // if (WANT_ROUNDING && ux == 0x3f800000) return 0;\n if (ux - 0x00800000 >= 0x7F800000 - 0x00800000) {\n // x < 0x1p-126 or inf or nan.\n if ((ux << 1) == 0) return -Infinity;\n if (ux == 0x7F800000) return x; // log(inf) == inf.\n if ((ux >> 31) || (ux << 1) >= 0xFF000000) return (x - x) / (x - x);\n // x is subnormal, normalize it.\n ux = reinterpret(x * Ox1p23f);\n ux -= 23 << 23;\n }\n // x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ux - 0x3F330000;\n let i = (tmp >> (23 - LOGF_TABLE_BITS)) & N_MASK;\n let k = tmp >> 23;\n let iz = ux - (tmp & 0x1FF << 23);\n\n let invc = load(LOGF_DATA_TAB + (i << (1 + alignof())), 0 << alignof());\n let logc = load(LOGF_DATA_TAB + (i << (1 + alignof())), 1 << alignof());\n\n let z = reinterpret(iz);\n\n // log(x) = log1p(z/c-1) + log(c) + k*Ln2\n let r = z * invc - 1;\n let y0 = logc + k * Ln2;\n\n // Pipelined polynomial evaluation to approximate log1p(r).\n let r2 = r * r;\n let y = A1 * r + A2;\n y += A0 * r2;\n y = y * r2 + (y0 + r);\n\n return y;\n}\n\n//\n// Lookup data for powf. See: https://git.musl-libc.org/cgit/musl/tree/src/math/powf.c\n//\n\n// @ts-ignore: decorator\n@inline\nfunction zeroinfnanf(ux: u32): bool {\n return (ux << 1) - 1 >= (0x7f800000 << 1) - 1;\n}\n\n// Returns 0 if not int, 1 if odd int, 2 if even int. The argument is\n// the bit representation of a non-zero finite floating-point value.\n// @ts-ignore: decorator\n@inline\nfunction checkintf(iy: u32): i32 {\n let e = iy >> 23 & 0xFF;\n if (e < 0x7F ) return 0;\n if (e > 0x7F + 23) return 2;\n e = 1 << (0x7F + 23 - e);\n if (iy & (e - 1)) return 0;\n if (iy & e ) return 1;\n return 2;\n}\n\n// Subnormal input is normalized so ix has negative biased exponent.\n// Output is multiplied by N (POWF_SCALE) if TOINT_INTRINICS is set.\n// @ts-ignore: decorator\n@inline\nfunction log2f_inline(ux: u32): f64 {\n const N_MASK = (1 << LOG2F_TABLE_BITS) - 1;\n\n const\n A0 = reinterpret(0x3FD27616C9496E0B), // 0x1.27616c9496e0bp-2\n A1 = reinterpret(0xBFD71969A075C67A), // -0x1.71969a075c67ap-2\n A2 = reinterpret(0x3FDEC70A6CA7BADD), // 0x1.ec70a6ca7baddp-2\n A3 = reinterpret(0xBFE7154748BEF6C8), // -0x1.7154748bef6c8p-1\n A4 = reinterpret(0x3FF71547652AB82B); // 0x1.71547652ab82bp+0\n\n // x = 2^k z; where z is in range [OFF,2*OFF] and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ux - 0x3F330000;\n let i = usize((tmp >> (23 - LOG2F_TABLE_BITS)) & N_MASK);\n let top = tmp & 0xFF800000;\n let uz = ux - top;\n let k = top >> 23;\n\n let invc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 0 << alignof());\n let logc = load(LOG2F_DATA_TAB + (i << (1 + alignof())), 1 << alignof());\n let z = reinterpret(uz);\n\n // log2(x) = log1p(z/c-1)/ln2 + log2(c) + k\n let r = z * invc - 1;\n let y0 = logc + k;\n\n // Pipelined polynomial evaluation to approximate log1p(r)/ln2.\n let y = A0 * r + A1;\n let p = A2 * r + A3;\n let q = A4 * r + y0;\n\n r *= r;\n q += p * r;\n y = y * (r * r) + q;\n\n return y;\n}\n\n// The output of log2 and thus the input of exp2 is either scaled by N\n// (in case of fast toint intrinsics) or not. The unscaled xd must be\n// in [-1021,1023], sign_bias sets the sign of the result.\n// @ts-ignore: decorator\n@inline\nfunction exp2f_inline(xd: f64, signBias: u32): f32 {\n const\n N = 1 << EXP2F_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000) / N; // 0x1.8p+52\n\n const\n C0 = reinterpret(0x3FAC6AF84B912394), // 0x1.c6af84b912394p-5\n C1 = reinterpret(0x3FCEBFCE50FAC4F3), // 0x1.ebfce50fac4f3p-3\n C2 = reinterpret(0x3FE62E42FF0C52D6); // 0x1.62e42ff0c52d6p-1\n\n // x = k/N + r with r in [-1/(2N), 1/(2N)]\n let kd = (xd + shift);\n let ki = reinterpret(kd);\n let r = xd - (kd - shift);\n let t: u64, z: f64, y: f64, s: f64;\n\n // exp2(x) = 2^(k/N) * 2^r ~= s * (C0*r^3 + C1*r^2 + C2*r + 1)\n t = load(EXP2F_DATA_TAB + ((ki & N_MASK) << alignof()));\n t += (ki + signBias) << (52 - EXP2F_TABLE_BITS);\n s = reinterpret(t);\n z = C0 * r + C1;\n y = C2 * r + 1;\n y += z * (r * r);\n y *= s;\n return y;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction xflowf(sign: u32, y: f32): f32 {\n return select(-y, y, sign) * y;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction oflowf(sign: u32): f32 {\n return xflowf(sign, reinterpret(0x70000000)); // 0x1p97f\n}\n\n// @ts-ignore: decorator\n@inline\nfunction uflowf(sign: u32): f32 {\n return xflowf(sign, reinterpret(0x10000000)); // 0x1p-95f\n}\n\n// @ts-ignore: decorator\n@inline\nexport function powf_lut(x: f32, y: f32): f32 {\n const\n Ox1p23f = reinterpret(0x4B000000), // 0x1p23f\n UPPER_LIMIT = reinterpret(0x405FFFFFFFD1D571), // 0x1.fffffffd1d571p+6\n LOWER_LIMIT = -150.0,\n SIGN_BIAS = 1 << (EXP2F_TABLE_BITS + 11);\n\n let signBias: u32 = 0;\n let ix = reinterpret(x);\n let iy = reinterpret(y);\n let ny = 0;\n\n if (i32(ix - 0x00800000 >= 0x7f800000 - 0x00800000) | (ny = i32(zeroinfnanf(iy)))) {\n // Either (x < 0x1p-126 or inf or nan) or (y is 0 or inf or nan).\n if (ny) {\n if ((iy << 1) == 0) return 1.0;\n if (ix == 0x3F800000) return NaN; // original: 1.0\n if ((ix << 1) > (0x7F800000 << 1) || (iy << 1) > (0x7F800000 << 1)) return x + y;\n if ((ix << 1) == (0x3F800000 << 1)) return NaN; // original: 1.0\n if (((ix << 1) < (0x3F800000 << 1)) == !(iy >> 31)) return 0; // |x| < 1 && y==inf or |x| > 1 && y==-inf.\n return y * y;\n }\n if (zeroinfnanf(ix)) {\n let x2 = x * x;\n if ((ix >> 31) && checkintf(iy) == 1) x2 = -x2;\n return iy < 0 ? 1 / x2 : x2;\n }\n // x and y are non-zero finite.\n if (ix < 0) {\n // Finite x < 0.\n let yint = checkintf(iy);\n if (yint == 0) return (x - x) / (x - x);\n if (yint == 1) signBias = SIGN_BIAS;\n ix &= 0x7FFFFFFF;\n }\n if (ix < 0x00800000) {\n // Normalize subnormal x so exponent becomes negative.\n ix = reinterpret(x * Ox1p23f);\n ix &= 0x7FFFFFFF;\n ix -= 23 << 23;\n }\n }\n let logx = log2f_inline(ix);\n let ylogx = y * logx; // cannot overflow, y is single prec.\n if ((reinterpret(ylogx) >> 47 & 0xFFFF) >= 0x80BF) { // reinterpret(126.0) >> 47\n // |y * log(x)| >= 126\n if (ylogx > UPPER_LIMIT) return oflowf(signBias); // overflow\n if (ylogx <= LOWER_LIMIT) return uflowf(signBias); // underflow\n }\n return exp2f_inline(ylogx, signBias);\n}\n\n//\n// Lookup data for exp. See: https://git.musl-libc.org/cgit/musl/tree/src/math/exp.c\n//\n\n// @ts-ignore: decorator\n@inline const EXP_TABLE_BITS = 7;\n\n// @ts-ignore: decorator\n@lazy @inline const EXP_DATA_TAB = memory.data([\n 0x0000000000000000, 0x3FF0000000000000,\n 0x3C9B3B4F1A88BF6E, 0x3FEFF63DA9FB3335,\n 0xBC7160139CD8DC5D, 0x3FEFEC9A3E778061,\n 0xBC905E7A108766D1, 0x3FEFE315E86E7F85,\n 0x3C8CD2523567F613, 0x3FEFD9B0D3158574,\n 0xBC8BCE8023F98EFA, 0x3FEFD06B29DDF6DE,\n 0x3C60F74E61E6C861, 0x3FEFC74518759BC8,\n 0x3C90A3E45B33D399, 0x3FEFBE3ECAC6F383,\n 0x3C979AA65D837B6D, 0x3FEFB5586CF9890F,\n 0x3C8EB51A92FDEFFC, 0x3FEFAC922B7247F7,\n 0x3C3EBE3D702F9CD1, 0x3FEFA3EC32D3D1A2,\n 0xBC6A033489906E0B, 0x3FEF9B66AFFED31B,\n 0xBC9556522A2FBD0E, 0x3FEF9301D0125B51,\n 0xBC5080EF8C4EEA55, 0x3FEF8ABDC06C31CC,\n 0xBC91C923B9D5F416, 0x3FEF829AAEA92DE0,\n 0x3C80D3E3E95C55AF, 0x3FEF7A98C8A58E51,\n 0xBC801B15EAA59348, 0x3FEF72B83C7D517B,\n 0xBC8F1FF055DE323D, 0x3FEF6AF9388C8DEA,\n 0x3C8B898C3F1353BF, 0x3FEF635BEB6FCB75,\n 0xBC96D99C7611EB26, 0x3FEF5BE084045CD4,\n 0x3C9AECF73E3A2F60, 0x3FEF54873168B9AA,\n 0xBC8FE782CB86389D, 0x3FEF4D5022FCD91D,\n 0x3C8A6F4144A6C38D, 0x3FEF463B88628CD6,\n 0x3C807A05B0E4047D, 0x3FEF3F49917DDC96,\n 0x3C968EFDE3A8A894, 0x3FEF387A6E756238,\n 0x3C875E18F274487D, 0x3FEF31CE4FB2A63F,\n 0x3C80472B981FE7F2, 0x3FEF2B4565E27CDD,\n 0xBC96B87B3F71085E, 0x3FEF24DFE1F56381,\n 0x3C82F7E16D09AB31, 0x3FEF1E9DF51FDEE1,\n 0xBC3D219B1A6FBFFA, 0x3FEF187FD0DAD990,\n 0x3C8B3782720C0AB4, 0x3FEF1285A6E4030B,\n 0x3C6E149289CECB8F, 0x3FEF0CAFA93E2F56,\n 0x3C834D754DB0ABB6, 0x3FEF06FE0A31B715,\n 0x3C864201E2AC744C, 0x3FEF0170FC4CD831,\n 0x3C8FDD395DD3F84A, 0x3FEEFC08B26416FF,\n 0xBC86A3803B8E5B04, 0x3FEEF6C55F929FF1,\n 0xBC924AEDCC4B5068, 0x3FEEF1A7373AA9CB,\n 0xBC9907F81B512D8E, 0x3FEEECAE6D05D866,\n 0xBC71D1E83E9436D2, 0x3FEEE7DB34E59FF7,\n 0xBC991919B3CE1B15, 0x3FEEE32DC313A8E5,\n 0x3C859F48A72A4C6D, 0x3FEEDEA64C123422,\n 0xBC9312607A28698A, 0x3FEEDA4504AC801C,\n 0xBC58A78F4817895B, 0x3FEED60A21F72E2A,\n 0xBC7C2C9B67499A1B, 0x3FEED1F5D950A897,\n 0x3C4363ED60C2AC11, 0x3FEECE086061892D,\n 0x3C9666093B0664EF, 0x3FEECA41ED1D0057,\n 0x3C6ECCE1DAA10379, 0x3FEEC6A2B5C13CD0,\n 0x3C93FF8E3F0F1230, 0x3FEEC32AF0D7D3DE,\n 0x3C7690CEBB7AAFB0, 0x3FEEBFDAD5362A27,\n 0x3C931DBDEB54E077, 0x3FEEBCB299FDDD0D,\n 0xBC8F94340071A38E, 0x3FEEB9B2769D2CA7,\n 0xBC87DECCDC93A349, 0x3FEEB6DAA2CF6642,\n 0xBC78DEC6BD0F385F, 0x3FEEB42B569D4F82,\n 0xBC861246EC7B5CF6, 0x3FEEB1A4CA5D920F,\n 0x3C93350518FDD78E, 0x3FEEAF4736B527DA,\n 0x3C7B98B72F8A9B05, 0x3FEEAD12D497C7FD,\n 0x3C9063E1E21C5409, 0x3FEEAB07DD485429,\n 0x3C34C7855019C6EA, 0x3FEEA9268A5946B7,\n 0x3C9432E62B64C035, 0x3FEEA76F15AD2148,\n 0xBC8CE44A6199769F, 0x3FEEA5E1B976DC09,\n 0xBC8C33C53BEF4DA8, 0x3FEEA47EB03A5585,\n 0xBC845378892BE9AE, 0x3FEEA34634CCC320,\n 0xBC93CEDD78565858, 0x3FEEA23882552225,\n 0x3C5710AA807E1964, 0x3FEEA155D44CA973,\n 0xBC93B3EFBF5E2228, 0x3FEEA09E667F3BCD,\n 0xBC6A12AD8734B982, 0x3FEEA012750BDABF,\n 0xBC6367EFB86DA9EE, 0x3FEE9FB23C651A2F,\n 0xBC80DC3D54E08851, 0x3FEE9F7DF9519484,\n 0xBC781F647E5A3ECF, 0x3FEE9F75E8EC5F74,\n 0xBC86EE4AC08B7DB0, 0x3FEE9F9A48A58174,\n 0xBC8619321E55E68A, 0x3FEE9FEB564267C9,\n 0x3C909CCB5E09D4D3, 0x3FEEA0694FDE5D3F,\n 0xBC7B32DCB94DA51D, 0x3FEEA11473EB0187,\n 0x3C94ECFD5467C06B, 0x3FEEA1ED0130C132,\n 0x3C65EBE1ABD66C55, 0x3FEEA2F336CF4E62,\n 0xBC88A1C52FB3CF42, 0x3FEEA427543E1A12,\n 0xBC9369B6F13B3734, 0x3FEEA589994CCE13,\n 0xBC805E843A19FF1E, 0x3FEEA71A4623C7AD,\n 0xBC94D450D872576E, 0x3FEEA8D99B4492ED,\n 0x3C90AD675B0E8A00, 0x3FEEAAC7D98A6699,\n 0x3C8DB72FC1F0EAB4, 0x3FEEACE5422AA0DB,\n 0xBC65B6609CC5E7FF, 0x3FEEAF3216B5448C,\n 0x3C7BF68359F35F44, 0x3FEEB1AE99157736,\n 0xBC93091FA71E3D83, 0x3FEEB45B0B91FFC6,\n 0xBC5DA9B88B6C1E29, 0x3FEEB737B0CDC5E5,\n 0xBC6C23F97C90B959, 0x3FEEBA44CBC8520F,\n 0xBC92434322F4F9AA, 0x3FEEBD829FDE4E50,\n 0xBC85CA6CD7668E4B, 0x3FEEC0F170CA07BA,\n 0x3C71AFFC2B91CE27, 0x3FEEC49182A3F090,\n 0x3C6DD235E10A73BB, 0x3FEEC86319E32323,\n 0xBC87C50422622263, 0x3FEECC667B5DE565,\n 0x3C8B1C86E3E231D5, 0x3FEED09BEC4A2D33,\n 0xBC91BBD1D3BCBB15, 0x3FEED503B23E255D,\n 0x3C90CC319CEE31D2, 0x3FEED99E1330B358,\n 0x3C8469846E735AB3, 0x3FEEDE6B5579FDBF,\n 0xBC82DFCD978E9DB4, 0x3FEEE36BBFD3F37A,\n 0x3C8C1A7792CB3387, 0x3FEEE89F995AD3AD,\n 0xBC907B8F4AD1D9FA, 0x3FEEEE07298DB666,\n 0xBC55C3D956DCAEBA, 0x3FEEF3A2B84F15FB,\n 0xBC90A40E3DA6F640, 0x3FEEF9728DE5593A,\n 0xBC68D6F438AD9334, 0x3FEEFF76F2FB5E47,\n 0xBC91EEE26B588A35, 0x3FEF05B030A1064A,\n 0x3C74FFD70A5FDDCD, 0x3FEF0C1E904BC1D2,\n 0xBC91BDFBFA9298AC, 0x3FEF12C25BD71E09,\n 0x3C736EAE30AF0CB3, 0x3FEF199BDD85529C,\n 0x3C8EE3325C9FFD94, 0x3FEF20AB5FFFD07A,\n 0x3C84E08FD10959AC, 0x3FEF27F12E57D14B,\n 0x3C63CDAF384E1A67, 0x3FEF2F6D9406E7B5,\n 0x3C676B2C6C921968, 0x3FEF3720DCEF9069,\n 0xBC808A1883CCB5D2, 0x3FEF3F0B555DC3FA,\n 0xBC8FAD5D3FFFFA6F, 0x3FEF472D4A07897C,\n 0xBC900DAE3875A949, 0x3FEF4F87080D89F2,\n 0x3C74A385A63D07A7, 0x3FEF5818DCFBA487,\n 0xBC82919E2040220F, 0x3FEF60E316C98398,\n 0x3C8E5A50D5C192AC, 0x3FEF69E603DB3285,\n 0x3C843A59AC016B4B, 0x3FEF7321F301B460,\n 0xBC82D52107B43E1F, 0x3FEF7C97337B9B5F,\n 0xBC892AB93B470DC9, 0x3FEF864614F5A129,\n 0x3C74B604603A88D3, 0x3FEF902EE78B3FF6,\n 0x3C83C5EC519D7271, 0x3FEF9A51FBC74C83,\n 0xBC8FF7128FD391F0, 0x3FEFA4AFA2A490DA,\n 0xBC8DAE98E223747D, 0x3FEFAF482D8E67F1,\n 0x3C8EC3BC41AA2008, 0x3FEFBA1BEE615A27,\n 0x3C842B94C3A9EB32, 0x3FEFC52B376BBA97,\n 0x3C8A64A931D185EE, 0x3FEFD0765B6E4540,\n 0xBC8E37BAE43BE3ED, 0x3FEFDBFDAD9CBE14,\n 0x3C77893B4D91CD9D, 0x3FEFE7C1819E90D8,\n 0x3C5305C14160CC89, 0x3FEFF3C22B8F71F1\n]);\n\n// Handle cases that may overflow or underflow when computing the result that\n// is scale*(1+TMP) without intermediate rounding. The bit representation of\n// scale is in SBITS, however it has a computed exponent that may have\n// overflown into the sign bit so that needs to be adjusted before using it as\n// a double. (int32_t)KI is the k used in the argument reduction and exponent\n// adjustment of scale, positive k here means the result may overflow and\n// negative k means the result may underflow.\n// @ts-ignore: decorator\n@inline\nfunction specialcase(tmp: f64, sbits: u64, ki: u64): f64 {\n const\n Ox1p_1022 = reinterpret(0x0010000000000000), // 0x1p-1022\n Ox1p1009 = reinterpret(0x7F00000000000000); // 0x1p1009\n\n let scale: f64;\n if (!(ki & 0x80000000)) {\n // k > 0, the exponent of scale might have overflowed by <= 460.\n sbits -= u64(1009) << 52;\n scale = reinterpret(sbits);\n return Ox1p1009 * (scale + scale * tmp); // 0x1p1009\n }\n // k < 0, need special care in the subnormal range.\n sbits += u64(1022) << 52;\n // Note: sbits is signed scale.\n scale = reinterpret(sbits);\n let y = scale + scale * tmp;\n if (abs(y) < 1.0) {\n // Round y to the right precision before scaling it into the subnormal\n // range to avoid double rounding that can cause 0.5+E/2 ulp error where\n // E is the worst-case ulp error outside the subnormal range. So this\n // is only useful if the goal is better than 1 ulp worst-case error.\n let one = copysign(1.0, y);\n let lo = scale - y + scale * tmp;\n let hi = one + y;\n lo = one - hi + y + lo;\n y = (hi + lo) - one;\n // Fix the sign of 0.\n if (y == 0.0) y = reinterpret(sbits & 0x8000000000000000);\n }\n return y * Ox1p_1022;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function exp_lut(x: f64): f64 {\n const\n N = 1 << EXP_TABLE_BITS,\n N_MASK = N - 1;\n\n const\n InvLn2N = reinterpret(0x3FF71547652B82FE) * N, // 0x1.71547652b82fep0\n NegLn2hiN = reinterpret(0xBF762E42FEFA0000), // -0x1.62e42fefa0000p-8\n NegLn2loN = reinterpret(0xBD0CF79ABC9E3B3A), // -0x1.cf79abc9e3b3ap-47\n shift = reinterpret(0x4338000000000000); // 0x1.8p52;\n\n const\n C2 = reinterpret(0x3FDFFFFFFFFFFDBD), // __exp_data.poly[0] (0x1.ffffffffffdbdp-2)\n C3 = reinterpret(0x3FC555555555543C), // __exp_data.poly[1] (0x1.555555555543cp-3)\n C4 = reinterpret(0x3FA55555CF172B91), // __exp_data.poly[2] (0x1.55555cf172b91p-5)\n C5 = reinterpret(0x3F81111167A4D017); // __exp_data.poly[3] (0x1.1111167a4d017p-7)\n\n let ux = reinterpret(x);\n let abstop = u32(ux >> 52) & 0x7FF;\n if (abstop - 0x3C9 >= 0x03F) {\n if (abstop - 0x3C9 >= 0x80000000) return 1;\n if (abstop >= 0x409) {\n if (ux == 0xFFF0000000000000) return 0;\n if (abstop >= 0x7FF) {\n return 1.0 + x;\n } else {\n return select(0, Infinity, ux < 0);\n }\n }\n // Large x is special cased below.\n abstop = 0;\n }\n\n // exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)]\n // x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N]\n let z = InvLn2N * x;\n // #if TOINT_INTRINSICS\n // \tkd = roundtoint(z);\n // \tki = converttoint(z);\n // #elif EXP_USE_TOINT_NARROW\n // \t// z - kd is in [-0.5-2^-16, 0.5] in all rounding modes.\n // let kd = z + shift;\n // let ki = reinterpret(kd) >> 16;\n // let kd = ki;\n // #else\n // z - kd is in [-1, 1] in non-nearest rounding modes.\n let kd = z + shift;\n let ki = reinterpret(kd);\n kd -= shift;\n // #endif\n let r = x + kd * NegLn2hiN + kd * NegLn2loN;\n // 2^(k/N) ~= scale * (1 + tail).\n let idx = usize((ki & N_MASK) << 1);\n let top = ki << (52 - EXP_TABLE_BITS);\n\n let tail = reinterpret(load(EXP_DATA_TAB + (idx << alignof()))); // T[idx]\n // This is only a valid scale when -1023*N < k < 1024*N\n let sbits = load(EXP_DATA_TAB + (idx << alignof()), 1 << alignof()) + top; // T[idx + 1]\n // exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1).\n // Evaluation is optimized assuming superscalar pipelined execution.\n let r2 = r * r;\n // Without fma the worst case error is 0.25/N ulp larger.\n // Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp.\n let tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n if (abstop == 0) return specialcase(tmp, sbits, ki);\n let scale = reinterpret(sbits);\n // Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there\n // is no spurious underflow here even without fma.\n return scale + scale * tmp;\n}\n\n//\n// Lookup data for exp2. See: https://git.musl-libc.org/cgit/musl/tree/src/math/exp2.c\n//\n\n// Handle cases that may overflow or underflow when computing the result that\n// is scale*(1+TMP) without intermediate rounding. The bit representation of\n// scale is in SBITS, however it has a computed exponent that may have\n// overflown into the sign bit so that needs to be adjusted before using it as\n// a double. (int32_t)KI is the k used in the argument reduction and exponent\n// adjustment of scale, positive k here means the result may overflow and\n// negative k means the result may underflow.\n// @ts-ignore: decorator\n@inline\nfunction specialcase2(tmp: f64, sbits: u64, ki: u64): f64 {\n const Ox1p_1022 = reinterpret(0x10000000000000); // 0x1p-1022\n let scale: f64;\n if ((ki & 0x80000000) == 0) {\n // k > 0, the exponent of scale might have overflowed by 1\n sbits -= u64(1) << 52;\n scale = reinterpret(sbits);\n return 2 * (scale * tmp + scale);\n }\n // k < 0, need special care in the subnormal range\n sbits += u64(1022) << 52;\n scale = reinterpret(sbits);\n let y = scale * tmp + scale;\n if (y < 1.0) {\n // Round y to the right precision before scaling it into the subnormal\n // range to avoid double rounding that can cause 0.5+E/2 ulp error where\n // E is the worst-case ulp error outside the subnormal range. So this\n // is only useful if the goal is better than 1 ulp worst-case error.\n let hi: f64, lo: f64;\n lo = scale - y + scale * tmp;\n hi = 1.0 + y;\n lo = 1.0 - hi + y + lo;\n y = (hi + lo) - 1.0;\n }\n return y * Ox1p_1022;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function exp2_lut(x: f64): f64 {\n const\n N = 1 << EXP_TABLE_BITS,\n N_MASK = N - 1,\n shift = reinterpret(0x4338000000000000) / N; // 0x1.8p52\n\n const\n C1 = reinterpret(0x3FE62E42FEFA39EF), // 0x1.62e42fefa39efp-1\n C2 = reinterpret(0x3FCEBFBDFF82C424), // 0x1.ebfbdff82c424p-3\n C3 = reinterpret(0x3FAC6B08D70CF4B5), // 0x1.c6b08d70cf4b5p-5\n C4 = reinterpret(0x3F83B2ABD24650CC), // 0x1.3b2abd24650ccp-7\n C5 = reinterpret(0x3F55D7E09B4E3A84); // 0x1.5d7e09b4e3a84p-10\n\n let ux = reinterpret(x);\n let abstop = u32(ux >> 52) & 0x7ff;\n if (abstop - 0x3C9 >= 0x03F) {\n if (abstop - 0x3C9 >= 0x80000000) return 1.0;\n if (abstop >= 0x409) {\n if (ux == 0xFFF0000000000000) return 0;\n if (abstop >= 0x7FF) return 1.0 + x;\n if (ux >= 0) return Infinity;\n else if (ux >= 0xC090CC0000000000) return 0;\n }\n if ((ux << 1) > 0x811A000000000000) abstop = 0; // Large x is special cased below.\n }\n\n // exp2(x) = 2^(k/N) * 2^r, with 2^r in [2^(-1/2N),2^(1/2N)].\n // x = k/N + r, with int k and r in [-1/2N, 1/2N]\n let kd = x + shift;\n let ki = reinterpret(kd);\n kd -= shift; // k/N for int k\n let r = x - kd;\n // 2^(k/N) ~= scale * (1 + tail)\n let idx = usize((ki & N_MASK) << 1);\n let top = ki << (52 - EXP_TABLE_BITS);\n\n let tail = reinterpret(load(EXP_DATA_TAB + (idx << alignof()), 0 << alignof())); // T[idx])\n // This is only a valid scale when -1023*N < k < 1024*N\n let sbits = load(EXP_DATA_TAB + (idx << alignof()), 1 << alignof()) + top; // T[idx + 1]\n // exp2(x) = 2^(k/N) * 2^r ~= scale + scale * (tail + 2^r - 1).\n // Evaluation is optimized assuming superscalar pipelined execution\n let r2 = r * r;\n // Without fma the worst case error is 0.5/N ulp larger.\n // Worst case error is less than 0.5+0.86/N+(abs poly error * 2^53) ulp.\n let tmp = tail + r * C1 + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n if (abstop == 0) return specialcase2(tmp, sbits, ki);\n let scale = reinterpret(sbits);\n // Note: tmp == 0 or |tmp| > 2^-65 and scale > 2^-928, so there\n // is no spurious underflow here even without fma.\n return scale * tmp + scale;\n}\n\n//\n// Lookup data for log2. See: https://git.musl-libc.org/cgit/musl/tree/src/math/log2.c\n//\n\n// @ts-ignore: decorator\n@inline const LOG2_TABLE_BITS = 6;\n\n/* Algorithm:\n\n x = 2^k z\n log2(x) = k + log2(c) + log2(z/c)\n log2(z/c) = poly(z/c - 1)\n\nwhere z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls\ninto the ith one, then table entries are computed as\n\n tab[i].invc = 1/c\n tab[i].logc = (double)log2(c)\n tab2[i].chi = (double)c\n tab2[i].clo = (double)(c - (double)c)\n\nwhere c is near the center of the subinterval and is chosen by trying +-2^29\nfloating point invc candidates around 1/center and selecting one for which\n\n 1) the rounding error in 0x1.8p10 + logc is 0,\n 2) the rounding error in z - chi - clo is < 0x1p-64 and\n 3) the rounding error in (double)log2(c) is minimized (< 0x1p-68).\n\nNote: 1) ensures that k + logc can be computed without rounding error, 2)\nensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to a\nsingle rounding error when there is no fast fma for z*invc - 1, 3) ensures\nthat logc + poly(z/c - 1) has small error, however near x == 1 when\n|log2(x)| < 0x1p-4, this is not enough so that is special cased. */\n\n// @ts-ignore: decorator\n@lazy @inline const LOG2_DATA_TAB1 = memory.data([\n // invc , logc\n 0x3FF724286BB1ACF8, 0xBFE1095FEECDB000,\n 0x3FF6E1F766D2CCA1, 0xBFE08494BD76D000,\n 0x3FF6A13D0E30D48A, 0xBFE00143AEE8F800,\n 0x3FF661EC32D06C85, 0xBFDEFEC5360B4000,\n 0x3FF623FA951198F8, 0xBFDDFDD91AB7E000,\n 0x3FF5E75BA4CF026C, 0xBFDCFFAE0CC79000,\n 0x3FF5AC055A214FB8, 0xBFDC043811FDA000,\n 0x3FF571ED0F166E1E, 0xBFDB0B67323AE000,\n 0x3FF53909590BF835, 0xBFDA152F5A2DB000,\n 0x3FF5014FED61ADDD, 0xBFD9217F5AF86000,\n 0x3FF4CAB88E487BD0, 0xBFD8304DB0719000,\n 0x3FF49539B4334FEE, 0xBFD74189F9A9E000,\n 0x3FF460CBDFAFD569, 0xBFD6552BB5199000,\n 0x3FF42D664EE4B953, 0xBFD56B23A29B1000,\n 0x3FF3FB01111DD8A6, 0xBFD483650F5FA000,\n 0x3FF3C995B70C5836, 0xBFD39DE937F6A000,\n 0x3FF3991C4AB6FD4A, 0xBFD2BAA1538D6000,\n 0x3FF3698E0CE099B5, 0xBFD1D98340CA4000,\n 0x3FF33AE48213E7B2, 0xBFD0FA853A40E000,\n 0x3FF30D191985BDB1, 0xBFD01D9C32E73000,\n 0x3FF2E025CAB271D7, 0xBFCE857DA2FA6000,\n 0x3FF2B404CF13CD82, 0xBFCCD3C8633D8000,\n 0x3FF288B02C7CCB50, 0xBFCB26034C14A000,\n 0x3FF25E2263944DE5, 0xBFC97C1C2F4FE000,\n 0x3FF234563D8615B1, 0xBFC7D6023F800000,\n 0x3FF20B46E33EAF38, 0xBFC633A71A05E000,\n 0x3FF1E2EEFDCDA3DD, 0xBFC494F5E9570000,\n 0x3FF1BB4A580B3930, 0xBFC2F9E424E0A000,\n 0x3FF19453847F2200, 0xBFC162595AFDC000,\n 0x3FF16E06C0D5D73C, 0xBFBF9C9A75BD8000,\n 0x3FF1485F47B7E4C2, 0xBFBC7B575BF9C000,\n 0x3FF12358AD0085D1, 0xBFB960C60FF48000,\n 0x3FF0FEF00F532227, 0xBFB64CE247B60000,\n 0x3FF0DB2077D03A8F, 0xBFB33F78B2014000,\n 0x3FF0B7E6D65980D9, 0xBFB0387D1A42C000,\n 0x3FF0953EFE7B408D, 0xBFAA6F9208B50000,\n 0x3FF07325CAC53B83, 0xBFA47A954F770000,\n 0x3FF05197E40D1B5C, 0xBF9D23A8C50C0000,\n 0x3FF03091C1208EA2, 0xBF916A2629780000,\n 0x3FF0101025B37E21, 0xBF7720F8D8E80000,\n 0x3FEFC07EF9CAA76B, 0x3F86FE53B1500000,\n 0x3FEF4465D3F6F184, 0x3FA11CCCE10F8000,\n 0x3FEECC079F84107F, 0x3FAC4DFC8C8B8000,\n 0x3FEE573A99975AE8, 0x3FB3AA321E574000,\n 0x3FEDE5D6F0BD3DE6, 0x3FB918A0D08B8000,\n 0x3FED77B681FF38B3, 0x3FBE72E9DA044000,\n 0x3FED0CB5724DE943, 0x3FC1DCD2507F6000,\n 0x3FECA4B2DC0E7563, 0x3FC476AB03DEA000,\n 0x3FEC3F8EE8D6CB51, 0x3FC7074377E22000,\n 0x3FEBDD2B4F020C4C, 0x3FC98EDE8BA94000,\n 0x3FEB7D6C006015CA, 0x3FCC0DB86AD2E000,\n 0x3FEB20366E2E338F, 0x3FCE840AAFCEE000,\n 0x3FEAC57026295039, 0x3FD0790AB4678000,\n 0x3FEA6D01BC2731DD, 0x3FD1AC056801C000,\n 0x3FEA16D3BC3FF18B, 0x3FD2DB11D4FEE000,\n 0x3FE9C2D14967FEAD, 0x3FD406464EC58000,\n 0x3FE970E4F47C9902, 0x3FD52DBE093AF000,\n 0x3FE920FB3982BCF2, 0x3FD651902050D000,\n 0x3FE8D30187F759F1, 0x3FD771D2CDEAF000,\n 0x3FE886E5EBB9F66D, 0x3FD88E9C857D9000,\n 0x3FE83C97B658B994, 0x3FD9A80155E16000,\n 0x3FE7F405FFC61022, 0x3FDABE186ED3D000,\n 0x3FE7AD22181415CA, 0x3FDBD0F2AEA0E000,\n 0x3FE767DCF99EFF8C, 0x3FDCE0A43DBF4000\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const LOG2_DATA_TAB2 = memory.data([\n // chi , clo\n 0x3FE6200012B90A8E, 0x3C8904AB0644B605,\n 0x3FE66000045734A6, 0x3C61FF9BEA62F7A9,\n 0x3FE69FFFC325F2C5, 0x3C827ECFCB3C90BA,\n 0x3FE6E00038B95A04, 0x3C88FF8856739326,\n 0x3FE71FFFE09994E3, 0x3C8AFD40275F82B1,\n 0x3FE7600015590E10, 0xBC72FD75B4238341,\n 0x3FE7A00012655BD5, 0x3C7808E67C242B76,\n 0x3FE7E0003259E9A6, 0xBC6208E426F622B7,\n 0x3FE81FFFEDB4B2D2, 0xBC8402461EA5C92F,\n 0x3FE860002DFAFCC3, 0x3C6DF7F4A2F29A1F,\n 0x3FE89FFFF78C6B50, 0xBC8E0453094995FD,\n 0x3FE8E00039671566, 0xBC8A04F3BEC77B45,\n 0x3FE91FFFE2BF1745, 0xBC77FA34400E203C,\n 0x3FE95FFFCC5C9FD1, 0xBC76FF8005A0695D,\n 0x3FE9A0003BBA4767, 0x3C70F8C4C4EC7E03,\n 0x3FE9DFFFE7B92DA5, 0x3C8E7FD9478C4602,\n 0x3FEA1FFFD72EFDAF, 0xBC6A0C554DCDAE7E,\n 0x3FEA5FFFDE04FF95, 0x3C867DA98CE9B26B,\n 0x3FEA9FFFCA5E8D2B, 0xBC8284C9B54C13DE,\n 0x3FEADFFFDDAD03EA, 0x3C5812C8EA602E3C,\n 0x3FEB1FFFF10D3D4D, 0xBC8EFADDAD27789C,\n 0x3FEB5FFFCE21165A, 0x3C53CB1719C61237,\n 0x3FEB9FFFD950E674, 0x3C73F7D94194CE00,\n 0x3FEBE000139CA8AF, 0x3C750AC4215D9BC0,\n 0x3FEC20005B46DF99, 0x3C6BEEA653E9C1C9,\n 0x3FEC600040B9F7AE, 0xBC7C079F274A70D6,\n 0x3FECA0006255FD8A, 0xBC7A0B4076E84C1F,\n 0x3FECDFFFD94C095D, 0x3C88F933F99AB5D7,\n 0x3FED1FFFF975D6CF, 0xBC582C08665FE1BE,\n 0x3FED5FFFA2561C93, 0xBC7B04289BD295F3,\n 0x3FED9FFF9D228B0C, 0x3C870251340FA236,\n 0x3FEDE00065BC7E16, 0xBC75011E16A4D80C,\n 0x3FEE200002F64791, 0x3C89802F09EF62E0,\n 0x3FEE600057D7A6D8, 0xBC7E0B75580CF7FA,\n 0x3FEEA00027EDC00C, 0xBC8C848309459811,\n 0x3FEEE0006CF5CB7C, 0xBC8F8027951576F4,\n 0x3FEF2000782B7DCC, 0xBC8F81D97274538F,\n 0x3FEF6000260C450A, 0xBC4071002727FFDC,\n 0x3FEF9FFFE88CD533, 0xBC581BDCE1FDA8B0,\n 0x3FEFDFFFD50F8689, 0x3C87F91ACB918E6E,\n 0x3FF0200004292367, 0x3C9B7FF365324681,\n 0x3FF05FFFE3E3D668, 0x3C86FA08DDAE957B,\n 0x3FF0A0000A85A757, 0xBC57E2DE80D3FB91,\n 0x3FF0E0001A5F3FCC, 0xBC91823305C5F014,\n 0x3FF11FFFF8AFBAF5, 0xBC8BFABB6680BAC2,\n 0x3FF15FFFE54D91AD, 0xBC9D7F121737E7EF,\n 0x3FF1A00011AC36E1, 0x3C9C000A0516F5FF,\n 0x3FF1E00019C84248, 0xBC9082FBE4DA5DA0,\n 0x3FF220000FFE5E6E, 0xBC88FDD04C9CFB43,\n 0x3FF26000269FD891, 0x3C8CFE2A7994D182,\n 0x3FF2A00029A6E6DA, 0xBC700273715E8BC5,\n 0x3FF2DFFFE0293E39, 0x3C9B7C39DAB2A6F9,\n 0x3FF31FFFF7DCF082, 0x3C7DF1336EDC5254,\n 0x3FF35FFFF05A8B60, 0xBC9E03564CCD31EB,\n 0x3FF3A0002E0EAECC, 0x3C75F0E74BD3A477,\n 0x3FF3E000043BB236, 0x3C9C7DCB149D8833,\n 0x3FF4200002D187FF, 0x3C7E08AFCF2D3D28,\n 0x3FF460000D387CB1, 0x3C820837856599A6,\n 0x3FF4A00004569F89, 0xBC89FA5C904FBCD2,\n 0x3FF4E000043543F3, 0xBC781125ED175329,\n 0x3FF51FFFCC027F0F, 0x3C9883D8847754DC,\n 0x3FF55FFFFD87B36F, 0xBC8709E731D02807,\n 0x3FF59FFFF21DF7BA, 0x3C87F79F68727B02,\n 0x3FF5DFFFEBFC3481, 0xBC9180902E30E93E\n]);\n\n// @ts-ignore: decorator\n@inline\nexport function log2_lut(x: f64): f64 {\n const N_MASK = (1 << LOG2_TABLE_BITS) - 1;\n\n const\n LO: u64 = 0x3FEEA4AF00000000, // reinterpret(1.0 - 0x1.5b51p-5)\n HI: u64 = 0x3FF0B55900000000; // reinterpret(1.0 + 0x1.6ab2p-5)\n\n const\n InvLn2hi = reinterpret(0x3FF7154765200000), // 0x1.7154765200000p+0\n InvLn2lo = reinterpret(0x3DE705FC2EEFA200), // 0x1.705fc2eefa200p-33\n Ox1p52 = reinterpret(0x4330000000000000); // 0x1p52\n\n const\n B0 = reinterpret(0xBFE71547652B82FE), // -0x1.71547652b82fep-1\n B1 = reinterpret(0x3FDEC709DC3A03F7), // 0x1.ec709dc3a03f7p-2\n B2 = reinterpret(0xBFD71547652B7C3F), // -0x1.71547652b7c3fp-2\n B3 = reinterpret(0x3FD2776C50F05BE4), // 0x1.2776c50f05be4p-2\n B4 = reinterpret(0xBFCEC709DD768FE5), // -0x1.ec709dd768fe5p-3\n B5 = reinterpret(0x3FCA61761EC4E736), // 0x1.a61761ec4e736p-3\n B6 = reinterpret(0xBFC7153FBC64A79B), // -0x1.7153fbc64a79bp-3\n B7 = reinterpret(0x3FC484D154F01B4A), // 0x1.484d154f01b4ap-3\n B8 = reinterpret(0xBFC289E4A72C383C), // -0x1.289e4a72c383cp-3\n B9 = reinterpret(0x3FC0B32F285AEE66); // 0x1.0b32f285aee66p-3\n\n const\n A0 = reinterpret(0xBFE71547652B8339), // -0x1.71547652b8339p-1\n A1 = reinterpret(0x3FDEC709DC3A04BE), // 0x1.ec709dc3a04bep-2\n A2 = reinterpret(0xBFD7154764702FFB), // -0x1.7154764702ffbp-2\n A3 = reinterpret(0x3FD2776C50034C48), // 0x1.2776c50034c48p-2\n A4 = reinterpret(0xBFCEC7B328EA92BC), // -0x1.ec7b328ea92bcp-3\n A5 = reinterpret(0x3FCA6225E117F92E); // 0x1.a6225e117f92ep-3\n\n let ix = reinterpret(x);\n if (ix - LO < HI - LO) {\n let r = x - 1.0;\n // #if __FP_FAST_FMA\n // hi = r * InvLn2hi;\n // lo = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -hi);\n // #else\n let rhi = reinterpret(reinterpret(r) & 0xFFFFFFFF00000000);\n let rlo = r - rhi;\n let hi = rhi * InvLn2hi;\n let lo = rlo * InvLn2hi + r * InvLn2lo;\n // #endif\n let r2 = r * r; // rounding error: 0x1p-62\n let r4 = r2 * r2;\n // Worst-case error is less than 0.54 ULP (0.55 ULP without fma)\n let p = r2 * (B0 + r * B1);\n let y = hi + p;\n lo += hi - y + p;\n lo += r4 * (B2 + r * B3 + r2 * (B4 + r * B5) +\n r4 * (B6 + r * B7 + r2 * (B8 + r * B9)));\n return y + lo;\n }\n let top = u32(ix >> 48);\n if (top - 0x0010 >= 0x7ff0 - 0x0010) {\n // x < 0x1p-1022 or inf or nan.\n if ((ix << 1) == 0) return -1.0 / (x * x);\n if (ix == 0x7FF0000000000000) return x; // log(inf) == inf\n if ((top & 0x8000) || (top & 0x7FF0) == 0x7FF0) return (x - x) / (x - x);\n // x is subnormal, normalize it.\n ix = reinterpret(x * Ox1p52);\n ix -= u64(52) << 52;\n }\n\n // x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ix - 0x3FE6000000000000;\n let i = ((tmp >> (52 - LOG2_TABLE_BITS)) & N_MASK);\n let k = tmp >> 52;\n let iz = ix - (tmp & 0xFFF0000000000000);\n\n let invc = load(LOG2_DATA_TAB1 + (i << (1 + alignof())), 0 << alignof()); // T[i].invc;\n let logc = load(LOG2_DATA_TAB1 + (i << (1 + alignof())), 1 << alignof()); // T[i].logc;\n let z = reinterpret(iz);\n let kd = k;\n\n // log2(x) = log2(z/c) + log2(c) + k.\n // r ~= z/c - 1, |r| < 1/(2*N).\n // #if __FP_FAST_FMA\n // \t// rounding error: 0x1p-55/N.\n // \tr = __builtin_fma(z, invc, -1.0);\n // \tt1 = r * InvLn2hi;\n // \tt2 = r * InvLn2lo + __builtin_fma(r, InvLn2hi, -t1);\n // #else\n // rounding error: 0x1p-55/N + 0x1p-65.\n let chi = load(LOG2_DATA_TAB2 + (i << (1 + alignof())), 0 << alignof()); // T[i].chi;\n let clo = load(LOG2_DATA_TAB2 + (i << (1 + alignof())), 1 << alignof()); // T[i].clo;\n\n let r = (z - chi - clo) * invc;\n let rhi = reinterpret(reinterpret(r) & 0xFFFFFFFF00000000);\n let rlo = r - rhi;\n let t1 = rhi * InvLn2hi;\n let t2 = rlo * InvLn2hi + r * InvLn2lo;\n // #endif\n\n // hi + lo = r/ln2 + log2(c) + k\n let t3 = kd + logc;\n let hi = t3 + t1;\n let lo = t3 - hi + t1 + t2;\n\n // log2(r+1) = r/ln2 + r^2*poly(r)\n // Evaluation is optimized assuming superscalar pipelined execution\n let r2 = r * r; // rounding error: 0x1p-54/N^2\n // Worst-case error if |y| > 0x1p-4: 0.547 ULP (0.550 ULP without fma).\n // ~ 0.5 + 2/N/ln2 + abs-poly-error*0x1p56 ULP (+ 0.003 ULP without fma).\n let p = A0 + r * A1 + r2 * (A2 + r * A3) + (r2 * r2) * (A4 + r * A5);\n return lo + r2 * p + hi;\n}\n\n//\n// Lookup data for log. See: https://git.musl-libc.org/cgit/musl/tree/src/math/log.c\n//\n\n// @ts-ignore: decorator\n@inline const LOG_TABLE_BITS = 7;\n\n/* Algorithm:\n\n x = 2^k z\n log(x) = k ln2 + log(c) + log(z/c)\n log(z/c) = poly(z/c - 1)\n\nwhere z is in [1.6p-1; 1.6p0] which is split into N subintervals and z falls\ninto the ith one, then table entries are computed as\n\n tab[i].invc = 1/c\n tab[i].logc = (double)log(c)\n tab2[i].chi = (double)c\n tab2[i].clo = (double)(c - (double)c)\n\nwhere c is near the center of the subinterval and is chosen by trying +-2^29\nfloating point invc candidates around 1/center and selecting one for which\n\n 1) the rounding error in 0x1.8p9 + logc is 0,\n 2) the rounding error in z - chi - clo is < 0x1p-66 and\n 3) the rounding error in (double)log(c) is minimized (< 0x1p-66).\n\nNote: 1) ensures that k*ln2hi + logc can be computed without rounding error,\n2) ensures that z/c - 1 can be computed as (z - chi - clo)*invc with close to\na single rounding error when there is no fast fma for z*invc - 1, 3) ensures\nthat logc + poly(z/c - 1) has small error, however near x == 1 when\n|log(x)| < 0x1p-4, this is not enough so that is special cased.*/\n\n// @ts-ignore: decorator\n@lazy @inline const LOG_DATA_TAB1 = memory.data([\n // invc , logc\n 0x3FF734F0C3E0DE9F, 0xBFD7CC7F79E69000,\n 0x3FF713786A2CE91F, 0xBFD76FEEC20D0000,\n 0x3FF6F26008FAB5A0, 0xBFD713E31351E000,\n 0x3FF6D1A61F138C7D, 0xBFD6B85B38287800,\n 0x3FF6B1490BC5B4D1, 0xBFD65D5590807800,\n 0x3FF69147332F0CBA, 0xBFD602D076180000,\n 0x3FF6719F18224223, 0xBFD5A8CA86909000,\n 0x3FF6524F99A51ED9, 0xBFD54F4356035000,\n 0x3FF63356AA8F24C4, 0xBFD4F637C36B4000,\n 0x3FF614B36B9DDC14, 0xBFD49DA7FDA85000,\n 0x3FF5F66452C65C4C, 0xBFD445923989A800,\n 0x3FF5D867B5912C4F, 0xBFD3EDF439B0B800,\n 0x3FF5BABCCB5B90DE, 0xBFD396CE448F7000,\n 0x3FF59D61F2D91A78, 0xBFD3401E17BDA000,\n 0x3FF5805612465687, 0xBFD2E9E2EF468000,\n 0x3FF56397CEE76BD3, 0xBFD2941B3830E000,\n 0x3FF54725E2A77F93, 0xBFD23EC58CDA8800,\n 0x3FF52AFF42064583, 0xBFD1E9E129279000,\n 0x3FF50F22DBB2BDDF, 0xBFD1956D2B48F800,\n 0x3FF4F38F4734DED7, 0xBFD141679AB9F800,\n 0x3FF4D843CFDE2840, 0xBFD0EDD094EF9800,\n 0x3FF4BD3EC078A3C8, 0xBFD09AA518DB1000,\n 0x3FF4A27FC3E0258A, 0xBFD047E65263B800,\n 0x3FF4880524D48434, 0xBFCFEB224586F000,\n 0x3FF46DCE1B192D0B, 0xBFCF474A7517B000,\n 0x3FF453D9D3391854, 0xBFCEA4443D103000,\n 0x3FF43A2744B4845A, 0xBFCE020D44E9B000,\n 0x3FF420B54115F8FB, 0xBFCD60A22977F000,\n 0x3FF40782DA3EF4B1, 0xBFCCC00104959000,\n 0x3FF3EE8F5D57FE8F, 0xBFCC202956891000,\n 0x3FF3D5D9A00B4CE9, 0xBFCB81178D811000,\n 0x3FF3BD60C010C12B, 0xBFCAE2C9CCD3D000,\n 0x3FF3A5242B75DAB8, 0xBFCA45402E129000,\n 0x3FF38D22CD9FD002, 0xBFC9A877681DF000,\n 0x3FF3755BC5847A1C, 0xBFC90C6D69483000,\n 0x3FF35DCE49AD36E2, 0xBFC87120A645C000,\n 0x3FF34679984DD440, 0xBFC7D68FB4143000,\n 0x3FF32F5CCEFFCB24, 0xBFC73CB83C627000,\n 0x3FF3187775A10D49, 0xBFC6A39A9B376000,\n 0x3FF301C8373E3990, 0xBFC60B3154B7A000,\n 0x3FF2EB4EBB95F841, 0xBFC5737D76243000,\n 0x3FF2D50A0219A9D1, 0xBFC4DC7B8FC23000,\n 0x3FF2BEF9A8B7FD2A, 0xBFC4462C51D20000,\n 0x3FF2A91C7A0C1BAB, 0xBFC3B08ABC830000,\n 0x3FF293726014B530, 0xBFC31B996B490000,\n 0x3FF27DFA5757A1F5, 0xBFC2875490A44000,\n 0x3FF268B39B1D3BBF, 0xBFC1F3B9F879A000,\n 0x3FF2539D838FF5BD, 0xBFC160C8252CA000,\n 0x3FF23EB7AAC9083B, 0xBFC0CE7F57F72000,\n 0x3FF22A012BA940B6, 0xBFC03CDC49FEA000,\n 0x3FF2157996CC4132, 0xBFBF57BDBC4B8000,\n 0x3FF201201DD2FC9B, 0xBFBE370896404000,\n 0x3FF1ECF4494D480B, 0xBFBD17983EF94000,\n 0x3FF1D8F5528F6569, 0xBFBBF9674ED8A000,\n 0x3FF1C52311577E7C, 0xBFBADC79202F6000,\n 0x3FF1B17C74CB26E9, 0xBFB9C0C3E7288000,\n 0x3FF19E010C2C1AB6, 0xBFB8A646B372C000,\n 0x3FF18AB07BB670BD, 0xBFB78D01B3AC0000,\n 0x3FF1778A25EFBCB6, 0xBFB674F145380000,\n 0x3FF1648D354C31DA, 0xBFB55E0E6D878000,\n 0x3FF151B990275FDD, 0xBFB4485CDEA1E000,\n 0x3FF13F0EA432D24C, 0xBFB333D94D6AA000,\n 0x3FF12C8B7210F9DA, 0xBFB22079F8C56000,\n 0x3FF11A3028ECB531, 0xBFB10E4698622000,\n 0x3FF107FBDA8434AF, 0xBFAFFA6C6AD20000,\n 0x3FF0F5EE0F4E6BB3, 0xBFADDA8D4A774000,\n 0x3FF0E4065D2A9FCE, 0xBFABBCECE4850000,\n 0x3FF0D244632CA521, 0xBFA9A1894012C000,\n 0x3FF0C0A77CE2981A, 0xBFA788583302C000,\n 0x3FF0AF2F83C636D1, 0xBFA5715E67D68000,\n 0x3FF09DDB98A01339, 0xBFA35C8A49658000,\n 0x3FF08CABAF52E7DF, 0xBFA149E364154000,\n 0x3FF07B9F2F4E28FB, 0xBF9E72C082EB8000,\n 0x3FF06AB58C358F19, 0xBF9A55F152528000,\n 0x3FF059EEA5ECF92C, 0xBF963D62CF818000,\n 0x3FF04949CDD12C90, 0xBF9228FB8CAA0000,\n 0x3FF038C6C6F0ADA9, 0xBF8C317B20F90000,\n 0x3FF02865137932A9, 0xBF8419355DAA0000,\n 0x3FF0182427EA7348, 0xBF781203C2EC0000,\n 0x3FF008040614B195, 0xBF60040979240000,\n 0x3FEFE01FF726FA1A, 0x3F6FEFF384900000,\n 0x3FEFA11CC261EA74, 0x3F87DC41353D0000,\n 0x3FEF6310B081992E, 0x3F93CEA3C4C28000,\n 0x3FEF25F63CEEADCD, 0x3F9B9FC114890000,\n 0x3FEEE9C8039113E7, 0x3FA1B0D8CE110000,\n 0x3FEEAE8078CBB1AB, 0x3FA58A5BD001C000,\n 0x3FEE741AA29D0C9B, 0x3FA95C8340D88000,\n 0x3FEE3A91830A99B5, 0x3FAD276AEF578000,\n 0x3FEE01E009609A56, 0x3FB07598E598C000,\n 0x3FEDCA01E577BB98, 0x3FB253F5E30D2000,\n 0x3FED92F20B7C9103, 0x3FB42EDD8B380000,\n 0x3FED5CAC66FB5CCE, 0x3FB606598757C000,\n 0x3FED272CAA5EDE9D, 0x3FB7DA76356A0000,\n 0x3FECF26E3E6B2CCD, 0x3FB9AB434E1C6000,\n 0x3FECBE6DA2A77902, 0x3FBB78C7BB0D6000,\n 0x3FEC8B266D37086D, 0x3FBD431332E72000,\n 0x3FEC5894BD5D5804, 0x3FBF0A3171DE6000,\n 0x3FEC26B533BB9F8C, 0x3FC067152B914000,\n 0x3FEBF583EEECE73F, 0x3FC147858292B000,\n 0x3FEBC4FD75DB96C1, 0x3FC2266ECDCA3000,\n 0x3FEB951E0C864A28, 0x3FC303D7A6C55000,\n 0x3FEB65E2C5EF3E2C, 0x3FC3DFC33C331000,\n 0x3FEB374867C9888B, 0x3FC4BA366B7A8000,\n 0x3FEB094B211D304A, 0x3FC5933928D1F000,\n 0x3FEADBE885F2EF7E, 0x3FC66ACD2418F000,\n 0x3FEAAF1D31603DA2, 0x3FC740F8EC669000,\n 0x3FEA82E63FD358A7, 0x3FC815C0F51AF000,\n 0x3FEA5740EF09738B, 0x3FC8E92954F68000,\n 0x3FEA2C2A90AB4B27, 0x3FC9BB3602F84000,\n 0x3FEA01A01393F2D1, 0x3FCA8BED1C2C0000,\n 0x3FE9D79F24DB3C1B, 0x3FCB5B515C01D000,\n 0x3FE9AE2505C7B190, 0x3FCC2967CCBCC000,\n 0x3FE9852EF297CE2F, 0x3FCCF635D5486000,\n 0x3FE95CBAEEA44B75, 0x3FCDC1BD3446C000,\n 0x3FE934C69DE74838, 0x3FCE8C01B8CFE000,\n 0x3FE90D4F2F6752E6, 0x3FCF5509C0179000,\n 0x3FE8E6528EFFD79D, 0x3FD00E6C121FB800,\n 0x3FE8BFCE9FCC007C, 0x3FD071B80E93D000,\n 0x3FE899C0DABEC30E, 0x3FD0D46B9E867000,\n 0x3FE87427AA2317FB, 0x3FD13687334BD000,\n 0x3FE84F00ACB39A08, 0x3FD1980D67234800,\n 0x3FE82A49E8653E55, 0x3FD1F8FFE0CC8000,\n 0x3FE8060195F40260, 0x3FD2595FD7636800,\n 0x3FE7E22563E0A329, 0x3FD2B9300914A800,\n 0x3FE7BEB377DCB5AD, 0x3FD3187210436000,\n 0x3FE79BAA679725C2, 0x3FD377266DEC1800,\n 0x3FE77907F2170657, 0x3FD3D54FFBAF3000,\n 0x3FE756CADBD6130C, 0x3FD432EEE32FE000\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const LOG_DATA_TAB2 = memory.data([\n // chi , clo\n 0x3FE61000014FB66B, 0x3C7E026C91425B3C,\n 0x3FE63000034DB495, 0x3C8DBFEA48005D41,\n 0x3FE650000D94D478, 0x3C8E7FA786D6A5B7,\n 0x3FE67000074E6FAD, 0x3C61FCEA6B54254C,\n 0x3FE68FFFFEDF0FAE, 0xBC7C7E274C590EFD,\n 0x3FE6B0000763C5BC, 0xBC8AC16848DCDA01,\n 0x3FE6D0001E5CC1F6, 0x3C833F1C9D499311,\n 0x3FE6EFFFEB05F63E, 0xBC7E80041AE22D53,\n 0x3FE710000E869780, 0x3C7BFF6671097952,\n 0x3FE72FFFFC67E912, 0x3C8C00E226BD8724,\n 0x3FE74FFFDF81116A, 0xBC6E02916EF101D2,\n 0x3FE770000F679C90, 0xBC67FC71CD549C74,\n 0x3FE78FFFFA7EC835, 0x3C81BEC19EF50483,\n 0x3FE7AFFFFE20C2E6, 0xBC707E1729CC6465,\n 0x3FE7CFFFED3FC900, 0xBC808072087B8B1C,\n 0x3FE7EFFFE9261A76, 0x3C8DC0286D9DF9AE,\n 0x3FE81000049CA3E8, 0x3C897FD251E54C33,\n 0x3FE8300017932C8F, 0xBC8AFEE9B630F381,\n 0x3FE850000633739C, 0x3C89BFBF6B6535BC,\n 0x3FE87000204289C6, 0xBC8BBF65F3117B75,\n 0x3FE88FFFEBF57904, 0xBC89006EA23DCB57,\n 0x3FE8B00022BC04DF, 0xBC7D00DF38E04B0A,\n 0x3FE8CFFFE50C1B8A, 0xBC88007146FF9F05,\n 0x3FE8EFFFFC918E43, 0x3C83817BD07A7038,\n 0x3FE910001EFA5FC7, 0x3C893E9176DFB403,\n 0x3FE9300013467BB9, 0x3C7F804E4B980276,\n 0x3FE94FFFE6EE076F, 0xBC8F7EF0D9FF622E,\n 0x3FE96FFFDE3C12D1, 0xBC7082AA962638BA,\n 0x3FE98FFFF4458A0D, 0xBC87801B9164A8EF,\n 0x3FE9AFFFDD982E3E, 0xBC8740E08A5A9337,\n 0x3FE9CFFFED49FB66, 0x3C3FCE08C19BE000,\n 0x3FE9F00020F19C51, 0xBC8A3FAA27885B0A,\n 0x3FEA10001145B006, 0x3C74FF489958DA56,\n 0x3FEA300007BBF6FA, 0x3C8CBEAB8A2B6D18,\n 0x3FEA500010971D79, 0x3C88FECADD787930,\n 0x3FEA70001DF52E48, 0xBC8F41763DD8ABDB,\n 0x3FEA90001C593352, 0xBC8EBF0284C27612,\n 0x3FEAB0002A4F3E4B, 0xBC69FD043CFF3F5F,\n 0x3FEACFFFD7AE1ED1, 0xBC823EE7129070B4,\n 0x3FEAEFFFEE510478, 0x3C6A063EE00EDEA3,\n 0x3FEB0FFFDB650D5B, 0x3C5A06C8381F0AB9,\n 0x3FEB2FFFFEAACA57, 0xBC79011E74233C1D,\n 0x3FEB4FFFD995BADC, 0xBC79FF1068862A9F,\n 0x3FEB7000249E659C, 0x3C8AFF45D0864F3E,\n 0x3FEB8FFFF9871640, 0x3C7CFE7796C2C3F9,\n 0x3FEBAFFFD204CB4F, 0xBC63FF27EEF22BC4,\n 0x3FEBCFFFD2415C45, 0xBC6CFFB7EE3BEA21,\n 0x3FEBEFFFF86309DF, 0xBC814103972E0B5C,\n 0x3FEC0FFFE1B57653, 0x3C8BC16494B76A19,\n 0x3FEC2FFFF1FA57E3, 0xBC64FEEF8D30C6ED,\n 0x3FEC4FFFDCBFE424, 0xBC843F68BCEC4775,\n 0x3FEC6FFFED54B9F7, 0x3C847EA3F053E0EC,\n 0x3FEC8FFFEB998FD5, 0x3C7383068DF992F1,\n 0x3FECB0002125219A, 0xBC68FD8E64180E04,\n 0x3FECCFFFDD94469C, 0x3C8E7EBE1CC7EA72,\n 0x3FECEFFFEAFDC476, 0x3C8EBE39AD9F88FE,\n 0x3FED1000169AF82B, 0x3C757D91A8B95A71,\n 0x3FED30000D0FF71D, 0x3C89C1906970C7DA,\n 0x3FED4FFFEA790FC4, 0xBC580E37C558FE0C,\n 0x3FED70002EDC87E5, 0xBC7F80D64DC10F44,\n 0x3FED900021DC82AA, 0xBC747C8F94FD5C5C,\n 0x3FEDAFFFD86B0283, 0x3C8C7F1DC521617E,\n 0x3FEDD000296C4739, 0x3C88019EB2FFB153,\n 0x3FEDEFFFE54490F5, 0x3C6E00D2C652CC89,\n 0x3FEE0FFFCDABF694, 0xBC7F8340202D69D2,\n 0x3FEE2FFFDB52C8DD, 0x3C7B00C1CA1B0864,\n 0x3FEE4FFFF24216EF, 0x3C72FFA8B094AB51,\n 0x3FEE6FFFE88A5E11, 0xBC57F673B1EFBE59,\n 0x3FEE9000119EFF0D, 0xBC84808D5E0BC801,\n 0x3FEEAFFFDFA51744, 0x3C780006D54320B5,\n 0x3FEED0001A127FA1, 0xBC5002F860565C92,\n 0x3FEEF00007BABCC4, 0xBC8540445D35E611,\n 0x3FEF0FFFF57A8D02, 0xBC4FFB3139EF9105,\n 0x3FEF30001EE58AC7, 0x3C8A81ACF2731155,\n 0x3FEF4FFFF5823494, 0x3C8A3F41D4D7C743,\n 0x3FEF6FFFFCA94C6B, 0xBC6202F41C987875,\n 0x3FEF8FFFE1F9C441, 0x3C777DD1F477E74B,\n 0x3FEFAFFFD2E0E37E, 0xBC6F01199A7CA331,\n 0x3FEFD0001C77E49E, 0x3C7181EE4BCEACB1,\n 0x3FEFEFFFF7E0C331, 0xBC6E05370170875A,\n 0x3FF00FFFF465606E, 0xBC8A7EAD491C0ADA,\n 0x3FF02FFFF3867A58, 0xBC977F69C3FCB2E0,\n 0x3FF04FFFFDFC0D17, 0x3C97BFFE34CB945B,\n 0x3FF0700003CD4D82, 0x3C820083C0E456CB,\n 0x3FF08FFFF9F2CBE8, 0xBC6DFFDFBE37751A,\n 0x3FF0B000010CDA65, 0xBC913F7FAEE626EB,\n 0x3FF0D00001A4D338, 0x3C807DFA79489FF7,\n 0x3FF0EFFFFADAFDFD, 0xBC77040570D66BC0,\n 0x3FF110000BBAFD96, 0x3C8E80D4846D0B62,\n 0x3FF12FFFFAE5F45D, 0x3C9DBFFA64FD36EF,\n 0x3FF150000DD59AD9, 0x3C9A0077701250AE,\n 0x3FF170000F21559A, 0x3C8DFDF9E2E3DEEE,\n 0x3FF18FFFFC275426, 0x3C910030DC3B7273,\n 0x3FF1B000123D3C59, 0x3C997F7980030188,\n 0x3FF1CFFFF8299EB7, 0xBC65F932AB9F8C67,\n 0x3FF1EFFFF48AD400, 0x3C937FBF9DA75BEB,\n 0x3FF210000C8B86A4, 0x3C9F806B91FD5B22,\n 0x3FF2300003854303, 0x3C93FFC2EB9FBF33,\n 0x3FF24FFFFFBCF684, 0x3C7601E77E2E2E72,\n 0x3FF26FFFF52921D9, 0x3C7FFCBB767F0C61,\n 0x3FF2900014933A3C, 0xBC7202CA3C02412B,\n 0x3FF2B00014556313, 0xBC92808233F21F02,\n 0x3FF2CFFFEBFE523B, 0xBC88FF7E384FDCF2,\n 0x3FF2F0000BB8AD96, 0xBC85FF51503041C5,\n 0x3FF30FFFFB7AE2AF, 0xBC810071885E289D,\n 0x3FF32FFFFEAC5F7F, 0xBC91FF5D3FB7B715,\n 0x3FF350000CA66756, 0x3C957F82228B82BD,\n 0x3FF3700011FBF721, 0x3C8000BAC40DD5CC,\n 0x3FF38FFFF9592FB9, 0xBC943F9D2DB2A751,\n 0x3FF3B00004DDD242, 0x3C857F6B707638E1,\n 0x3FF3CFFFF5B2C957, 0x3C7A023A10BF1231,\n 0x3FF3EFFFEAB0B418, 0x3C987F6D66B152B0,\n 0x3FF410001532AFF4, 0x3C67F8375F198524,\n 0x3FF4300017478B29, 0x3C8301E672DC5143,\n 0x3FF44FFFE795B463, 0x3C89FF69B8B2895A,\n 0x3FF46FFFE80475E0, 0xBC95C0B19BC2F254,\n 0x3FF48FFFEF6FC1E7, 0x3C9B4009F23A2A72,\n 0x3FF4AFFFE5BEA704, 0xBC94FFB7BF0D7D45,\n 0x3FF4D000171027DE, 0xBC99C06471DC6A3D,\n 0x3FF4F0000FF03EE2, 0x3C977F890B85531C,\n 0x3FF5100012DC4BD1, 0x3C6004657166A436,\n 0x3FF530001605277A, 0xBC96BFCECE233209,\n 0x3FF54FFFECDB704C, 0xBC8902720505A1D7,\n 0x3FF56FFFEF5F54A9, 0x3C9BBFE60EC96412,\n 0x3FF5900017E61012, 0x3C887EC581AFEF90,\n 0x3FF5B00003C93E92, 0xBC9F41080ABF0CC0,\n 0x3FF5D0001D4919BC, 0xBC98812AFB254729,\n 0x3FF5EFFFE7B87A89, 0xBC947EB780ED6904\n]);\n\n// @ts-ignore: decorator\n@inline\nexport function log_lut(x: f64): f64 {\n const N_MASK = (1 << LOG_TABLE_BITS) - 1;\n\n const\n B0 = reinterpret(0xBFE0000000000000), // -0x1p-1\n B1 = reinterpret(0x3FD5555555555577), // 0x1.5555555555577p-2\n B2 = reinterpret(0xBFCFFFFFFFFFFDCB), // -0x1.ffffffffffdcbp-3\n B3 = reinterpret(0x3FC999999995DD0C), // 0x1.999999995dd0cp-3\n B4 = reinterpret(0xBFC55555556745A7), // -0x1.55555556745a7p-3\n B5 = reinterpret(0x3FC24924A344DE30), // 0x1.24924a344de3p-3\n B6 = reinterpret(0xBFBFFFFFA4423D65), // -0x1.fffffa4423d65p-4\n B7 = reinterpret(0x3FBC7184282AD6CA), // 0x1.c7184282ad6cap-4\n B8 = reinterpret(0xBFB999EB43B068FF), // -0x1.999eb43b068ffp-4\n B9 = reinterpret(0x3FB78182F7AFD085), // 0x1.78182f7afd085p-4\n B10 = reinterpret(0xBFB5521375D145CD); // -0x1.5521375d145cdp-4\n\n const\n A0 = reinterpret(0xBFE0000000000001), // -0x1.0000000000001p-1\n A1 = reinterpret(0x3FD555555551305B), // 0x1.555555551305bp-2\n A2 = reinterpret(0xBFCFFFFFFFEB4590), // -0x1.fffffffeb459p-3\n A3 = reinterpret(0x3FC999B324F10111), // 0x1.999b324f10111p-3\n A4 = reinterpret(0xBFC55575E506C89F); // -0x1.55575e506c89fp-3\n\n const\n LO: u64 = 0x3FEE000000000000,\n HI: u64 = 0x3FF1090000000000;\n\n const\n Ln2hi = reinterpret(0x3FE62E42FEFA3800), // 0x1.62e42fefa3800p-1\n Ln2lo = reinterpret(0x3D2EF35793C76730), // 0x1.ef35793c76730p-45\n Ox1p27 = reinterpret(0x41A0000000000000), // 0x1p27\n Ox1p52 = reinterpret(0x4330000000000000); // 0x1p52\n\n let ix = reinterpret(x);\n if (ix - LO < HI - LO) {\n let r = x - 1.0;\n let r2 = r * r;\n let r3 = r2 * r;\n let y =\n r3 * (B1 + r * B2 + r2 * B3 +\n r3 * (B4 + r * B5 + r2 * B6 +\n r3 * (B7 + r * B8 + r2 * B9 + r3 * B10)));\n // Worst-case error is around 0.507 ULP\n let w = r * Ox1p27;\n let rhi = r + w - w;\n let rlo = r - rhi;\n w = rhi * rhi * B0; // B[0] == -0.5\n let hi = r + w;\n let lo = r - hi + w;\n lo += B0 * rlo * (rhi + r);\n return y + lo + hi;\n }\n let top = u32(ix >> 48);\n if (top - 0x0010 >= 0x7FF0 - 0x0010) {\n // x < 0x1p-1022 or inf or nan\n if ((ix << 1) == 0) return -1.0 / (x * x);\n if (ix == reinterpret(Infinity)) return x; // log(inf) == inf\n if ((top & 0x8000) || (top & 0x7FF0) == 0x7FF0) return (x - x) / (x - x);\n // x is subnormal, normalize it\n ix = reinterpret(x * Ox1p52);\n ix -= u64(52) << 52;\n }\n\n // x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ix - 0x3FE6000000000000;\n let i = ((tmp >> (52 - LOG_TABLE_BITS)) & N_MASK);\n let k = tmp >> 52;\n let iz = ix - (tmp & (u64(0xFFF) << 52));\n\n let invc = load(LOG_DATA_TAB1 + (i << (1 + alignof())), 0 << alignof()); // T[i].invc;\n let logc = load(LOG_DATA_TAB1 + (i << (1 + alignof())), 1 << alignof()); // T[i].logc;\n let z = reinterpret(iz);\n\n // log(x) = log1p(z/c-1) + log(c) + k*Ln2.\n // r ~= z/c - 1, |r| < 1/(2*N)\n // #if __FP_FAST_FMA\n // \t// rounding error: 0x1p-55/N\n // \tr = __builtin_fma(z, invc, -1.0);\n // #else\n // rounding error: 0x1p-55/N + 0x1p-66\n const chi = load(LOG_DATA_TAB2 + (i << (1 + alignof())), 0 << alignof()); // T2[i].chi\n const clo = load(LOG_DATA_TAB2 + (i << (1 + alignof())), 1 << alignof()); // T2[i].clo\n let r = (z - chi - clo) * invc;\n // #endif\n let kd = k;\n\n // hi + lo = r + log(c) + k*Ln2\n let w = kd * Ln2hi + logc;\n let hi = w + r;\n let lo = w - hi + r + kd * Ln2lo;\n\n // log(x) = lo + (log1p(r) - r) + hi\n let r2 = r * r; // rounding error: 0x1p-54/N^2\n // Worst case error if |y| > 0x1p-5:\n // 0.5 + 4.13/N + abs-poly-error*2^57 ULP (+ 0.002 ULP without fma)\n // Worst case error if |y| > 0x1p-4:\n // 0.5 + 2.06/N + abs-poly-error*2^56 ULP (+ 0.001 ULP without fma).\n return lo + r2 * A0 + r * r2 * (A1 + r * A2 + r2 * (A3 + r * A4)) + hi;\n}\n\n//\n// Lookup data for pow. See: https://git.musl-libc.org/cgit/musl/tree/src/math/pow.c\n//\n\n// @ts-ignore: decorator\n@inline const POW_LOG_TABLE_BITS = 7;\n\n/* Algorithm:\n\n x = 2^k z\n log(x) = k ln2 + log(c) + log(z/c)\n log(z/c) = poly(z/c - 1)\n\nwhere z is in [0x1.69555p-1; 0x1.69555p0] which is split into N subintervals\nand z falls into the ith one, then table entries are computed as\n\n tab[i].invc = 1/c\n tab[i].logc = round(0x1p43*log(c))/0x1p43\n tab[i].logctail = (double)(log(c) - logc)\n\nwhere c is chosen near the center of the subinterval such that 1/c has only a\nfew precision bits so z/c - 1 is exactly representible as double:\n\n 1/c = center < 1 ? round(N/center)/N : round(2*N/center)/N/2\n\nNote: |z/c - 1| < 1/N for the chosen c, |log(c) - logc - logctail| < 0x1p-97,\nthe last few bits of logc are rounded away so k*ln2hi + logc has no rounding\nerror and the interval for z is selected such that near x == 1, where log(x)\nis tiny, large cancellation error is avoided in logc + poly(z/c - 1). */\n\n// @ts-ignore: decorator\n@lazy @inline const POW_LOG_DATA_TAB = memory.data([\n // invc ,pad, logc , logctail\n 0x3FF6A00000000000, 0, 0xBFD62C82F2B9C800, 0x3CFAB42428375680,\n 0x3FF6800000000000, 0, 0xBFD5D1BDBF580800, 0xBD1CA508D8E0F720,\n 0x3FF6600000000000, 0, 0xBFD5767717455800, 0xBD2362A4D5B6506D,\n 0x3FF6400000000000, 0, 0xBFD51AAD872DF800, 0xBCE684E49EB067D5,\n 0x3FF6200000000000, 0, 0xBFD4BE5F95777800, 0xBD041B6993293EE0,\n 0x3FF6000000000000, 0, 0xBFD4618BC21C6000, 0x3D13D82F484C84CC,\n 0x3FF5E00000000000, 0, 0xBFD404308686A800, 0x3CDC42F3ED820B3A,\n 0x3FF5C00000000000, 0, 0xBFD3A64C55694800, 0x3D20B1C686519460,\n 0x3FF5A00000000000, 0, 0xBFD347DD9A988000, 0x3D25594DD4C58092,\n 0x3FF5800000000000, 0, 0xBFD2E8E2BAE12000, 0x3D267B1E99B72BD8,\n 0x3FF5600000000000, 0, 0xBFD2895A13DE8800, 0x3D15CA14B6CFB03F,\n 0x3FF5600000000000, 0, 0xBFD2895A13DE8800, 0x3D15CA14B6CFB03F,\n 0x3FF5400000000000, 0, 0xBFD22941FBCF7800, 0xBD165A242853DA76,\n 0x3FF5200000000000, 0, 0xBFD1C898C1699800, 0xBD1FAFBC68E75404,\n 0x3FF5000000000000, 0, 0xBFD1675CABABA800, 0x3D1F1FC63382A8F0,\n 0x3FF4E00000000000, 0, 0xBFD1058BF9AE4800, 0xBD26A8C4FD055A66,\n 0x3FF4C00000000000, 0, 0xBFD0A324E2739000, 0xBD0C6BEE7EF4030E,\n 0x3FF4A00000000000, 0, 0xBFD0402594B4D000, 0xBCF036B89EF42D7F,\n 0x3FF4A00000000000, 0, 0xBFD0402594B4D000, 0xBCF036B89EF42D7F,\n 0x3FF4800000000000, 0, 0xBFCFB9186D5E4000, 0x3D0D572AAB993C87,\n 0x3FF4600000000000, 0, 0xBFCEF0ADCBDC6000, 0x3D2B26B79C86AF24,\n 0x3FF4400000000000, 0, 0xBFCE27076E2AF000, 0xBD172F4F543FFF10,\n 0x3FF4200000000000, 0, 0xBFCD5C216B4FC000, 0x3D21BA91BBCA681B,\n 0x3FF4000000000000, 0, 0xBFCC8FF7C79AA000, 0x3D27794F689F8434,\n 0x3FF4000000000000, 0, 0xBFCC8FF7C79AA000, 0x3D27794F689F8434,\n 0x3FF3E00000000000, 0, 0xBFCBC286742D9000, 0x3D194EB0318BB78F,\n 0x3FF3C00000000000, 0, 0xBFCAF3C94E80C000, 0x3CBA4E633FCD9066,\n 0x3FF3A00000000000, 0, 0xBFCA23BC1FE2B000, 0xBD258C64DC46C1EA,\n 0x3FF3A00000000000, 0, 0xBFCA23BC1FE2B000, 0xBD258C64DC46C1EA,\n 0x3FF3800000000000, 0, 0xBFC9525A9CF45000, 0xBD2AD1D904C1D4E3,\n 0x3FF3600000000000, 0, 0xBFC87FA06520D000, 0x3D2BBDBF7FDBFA09,\n 0x3FF3400000000000, 0, 0xBFC7AB890210E000, 0x3D2BDB9072534A58,\n 0x3FF3400000000000, 0, 0xBFC7AB890210E000, 0x3D2BDB9072534A58,\n 0x3FF3200000000000, 0, 0xBFC6D60FE719D000, 0xBD10E46AA3B2E266,\n 0x3FF3000000000000, 0, 0xBFC5FF3070A79000, 0xBD1E9E439F105039,\n 0x3FF3000000000000, 0, 0xBFC5FF3070A79000, 0xBD1E9E439F105039,\n 0x3FF2E00000000000, 0, 0xBFC526E5E3A1B000, 0xBD20DE8B90075B8F,\n 0x3FF2C00000000000, 0, 0xBFC44D2B6CCB8000, 0x3D170CC16135783C,\n 0x3FF2C00000000000, 0, 0xBFC44D2B6CCB8000, 0x3D170CC16135783C,\n 0x3FF2A00000000000, 0, 0xBFC371FC201E9000, 0x3CF178864D27543A,\n 0x3FF2800000000000, 0, 0xBFC29552F81FF000, 0xBD248D301771C408,\n 0x3FF2600000000000, 0, 0xBFC1B72AD52F6000, 0xBD2E80A41811A396,\n 0x3FF2600000000000, 0, 0xBFC1B72AD52F6000, 0xBD2E80A41811A396,\n 0x3FF2400000000000, 0, 0xBFC0D77E7CD09000, 0x3D0A699688E85BF4,\n 0x3FF2400000000000, 0, 0xBFC0D77E7CD09000, 0x3D0A699688E85BF4,\n 0x3FF2200000000000, 0, 0xBFBFEC9131DBE000, 0xBD2575545CA333F2,\n 0x3FF2000000000000, 0, 0xBFBE27076E2B0000, 0x3D2A342C2AF0003C,\n 0x3FF2000000000000, 0, 0xBFBE27076E2B0000, 0x3D2A342C2AF0003C,\n 0x3FF1E00000000000, 0, 0xBFBC5E548F5BC000, 0xBD1D0C57585FBE06,\n 0x3FF1C00000000000, 0, 0xBFBA926D3A4AE000, 0x3D253935E85BAAC8,\n 0x3FF1C00000000000, 0, 0xBFBA926D3A4AE000, 0x3D253935E85BAAC8,\n 0x3FF1A00000000000, 0, 0xBFB8C345D631A000, 0x3D137C294D2F5668,\n 0x3FF1A00000000000, 0, 0xBFB8C345D631A000, 0x3D137C294D2F5668,\n 0x3FF1800000000000, 0, 0xBFB6F0D28AE56000, 0xBD269737C93373DA,\n 0x3FF1600000000000, 0, 0xBFB51B073F062000, 0x3D1F025B61C65E57,\n 0x3FF1600000000000, 0, 0xBFB51B073F062000, 0x3D1F025B61C65E57,\n 0x3FF1400000000000, 0, 0xBFB341D7961BE000, 0x3D2C5EDACCF913DF,\n 0x3FF1400000000000, 0, 0xBFB341D7961BE000, 0x3D2C5EDACCF913DF,\n 0x3FF1200000000000, 0, 0xBFB16536EEA38000, 0x3D147C5E768FA309,\n 0x3FF1000000000000, 0, 0xBFAF0A30C0118000, 0x3D2D599E83368E91,\n 0x3FF1000000000000, 0, 0xBFAF0A30C0118000, 0x3D2D599E83368E91,\n 0x3FF0E00000000000, 0, 0xBFAB42DD71198000, 0x3D1C827AE5D6704C,\n 0x3FF0E00000000000, 0, 0xBFAB42DD71198000, 0x3D1C827AE5D6704C,\n 0x3FF0C00000000000, 0, 0xBFA77458F632C000, 0xBD2CFC4634F2A1EE,\n 0x3FF0C00000000000, 0, 0xBFA77458F632C000, 0xBD2CFC4634F2A1EE,\n 0x3FF0A00000000000, 0, 0xBFA39E87B9FEC000, 0x3CF502B7F526FEAA,\n 0x3FF0A00000000000, 0, 0xBFA39E87B9FEC000, 0x3CF502B7F526FEAA,\n 0x3FF0800000000000, 0, 0xBF9F829B0E780000, 0xBD2980267C7E09E4,\n 0x3FF0800000000000, 0, 0xBF9F829B0E780000, 0xBD2980267C7E09E4,\n 0x3FF0600000000000, 0, 0xBF97B91B07D58000, 0xBD288D5493FAA639,\n 0x3FF0400000000000, 0, 0xBF8FC0A8B0FC0000, 0xBCDF1E7CF6D3A69C,\n 0x3FF0400000000000, 0, 0xBF8FC0A8B0FC0000, 0xBCDF1E7CF6D3A69C,\n 0x3FF0200000000000, 0, 0xBF7FE02A6B100000, 0xBD19E23F0DDA40E4,\n 0x3FF0200000000000, 0, 0xBF7FE02A6B100000, 0xBD19E23F0DDA40E4,\n 0x3FF0000000000000, 0, 0, 0,\n 0x3FF0000000000000, 0, 0, 0,\n 0x3FEFC00000000000, 0, 0x3F80101575890000, 0xBD10C76B999D2BE8,\n 0x3FEF800000000000, 0, 0x3F90205658938000, 0xBD23DC5B06E2F7D2,\n 0x3FEF400000000000, 0, 0x3F98492528C90000, 0xBD2AA0BA325A0C34,\n 0x3FEF000000000000, 0, 0x3FA0415D89E74000, 0x3D0111C05CF1D753,\n 0x3FEEC00000000000, 0, 0x3FA466AED42E0000, 0xBD2C167375BDFD28,\n 0x3FEE800000000000, 0, 0x3FA894AA149FC000, 0xBD197995D05A267D,\n 0x3FEE400000000000, 0, 0x3FACCB73CDDDC000, 0xBD1A68F247D82807,\n 0x3FEE200000000000, 0, 0x3FAEEA31C006C000, 0xBD0E113E4FC93B7B,\n 0x3FEDE00000000000, 0, 0x3FB1973BD1466000, 0xBD25325D560D9E9B,\n 0x3FEDA00000000000, 0, 0x3FB3BDF5A7D1E000, 0x3D2CC85EA5DB4ED7,\n 0x3FED600000000000, 0, 0x3FB5E95A4D97A000, 0xBD2C69063C5D1D1E,\n 0x3FED400000000000, 0, 0x3FB700D30AEAC000, 0x3CEC1E8DA99DED32,\n 0x3FED000000000000, 0, 0x3FB9335E5D594000, 0x3D23115C3ABD47DA,\n 0x3FECC00000000000, 0, 0x3FBB6AC88DAD6000, 0xBD1390802BF768E5,\n 0x3FECA00000000000, 0, 0x3FBC885801BC4000, 0x3D2646D1C65AACD3,\n 0x3FEC600000000000, 0, 0x3FBEC739830A2000, 0xBD2DC068AFE645E0,\n 0x3FEC400000000000, 0, 0x3FBFE89139DBE000, 0xBD2534D64FA10AFD,\n 0x3FEC000000000000, 0, 0x3FC1178E8227E000, 0x3D21EF78CE2D07F2,\n 0x3FEBE00000000000, 0, 0x3FC1AA2B7E23F000, 0x3D2CA78E44389934,\n 0x3FEBA00000000000, 0, 0x3FC2D1610C868000, 0x3D039D6CCB81B4A1,\n 0x3FEB800000000000, 0, 0x3FC365FCB0159000, 0x3CC62FA8234B7289,\n 0x3FEB400000000000, 0, 0x3FC4913D8333B000, 0x3D25837954FDB678,\n 0x3FEB200000000000, 0, 0x3FC527E5E4A1B000, 0x3D2633E8E5697DC7,\n 0x3FEAE00000000000, 0, 0x3FC6574EBE8C1000, 0x3D19CF8B2C3C2E78,\n 0x3FEAC00000000000, 0, 0x3FC6F0128B757000, 0xBD25118DE59C21E1,\n 0x3FEAA00000000000, 0, 0x3FC7898D85445000, 0xBD1C661070914305,\n 0x3FEA600000000000, 0, 0x3FC8BEAFEB390000, 0xBD073D54AAE92CD1,\n 0x3FEA400000000000, 0, 0x3FC95A5ADCF70000, 0x3D07F22858A0FF6F,\n 0x3FEA000000000000, 0, 0x3FCA93ED3C8AE000, 0xBD28724350562169,\n 0x3FE9E00000000000, 0, 0x3FCB31D8575BD000, 0xBD0C358D4EACE1AA,\n 0x3FE9C00000000000, 0, 0x3FCBD087383BE000, 0xBD2D4BC4595412B6,\n 0x3FE9A00000000000, 0, 0x3FCC6FFBC6F01000, 0xBCF1EC72C5962BD2,\n 0x3FE9600000000000, 0, 0x3FCDB13DB0D49000, 0xBD2AFF2AF715B035,\n 0x3FE9400000000000, 0, 0x3FCE530EFFE71000, 0x3CC212276041F430,\n 0x3FE9200000000000, 0, 0x3FCEF5ADE4DD0000, 0xBCCA211565BB8E11,\n 0x3FE9000000000000, 0, 0x3FCF991C6CB3B000, 0x3D1BCBECCA0CDF30,\n 0x3FE8C00000000000, 0, 0x3FD07138604D5800, 0x3CF89CDB16ED4E91,\n 0x3FE8A00000000000, 0, 0x3FD0C42D67616000, 0x3D27188B163CEAE9,\n 0x3FE8800000000000, 0, 0x3FD1178E8227E800, 0xBD2C210E63A5F01C,\n 0x3FE8600000000000, 0, 0x3FD16B5CCBACF800, 0x3D2B9ACDF7A51681,\n 0x3FE8400000000000, 0, 0x3FD1BF99635A6800, 0x3D2CA6ED5147BDB7,\n 0x3FE8200000000000, 0, 0x3FD214456D0EB800, 0x3D0A87DEBA46BAEA,\n 0x3FE7E00000000000, 0, 0x3FD2BEF07CDC9000, 0x3D2A9CFA4A5004F4,\n 0x3FE7C00000000000, 0, 0x3FD314F1E1D36000, 0xBD28E27AD3213CB8,\n 0x3FE7A00000000000, 0, 0x3FD36B6776BE1000, 0x3D116ECDB0F177C8,\n 0x3FE7800000000000, 0, 0x3FD3C25277333000, 0x3D183B54B606BD5C,\n 0x3FE7600000000000, 0, 0x3FD419B423D5E800, 0x3D08E436EC90E09D,\n 0x3FE7400000000000, 0, 0x3FD4718DC271C800, 0xBD2F27CE0967D675,\n 0x3FE7200000000000, 0, 0x3FD4C9E09E173000, 0xBD2E20891B0AD8A4,\n 0x3FE7000000000000, 0, 0x3FD522AE0738A000, 0x3D2EBE708164C759,\n 0x3FE6E00000000000, 0, 0x3FD57BF753C8D000, 0x3D1FADEDEE5D40EF,\n 0x3FE6C00000000000, 0, 0x3FD5D5BDDF596000, 0xBD0A0B2A08A465DC\n]);\n\n// Returns 0 if not int, 1 if odd int, 2 if even int. The argument is\n// the bit representation of a non-zero finite floating-point value.\n// @ts-ignore: decorator\n@inline\nfunction checkint(iy: u64): i32 {\n let e = iy >> 52 & 0x7FF;\n if (e < 0x3FF ) return 0;\n if (e > 0x3FF + 52) return 2;\n e = u64(1) << (0x3FF + 52 - e);\n if (iy & (e - 1)) return 0;\n if (iy & e ) return 1;\n return 2;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction xflow(sign: u32, y: f64): f64 {\n return select(-y, y, sign) * y;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction uflow(sign: u32): f64 {\n return xflow(sign, reinterpret(0x1000000000000000)); // 0x1p-767\n}\n\n// @ts-ignore: decorator\n@inline\nfunction oflow(sign: u32): f64 {\n return xflow(sign, reinterpret(0x7000000000000000)); // 0x1p769\n}\n\n// Returns 1 if input is the bit representation of 0, infinity or nan.\n// @ts-ignore: decorator\n@inline\nfunction zeroinfnan(u: u64): bool {\n return (u << 1) - 1 >= 0xFFE0000000000000 - 1;\n}\n\n// @ts-ignore: decorator\n@lazy let log_tail: f64 = 0;\n\n// Compute y+TAIL = log(x) where the rounded result is y and TAIL has about\n// additional 15 bits precision. IX is the bit representation of x, but\n// normalized in the subnormal range using the sign bit for the exponent.\n// @ts-ignore: decorator\n@inline\nfunction log_inline(ix: u64): f64 {\n const N = 1 << POW_LOG_TABLE_BITS;\n const N_MASK = N - 1;\n\n const\n Ln2hi = reinterpret(0x3FE62E42FEFA3800),\n Ln2lo = reinterpret(0x3D2EF35793C76730);\n\n const\n A0 = reinterpret(0xBFE0000000000000),\n A1 = reinterpret(0xBFE5555555555560),\n A2 = reinterpret(0x3FE0000000000006),\n A3 = reinterpret(0x3FE999999959554E),\n A4 = reinterpret(0xBFE555555529A47A),\n A5 = reinterpret(0xBFF2495B9B4845E9),\n A6 = reinterpret(0x3FF0002B8B263FC3);\n\n // x = 2^k z; where z is in range [OFF,2*OFF) and exact.\n // The range is split into N subintervals.\n // The ith subinterval contains z and c is near its center.\n let tmp = ix - 0x3fE6955500000000;\n let i = usize((tmp >> (52 - POW_LOG_TABLE_BITS)) & N_MASK);\n let k = tmp >> 52;\n let iz = ix - (tmp & u64(0xFFF) << 52);\n let z = reinterpret(iz);\n let kd = k;\n\n // log(x) = k*Ln2 + log(c) + log1p(z/c-1).\n let invc = load(POW_LOG_DATA_TAB + (i << (2 + alignof())), 0 << alignof()); // tab[i].invc\n let logc = load(POW_LOG_DATA_TAB + (i << (2 + alignof())), 2 << alignof()); // tab[i].logc\n let logctail = load(POW_LOG_DATA_TAB + (i << (2 + alignof())), 3 << alignof()); // tab[i].logctail\n\n // Note: 1/c is j/N or j/N/2 where j is an integer in [N,2N) and\n // |z/c - 1| < 1/N, so r = z/c - 1 is exactly representible.\n // Split z such that rhi, rlo and rhi*rhi are exact and |rlo| <= |r|.\n let zhi = reinterpret((iz + u64(0x80000000)) & 0xFFFFFFFF00000000);\n let zlo = z - zhi;\n let rhi = zhi * invc - 1.0;\n let rlo = zlo * invc;\n let r = rhi + rlo;\n\n // k * Ln2 + log(c) + r.\n let t1 = kd * Ln2hi + logc;\n let t2 = t1 + r;\n let lo1 = kd * Ln2lo + logctail;\n let lo2 = t1 - t2 + r;\n\n // Evaluation is optimized assuming superscalar pipelined execution.\n let ar = A0 * r; // A[0] = -0.5\n let ar2 = r * ar;\n let ar3 = r * ar2;\n // k * Ln2 + log(c) + r + A[0] * r * r.\n let arhi = A0 * rhi;\n let arhi2 = rhi * arhi;\n let hi = t2 + arhi2;\n let lo3 = rlo * (ar + arhi);\n let lo4 = t2 - hi + arhi2;\n\n // p = log1p(r) - r - A[0] * r * r.\n let p = ar3 * (A1 + r * A2 + ar2 * (A3 + r * A4 + ar2 * (A5 + r * A6)));\n let lo = lo1 + lo2 + lo3 + lo4 + p;\n let y = hi + lo;\n log_tail = hi - y + lo;\n\n return y;\n}\n\n// @ts-ignore: decorator\n@inline const SIGN_BIAS = 0x800 << EXP_TABLE_BITS;\n\n// Computes sign*exp(x+xtail) where |xtail| < 2^-8/N and |xtail| <= |x|.\n// The sign_bias argument is SIGN_BIAS or 0 and sets the sign to -1 or 1.\n// @ts-ignore: decorator\n@inline\nfunction exp_inline(x: f64, xtail: f64, sign_bias: u32): f64 {\n const N = 1 << EXP_TABLE_BITS;\n const N_MASK = N - 1;\n\n const\n InvLn2N = reinterpret(0x3FF71547652B82FE) * N, // 0x1.71547652b82fep0\n NegLn2hiN = reinterpret(0xBF762E42FEFA0000), // -0x1.62e42fefa0000p-8\n NegLn2loN = reinterpret(0xBD0CF79ABC9E3B3A), // -0x1.cf79abc9e3b3ap-47\n shift = reinterpret(0x4338000000000000); // 0x1.8p52\n\n const\n C2 = reinterpret(0x3FDFFFFFFFFFFDBD), // __exp_data.poly[0] (0x1.ffffffffffdbdp-2)\n C3 = reinterpret(0x3FC555555555543C), // __exp_data.poly[1] (0x1.555555555543cp-3)\n C4 = reinterpret(0x3FA55555CF172B91), // __exp_data.poly[2] (0x1.55555cf172b91p-5)\n C5 = reinterpret(0x3F81111167A4D017); // __exp_data.poly[3] (0x1.1111167a4d017p-7)\n\n let abstop: u32;\n let ki: u64, top: u64, sbits: u64;\n let idx: usize;\n // double_t for better performance on targets with FLT_EVAL_METHOD==2.\n let kd: f64, z: f64, r: f64, r2: f64, scale: f64, tail: f64, tmp: f64;\n\n let ux = reinterpret(x);\n abstop = u32(ux >> 52) & 0x7FF;\n if (abstop - 0x3C9 >= 0x03F) {\n if (abstop - 0x3C9 >= 0x80000000) {\n // Avoid spurious underflow for tiny x.\n // Note: 0 is common input.\n return select(-1.0, 1.0, sign_bias);\n }\n if (abstop >= 0x409) { // top12(1024.0)\n // Note: inf and nan are already handled.\n return ux < 0\n ? uflow(sign_bias)\n : oflow(sign_bias);\n }\n // Large x is special cased below.\n abstop = 0;\n }\n\n // exp(x) = 2^(k/N) * exp(r), with exp(r) in [2^(-1/2N),2^(1/2N)].\n // x = ln2/N*k + r, with int k and r in [-ln2/2N, ln2/2N].\n z = InvLn2N * x;\n\n // #if TOINT_INTRINSICS\n // kd = roundtoint(z);\n // ki = converttoint(z);\n // #elif EXP_USE_TOINT_NARROW\n // // z - kd is in [-0.5-2^-16, 0.5] in all rounding modes.\n // kd = eval_as_double(z + shift);\n // ki = asuint64(kd) >> 16;\n // kd = (double_t)(int32_t)ki;\n // #else\n // z - kd is in [-1, 1] in non-nearest rounding modes\n kd = z + shift;\n ki = reinterpret(kd);\n kd -= shift;\n // #endif\n r = x + kd * NegLn2hiN + kd * NegLn2loN;\n // The code assumes 2^-200 < |xtail| < 2^-8/N\n r += xtail;\n // 2^(k/N) ~= scale * (1 + tail)\n idx = usize((ki & N_MASK) << 1);\n top = (ki + sign_bias) << (52 - EXP_TABLE_BITS);\n\n tail = reinterpret(load(EXP_DATA_TAB + (idx << alignof())));\n // This is only a valid scale when -1023*N < k < 1024*N\n sbits = load(EXP_DATA_TAB + (idx << alignof()), 1 << alignof()) + top;\n // exp(x) = 2^(k/N) * exp(r) ~= scale + scale * (tail + exp(r) - 1).\n // Evaluation is optimized assuming superscalar pipelined execution.\n r2 = r * r;\n // Without fma the worst case error is 0.25/N ulp larger.\n // Worst case error is less than 0.5+1.11/N+(abs poly error * 2^53) ulp\n tmp = tail + r + r2 * (C2 + r * C3) + r2 * r2 * (C4 + r * C5);\n if (abstop == 0) return specialcase(tmp, sbits, ki);\n scale = reinterpret(sbits);\n // Note: tmp == 0 or |tmp| > 2^-200 and scale > 2^-739, so there\n // is no spurious underflow here even without fma.\n return scale + scale * tmp;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function pow_lut(x: f64, y: f64): f64 {\n const Ox1p52 = reinterpret(0x4330000000000000); // 0x1p52\n\n let sign_bias: u32 = 0;\n let ix = reinterpret(x);\n let iy = reinterpret(y);\n let topx = ix >> 52;\n let topy = iy >> 52;\n\n if (topx - 0x001 >= 0x7FF - 0x001 || (topy & 0x7FF) - 0x3BE >= 0x43e - 0x3BE) {\n // Note: if |y| > 1075 * ln2 * 2^53 ~= 0x1.749p62 then pow(x,y) = inf/0\n // and if |y| < 2^-54 / 1075 ~= 0x1.e7b6p-65 then pow(x,y) = +-1.\n // Special cases: (x < 0x1p-126 or inf or nan) or\n // (|y| < 0x1p-65 or |y| >= 0x1p63 or nan).\n if (zeroinfnan(iy)) {\n if ((iy << 1) == 0) return 1.0;\n if (ix == 0x3FF0000000000000) return NaN; // original: 1.0\n if ((ix << 1) > 0xFFE0000000000000 || (iy << 1) > 0xFFE0000000000000) return x + y;\n if ((ix << 1) == 0x7FE0000000000000) return NaN; // original: 1.0\n if (((ix << 1) < 0x7FE0000000000000) == !(iy >> 63)) return 0; // |x|<1 && y==inf or |x|>1 && y==-inf.\n return y * y;\n }\n if (zeroinfnan(ix)) {\n let x2 = x * x;\n if (i32(ix >> 63) && checkint(iy) == 1) x2 = -x2;\n return iy < 0 ? 1 / x2 : x2;\n }\n // Here x and y are non-zero finite\n if (ix < 0) {\n // Finite x < 0\n let yint = checkint(iy);\n if (yint == 0) return (x - x) / (x - x);\n if (yint == 1) sign_bias = SIGN_BIAS;\n ix &= 0x7FFFFFFFFFFFFFFF;\n topx &= 0x7FF;\n }\n if ((topy & 0x7FF) - 0x3BE >= 0x43E - 0x3BE) {\n // Note: sign_bias == 0 here because y is not odd.\n if (ix == 0x3FF0000000000000) return 1;\n if ((topy & 0x7FF) < 0x3BE) return 1; // |y| < 2^-65, x^y ~= 1 + y*log(x).\n return (ix > 0x3FF0000000000000) == (topy < 0x800) ? Infinity : 0;\n }\n if (topx == 0) {\n // Normalize subnormal x so exponent becomes negative.\n ix = reinterpret(x * Ox1p52);\n ix &= 0x7FFFFFFFFFFFFFFF;\n ix -= u64(52) << 52;\n }\n }\n\n let hi = log_inline(ix);\n let lo = log_tail;\n let ehi: f64, elo: f64;\n // #if __FP_FAST_FMA\n // ehi = y * hi;\n // elo = y * lo + __builtin_fma(y, hi, -ehi);\n // #else\n let yhi = reinterpret(iy & 0xFFFFFFFFF8000000);\n let ylo = y - yhi;\n let lhi = reinterpret(reinterpret(hi) & 0xFFFFFFFFF8000000);\n let llo = hi - lhi + lo;\n ehi = yhi * lhi;\n elo = ylo * lhi + y * llo; // |elo| < |ehi| * 2^-25.\n // #endif\n return exp_inline(ehi, elo, sign_bias);\n}\n","import {\n itoa32,\n utoa32,\n itoa64,\n utoa64,\n dtoa,\n itoa_buffered,\n dtoa_buffered,\n MAX_DOUBLE_LENGTH\n} from \"./number\";\n\nimport {\n ipow32\n} from \"../math\";\n\n// All tables are stored as two staged lookup tables (static tries)\n// because the full range of Unicode symbols can't be efficiently\n// represented as-is in memory (see Unicode spec ch 5, p.196):\n// https://www.unicode.org/versions/Unicode12.0.0/ch05.pdf\n// Tables have been generated using these forked musl tools:\n// https://github.com/MaxGraey/musl-chartable-tools/tree/case-ignorable\n\n// Lookup table to check if a character is alphanumeric or not\n// See: https://git.musl-libc.org/cgit/musl/tree/src/ctype/alpha.h\n// size: 3904 bytes\n// @ts-ignore\n@inline @lazy const ALPHA_TABLE = memory.data([\n 18,17,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,17,34,35,36,17,37,38,39,40,\n 41,42,43,44,17,45,46,47,16,16,48,16,16,16,16,16,16,16,49,50,51,16,52,53,16,16,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,54,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,55,17,17,17,17,56,17,57,58,59,60,61,62,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,63,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,64,65,17,66,67,\n 68,69,70,71,72,73,74,17,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,\n 93,94,16,95,96,97,98,17,17,17,99,100,101,16,16,16,16,16,16,16,16,16,16,17,17,\n 17,17,102,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,17,17,103,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,17,17,104,105,16,16,106,107,17,17,17,17,17,17,17,17,17,17,17,17,17,\n 17,17,17,17,17,17,17,17,17,17,108,17,17,17,17,109,110,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 17,111,112,16,16,16,16,16,16,16,16,16,113,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,114,115,116,117,16,16,16,16,16,16,16,16,118,\n 119,120,16,16,16,16,16,121,122,16,16,16,16,123,16,16,124,16,16,16,16,16,16,16,\n 16,16,125,16,16,16,\n 16,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,254,255,255,7,254,\n 255,255,7,0,0,0,0,0,4,32,4,255,255,127,255,255,255,127,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,195,255,3,0,31,80,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,223,188,64,215,255,255,\n 251,255,255,255,255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,3,252,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,254,255,255,255,127,2,255,255,255,\n 255,255,1,0,0,0,0,255,191,182,0,255,255,255,135,7,0,0,0,255,7,255,255,255,255,\n 255,255,255,254,255,195,255,255,255,255,255,255,255,255,255,255,255,255,239,\n 31,254,225,255,\n 159,0,0,255,255,255,255,255,255,0,224,255,255,255,255,255,255,255,255,255,255,\n 255,255,3,0,255,255,255,255,255,7,48,4,255,255,255,252,255,31,0,0,255,255,255,\n 1,255,7,0,0,0,0,0,0,255,255,223,255,255,0,240,255,248,3,255,255,255,255,255,\n 255,255,255,255,239,255,223,225,255,207,255,254,255,239,159,249,255,255,253,\n 197,227,159,89,128,176,207,255,3,16,238,135,249,255,255,253,109,195,135,25,2,\n 94,192,255,63,0,238,191,251,255,255,253,237,227,191,27,1,0,207,255,0,30,238,\n 159,249,255,255,253,237,227,159,25,192,176,207,255,2,0,236,199,61,214,24,199,\n 255,195,199,29,129,0,192,255,0,0,239,223,253,255,255,253,255,227,223,29,96,7,\n 207,255,0,0,239,223,253,255,255,253,239,227,223,29,96,64,207,255,6,0,255,223,\n 253,255,255,255,255,231,223,93,240,128,207,255,0,252,238,255,127,252,255,255,\n 251,47,127,128,95,255,192,255,12,0,254,255,255,255,255,127,255,7,63,32,255,3,\n 0,0,0,0,214,247,255,255,175,255,255,59,95,32,255,243,0,0,0,\n 0,1,0,0,0,255,3,0,0,255,254,255,255,255,31,254,255,3,255,255,254,255,255,255,\n 31,0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,249,255,3,255,255,255,255,255,\n 255,255,255,255,63,255,255,255,255,191,32,255,255,255,255,255,247,255,255,255,\n 255,255,255,255,255,255,61,127,61,255,255,255,255,255,61,255,255,255,255,61,\n 127,61,255,127,255,255,255,255,255,255,255,61,255,255,255,255,255,255,255,255,\n 7,0,0,0,0,255,255,0,0,255,255,255,255,255,255,255,255,255,255,63,63,254,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,159,255,255,254,255,255,7,255,255,255,255,255,255,255,255,\n 255,199,255,1,255,223,15,0,255,255,15,0,255,255,15,0,255,223,13,0,255,255,255,\n 255,255,255,207,255,255,1,128,16,255,3,0,0,0,0,255,3,255,255,255,255,255,255,\n 255,255,255,255,255,1,255,255,255,255,255,7,255,255,255,255,255,255,255,255,\n 63,\n 0,255,255,255,127,255,15,255,1,192,255,255,255,255,63,31,0,255,255,255,255,\n 255,15,255,255,255,3,255,3,0,0,0,0,255,255,255,15,255,255,255,255,255,255,255,\n 127,254,255,31,0,255,3,255,3,128,0,0,128,1,0,0,0,0,0,0,0,255,255,255,255,255,\n 255,239,255,239,15,255,3,0,0,0,0,255,255,255,255,255,243,255,255,255,255,255,\n 255,191,255,3,0,255,255,255,255,255,255,127,0,255,227,255,255,255,255,255,63,\n 255,1,255,255,255,255,255,231,0,0,0,0,0,222,111,4,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,0,\n 128,255,31,0,255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,255,\n 255,255,255,255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,2,128,0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,132,252,47,62,80,189,255,243,\n 224,67,0,0,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,\n 0,255,255,255,255,255,127,255,255,255,255,255,127,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,31,120,12,0,255,255,255,255,191,32,255,\n 255,255,255,255,255,255,128,0,0,255,255,127,0,127,127,127,127,127,127,127,127,\n 255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,224,0,0,0,254,3,62,31,254,255,255,255,255,255,255,255,255,255,127,224,254,\n 255,255,255,255,255,255,255,255,255,255,247,224,255,255,255,255,255,254,255,\n 255,255,255,255,255,255,255,255,255,127,0,0,255,255,255,255,0,0,0,0,0,0,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,\n 31,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,\n 0,0,0,0,0,0,255,255,255,255,255,63,255,31,255,255,255,15,0,0,255,255,255,255,\n 255,127,240,143,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0,0,0,\n 0,128,255,252,255,255,255,255,255,255,255,255,255,255,255,255,249,255,255,255,\n 255,255,255,252,7,0,0,0,0,224,255,191,255,255,255,255,0,0,0,255,255,255,255,\n 255,255,15,0,255,255,255,255,255,255,255,255,47,0,255,3,0,0,252,232,255,255,\n 255,255,255,7,255,255,255,255,7,0,255,255,255,31,255,255,255,255,255,255,247,\n 255,0,128,255,3,255,255,255,127,255,255,255,255,255,255,127,0,255,63,255,3,\n 255,255,127,252,255,255,255,255,255,255,255,127,5,0,0,56,255,255,60,0,126,126,\n 126,0,127,127,255,255,255,255,255,247,255,3,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,7,255,3,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,15,0,255,255,127,248,255,255,255,255,\n 255,\n 15,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,3,0,0,0,0,127,0,248,224,255,253,127,95,219,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,3,0,0,0,248,255,255,255,\n 255,255,255,255,255,255,255,255,255,63,0,0,255,255,255,255,255,255,255,255,\n 252,255,255,255,255,255,255,0,0,0,0,0,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,223,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,0,0,255,3,\n 254,255,255,7,254,255,255,7,192,255,255,255,255,255,255,255,255,255,255,127,\n 252,252,252,28,0,0,0,0,255,239,255,255,127,255,255,183,255,63,255,63,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,31,255,255,255,255,255,255,1,0,0,0,0,\n 0,255,255,255,255,0,224,255,255,255,7,255,255,255,255,255,7,255,255,255,63,\n 255,255,255,255,15,255,62,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,63,255,3,255,255,255,255,15,255,255,255,\n 255,15,255,255,255,255,255,0,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,127,0,255,255,63,0,255,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,63,253,255,255,255,255,191,145,255,255,63,0,255,255,\n 127,0,255,255,255,127,0,0,0,0,0,0,0,0,255,255,55,0,255,255,63,0,255,255,255,3,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,192,0,0,0,0,0,0,0,0,111,240,239,\n 254,255,255,63,0,0,0,0,0,255,255,255,31,255,255,255,31,0,0,0,0,255,254,255,\n 255,31,0,0,0,255,255,255,255,255,255,63,0,255,255,63,0,255,255,7,0,255,255,3,\n 0,0,0,0,0,0,0,0,0,0,0,0,\n 0,255,255,255,255,255,255,255,255,255,1,0,0,0,0,0,0,255,255,255,255,255,255,7,\n 0,255,255,255,255,255,255,7,0,255,255,255,255,255,0,255,3,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,\n 255,27,3,0,0,0,0,0,0,0,0,0,255,255,255,31,128,0,255,255,63,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,255,255,31,0,0,0,255,255,127,0,255,255,255,255,255,255,255,255,63,0,0,\n 0,192,255,0,0,252,255,255,255,255,255,255,1,0,0,255,255,255,1,255,3,255,255,\n 255,255,255,255,199,255,240,0,255,255,255,255,71,0,255,255,255,255,255,255,\n 255,255,30,192,255,23,0,0,0,0,255,255,251,255,255,255,159,64,0,0,0,0,0,0,0,0,\n 127,189,255,191,255,1,255,255,255,255,255,255,255,1,255,3,239,159,249,255,255,\n 253,237,227,159,25,129,224,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,255,255,255,255,255,255,255,255,187,7,255,131,3,0,0,0,255,255,255,255,255,\n 255,255,255,179,0,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n 255,255,255,63,127,0,0,0,63,0,0,0,0,255,255,255,255,255,255,255,127,17,0,255,\n 3,0,0,0,0,255,255,255,255,255,255,63,1,255,3,0,0,0,0,0,0,255,255,255,231,255,\n 7,255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,\n 255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,3,0,128,\n 127,242,111,255,255,255,191,153,7,0,255,3,0,0,0,0,0,0,0,0,255,252,255,255,255,\n 255,255,252,26,0,0,0,255,255,255,255,255,255,231,127,0,0,255,255,255,255,255,\n 255,255,255,255,32,0,0,0,0,255,255,255,255,255,255,255,1,255,253,255,255,255,\n 255,127,127,1,0,255,3,0,0,252,255,255,255,252,255,255,254,127,0,0,0,0,0,0,0,0,\n 0,127,251,255,255,255,255,127,180,203,0,255,3,191,253,255,255,255,127,123,1,\n 255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,\n 0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,3,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,127,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,255,255,255,255,255,255,255,255,127,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,\n 0,255,255,255,255,255,255,255,1,255,255,255,127,255,3,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,63,0,0,255,255,255,255,255,255,0,0,15,0,255,3,248,255,255,224,255,\n 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,\n 255,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,135,\n 255,255,255,255,255,255,255,128,255,255,0,0,0,0,0,0,0,0,11,0,3,0,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,0,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,0,0,0,0,0,\n 255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,\n 127,0,0,0,0,0,0,7,0,240,0,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,15,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,7,255,31,255,1,255,67,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,255,255,255,\n 223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,223,223,255,255,\n 255,123,95,252,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,63,255,255,255,253,255,255,247,255,255,255,\n 247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,255,255,255,253,\n 255,255,255,253,255,255,247,207,255,255,255,255,255,255,127,255,255,249,219,7,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,31,\n 128,63,255,67,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,15,255,\n 3,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,31,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,143,8,\n 255,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,239,255,255,255,150,254,247,10,\n 132,234,150,170,150,247,247,94,255,251,255,15,238,251,255,15,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,255,255,255,3,255,255,255,3,255,255,255,3,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,3\n]);\n\n// size: 1568 bytes (compressed to ~1380 bytes after binaryen)\n// @ts-ignore: decorator\n@lazy @inline const CASED = memory.data([\n 18,19,20,21,22,23,16,16,16,16,16,16,16,16,16,16,\n 24,16,16,25,16,16,16,16,16,16,16,16,26,27,17,28,\n 29,30,16,16,31,16,16,16,16,16,16,16,32,33,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,34,35,16,16,16,36,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,37,16,16,16,38,\n 16,16,16,16,39,16,16,16,16,16,16,16,40,16,16,16,\n 16,16,16,16,16,16,16,16,41,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,42,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,43,44,45,46,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,47,16,16,16,16,16,16,\n 16,48,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,0,0,0,0,254,255,255,7,254,255,255,7,0,0,0,0,0,4,32,4,\n 255,255,127,255,255,255,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,247,240,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,239,255,255,255,255,1,3,0,0,0,31,0,0,0,\n 0,0,0,0,0,0,0,0,32,0,0,0,0,0,207,188,64,215,255,255,251,255,255,255,\n 255,255,255,255,255,255,191,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 3,252,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,254,255,\n 255,255,127,0,255,255,255,255,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,\n 191,32,255,255,255,255,255,231,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,255,255,255,255,255,255,255,255,255,255,63,63,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,1,255,255,255,255,255,231,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,0,0,0,0,255,255,63,63,255,255,255,255,63,63,255,170,255,255,255,63,\n 255,255,255,255,255,255,223,95,220,31,207,15,255,31,220,31,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,2,128,0,0,255,31,0,0,0,0,0,0,0,0,0,0,0,0,\n 132,252,47,62,80,189,31,242,224,67,0,0,255,255,255,255,24,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,192,255,255,255,255,255,255,3,0,0,255,255,255,255,255,127,255,255,\n 255,255,255,127,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,31,120,12,0,\n 255,255,255,255,191,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,63,0,0,\n 255,255,255,63,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,255,255,255,\n 255,255,255,255,255,255,255,255,255,120,255,255,255,255,255,255,252,7,0,0,0,0,96,7,\n 0,0,0,0,0,0,255,255,255,255,255,247,255,1,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,0,0,0,0,127,0,248,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,254,255,255,7,\n 254,255,255,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0,0,0,255,255,\n 255,255,15,255,255,255,255,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,7,0,255,255,255,255,255,255,7,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,223,255,255,255,255,255,\n 255,255,255,223,100,222,255,235,239,255,255,255,255,255,255,255,191,231,223,223,255,255,255,123,\n 95,252,253,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,63,255,255,255,\n 253,255,255,247,255,255,255,247,255,255,223,255,255,255,223,255,255,127,255,255,255,127,255,255,\n 255,253,255,255,255,253,255,255,247,15,0,0,0,0,0,0,255,255,255,255,255,255,255,255,\n 15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,255,255,255,3,255,255,255,3,255,255,255,3,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0\n]);\n\n// size: 2976 bytes (compressed to ~2050 bytes after binaryen)\n// @ts-ignore: decorator\n@lazy @inline const CASE_IGNORABLES = memory.data([\n 18,16,19,20,21,22,23,24,25,26,27,28,29,30,31,32,\n 33,16,16,34,16,16,16,35,36,37,38,39,40,41,16,42,\n 43,16,16,16,16,16,16,16,16,16,16,16,44,45,46,16,\n 47,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 48,16,16,16,49,16,50,51,52,53,54,55,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,56,16,16,57,58,\n 16,59,60,61,16,16,16,16,16,16,62,16,16,63,64,65,\n 66,67,68,69,70,71,72,73,74,75,76,16,77,78,79,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,80,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,81,82,16,16,16,83,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,84,16,16,16,\n 16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,\n 16,85,86,16,16,16,16,16,16,16,87,16,16,16,16,16,\n 88,89,90,16,16,16,16,16,91,92,16,16,16,16,16,16,\n 16,16,16,93,16,16,16,16,16,16,16,16,16,16,16,16,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 0,0,0,0,128,64,0,4,0,0,0,64,1,0,0,0,0,0,0,0,0,161,144,1,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,\n 255,255,255,255,255,255,48,4,176,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,248,3,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,130,0,0,0,0,\n 0,0,254,255,255,255,255,191,182,0,0,0,0,0,16,0,63,0,255,23,0,0,0,0,\n 1,248,255,255,0,0,1,0,0,0,0,0,0,0,0,0,0,0,192,191,255,61,0,0,\n 0,128,2,0,0,0,255,255,255,7,0,0,0,0,0,0,0,0,0,0,192,255,1,0,\n 0,0,0,0,0,248,63,36,0,0,192,255,255,63,0,0,0,0,0,14,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,248,255,255,255,255,255,7,0,0,0,0,0,0,20,\n 254,33,254,0,12,0,2,0,2,0,0,0,0,0,0,16,30,32,0,0,12,0,0,64,\n 6,0,0,0,0,0,0,16,134,57,2,0,0,0,35,0,6,0,0,0,0,0,0,16,\n 190,33,0,0,12,0,0,252,2,0,0,0,0,0,0,144,30,32,96,0,12,0,0,0,\n 4,0,0,0,0,0,0,0,1,32,0,0,0,0,0,0,17,0,0,0,0,0,0,192,\n 193,61,96,0,12,0,0,0,2,0,0,0,0,0,0,144,64,48,0,0,12,0,0,0,\n 3,0,0,0,0,0,0,24,30,32,0,0,12,0,0,0,2,0,0,0,0,0,0,0,\n 0,4,92,0,0,0,0,0,0,0,0,0,0,0,242,7,192,127,0,0,0,0,0,0,\n 0,0,0,0,0,0,242,31,64,63,0,0,0,0,0,0,0,0,0,3,0,0,160,2,\n 0,0,0,0,0,0,254,127,223,224,255,254,255,255,255,31,64,0,0,0,0,0,0,0,\n 0,0,0,0,0,224,253,102,0,0,0,195,1,0,30,0,100,32,0,32,0,0,0,0,\n 0,0,0,0,0,0,0,16,0,0,0,0,0,0,0,0,0,0,0,224,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,28,0,0,0,28,0,\n 0,0,12,0,0,0,12,0,0,0,0,0,0,0,176,63,64,254,143,32,0,0,0,0,\n 0,120,0,0,0,0,0,0,8,0,0,0,0,0,0,0,96,0,0,0,0,2,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,135,1,4,14,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,9,0,0,0,0,\n 0,0,64,127,229,31,248,159,0,0,0,0,128,0,255,255,1,0,0,0,0,0,0,0,\n 15,0,0,0,0,0,208,23,4,0,0,0,0,248,15,0,3,0,0,0,60,59,0,0,\n 0,0,0,0,64,163,3,0,0,0,0,0,0,240,207,0,0,0,0,0,0,0,0,63,\n 0,0,0,0,0,0,0,0,0,0,247,255,253,33,16,3,0,0,0,0,0,240,255,255,\n 255,255,255,255,255,7,0,1,0,0,0,248,255,255,255,255,255,255,255,255,255,255,255,251,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,160,\n 3,224,0,224,0,224,0,96,0,248,0,3,144,124,0,0,0,0,0,0,223,255,2,128,\n 0,0,255,31,0,0,0,0,0,0,255,255,255,255,1,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,48,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,128,0,128,0,0,0,0,0,0,0,0,\n 0,0,0,0,255,255,255,255,0,0,0,0,0,128,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,60,62,8,\n 0,0,0,0,0,0,0,0,0,0,0,126,0,0,0,0,0,0,0,0,0,0,0,112,\n 0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,63,0,16,0,0,0,0,0,0,\n 0,0,0,0,0,128,247,191,0,0,0,240,0,0,0,0,0,0,0,0,0,0,3,0,\n 255,255,255,255,3,0,0,0,0,0,0,0,0,0,1,0,0,7,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,3,68,8,0,0,96,16,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,48,0,0,0,255,255,3,128,0,0,0,0,192,63,0,0,\n 128,255,3,0,0,0,0,0,7,0,0,0,0,0,200,51,0,128,0,0,96,0,0,0,\n 0,0,0,0,0,126,102,0,8,16,0,0,0,0,1,16,0,0,0,0,0,0,157,193,\n 2,0,0,32,0,48,88,0,0,0,0,0,0,0,0,0,0,0,0,248,0,14,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,32,33,0,0,0,0,0,64,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,252,255,3,0,0,0,0,0,0,0,\n 255,255,8,0,255,255,0,0,0,0,36,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,128,128,64,0,4,0,0,0,64,1,0,0,0,0,0,1,0,\n 0,0,0,192,0,0,0,0,0,0,0,0,8,0,0,14,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,192,7,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,110,240,0,0,0,0,0,135,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,0,0,0,\n 0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 192,255,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 2,0,0,0,0,0,0,255,127,0,0,0,0,0,0,128,3,0,0,0,0,0,120,38,\n 0,32,0,0,0,0,0,0,7,0,0,0,128,239,31,0,0,0,0,0,0,0,8,0,\n 3,0,0,0,0,0,192,127,0,158,0,0,0,0,0,0,0,0,0,0,0,128,211,64,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,248,7,0,0,\n 3,0,0,0,0,0,0,24,1,0,0,0,192,31,31,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,92,0,0,64,0,0,0,0,\n 0,0,0,0,0,0,248,133,13,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,60,176,1,0,0,48,0,0,0,0,\n 0,0,0,0,0,0,248,167,1,0,0,0,0,0,0,0,0,0,0,0,0,40,191,0,\n 0,0,0,0,0,0,0,0,0,0,0,224,188,15,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,255,6,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,88,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,240,12,1,0,0,0,254,7,0,0,0,0,248,121,128,0,126,14,0,0,0,0,\n 0,252,127,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,127,191,\n 0,0,0,0,0,0,0,0,0,0,252,255,255,252,109,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,126,180,191,0,0,0,0,0,0,0,0,0,163,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,24,0,0,0,0,0,0,0,255,1,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,31,0,0,0,0,0,0,0,127,0,15,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,128,0,0,0,0,0,0,0,128,255,255,0,0,0,0,0,0,0,0,27,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,96,15,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,3,248,255,\n 231,15,0,0,0,60,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 28,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 255,255,255,255,255,255,127,248,255,255,255,255,255,31,32,0,16,0,0,248,254,255,0,0,\n 0,0,0,0,0,0,0,0,127,255,255,249,219,7,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,255,63,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,240,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 240,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\n 0,0,0,0,0,0,0,248\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const LOWER127 = memory.data([\n 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,\n 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,\n 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,\n 64,\n 97,98,99,100,101,102,103,104,105,106,107,108,109,\n 110,111,112,113,114,115,116,117,118,119,120,121,122,\n 91,92,93,94,95,96,\n 97,98,99,100,101,102,103,104,105,106,107,108,109,\n 110,111,112,113,114,115,116,117,118,119,120,121,122,\n 123,124,125,126,127\n]);\n\n// @ts-ignore: decorator\n@lazy @inline const UPPER127 = memory.data([\n 0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,\n 16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,\n 32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,\n 48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,\n 64,\n 65,66,67,68,69,70,71,72,73,74,75,76,77,\n 78,79,80,81,82,83,84,85,86,87,88,89,90,\n 91,92,93,94,95,96,\n 65,66,67,68,69,70,71,72,73,74,75,76,77,\n 78,79,80,81,82,83,84,85,86,87,88,89,90,\n 123,124,125,126,127\n]);\n\n// 23 * 8 = 184 bytes\n// @ts-ignore: decorator\n@lazy @inline const POWERS10 = memory.data([\n 1e00, 1e01, 1e02, 1e03, 1e04, 1e05, 1e06, 1e07, 1e08, 1e09,\n 1e10, 1e11, 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19,\n 1e20, 1e21, 1e22\n]);\n\n// @ts-ignore: decorator\n@inline\nexport const enum CharCode {\n PERCENT = 0x25,\n PLUS = 0x2B,\n MINUS = 0x2D,\n DOT = 0x2E,\n _0 = 0x30,\n _1 = 0x31,\n _2 = 0x32,\n _3 = 0x33,\n _4 = 0x34,\n _5 = 0x35,\n _6 = 0x36,\n _7 = 0x37,\n _8 = 0x38,\n _9 = 0x39,\n A = 0x41,\n B = 0x42,\n E = 0x45,\n I = 0x49,\n N = 0x4E,\n O = 0x4F,\n X = 0x58,\n Z = 0x5A,\n a = 0x61,\n b = 0x62,\n e = 0x65,\n n = 0x6E,\n o = 0x6F,\n u = 0x75,\n x = 0x78,\n z = 0x7A\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isAscii(c: u32): bool {\n return !(c >> 7);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isLower8(c: u32): bool {\n return c - CharCode.a < 26;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isUpper8(c: u32): bool {\n return c - CharCode.A < 26;\n}\n\nexport function isSpace(c: u32): bool {\n if (c < 0x1680) { // < (1)\n // , , , , , and \n // (c == 0x20 || c == 0xA0) was optimized to (c | 0x80) == 0xA0\n return ((c | 0x80) == 0xA0) || (c - 0x09 <= 0x0D - 0x09);\n }\n if (c - 0x2000 <= 0x200A - 0x2000) return true;\n switch (c) {\n case 0x1680: // (1)\n case 0x2028: // (2)\n case 0x2029: // \n case 0x202F: // \n case 0x205F: // \n case 0x3000: // \n case 0xFEFF: return true; // \n }\n return false;\n}\n\nexport function isAlpha(c: u32): bool {\n if (isAscii(c)) return (c | 32) - CharCode.a < 26;\n if (c < 0x20000) {\n // @ts-ignore: cast\n return stagedBinaryLookup(ALPHA_TABLE, c);\n }\n return c < 0x2FFFE;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isCased(c: u32): bool {\n // @ts-ignore: cast\n return c < 0x1F18A && stagedBinaryLookup(CASED, c);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isCaseIgnorable(c: u32): bool {\n // @ts-ignore: cast\n return c < 0xE01F0 && stagedBinaryLookup(CASE_IGNORABLES, c);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function isFinalSigma(buffer: usize, index: isize, len: isize): bool {\n const lookaheadLimit = 30; // max lookahead limit\n let found = false;\n let pos = index;\n let minPos = max(0, pos - lookaheadLimit);\n while (pos > minPos) {\n let c = codePointBefore(buffer, pos);\n if (!isCaseIgnorable(c)) {\n if (isCased(c)) {\n found = true;\n } else {\n return false;\n }\n }\n pos -= isize(c >= 0x10000) + 1;\n }\n if (!found) return false;\n pos = index + 1;\n let maxPos = min(pos + lookaheadLimit, len);\n while (pos < maxPos) {\n let c = load(buffer + (pos << 1));\n if (u32((c & 0xFC00) == 0xD800) & u32(pos + 1 != len)) {\n let c1 = load(buffer + (pos << 1), 2);\n if ((c1 & 0xFC00) == 0xDC00) {\n c = (c - 0xD800 << 10) + (c1 - 0xDC00) + 0x10000;\n }\n }\n if (!isCaseIgnorable(c)) {\n return !isCased(c);\n }\n pos += isize(c >= 0x10000) + 1;\n }\n return true;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction codePointBefore(buffer: usize, index: isize): i32 {\n if (index <= 0) return -1;\n let c = load(buffer + (index - 1 << 1));\n if (u32((c & 0xFC00) == 0xDC00) & u32(index - 2 >= 0)) {\n let c1 = load(buffer + (index - 2 << 1));\n if ((c1 & 0xFC00) == 0xD800) {\n return ((c1 & 0x3FF) << 10) + (c & 0x3FF) + 0x10000;\n }\n }\n return (c & 0xF800) == 0xD800 ? 0xFFFD : c;\n}\n\n// Search routine for two-staged lookup tables\nfunction stagedBinaryLookup(table: usize, c: u32): bool {\n return ((load(table + (load(table + (c >>> 8)) << 5) + ((c & 255) >> 3)) >>> (c & 7)) & 1);\n}\n\nexport function compareImpl(str1: string, index1: usize, str2: string, index2: usize, len: usize): i32 {\n let ptr1 = changetype(str1) + (index1 << 1);\n let ptr2 = changetype(str2) + (index2 << 1);\n if (ASC_SHRINK_LEVEL < 2) {\n if (len >= 4 && !((ptr1 & 7) | (ptr2 & 7))) {\n do {\n if (load(ptr1) != load(ptr2)) break;\n ptr1 += 8;\n ptr2 += 8;\n len -= 4;\n } while (len >= 4);\n }\n }\n while (len--) {\n let a = load(ptr1);\n let b = load(ptr2);\n if (a != b) return a - b;\n ptr1 += 2;\n ptr2 += 2;\n }\n return 0;\n}\n\n// @ts-ignore: decorator\n@inline\nexport function toLower8(c: u32): u32 {\n if (ASC_SHRINK_LEVEL > 0) {\n return c | u32(isUpper8(c)) << 5;\n } else {\n return load(LOWER127 + c);\n }\n}\n\n// @ts-ignore: decorator\n@inline\nexport function toUpper8(c: u32): u32 {\n if (ASC_SHRINK_LEVEL > 0) {\n return c & ~(u32(isLower8(c)) << 5);\n } else {\n return load(UPPER127 + c);\n }\n}\n\n/** Parses a string to an integer (usually), using the specified radix. */\nexport function strtol(str: string, radix: i32 = 0): T {\n let len = str.length;\n if (!len) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n\n let ptr = changetype(str) /* + HEAD -> offset */;\n let code = load(ptr);\n\n // trim white spaces\n while (isSpace(code)) {\n code = load(ptr += 2);\n --len;\n }\n // determine sign\n // @ts-ignore\n let sign: T = 1;\n if (code == CharCode.MINUS || code == CharCode.PLUS) {\n if (!--len) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n if (code == CharCode.MINUS) {\n // @ts-ignore: type\n sign = -1;\n }\n code = load(ptr += 2);\n }\n\n // See https://tc39.es/ecma262/#sec-parseint-string-radix\n if (radix) {\n if (radix < 2 || radix > 36) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n // handle case as parseInt(\"0xFF\", 16) by spec\n if (radix == 16) {\n if (\n len > 2 &&\n code == CharCode._0 &&\n (load(ptr, 2) | 32) == CharCode.x\n ) {\n ptr += 4; len -= 2;\n }\n }\n } else {\n // determine radix by literal prefix\n if (code == CharCode._0 && len > 2) {\n switch (load(ptr, 2) | 32) {\n case CharCode.b: {\n ptr += 4; len -= 2;\n radix = 2;\n break;\n }\n case CharCode.o: {\n ptr += 4; len -= 2;\n radix = 8;\n break;\n }\n case CharCode.x: {\n ptr += 4; len -= 2;\n radix = 16;\n break;\n }\n }\n }\n if (!radix) radix = 10;\n }\n\n // calculate value\n // @ts-ignore: type\n let num: T = 0;\n let initial = len - 1;\n while (len--) {\n code = load(ptr);\n if (code - CharCode._0 < 10) {\n code -= CharCode._0;\n } else if (code - CharCode.A <= (CharCode.Z - CharCode.A)) {\n code -= CharCode.A - 10;\n } else if (code - CharCode.a <= (CharCode.z - CharCode.a)) {\n code -= CharCode.a - 10;\n }\n if (code >= radix) {\n if (initial == len) {\n if (isFloat()) {\n // @ts-ignore: cast\n return NaN;\n } else {\n // @ts-ignore: cast\n return 0;\n }\n }\n break;\n }\n // @ts-ignore: type\n num = num * radix + code;\n ptr += 2;\n }\n // @ts-ignore: type\n return sign * num;\n}\n\nexport function strtod(str: string): f64 {\n let len = str.length;\n if (!len) return NaN;\n\n let ptr = changetype(str);\n let code = load(ptr);\n\n let sign = 1.0;\n // skip white spaces\n while (len && isSpace(code)) {\n code = load(ptr += 2);\n --len;\n }\n if (!len) return NaN;\n\n // try parse '-' or '+'\n if (code == CharCode.MINUS) {\n if (!--len) return NaN;\n code = load(ptr += 2);\n sign = -1;\n } else if (code == CharCode.PLUS) {\n if (!--len) return NaN;\n code = load(ptr += 2);\n }\n\n // try parse Infinity\n if (len >= 8 && code == CharCode.I) {\n if (\n load(ptr, 0) == 0x690066006E0049 && // ifnI\n load(ptr, 8) == 0x7900740069006E // ytin\n ) {\n return Infinity * sign;\n }\n return NaN;\n }\n // validate next symbol\n if (code != CharCode.DOT && (code - CharCode._0) >= 10) {\n return NaN;\n }\n let savedPtr = ptr;\n // skip zeros\n while (code == CharCode._0) {\n code = load(ptr += 2);\n --len;\n }\n if (len <= 0) return 0.0 * sign;\n const capacity = 19; // int(64 * 0.3010)\n let pointed = false;\n let consumed = 0;\n let position = 0;\n let x: u64 = 0;\n if (code == CharCode.DOT) {\n let noDigits = !(savedPtr - ptr);\n ptr += 2; --len;\n if (!len && noDigits) return NaN;\n for (pointed = true; (code = load(ptr)) == CharCode._0; --position, ptr += 2) --len;\n if (len <= 0) return 0.0 * sign;\n if (!position && noDigits && code - CharCode._0 >= 10) return NaN;\n }\n for (let digit = code - CharCode._0; digit < 10 || (code == CharCode.DOT && !pointed); digit = code - CharCode._0) {\n if (digit < 10) {\n x = consumed < capacity ? 10 * x + digit : x | u64(!!digit);\n ++consumed;\n } else {\n position = consumed;\n pointed = true;\n }\n if (!--len) break;\n code = load(ptr += 2);\n }\n\n if (!pointed) position = consumed;\n return copysign(scientific(x, position - min(capacity, consumed) + parseExp(ptr, len)), sign);\n}\n\nexport function strtob(str: string): bool {\n let size: usize = str.length << 1;\n let offset: usize = 0;\n if (size > 8) {\n // try trim end whitespaces first\n while (size && isSpace(load(changetype(str) + size - 2))) size -= 2;\n if (size > 8) {\n // trim start whitespaces\n while (offset < size && isSpace(load(changetype(str) + offset))) offset += 2;\n size -= offset;\n }\n }\n if (size != 8) return false;\n // \"true\" represents as \\00\\e\\00\\u\\00\\e\\00\\t (00 65 00 75 00 72 00 74)\n return load(changetype(str) + offset) == 0x0065_0075_0072_0074;\n}\n\nexport function joinBooleanArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) return select(\"true\", \"false\", load(dataStart));\n\n let sepLen = separator.length;\n let valueLen = 5; // max possible length of element len(\"false\")\n let estLen = (valueLen + sepLen) * lastIndex + valueLen;\n let result = changetype(__new(estLen << 1, idof()));\n let offset = 0;\n let value: bool;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + i);\n valueLen = 4 + i32(!value);\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(select(\"true\", \"false\", value)),\n valueLen << 1\n );\n offset += valueLen;\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + lastIndex);\n valueLen = 4 + i32(!value);\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(select(\"true\", \"false\", value)),\n valueLen << 1\n );\n offset += valueLen;\n\n if (estLen > offset) return result.substring(0, offset);\n return result;\n}\n\nexport function joinIntegerArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) {\n let value = load(dataStart);\n if (isSigned()) {\n if (sizeof() <= 4) {\n // @ts-ignore: type\n return changetype(itoa32(value, 10));\n } else {\n // @ts-ignore: type\n return changetype(itoa64(value, 10));\n }\n } else {\n if (sizeof() <= 4) {\n // @ts-ignore: type\n return changetype(utoa32(value, 10));\n } else {\n // @ts-ignore: type\n return changetype(utoa64(value, 10));\n }\n }\n }\n\n let sepLen = separator.length;\n const valueLen = (sizeof() <= 4 ? 10 : 20) + i32(isSigned());\n let estLen = (valueLen + sepLen) * lastIndex + valueLen;\n let result = changetype(__new(estLen << 1, idof()));\n let offset = 0;\n let value: T;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n // @ts-ignore: type\n offset += itoa_buffered(changetype(result) + (offset << 1), value);\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + (lastIndex << alignof()));\n // @ts-ignore: type\n offset += itoa_buffered(changetype(result) + (offset << 1), value);\n if (estLen > offset) return result.substring(0, offset);\n return result;\n}\n\nexport function joinFloatArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) {\n return changetype(dtoa(\n // @ts-ignore: type\n load(dataStart))\n );\n }\n\n const valueLen = MAX_DOUBLE_LENGTH;\n let sepLen = separator.length;\n let estLen = (valueLen + sepLen) * lastIndex + valueLen;\n let result = changetype(__new(estLen << 1, idof()));\n let offset = 0;\n let value: T;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n // @ts-ignore: type\n offset += dtoa_buffered(changetype(result) + (offset << 1), value);\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + (lastIndex << alignof()));\n // @ts-ignore: type\n offset += dtoa_buffered(changetype(result) + (offset << 1), value);\n if (estLen > offset) return result.substring(0, offset);\n return result;\n}\n\nexport function joinStringArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n if (!lastIndex) {\n // @ts-ignore: type\n return load(dataStart) || \"\";\n }\n let estLen = 0;\n let value: string;\n for (let i = 0; i < length; ++i) {\n value = load(dataStart + (i << alignof()));\n if (changetype(value) != 0) estLen += value.length;\n }\n let offset = 0;\n let sepLen = separator.length;\n let result = changetype(__new((estLen + sepLen * lastIndex) << 1, idof()));\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n if (changetype(value) != 0) {\n let valueLen = value.length;\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(value),\n valueLen << 1\n );\n offset += valueLen;\n }\n if (sepLen) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(separator),\n sepLen << 1\n );\n offset += sepLen;\n }\n }\n value = load(dataStart + (lastIndex << alignof()));\n if (changetype(value) != 0) {\n memory.copy(\n changetype(result) + (offset << 1),\n changetype(value),\n value.length << 1\n );\n }\n return result;\n}\n\nexport function joinReferenceArray(dataStart: usize, length: i32, separator: string): string {\n let lastIndex = length - 1;\n if (lastIndex < 0) return \"\";\n let value: T;\n if (!lastIndex) {\n value = load(dataStart);\n // @ts-ignore: type\n return value != null ? value.toString() : \"\";\n }\n let result = \"\";\n let sepLen = separator.length;\n for (let i = 0; i < lastIndex; ++i) {\n value = load(dataStart + (i << alignof()));\n // @ts-ignore: type\n if (value != null) result += value.toString();\n if (sepLen) result += separator;\n }\n value = load(dataStart + (lastIndex << alignof()));\n // @ts-ignore: type\n if (value != null) result += value.toString();\n return result;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction scientific(significand: u64, exp: i32): f64 {\n if (!significand || exp < -342) return 0;\n if (exp > 308) return Infinity;\n // Try use fast path\n // Use fast path for string-to-double conversion if possible\n // see http://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion\n // Simple integer\n let significandf = significand;\n if (!exp) return significandf;\n if (exp > 22 && exp <= 22 + 15) {\n significandf *= pow10(exp - 22);\n exp = 22;\n }\n if (significand <= 9007199254740991 && abs(exp) <= 22) {\n if (exp > 0) return significandf * pow10(exp);\n return significandf / pow10(-exp);\n } else if (exp < 0) {\n return scaledown(significand, exp);\n } else {\n return scaleup(significand, exp);\n }\n}\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction scaledown(significand: u64, exp: i32): f64 {\n const denom: u64 = 6103515625; // 1e14 * 0x1p-14\n const scale = reinterpret(0x3F06849B86A12B9B); // 1e-14 * 0x1p32\n\n let shift = clz(significand);\n significand <<= shift;\n shift = exp - shift;\n\n for (; exp <= -14; exp += 14) {\n let q = significand / denom;\n let r = significand % denom;\n let s = clz(q);\n significand = (q << s) + nearest(scale * (r << (s - 18)));\n shift -= s;\n }\n let b = ipow32(5, -exp);\n let q = significand / b;\n let r = significand % b;\n let s = clz(q);\n significand = (q << s) + (reinterpret(reinterpret(r) + (s << 52)) / b);\n shift -= s;\n\n return NativeMath.scalbn(significand, shift);\n}\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction scaleup(significand: u64, exp: i32): f64 {\n const coeff: u32 = 1220703125; // 1e13 * 0x1p-13;\n let shift = ctz(significand);\n significand >>= shift;\n shift += exp;\n\n __fixmulShift = shift;\n for (; exp >= 13; exp -= 13) {\n significand = fixmul(significand, coeff);\n }\n significand = fixmul(significand, ipow32(5, exp));\n shift = __fixmulShift;\n return NativeMath.scalbn(significand, shift);\n}\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction parseExp(ptr: usize, len: i32): i32 {\n let sign = 1, magnitude = 0;\n let code = load(ptr);\n // check code is 'e' or 'E'\n if ((code | 32) != CharCode.e) return 0;\n\n if (!--len) return 0;\n code = load(ptr += 2);\n if (code == CharCode.MINUS) {\n if (!--len) return 0;\n code = load(ptr += 2);\n sign = -1;\n } else if (code == CharCode.PLUS) {\n if (!--len) return 0;\n code = load(ptr += 2);\n }\n // skip zeros\n while (code == CharCode._0) {\n if (!--len) return 0;\n code = load(ptr += 2);\n }\n for (let digit: u32 = code - CharCode._0; len && digit < 10; digit = code - CharCode._0) {\n if (magnitude >= 3200) return sign * 3200;\n magnitude = 10 * magnitude + digit;\n code = load(ptr += 2);\n --len;\n }\n return sign * magnitude;\n}\n\n// @ts-ignore: decorator\n@lazy let __fixmulShift: u64 = 0;\n\n// Adopted from metallic lib:\n// https://github.com/jdh8/metallic/blob/master/src/stdlib/parse/scientific.h\n// @ts-ignore: decorator\n@inline\nfunction fixmul(a: u64, b: u32): u64 {\n let low = (a & 0xFFFFFFFF) * b;\n let high = (a >> 32) * b + (low >> 32);\n let overflow = (high >> 32);\n let space = clz(overflow);\n let revspace: u64 = 32 - space;\n __fixmulShift += revspace;\n return (high << space | (low & 0xFFFFFFFF) >> revspace) + (low << space >> 31 & 1);\n}\n\n// @ts-ignore: decorator\n@inline\nfunction pow10(n: i32): f64 {\n // argument `n` should bounds in [0, 22] range\n return load(POWERS10 + (n << alignof()));\n}\n","import { Typeinfo, TypeinfoFlags } from \"./shared/typeinfo\";\nimport { E_INDEXOUTOFRANGE } from \"./util/error\";\nimport { ArrayBufferView } from \"./arraybuffer\";\n\n// @ts-ignore: decorator\n@builtin\nexport declare const __rtti_base: usize;\n\n// @ts-ignore: decorator\n@builtin @unsafe\nexport declare function __visit_globals(cookie: u32): void;\n\n// @ts-ignore: decorator\n@builtin @unsafe\nexport declare function __visit_members(ref: usize, cookie: u32): void;\n\n// @ts-ignore: decorator\n@unsafe\nexport function __typeinfo(id: u32): TypeinfoFlags {\n let ptr = __rtti_base;\n if (id > load(ptr)) throw new Error(E_INDEXOUTOFRANGE);\n return changetype(ptr + sizeof() + id * offsetof()).flags;\n}\n\n// @ts-ignore: decorator\n@unsafe\nexport function __newBuffer(size: usize, id: u32, data: usize = 0): usize {\n let buffer = __new(size, id);\n if (data) memory.copy(buffer, data, size);\n return buffer;\n}\n\n// @ts-ignore: decorator\n@unsafe\nexport function __newArray(length: i32, alignLog2: usize, id: u32, data: usize = 0): usize {\n let bufferSize = length << alignLog2;\n // make sure `buffer` is tracked by the shadow stack\n let buffer = changetype(__newBuffer(bufferSize, idof(), data));\n // ...since allocating the array may trigger GC steps\n let array = __new(offsetof(), id);\n store(array, changetype(buffer), offsetof(\"buffer\"));\n __link(array, changetype(buffer), false);\n store(array, changetype(buffer), offsetof(\"dataStart\"));\n store(array, bufferSize, offsetof(\"byteLength\"));\n store(array, length, offsetof(\"length_\"));\n return array;\n}\n\n// @ts-ignore: decorator\n@global @unsafe\nfunction __tostack(ptr: usize): usize { // eslint-disable-line\n return ptr;\n}\n\n// These are provided by the respective implementation, included as another entry file by asc:\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __alloc(size: usize): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __realloc(ptr: usize, size: usize): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __free(ptr: usize): void;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __new(size: usize, id: u32): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __renew(ptr: usize, size: usize): usize;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __link(parentPtr: usize, childPtr: usize, expectMultiple: bool): void;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __collect(): void;\n\n// // @ts-ignore: decorator\n// @builtin @unsafe\n// export declare function __visit(ptr: usize, cookie: u32): void;\n","import { toJson } from \"./formatPrint\";\n\nclass AssertResultCollector {\n total: u32 = 0;\n fail: u32 = 0;\n failed_info: Map = new Map();\n currentTestDescriptions: string[] = [];\n\n addDescription(description: string): void {\n this.currentTestDescriptions.push(description);\n }\n removeDescription(): void {\n this.currentTestDescriptions.pop();\n }\n collectCheckResult(\n result: bool,\n codeInfoIndex: u32,\n actualValue: string,\n expectValue: string,\n ): void {\n this.total++;\n if (!result) {\n this.fail++;\n const testCaseFullName = this.currentTestDescriptions.join(\" - \");\n const assertMessage = [\n codeInfoIndex.toString(),\n actualValue,\n expectValue,\n ];\n if (this.failed_info.has(testCaseFullName)) {\n this.failed_info.get(testCaseFullName).push(assertMessage);\n } else {\n this.failed_info.set(testCaseFullName, [assertMessage]);\n }\n }\n }\n\n clear(): void {\n this.failed_info = new Map();\n this.currentTestDescriptions = [];\n __collect();\n }\n\n totalString(): string {\n return `\"total\":` + this.total.toString();\n }\n failString(): string {\n return `\"fail\":` + this.fail.toString();\n }\n failInfoString(): string {\n return `\"failed_info\":` + toJson(this.failed_info);\n }\n}\n\nexport const assertResult = new AssertResultCollector();\n","/// \n\nimport { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from \"./rt/common\";\nimport { Runtime } from \"shared/runtime\";\nimport { idof } from \"./builtins\";\nimport { E_INVALIDLENGTH } from \"./util/error\";\n\nexport abstract class ArrayBufferView {\n\n readonly buffer: ArrayBuffer;\n @unsafe readonly dataStart: usize;\n readonly byteLength: i32;\n\n get byteOffset(): i32 {\n return (this.dataStart - changetype(this.buffer));\n }\n\n protected constructor(length: i32, alignLog2: i32) {\n if (length > BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);\n let buffer = changetype(__new(length = length << alignLog2, idof()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(buffer), 0, length);\n }\n this.buffer = buffer; // links\n this.dataStart = changetype(buffer);\n this.byteLength = length;\n }\n}\n\n@final export class ArrayBuffer {\n\n static isView(value: T): bool {\n if (isNullable()) {\n if (changetype(value) == 0) return false;\n }\n if (value instanceof Int8Array) return true;\n if (value instanceof Uint8Array) return true;\n if (value instanceof Uint8ClampedArray) return true;\n if (value instanceof Int16Array) return true;\n if (value instanceof Uint16Array) return true;\n if (value instanceof Int32Array) return true;\n if (value instanceof Uint32Array) return true;\n if (value instanceof Int64Array) return true;\n if (value instanceof Uint64Array) return true;\n if (value instanceof Float32Array) return true;\n if (value instanceof Float64Array) return true;\n if (value instanceof DataView) return true;\n return false;\n }\n\n constructor(length: i32) {\n if (length > BLOCK_MAXSIZE) throw new RangeError(E_INVALIDLENGTH);\n let buffer = changetype(__new(length, idof()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(buffer), 0, length);\n }\n return buffer;\n }\n\n get byteLength(): i32 {\n return changetype(changetype(this) - TOTAL_OVERHEAD).rtSize;\n }\n\n slice(begin: i32 = 0, end: i32 = BLOCK_MAXSIZE): ArrayBuffer {\n let length = this.byteLength;\n begin = begin < 0 ? max(length + begin, 0) : min(begin, length);\n end = end < 0 ? max(length + end , 0) : min(end , length);\n let outSize = max(end - begin, 0);\n let out = changetype(__new(outSize, idof()));\n memory.copy(changetype(out), changetype(this) + begin, outSize);\n return out;\n }\n\n toString(): string {\n return \"[object ArrayBuffer]\";\n }\n}\n","export function HASH(key: T): u32 {\n if (isString()) {\n return hashStr(changetype(key));\n } else if (isReference()) {\n if (sizeof() == 4) return hash32(changetype(key));\n if (sizeof() == 8) return hash64(changetype(key));\n } else if (isFloat()) {\n if (sizeof() == 4) return hash32(reinterpret(f32(key)));\n if (sizeof() == 8) return hash64(reinterpret(f64(key)));\n } else {\n if (sizeof() <= 4) return hash32(u32(key), sizeof());\n if (sizeof() == 8) return hash64(u64(key));\n }\n return unreachable();\n}\n\n// XXHash 32-bit as a starting point, see: https://cyan4973.github.io/xxHash\n\n// primes\n// @ts-ignore: decorator\n@inline const XXH32_P1: u32 = 2654435761;\n// @ts-ignore: decorator\n@inline const XXH32_P2: u32 = 2246822519;\n// @ts-ignore: decorator\n@inline const XXH32_P3: u32 = 3266489917;\n// @ts-ignore: decorator\n@inline const XXH32_P4: u32 = 668265263;\n// @ts-ignore: decorator\n@inline const XXH32_P5: u32 = 374761393;\n// @ts-ignore: decorator\n@inline const XXH32_SEED: u32 = 0;\n\n// @ts-ignore: decorator\n@inline\nfunction hash32(key: u32, len: u32 = 4): u32 {\n let h: u32 = XXH32_SEED + XXH32_P5 + len;\n h += key * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n h ^= h >> 15;\n h *= XXH32_P2;\n h ^= h >> 13;\n h *= XXH32_P3;\n h ^= h >> 16;\n return h;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction hash64(key: u64): u32 {\n let h: u32 = XXH32_SEED + XXH32_P5 + 8;\n h += key * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n h += (key >> 32) * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n h ^= h >> 15;\n h *= XXH32_P2;\n h ^= h >> 13;\n h *= XXH32_P3;\n h ^= h >> 16;\n return h;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction mix(h: u32, key: u32): u32 {\n return rotl(h + key * XXH32_P2, 13) * XXH32_P1;\n}\n\n// @ts-ignore: decorator\n@inline\nfunction hashStr(key: string): u32 {\n if (changetype(key) == 0) return XXH32_SEED;\n\n let h: u32 = key.length << 1;\n let len: usize = h;\n let pos = changetype(key);\n\n if (len >= 16) {\n let s1 = XXH32_SEED + XXH32_P1 + XXH32_P2;\n let s2 = XXH32_SEED + XXH32_P2;\n let s3 = XXH32_SEED;\n let s4 = XXH32_SEED - XXH32_P1;\n\n let end = len + pos - 16;\n while (pos <= end) {\n s1 = mix(s1, load(pos ));\n s2 = mix(s2, load(pos, 4));\n s3 = mix(s3, load(pos, 8));\n s4 = mix(s4, load(pos, 12));\n pos += 16;\n }\n h += rotl(s1, 1) + rotl(s2, 7) + rotl(s3, 12) + rotl(s4, 18);\n } else {\n h += XXH32_SEED + XXH32_P5;\n }\n\n let end = changetype(key) + len - 4;\n while (pos <= end) {\n h += load(pos) * XXH32_P3;\n h = rotl(h, 17) * XXH32_P4;\n pos += 4;\n }\n\n end = changetype(key) + len;\n while (pos < end) {\n h += load(pos) * XXH32_P5;\n h = rotl(h, 11) * XXH32_P1;\n pos++;\n }\n\n h ^= h >> 15;\n h *= XXH32_P2;\n h ^= h >> 13;\n h *= XXH32_P3;\n h ^= h >> 16;\n return h;\n}\n","/// \n\nimport { HASH } from \"./util/hash\";\nimport { E_KEYNOTFOUND } from \"./util/error\";\n\n// A deterministic hash map based on CloseTable from https://github.com/jorendorff/dht\n\n// @ts-ignore: decorator\n@inline const INITIAL_CAPACITY = 4;\n\n// @ts-ignore: decorator\n@inline const FILL_FACTOR_N = 8;\n\n// @ts-ignore: decorator\n@inline const FILL_FACTOR_D = 3;\n\n// @ts-ignore: decorator\n@inline const FREE_FACTOR_N = 3;\n\n// @ts-ignore: decorator\n@inline const FREE_FACTOR_D = 4;\n\n/** Structure of a map entry. */\n@unmanaged class MapEntry {\n key: K;\n value: V;\n taggedNext: usize; // LSB=1 indicates EMPTY\n}\n\n/** Empty bit. */\n// @ts-ignore: decorator\n@inline const EMPTY: usize = 1 << 0;\n\n/** Size of a bucket. */\n// @ts-ignore: decorator\n@inline const BUCKET_SIZE = sizeof();\n\n/** Computes the alignment of an entry. */\n// @ts-ignore: decorator\n@inline\nfunction ENTRY_ALIGN(): usize {\n // can align to 4 instead of 8 if 32-bit and K/V is <= 32-bits\n const maxkv = sizeof() > sizeof() ? sizeof() : sizeof();\n const align = (maxkv > sizeof() ? maxkv : sizeof()) - 1;\n return align;\n}\n\n/** Computes the aligned size of an entry. */\n// @ts-ignore: decorator\n@inline\nfunction ENTRY_SIZE(): usize {\n const align = ENTRY_ALIGN();\n const size = (offsetof>() + align) & ~align;\n return size;\n}\n\nexport class Map {\n\n // buckets referencing their respective first entry, usize[bucketsMask + 1]\n private buckets: ArrayBuffer = new ArrayBuffer(INITIAL_CAPACITY * BUCKET_SIZE);\n private bucketsMask: u32 = INITIAL_CAPACITY - 1;\n\n // entries in insertion order, MapEntry[entriesCapacity]\n private entries: ArrayBuffer = new ArrayBuffer(INITIAL_CAPACITY * ENTRY_SIZE());\n private entriesCapacity: i32 = INITIAL_CAPACITY;\n private entriesOffset: i32 = 0;\n private entriesCount: i32 = 0;\n\n constructor() {\n /* nop */\n }\n\n get size(): i32 {\n return this.entriesCount;\n }\n\n clear(): void {\n this.buckets = new ArrayBuffer(INITIAL_CAPACITY * BUCKET_SIZE);\n this.bucketsMask = INITIAL_CAPACITY - 1;\n this.entries = new ArrayBuffer(INITIAL_CAPACITY * ENTRY_SIZE());\n this.entriesCapacity = INITIAL_CAPACITY;\n this.entriesOffset = 0;\n this.entriesCount = 0;\n }\n\n private find(key: K, hashCode: u32): MapEntry | null {\n let entry = load>( // unmanaged!\n changetype(this.buckets) + (hashCode & this.bucketsMask) * BUCKET_SIZE\n );\n while (entry) {\n let taggedNext = entry.taggedNext;\n if (!(taggedNext & EMPTY) && entry.key == key) return entry;\n entry = changetype>(taggedNext & ~EMPTY);\n }\n return null;\n }\n\n has(key: K): bool {\n return this.find(key, HASH(key)) != null;\n }\n\n @operator(\"[]\")\n get(key: K): V {\n let entry = this.find(key, HASH(key));\n if (!entry) throw new Error(E_KEYNOTFOUND); // cannot represent `undefined`\n return entry.value;\n }\n\n @operator(\"[]=\")\n set(key: K, value: V): this {\n let hashCode = HASH(key);\n let entry = this.find(key, hashCode); // unmanaged!\n if (entry) {\n entry.value = value;\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n } else {\n // check if rehashing is necessary\n if (this.entriesOffset == this.entriesCapacity) {\n this.rehash(\n this.entriesCount < this.entriesCapacity * FREE_FACTOR_N / FREE_FACTOR_D\n ? this.bucketsMask // just rehash if 1/4+ entries are empty\n : (this.bucketsMask << 1) | 1 // grow capacity to next 2^N\n );\n }\n // append new entry\n let entries = this.entries;\n entry = changetype>(changetype(entries) + (this.entriesOffset++) * ENTRY_SIZE());\n // link with the map\n entry.key = key;\n if (isManaged()) {\n __link(changetype(this), changetype(key), true);\n }\n entry.value = value;\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n ++this.entriesCount;\n // link with previous entry in bucket\n let bucketPtrBase = changetype(this.buckets) + (hashCode & this.bucketsMask) * BUCKET_SIZE;\n entry.taggedNext = load(bucketPtrBase);\n store(bucketPtrBase, changetype(entry));\n }\n return this;\n }\n\n delete(key: K): bool {\n let entry = this.find(key, HASH(key));\n if (!entry) return false;\n entry.taggedNext |= EMPTY;\n --this.entriesCount;\n // check if rehashing is appropriate\n let halfBucketsMask = this.bucketsMask >> 1;\n if (\n halfBucketsMask + 1 >= max(INITIAL_CAPACITY, this.entriesCount) &&\n this.entriesCount < this.entriesCapacity * FREE_FACTOR_N / FREE_FACTOR_D\n ) this.rehash(halfBucketsMask);\n return true;\n }\n\n private rehash(newBucketsMask: u32): void {\n let newBucketsCapacity = (newBucketsMask + 1);\n let newBuckets = new ArrayBuffer(newBucketsCapacity * BUCKET_SIZE);\n let newEntriesCapacity = newBucketsCapacity * FILL_FACTOR_N / FILL_FACTOR_D;\n let newEntries = new ArrayBuffer(newEntriesCapacity * ENTRY_SIZE());\n\n // copy old entries to new entries\n let oldPtr = changetype(this.entries);\n let oldEnd = oldPtr + this.entriesOffset * ENTRY_SIZE();\n let newPtr = changetype(newEntries);\n while (oldPtr != oldEnd) {\n let oldEntry = changetype>(oldPtr);\n if (!(oldEntry.taggedNext & EMPTY)) {\n let newEntry = changetype>(newPtr);\n let oldEntryKey = oldEntry.key;\n newEntry.key = oldEntryKey;\n newEntry.value = oldEntry.value;\n let newBucketIndex = HASH(oldEntryKey) & newBucketsMask;\n let newBucketPtrBase = changetype(newBuckets) + newBucketIndex * BUCKET_SIZE;\n newEntry.taggedNext = load(newBucketPtrBase);\n store(newBucketPtrBase, newPtr);\n newPtr += ENTRY_SIZE();\n }\n oldPtr += ENTRY_SIZE();\n }\n\n this.buckets = newBuckets;\n this.bucketsMask = newBucketsMask;\n this.entries = newEntries;\n this.entriesCapacity = newEntriesCapacity;\n this.entriesOffset = this.entriesCount;\n }\n\n keys(): K[] {\n // FIXME: this is preliminary, needs iterators/closures\n let start = changetype(this.entries);\n let size = this.entriesOffset;\n let keys = new Array(size);\n let length = 0;\n for (let i = 0; i < size; ++i) {\n let entry = changetype>(start + i * ENTRY_SIZE());\n if (!(entry.taggedNext & EMPTY)) {\n unchecked(keys[length++] = entry.key);\n }\n }\n keys.length = length;\n return keys;\n }\n\n values(): V[] {\n // FIXME: this is preliminary, needs iterators/closures\n let start = changetype(this.entries);\n let size = this.entriesOffset;\n let values = new Array(size);\n let length = 0;\n for (let i = 0; i < size; ++i) {\n let entry = changetype>(start + i * ENTRY_SIZE());\n if (!(entry.taggedNext & EMPTY)) {\n unchecked(values[length++] = entry.value);\n }\n }\n values.length = length;\n return values;\n }\n\n toString(): string {\n return \"[object Map]\";\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n __visit(changetype(this.buckets), cookie);\n let entries = changetype(this.entries);\n if (isManaged() || isManaged()) {\n let cur = entries;\n let end = cur + this.entriesOffset * ENTRY_SIZE();\n while (cur < end) {\n let entry = changetype>(cur);\n if (!(entry.taggedNext & EMPTY)) {\n if (isManaged()) {\n let val = changetype(entry.key);\n if (isNullable()) {\n if (val) __visit(val, cookie);\n } else __visit(val, cookie);\n }\n if (isManaged()) {\n let val = changetype(entry.value);\n if (isNullable()) {\n if (val) __visit(val, cookie);\n } else __visit(val, cookie);\n }\n }\n cur += ENTRY_SIZE();\n }\n }\n __visit(entries, cookie);\n }\n}\n","import { equal, isNull } from \"./comparison\";\nimport { assertResult } from \"./assertCollector\";\nimport { toJson } from \"./formatPrint\";\n\n\n@inline\nconst EXPECT_MAX_INDEX = 2147483647;\n\nexport class Value {\n data: T;\n constructor(_data: T) {\n this.data = _data;\n }\n isNull(codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value {\n assertResult.collectCheckResult(\n isNull(this.data),\n codeInfoIndex,\n toJson(this.data),\n \"to be null\",\n );\n return this;\n }\n notNull(codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value {\n assertResult.collectCheckResult(\n !isNull(this.data),\n codeInfoIndex,\n toJson(this.data),\n \"notNull\",\n );\n return this;\n }\n\n equal(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value {\n assertResult.collectCheckResult(\n equal(this.data, checkValue),\n codeInfoIndex,\n toJson(this.data),\n \"= \" + toJson(checkValue),\n );\n return this;\n }\n notEqual(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value {\n assertResult.collectCheckResult(\n !equal(this.data, checkValue),\n codeInfoIndex,\n toJson(this.data),\n \" != \" + toJson(checkValue),\n );\n return this;\n }\n\n greaterThan(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value {\n assertResult.collectCheckResult(\n this.data > checkValue,\n codeInfoIndex,\n toJson(this.data),\n \" > \" + toJson(checkValue),\n );\n return this;\n }\n greaterThanOrEqual(\n checkValue: T,\n codeInfoIndex: u32 = EXPECT_MAX_INDEX,\n ): Value {\n assertResult.collectCheckResult(\n this.data >= checkValue,\n codeInfoIndex,\n toJson(this.data),\n \" >= \" + toJson(checkValue),\n );\n return this;\n }\n lessThan(checkValue: T, codeInfoIndex: u32 = EXPECT_MAX_INDEX): Value {\n assertResult.collectCheckResult(\n this.data < checkValue,\n codeInfoIndex,\n toJson(this.data),\n \" < \" + toJson(checkValue),\n );\n return this;\n }\n lessThanOrEqual(\n checkValue: T,\n codeInfoIndex: u32 = EXPECT_MAX_INDEX,\n ): Value {\n assertResult.collectCheckResult(\n this.data <= checkValue,\n codeInfoIndex,\n toJson(this.data),\n \" <= \" + toJson(checkValue),\n );\n return this;\n }\n\n closeTo(\n checkValue: T,\n delta: number,\n codeInfoIndex: u32 = EXPECT_MAX_INDEX,\n ): Value {\n const data = this.data;\n if (isFloat(checkValue) && isFloat(data)) {\n assertResult.collectCheckResult(\n abs(data - checkValue) < delta,\n codeInfoIndex,\n toJson(this.data),\n \" closeTo \" + toJson(checkValue),\n );\n } else {\n ERROR(\"closeTo should only be used in f32 | f64\");\n }\n return this;\n }\n}\n","// Phase: wasi_snapshot_preview1\r\n// See: https://github.com/WebAssembly/WASI/tree/main/phases/snapshot/witx\r\n\r\n// helper types to be more explicit\r\ntype char = u8;\r\ntype ptr = usize; // all pointers are usize'd\r\ntype struct = T; // structs are references already in AS\r\n\r\n/** Read command-line argument data. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function args_get(\r\n /** Input: Pointer to a buffer to write the argument pointers. */\r\n argv: ptr>,\r\n /** Input: Pointer to a buffer to write the argument string data. */\r\n argv_buf: ptr\r\n): errno;\r\n\r\n/** Return command-line argument data sizes. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function args_sizes_get(\r\n /** Output: Number of arguments. */\r\n argc: ptr,\r\n /** Output: Size of the argument string data. */\r\n argv_buf_size: ptr\r\n): errno;\r\n\r\n/** Return the resolution of a clock. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function clock_res_get(\r\n /** Input: The clock for which to return the resolution. */\r\n clock: clockid,\r\n /** Output: The resolution of the clock. */\r\n resolution: ptr\r\n): errno;\r\n\r\n/** Return the time value of a clock. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function clock_time_get(\r\n /** Input: Cock for which to return the time. */\r\n clock: clockid,\r\n /** Input: Maximum lag (exclusive) that the returned time value may have, compared to its actual value. */\r\n precision: timestamp,\r\n /** Output: Time value of the clock. */\r\n time: ptr\r\n): errno;\r\n\r\n/** Read environment variable data. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function environ_get(\r\n /** Input: Pointer to a buffer to write the environment variable pointers. */\r\n environ: ptr,\r\n /** Input: Pointer to a buffer to write the environment variable string data. */\r\n environ_buf: usize\r\n): errno;\r\n\r\n/** Return command-line argument data sizes. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function environ_sizes_get(\r\n /** Output: The number of environment variables. */\r\n environ_count: ptr,\r\n /** Output: The size of the environment variable string data. */\r\n environ_buf_size: ptr\r\n): errno;\r\n\r\n/** Provide file advisory information on a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_advise(\r\n /** Input: The file descriptor for the file for which to provide file advisory information. */\r\n fd: fd,\r\n /** Input: The offset within the file to which the advisory applies. */\r\n offset: filesize,\r\n /** Input: The length of the region to which the advisory applies. */\r\n len: filesize,\r\n /** Input: The advice. */\r\n advice: advice\r\n): errno;\r\n\r\n/** Provide file advisory information on a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_allocate(\r\n /** Input: The file descriptor for the file in which to allocate space. */\r\n fd: fd,\r\n /** Input: The offset at which to start the allocation. */\r\n offset: filesize,\r\n /** Input: The length of the area that is allocated. */\r\n len: filesize\r\n): errno;\r\n\r\n/** Close a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_close(\r\n /** Input: The file descriptor to close. */\r\n fd: fd\r\n): errno;\r\n\r\n/** Synchronize the data of a file to disk. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_datasync(\r\n /** Input: The file descriptor of the file to synchronize to disk. */\r\n fd: fd\r\n): errno;\r\n\r\n/** Get the attributes of a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_fdstat_get(\r\n /** Input: The file descriptor to inspect. */\r\n fd: fd,\r\n /** Input: The buffer where the file descriptor's attributes are stored. */\r\n buf: struct\r\n): errno;\r\n\r\n/** Adjust the flags associated with a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_fdstat_set_flags(\r\n /** Input: The file descriptor to operate on. */\r\n fd: fd,\r\n /** Input: The desired values of the file descriptor flags. */\r\n flags: fdflags\r\n): errno;\r\n\r\n/** Adjust the rights associated with a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_fdstat_set_rights(\r\n /** Input: The file descriptor to operate on. */\r\n fd: fd,\r\n /** Input: The desired rights of the file descriptor. */\r\n fs_rights_base: rights,\r\n /** Input: The desired rights of the file descriptor. */\r\n fs_rights_inheriting: rights\r\n): errno;\r\n\r\n/** Return the attributes of an open file. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_filestat_get(\r\n /** Input: The file descriptor to inspect. */\r\n fd: fd,\r\n /** Input: The buffer where the file's attributes are stored. */\r\n buf: struct\r\n): errno;\r\n\r\n/** Adjust the size of an open file. If this increases the file's size, the extra bytes are filled with zeros. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_filestat_set_size(\r\n /** Input: A file descriptor for the file to adjust. */\r\n fd: fd,\r\n /** Input: The desired file size. */\r\n size: filesize\r\n): errno;\r\n\r\n/** Adjust the timestamps of an open file or directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_filestat_set_times(\r\n /** Input: The file descriptor to operate on. */\r\n fd: fd,\r\n /** Input: The desired values of the data access timestamp. */\r\n st_atim: timestamp,\r\n /** Input: The desired values of the data modification timestamp. */\r\n st_mtim: timestamp,\r\n /** Input: A bitmask indicating which timestamps to adjust. */\r\n fstflags: fstflags\r\n): errno;\r\n\r\n/** Read from a file descriptor, without using and updating the file descriptor's offset. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_pread(\r\n /** Input: The file descriptor from which to read data. */\r\n fd: fd,\r\n /** Input: List of scatter/gather vectors in which to store data. */\r\n iovs: ptr>,\r\n /** Input: Length of the list of scatter/gather vectors in which to store data. */\r\n iovs_len: usize,\r\n /** Input: The offset within the file at which to read. */\r\n offset: filesize,\r\n /** Output: The number of bytes read. */\r\n nread: ptr\r\n): errno;\r\n\r\n/** Return a description of the given preopened file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_prestat_get(\r\n /** Input: The file descriptor about which to retrieve information. */\r\n fd: fd,\r\n /** Input: The buffer where the description is stored. */\r\n buf: struct\r\n): errno;\r\n\r\n/** Return a description of the given preopened file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_prestat_dir_name(\r\n /** Input: The file descriptor about which to retrieve information. */\r\n fd: fd,\r\n /** Input: Buffer into which to write the preopened directory name. */\r\n path: ptr,\r\n /** Input: Length of the buffer into which to write the preopened directory name. */\r\n path_len: usize\r\n): errno;\r\n\r\n/** Write to a file descriptor, without using and updating the file descriptor's offset. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_pwrite(\r\n /** Input: The file descriptor to which to write data. */\r\n fd: fd,\r\n /** Input: List of scatter/gather vectors from which to retrieve data. */\r\n iovs: ptr>,\r\n /** Input: Length of the list of scatter/gather vectors from which to retrieve data. */\r\n iovs_len: usize,\r\n /** Input: The offset within the file at which to write. */\r\n offset: filesize,\r\n /** Output: The number of bytes written. */\r\n nwritten: ptr\r\n): errno;\r\n\r\n/** Read from a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_read(\r\n /** Input: The file descriptor from which to read data. */\r\n fd: fd,\r\n /** Input: List of scatter/gather vectors to which to store data. */\r\n iovs: ptr>,\r\n /** Input: Length of the list of scatter/gather vectors to which to store data. */\r\n iovs_len: usize,\r\n /** Output: The number of bytes read. */\r\n nread: ptr\r\n): errno;\r\n\r\n/** Read directory entries from a directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_readdir(\r\n /** Input: Directory from which to read the directory entries. */\r\n fd: fd,\r\n /** Input: Buffer where directory entries are stored. */\r\n buf: ptr>,\r\n /** Input: Length of the buffer where directory entries are stored. */\r\n buf_len: usize,\r\n /** Input: Location within the directory to start reading. */\r\n cookie: dircookie,\r\n /** Output: Number of bytes stored in the read buffer. If less than the size of the read buffer, the end of the directory has been reached. */\r\n buf_used: ptr\r\n): errno;\r\n\r\n/** Atomically replace a file descriptor by renumbering another file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_renumber(\r\n /** Input: The file descriptor to renumber. */\r\n from: fd,\r\n /** Input: The file descriptor to overwrite. */\r\n to: fd\r\n): errno;\r\n\r\n/** Move the offset of a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_seek(\r\n /** Input: The file descriptor to operate on. */\r\n fd: fd,\r\n /** Input: The number of bytes to move. */\r\n offset: filedelta,\r\n /** Input: The base from which the offset is relative. */\r\n whence: whence,\r\n /** Output: The new offset of the file descriptor, relative to the start of the file. */\r\n newoffset: ptr\r\n): errno;\r\n\r\n/** Synchronize the data and metadata of a file to disk. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_sync(\r\n /** Input: The file descriptor of the file containing the data and metadata to synchronize to disk. */\r\n fd: fd\r\n): errno;\r\n\r\n/** Return the current offset of a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_tell(\r\n /** Input: The file descriptor to inspect. */\r\n fd: fd,\r\n /** Output: The current offset of the file descriptor, relative to the start of the file. */\r\n newoffset: ptr\r\n): errno;\r\n\r\n/** Write to a file descriptor. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function fd_write(\r\n /** Input: The file descriptor to which to write data. */\r\n fd: fd,\r\n /** Input: List of scatter/gather vectors from which to retrieve data. */\r\n iovs: ptr>,\r\n /** Input: List of scatter/gather vectors from which to retrieve data. */\r\n iovs_len: usize,\r\n /** Output: The number of bytes written. */\r\n nwritten: ptr\r\n): errno;\r\n\r\n/* Create a directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_create_directory(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: The path at which to create the directory. */\r\n path: ptr,\r\n /** Input: The path at which to create the directory. */\r\n path_len: usize\r\n): errno;\r\n\r\n/** Return the attributes of a file or directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_filestat_get(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: Flags determining the method of how the path is resolved. */\r\n flags: lookupflags,\r\n /** Input: The path of the file or directory to inspect. */\r\n path: ptr,\r\n /** Input: The path of the file or directory to inspect. */\r\n path_len: usize,\r\n /** Input: The buffer where the file's attributes are stored. */\r\n buf: struct\r\n): errno;\r\n\r\n/** Adjust the timestamps of a file or directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_filestat_set_times(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: Flags determining the method of how the path is resolved. */\r\n flags: lookupflags,\r\n /** Input: The path of the file or directory to operate on. */\r\n path: ptr,\r\n /** Input: The path of the file or directory to operate on. */\r\n path_len: usize,\r\n /** Input: The desired values of the data access timestamp. */\r\n st_atim: timestamp,\r\n /** Input: The desired values of the data modification timestamp. */\r\n st_mtim: timestamp,\r\n /** Input: A bitmask indicating which timestamps to adjust. */\r\n fstflags: fstflags\r\n): errno;\r\n\r\n/** Create a hard link. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_link(\r\n /** Input: The working directory at which the resolution of the old path starts. */\r\n old_fd: fd,\r\n /** Input: Flags determining the method of how the path is resolved. */\r\n old_flags: lookupflags,\r\n /** Input: The source path from which to link. */\r\n old_path: ptr,\r\n /** Input: The source path from which to link. */\r\n old_path_len: usize,\r\n /** Input: The working directory at which the resolution of the new path starts. */\r\n new_fd: fd,\r\n /** Input: The destination path at which to create the hard link. */\r\n new_path: ptr,\r\n /** Input: The length of the destination path at which to create the hard link. */\r\n new_path_len: usize\r\n): errno;\r\n\r\n/** Open a file or directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_open(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n dirfd: fd,\r\n /** Input: Flags determining the method of how the path is resolved. */\r\n dirflags: lookupflags,\r\n /** Input: The path of the file or directory to open. */\r\n path: ptr,\r\n /** Input: The length of the path of the file or directory to open. */\r\n path_len: usize,\r\n /** Input: The method by which to open the file. */\r\n oflags: oflags,\r\n /** Input: The initial base rights that apply to operations using the file descriptor itself. */\r\n fs_rights_base: rights,\r\n /** Input: The initial inheriting rights that apply to file descriptors derived from it. */\r\n fs_rights_inheriting: rights,\r\n /** Input: The initial flags of the file descriptor. */\r\n fs_flags: fdflags,\r\n /** Output: The file descriptor of the file that has been opened. */\r\n fd: ptr\r\n): errno;\r\n\r\n/** Read the contents of a symbolic link. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_readlink(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: The path of the symbolic link from which to read. */\r\n path: ptr,\r\n /** Input: The length of the path of the symbolic link from which to read. */\r\n path_len: usize,\r\n /** Input: The buffer to which to write the contents of the symbolic link. */\r\n buf: ptr,\r\n /** Input: The length of the buffer to which to write the contents of the symbolic link. */\r\n buf_len: usize,\r\n /** Output: The number of bytes placed in the buffer. */\r\n buf_used: ptr\r\n): errno;\r\n\r\n/** Remove a directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_remove_directory(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: The path to a directory to remove. */\r\n path: ptr,\r\n /** Input: The length of the path to a directory to remove. */\r\n path_len: usize\r\n): errno;\r\n\r\n/** Rename a file or directory. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_rename(\r\n /** Input: The working directory at which the resolution of the old path starts. */\r\n old_fd: fd,\r\n /** Input: The source path of the file or directory to rename. */\r\n old_path: ptr,\r\n /** Input: The length of the source path of the file or directory to rename. */\r\n old_path_len: usize,\r\n /** Input: The working directory at which the resolution of the new path starts. */\r\n new_fd: fd,\r\n /** Input: The destination path to which to rename the file or directory. */\r\n new_path: ptr,\r\n /** Input: The length of the destination path to which to rename the file or directory. */\r\n new_path_len: usize\r\n): errno;\r\n\r\n/** Create a symbolic link. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_symlink(\r\n /** Input: The contents of the symbolic link. */\r\n old_path: ptr,\r\n /** Input: The length of the contents of the symbolic link. */\r\n old_path_len: usize,\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: The destination path at which to create the symbolic link. */\r\n new_path: ptr,\r\n /** Input: The length of the destination path at which to create the symbolic link. */\r\n new_path_len: usize\r\n): errno;\r\n\r\n/** Unlink a file. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function path_unlink_file(\r\n /** Input: The working directory at which the resolution of the path starts. */\r\n fd: fd,\r\n /** Input: The path to a file to unlink. */\r\n path: ptr,\r\n /** Input: The length of the path to a file to unlink. */\r\n path_len: usize\r\n): errno;\r\n\r\n/** Concurrently poll for the occurrence of a set of events. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function poll_oneoff(\r\n /** Input: The events to which to subscribe. */\r\n in_: ptr>,\r\n /** Input: The events that have occurred. */\r\n out: ptr>,\r\n /** Input: Both the number of subscriptions and events. */\r\n nsubscriptions: usize,\r\n /** Output: The number of events stored. */\r\n nevents: ptr\r\n): errno;\r\n\r\n/** Terminate the process normally. An exit code of 0 indicates successful termination of the program. The meanings of other values is dependent on the environment. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function proc_exit(\r\n /** Input: The exit code returned by the process. */\r\n rval: u32\r\n): void;\r\n\r\n/** Send a signal to the process of the calling thread. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function proc_raise(\r\n /** Input: The signal condition to trigger. */\r\n sig: signal\r\n): errno;\r\n\r\n/** Write high-quality random data into a buffer. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function random_get(\r\n /** Input: The buffer to fill with random data. */\r\n buf: usize,\r\n /** Input: The length of the buffer to fill with random data. */\r\n buf_len: usize\r\n): errno;\r\n\r\n/** Temporarily yield execution of the calling thread. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function sched_yield(): errno;\r\n\r\n/** Receive a message from a socket. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function sock_recv(\r\n /** Input: The socket on which to receive data. */\r\n sock: fd,\r\n /** Input: List of scatter/gather vectors to which to store data. */\r\n ri_data: ptr>,\r\n /** Input: The length of the list of scatter/gather vectors to which to store data. */\r\n ri_data_len: usize,\r\n /** Input: Message flags. */\r\n ri_flags: riflags,\r\n /** Output: Number of bytes stored in `ri_data`. */\r\n ro_datalen: ptr,\r\n /** Output: Message flags. */\r\n ro_flags: ptr\r\n): errno;\r\n\r\n/** Send a message on a socket. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function sock_send(\r\n /** Input: The socket on which to send data. */\r\n sock: fd,\r\n /** Input: List of scatter/gather vectors to which to retrieve data */\r\n si_data: ptr>,\r\n /** Input: The length of the list of scatter/gather vectors to which to retrieve data */\r\n si_data_len: usize,\r\n /** Input: Message flags. */\r\n si_flags: siflags,\r\n /** Output: Number of bytes transmitted. */\r\n so_datalen: ptr\r\n): errno;\r\n\r\n/** Shut down socket send and receive channels. */\r\n// @ts-ignore: decorator\r\n@unsafe\r\nexport declare function sock_shutdown(\r\n /** Input: The socket on which to shutdown channels. */\r\n sock: fd,\r\n /** Input: Which channels on the socket to shut down. */\r\n how: sdflags\r\n): errno;\r\n\r\n// === Types ======================================================================================\r\n\r\n/** File or memory access pattern advisory information. */\r\nexport namespace advice {\r\n /** The application has no advice to give on its behavior with respect to the specified data. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NORMAL: advice = 0;\r\n /** The application expects to access the specified data sequentially from lower offsets to higher offsets. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SEQUENTIAL : advice = 1;\r\n /** The application expects to access the specified data in a random order. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const RANDOM: advice = 2;\r\n /** The application expects to access the specified data in the near future. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const WILLNEED: advice = 3;\r\n /** The application expects that it will not access the specified data in the near future. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DONTNEED: advice = 4;\r\n /** The application expects to access the specified data once and then not reuse it thereafter. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOREUSE: advice = 5;\r\n}\r\nexport type advice = u8;\r\n\r\n/** Identifiers for clocks. */\r\nexport namespace clockid {\r\n /** The clock measuring real time. Time value zero corresponds with 1970-01-01T00:00:00Z. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const REALTIME: clockid = 0;\r\n /** The store-wide monotonic clock. Absolute value has no meaning. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const MONOTONIC: clockid = 1;\r\n /** The CPU-time clock associated with the current process. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PROCESS_CPUTIME_ID: clockid = 2;\r\n /** The CPU-time clock associated with the current thread. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const THREAD_CPUTIME_ID: clockid = 3;\r\n}\r\nexport type clockid = u32;\r\n\r\n/** Identifier for a device containing a file system. Can be used in combination with `inode` to uniquely identify a file or directory in the filesystem. */\r\nexport type device = u64;\r\n\r\n/** A reference to the offset of a directory entry. The value 0 signifies the start of the directory. */\r\nexport type dircookie = u64;\r\n\r\n/** A directory entry. */\r\n@unmanaged export class dirent {\r\n /** The offset of the next directory entry stored in this directory. */\r\n next: dircookie;\r\n /** The serial number of the file referred to by this directory entry. */\r\n ino: inode;\r\n /** The length of the name of the directory entry. */\r\n namlen: u32;\r\n /** The type of the file referred to by this directory entry. */\r\n type: filetype;\r\n private __padding0: u16;\r\n}\r\n\r\n/** Error codes returned by functions. */\r\nexport namespace errno {\r\n /** No error occurred. System call completed successfully. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SUCCESS: errno = 0;\r\n /** Argument list too long. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TOOBIG: errno = 1;\r\n /** Permission denied. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ACCES: errno = 2;\r\n /** Address in use. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ADDRINUSE: errno = 3;\r\n /** Address not available. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ADDRNOTAVAIL: errno = 4;\r\n /** Address family not supported. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const AFNOSUPPORT: errno = 5;\r\n /** Resource unavailable, or operation would block. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const AGAIN: errno = 6;\r\n /** Connection already in progress. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ALREADY: errno = 7;\r\n /** Bad file descriptor. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const BADF: errno = 8;\r\n /** Bad message. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const BADMSG: errno = 9;\r\n /** Device or resource busy. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const BUSY: errno = 10;\r\n /** Operation canceled. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CANCELED: errno = 11;\r\n /** No child processes. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CHILD: errno = 12;\r\n /** Connection aborted. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CONNABORTED: errno = 13;\r\n /** Connection refused. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CONNREFUSED: errno = 14;\r\n /** Connection reset. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CONNRESET: errno = 15;\r\n /** Resource deadlock would occur. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DEADLK: errno = 16;\r\n /** Destination address required. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DESTADDRREQ: errno = 17;\r\n /** Mathematics argument out of domain of function. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DOM: errno = 18;\r\n /** Reserved. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DQUOT: errno = 19;\r\n /** File exists. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const EXIST: errno = 20;\r\n /** Bad address. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FAULT: errno = 21;\r\n /** File too large. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FBIG: errno = 22;\r\n /** Host is unreachable. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const HOSTUNREACH: errno = 23;\r\n /** Identifier removed. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const IDRM: errno = 24;\r\n /** Illegal byte sequence. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ILSEQ: errno = 25;\r\n /** Operation in progress. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const INPROGRESS: errno = 26;\r\n /** Interrupted function. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const INTR: errno = 27;\r\n /** Invalid argument. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const INVAL: errno = 28;\r\n /** I/O error. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const IO: errno = 29;\r\n /** Socket is connected. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ISCONN: errno = 30;\r\n /** Is a directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ISDIR: errno = 31;\r\n /** Too many levels of symbolic links. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const LOOP: errno = 32;\r\n /** File descriptor value too large. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const MFILE: errno = 33;\r\n /** Too many links. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const MLINK: errno = 34;\r\n /** Message too large. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const MSGSIZE: errno = 35;\r\n /** Reserved. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const MULTIHOP: errno = 36;\r\n /** Filename too long. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NAMETOOLONG: errno = 37;\r\n /** Network is down. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NETDOWN: errno = 38;\r\n /** Connection aborted by network. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NETRESET: errno = 39;\r\n /** Network unreachable. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NETUNREACH: errno = 40;\r\n /** Too many files open in system. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NFILE: errno = 41;\r\n /** No buffer space available. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOBUFS: errno = 42;\r\n /** No such device. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NODEV: errno = 43;\r\n /** No such file or directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOENT: errno = 44;\r\n /** Executable file format error. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOEXEC: errno = 45;\r\n /** No locks available. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOLCK: errno = 46;\r\n /** Reserved. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOLINK: errno = 47;\r\n /** Not enough space. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOMEM: errno = 48;\r\n /** No message of the desired type. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOMSG: errno = 49;\r\n /** Protocol not available. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOPROTOOPT: errno = 50;\r\n /** No space left on device. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOSPC: errno = 51;\r\n /** Function not supported. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOSYS: errno = 52;\r\n /** The socket is not connected. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTCONN: errno = 53;\r\n /** Not a directory or a symbolic link to a directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTDIR: errno = 54;\r\n /** Directory not empty. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTEMPTY: errno = 55;\r\n /** State not recoverable. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTRECOVERABLE: errno = 56;\r\n /** Not a socket. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTSOCK: errno = 57;\r\n /** Not supported, or operation not supported on socket. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTSUP: errno = 58;\r\n /** Inappropriate I/O control operation. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTTY: errno = 59;\r\n /** No such device or address. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NXIO: errno = 60;\r\n /** Value too large to be stored in data type. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const OVERFLOW: errno = 61;\r\n /** Previous owner died. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const OWNERDEAD: errno = 62;\r\n /** Operation not permitted. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PERM: errno = 63;\r\n /** Broken pipe. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PIPE: errno = 64;\r\n /** Protocol error. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PROTO: errno = 65;\r\n /** Protocol not supported. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PROTONOSUPPORT: errno = 66;\r\n /** Protocol wrong type for socket. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PROTOTYPE: errno = 67;\r\n /** Result too large. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const RANGE: errno = 68;\r\n /** Read-only file system. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ROFS: errno = 69;\r\n /** Invalid seek. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SPIPE: errno = 70;\r\n /** No such process. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SRCH: errno = 71;\r\n /** Reserved. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const STALE: errno = 72;\r\n /** Connection timed out. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TIMEDOUT: errno = 73;\r\n /** Text file busy. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TXTBSY: errno = 74;\r\n /** Cross-device link. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const XDEV: errno = 75;\r\n /** Extension: Capabilities insufficient. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NOTCAPABLE: errno = 76;\r\n}\r\nexport type errno = u16;\r\n\r\n/** Translates an error code to a string. */\r\nexport function errnoToString(err: errno): string {\r\n switch (err) {\r\n case errno.SUCCESS: return \"SUCCESS\";\r\n case errno.TOOBIG: return \"TOOBIG\";\r\n case errno.ACCES: return \"ACCES\";\r\n case errno.ADDRINUSE: return \"ADDRINUSE\";\r\n case errno.ADDRNOTAVAIL: return \"ADDRNOTAVAIL\";\r\n case errno.AFNOSUPPORT: return \"AFNOSUPPORT\";\r\n case errno.AGAIN: return \"AGAIN\";\r\n case errno.ALREADY: return \"ALREADY\";\r\n case errno.BADF: return \"BADF\";\r\n case errno.BADMSG: return \"BADMSG\";\r\n case errno.BUSY: return \"BUSY\";\r\n case errno.CANCELED: return \"CANCELED\";\r\n case errno.CHILD: return \"CHILD\";\r\n case errno.CONNABORTED: return \"CONNABORTED\";\r\n case errno.CONNREFUSED: return \"CONNREFUSED\";\r\n case errno.CONNRESET: return \"CONNRESET\";\r\n case errno.DEADLK: return \"DEADLK\";\r\n case errno.DESTADDRREQ: return \"DESTADDRREQ\";\r\n case errno.DOM: return \"DOM\";\r\n case errno.DQUOT: return \"DQUOT\";\r\n case errno.EXIST: return \"EXIST\";\r\n case errno.FAULT: return \"FAULT\";\r\n case errno.FBIG: return \"FBIG\";\r\n case errno.HOSTUNREACH: return \"HOSTUNREACH\";\r\n case errno.IDRM: return \"IDRM\";\r\n case errno.ILSEQ: return \"ILSEQ\";\r\n case errno.INPROGRESS: return \"INPROGRESS\";\r\n case errno.INTR: return \"INTR\";\r\n case errno.INVAL: return \"INVAL\";\r\n case errno.IO: return \"IO\";\r\n case errno.ISCONN: return \"ISCONN\";\r\n case errno.ISDIR: return \"ISDIR\";\r\n case errno.LOOP: return \"LOOP\";\r\n case errno.MFILE: return \"MFILE\";\r\n case errno.MLINK: return \"MLINK\";\r\n case errno.MSGSIZE: return \"MSGSIZE\";\r\n case errno.MULTIHOP: return \"MULTIHOP\";\r\n case errno.NAMETOOLONG: return \"NAMETOOLONG\";\r\n case errno.NETDOWN: return \"NETDOWN\";\r\n case errno.NETRESET: return \"NETRESET\";\r\n case errno.NETUNREACH: return \"NETUNREACH\";\r\n case errno.NFILE: return \"NFILE\";\r\n case errno.NOBUFS: return \"NOBUFS\";\r\n case errno.NODEV: return \"NODEV\";\r\n case errno.NOENT: return \"NOENT\";\r\n case errno.NOEXEC: return \"NOEXEC\";\r\n case errno.NOLCK: return \"NOLCK\";\r\n case errno.NOLINK: return \"NOLINK\";\r\n case errno.NOMEM: return \"NOMEM\";\r\n case errno.NOMSG: return \"NOMSG\";\r\n case errno.NOPROTOOPT: return \"NOPROTOOPT\";\r\n case errno.NOSPC: return \"NOSPC\";\r\n case errno.NOSYS: return \"NOSYS\";\r\n case errno.NOTCONN: return \"NOTCONN\";\r\n case errno.NOTDIR: return \"NOTDIR\";\r\n case errno.NOTEMPTY: return \"NOTEMPTY\";\r\n case errno.NOTRECOVERABLE: return \"NOTRECOVERABLE\";\r\n case errno.NOTSOCK: return \"NOTSOCK\";\r\n case errno.NOTSUP: return \"NOTSUP\";\r\n case errno.NOTTY: return \"NOTTY\";\r\n case errno.NXIO: return \"NXIO\";\r\n case errno.OVERFLOW: return \"OVERFLOW\";\r\n case errno.OWNERDEAD: return \"OWNERDEAD\";\r\n case errno.PERM: return \"PERM\";\r\n case errno.PIPE: return \"PIPE\";\r\n case errno.PROTO: return \"PROTO\";\r\n case errno.PROTONOSUPPORT: return \"PROTONOSUPPORT\";\r\n case errno.PROTOTYPE: return \"PROTOTYPE\";\r\n case errno.RANGE: return \"RANGE\";\r\n case errno.ROFS: return \"ROFS\";\r\n case errno.SPIPE: return \"SPIPE\";\r\n case errno.SRCH: return \"SRCH\";\r\n case errno.STALE: return \"STALE\";\r\n case errno.TIMEDOUT: return \"TIMEDOUT\";\r\n case errno.TXTBSY: return \"TXTBSY\";\r\n case errno.XDEV: return \"XDEV\";\r\n case errno.NOTCAPABLE: return \"NOTCAPABLE\";\r\n }\r\n return \"UNKNOWN\";\r\n}\r\n\r\n@unmanaged abstract class $event { // size=16/32\r\n /** User-provided value that got attached to `subscription#userdata`. */\r\n userdata: userdata;\r\n /** If non-zero, an error that occurred while processing the subscription request. */\r\n error: errno;\r\n /** The type of the event that occurred. */\r\n type: eventtype;\r\n\r\n private __padding0: u16;\r\n}\r\n\r\n/** An event that occurred. */\r\n@unmanaged export abstract class event extends $event {\r\n private __padding1: u64;\r\n private __padding2: u64;\r\n}\r\n\r\n/** An event that occurred when type is `eventtype.FD_READ` or `eventtype.FD_WRITE`. */\r\n@unmanaged export class event_fd_readwrite extends $event {\r\n /* The number of bytes available for reading or writing. */\r\n nbytes: filesize;\r\n /* The state of the file descriptor. */\r\n flags: eventrwflags;\r\n\r\n private __padding1: u32;\r\n}\r\n\r\n/** The state of the file descriptor subscribed to with `eventtype.FD_READ` or `eventtype.FD_WRITE`. */\r\nexport namespace eventrwflags {\r\n /** The peer of this socket has closed or disconnected. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const HANGUP: eventrwflags = 1;\r\n}\r\nexport type eventrwflags = u16;\r\n\r\n/** Type of a subscription to an event or its occurrence. */\r\nexport namespace eventtype {\r\n /** The time value of clock has reached the timestamp. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CLOCK: eventtype = 0;\r\n /** File descriptor has data available for reading. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_READ: eventtype = 1;\r\n /** File descriptor has capacity available for writing */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_WRITE: eventtype = 2;\r\n}\r\nexport type eventtype = u8;\r\n\r\n/** Exit code generated by a process when exiting. */\r\nexport type exitcode = u32;\r\n\r\n/** A file descriptor number. */\r\nexport type fd = u32;\r\n\r\n/** File descriptor flags. */\r\nexport namespace fdflags {\r\n /** Append mode: Data written to the file is always appended to the file's end. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const APPEND: fdflags = 1;\r\n /** Write according to synchronized I/O data integrity completion. Only the data stored in the file is synchronized. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DSYNC: fdflags = 2;\r\n /** Non-blocking mode. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const NONBLOCK: fdflags = 4;\r\n /** Synchronized read I/O operations. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const RSYNC: fdflags = 8;\r\n /** Write according to synchronized I/O file integrity completion. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SYNC: fdflags = 16;\r\n}\r\nexport type fdflags = u16;\r\n\r\n/** File descriptor attributes. */\r\n@unmanaged export class fdstat {\r\n /** File type. */\r\n filetype: filetype;\r\n /** File descriptor flags. */\r\n flags: fdflags;\r\n /** Rights that apply to this file descriptor. */\r\n rights_base: rights;\r\n /** Maximum set of rights that may be installed on new file descriptors that are created through this file descriptor, e.g., through `path_open`. */\r\n rights_inheriting: rights;\r\n}\r\n\r\n/** Relative offset within a file. */\r\nexport type filedelta = i64;\r\n\r\n/** Non-negative file size or length of a region within a file. */\r\nexport type filesize = u64;\r\n\r\n/** File attributes. */\r\n@unmanaged export class filestat {\r\n /** Device ID of device containing the file. */\r\n dev: device;\r\n /** File serial number. */\r\n ino: inode;\r\n /** File type. */\r\n filetype: filetype;\r\n /** Number of hard links to the file. */\r\n nlink: linkcount;\r\n /** For regular files, the file size in bytes. For symbolic links, the length in bytes of the pathname contained in the symbolic link. */\r\n size: filesize;\r\n /** Last data access timestamp. */\r\n atim: timestamp;\r\n /** Last data modification timestamp. */\r\n mtim: timestamp;\r\n /** Last file status change timestamp. */\r\n ctim: timestamp;\r\n}\r\n\r\n/** The type of a file descriptor or file. */\r\nexport namespace filetype {\r\n /** The type of the file descriptor or file is unknown or is different from any of the other types specified. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const UNKNOWN: filetype = 0;\r\n /** The file descriptor or file refers to a block device inode. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const BLOCK_DEVICE: filetype = 1;\r\n /** The file descriptor or file refers to a character device inode. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CHARACTER_DEVICE: filetype = 2;\r\n /** The file descriptor or file refers to a directory inode. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DIRECTORY: filetype = 3;\r\n /** The file descriptor or file refers to a regular file inode. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const REGULAR_FILE: filetype = 4;\r\n /** The file descriptor or file refers to a datagram socket. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SOCKET_DGRAM: filetype = 5;\r\n /** The file descriptor or file refers to a byte-stream socket. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SOCKET_STREAM: filetype = 6;\r\n /** The file refers to a symbolic link inode. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SYMBOLIC_LINK: filetype = 7;\r\n}\r\nexport type filetype = u8;\r\n\r\n/** Which file time attributes to adjust. */\r\nexport namespace fstflags {\r\n /** Adjust the last data access timestamp to the value stored in `filestat#st_atim`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SET_ATIM: fstflags = 1;\r\n /** Adjust the last data access timestamp to the time of clock `clockid.REALTIME`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SET_ATIM_NOW: fstflags = 2;\r\n /** Adjust the last data modification timestamp to the value stored in `filestat#st_mtim`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SET_MTIM: fstflags = 4;\r\n /** Adjust the last data modification timestamp to the time of clock `clockid.REALTIME`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SET_MTIM_NOW: fstflags = 8;\r\n}\r\nexport type fstflags = u16;\r\n\r\n/** File serial number that is unique within its file system. */\r\nexport type inode = u64;\r\n\r\n/** A region of memory for scatter/gather reads. */\r\n@unmanaged export class iovec {\r\n /** The address of the buffer to be filled. */\r\n buf: usize;\r\n /** The length of the buffer to be filled. */\r\n buf_len: usize;\r\n}\r\n\r\n/** Number of hard links to an inode. */\r\nexport type linkcount = u64;\r\n\r\n/** Flags determining the method of how paths are resolved. */\r\nexport namespace lookupflags {\r\n /** As long as the resolved path corresponds to a symbolic link, it is expanded. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SYMLINK_FOLLOW: lookupflags = 1;\r\n}\r\nexport type lookupflags = u32;\r\n\r\n/** Open flags. */\r\nexport namespace oflags {\r\n /** Create file if it does not exist. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CREAT: oflags = 1;\r\n /** Fail if not a directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DIRECTORY: oflags = 2;\r\n /** Fail if file already exists. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const EXCL: oflags = 4;\r\n /** Truncate file to size 0. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TRUNC: oflags = 8;\r\n}\r\nexport type oflags = u16;\r\n\r\n/** Identifiers for preopened capabilities. */\r\nexport namespace preopentype {\r\n /** A pre-opened directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DIR: preopentype = 0;\r\n}\r\nexport type preopentype = u8;\r\n\r\n@unmanaged abstract class $prestat { // WASM32: size=1/8, WASM64: size=1/16\r\n /* The type of the pre-opened capability. */\r\n type: preopentype;\r\n}\r\n\r\n/* Information about a pre-opened capability. */\r\n@unmanaged export abstract class prestat extends $prestat {\r\n private __padding0: usize;\r\n}\r\n\r\n/** The contents of a $prestat when type is `preopentype.DIR`. */\r\n@unmanaged export class prestat_dir extends $prestat {\r\n /** The length of the directory name for use with `fd_prestat_dir_name`. */\r\n name_len: usize;\r\n}\r\n\r\n/** Flags provided to `sock_recv`. */\r\nexport namespace riflags {\r\n /** Returns the message without removing it from the socket's receive queue. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PEEK: riflags = 1;\r\n /** On byte-stream sockets, block until the full amount of data can be returned. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const WAITALL: riflags = 2;\r\n}\r\nexport type riflags = u16;\r\n\r\n/** File descriptor rights, determining which actions may be performed. */\r\nexport namespace rights {\r\n /** The right to invoke `fd_datasync`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_DATASYNC: rights = 1;\r\n /** The right to invoke `fd_read` and `sock_recv`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_READ: rights = 2;\r\n /** The right to invoke `fd_seek`. This flag implies `rights.FD_TELL`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_SEEK: rights = 4;\r\n /** The right to invoke `fd_fdstat_set_flags`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_FDSTAT_SET_FLAGS: rights = 8;\r\n /** The right to invoke `fd_sync`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_SYNC: rights = 16;\r\n /** The right to invoke `fd_seek` in such a way that the file offset remains unaltered (i.e., `whence.CUR` with offset zero), or to invoke `fd_tell`). */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_TELL: rights = 32;\r\n /** The right to invoke `fd_write` and `sock_send`. If `rights.FD_SEEK` is set, includes the right to invoke `fd_pwrite`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_WRITE: rights = 64;\r\n /** The right to invoke `fd_advise`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_ADVISE: rights = 128;\r\n /** The right to invoke `fd_allocate`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_ALLOCATE: rights = 256;\r\n /** The right to invoke `path_create_directory`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_CREATE_DIRECTORY: rights = 512;\r\n /** If `rights.PATH_OPEN` is set, the right to invoke `path_open` with `oflags.CREAT`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_CREATE_FILE: rights = 1024;\r\n /** The right to invoke `path_link` with the file descriptor as the source directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_LINK_SOURCE: rights = 2048;\r\n /** The right to invoke `path_link` with the file descriptor as the target directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_LINK_TARGET: rights = 4096;\r\n /** The right to invoke `path_open`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_OPEN: rights = 8192;\r\n /** The right to invoke `fd_readdir`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_READDIR: rights = 16384;\r\n /** The right to invoke `path_readlink`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_READLINK: rights = 32768;\r\n /** The right to invoke `path_rename` with the file descriptor as the source directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_RENAME_SOURCE: rights = 65536;\r\n /** The right to invoke `path_rename` with the file descriptor as the target directory. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_RENAME_TARGET: rights = 131072;\r\n /** The right to invoke `path_filestat_get`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_FILESTAT_GET: rights = 262144;\r\n /** The right to change a file's size (there is no `path_filestat_set_size`). If `rights.PATH_OPEN` is set, includes the right to invoke `path_open` with `oflags.TRUNC`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_FILESTAT_SET_SIZE: rights = 524288;\r\n /** The right to invoke `path_filestat_set_times`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_FILESTAT_SET_TIMES: rights = 1048576;\r\n /** The right to invoke `fd_filestat_get`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_FILESTAT_GET: rights = 2097152;\r\n /** The right to invoke `fd_filestat_set_size`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_FILESTAT_SET_SIZE: rights = 4194304;\r\n /** The right to invoke `fd_filestat_set_times`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FD_FILESTAT_SET_TIMES: rights = 8388608;\r\n /** The right to invoke `path_symlink`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const RIGHT_PATH_SYMLINK: rights = 16777216;\r\n /** The right to invoke `path_remove_directory`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_REMOVE_DIRECTORY: rights = 33554432;\r\n /** The right to invoke `path_unlink_file`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PATH_UNLINK_FILE: rights = 67108864;\r\n /** If `rights.FD_READ` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype.FD_READ`. If `rights.FD_WRITE` is set, includes the right to invoke `poll_oneoff` to subscribe to `eventtype.FD_WRITE`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const POLL_FD_READWRITE: rights = 134217728;\r\n /** The right to invoke `sock_shutdown`. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SOCK_SHUTDOWN: rights = 268435456;\r\n}\r\nexport type rights = u64;\r\n\r\n/** Flags returned by `sock_recv`. */\r\nexport namespace roflags {\r\n /** Message data has been truncated. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const DATA_TRUNCATED: roflags = 1;\r\n}\r\nexport type roflags = u16;\r\n\r\n/** Which channels on a socket to shut down. */\r\nexport namespace sdflags {\r\n /** Disables further receive operations. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const RD: sdflags = 1;\r\n /** Disables further send operations. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const WR: sdflags = 2;\r\n}\r\nexport type sdflags = u8;\r\n\r\n/** Flags provided to `sock_send`. */\r\nexport namespace siflags {\r\n // As there are currently no flags defined, it must be set to zero.\r\n}\r\nexport type siflags = u16;\r\n\r\n/** Signal condition. */\r\nexport namespace signal {\r\n /** Hangup. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const HUP: signal = 1;\r\n /** Terminate interrupt signal. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const INT: signal = 2;\r\n /** Terminal quit signal. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const QUIT: signal = 3;\r\n /** Illegal instruction. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ILL: signal = 4;\r\n /** Trace/breakpoint trap. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TRAP: signal = 5;\r\n /** Process abort signal. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ABRT: signal = 6;\r\n /** Access to an undefined portion of a memory object. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const BUS: signal = 7;\r\n /** Erroneous arithmetic operation. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const FPE: signal = 8;\r\n /** Kill. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const KILL: signal = 9;\r\n /** User-defined signal 1. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const USR1: signal = 10;\r\n /** Invalid memory reference. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SEGV: signal = 11;\r\n /** User-defined signal 2. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const USR2: signal = 12;\r\n /** Write on a pipe with no one to read it. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PIPE: signal = 13;\r\n /** Alarm clock. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ALRM: signal = 14;\r\n /** Termination signal. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TERM: signal = 15;\r\n /** Child process terminated, stopped, or continued. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CHLD: signal = 16;\r\n /** Continue executing, if stopped. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CONT: signal = 17;\r\n /** Stop executing. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const STOP: signal = 18;\r\n /** Terminal stop signal. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TSTP: signal = 19;\r\n /** Background process attempting read. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TTIN: signal = 20;\r\n /** Background process attempting write. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const TTOU: signal = 21;\r\n /** High bandwidth data is available at a socket. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const URG: signal = 22;\r\n /** CPU time limit exceeded. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const XCPU: signal = 23;\r\n /** File size limit exceeded. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const XFSZ: signal = 24;\r\n /** Virtual timer expired. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const VTALRM: signal = 25;\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PROF: signal = 26;\r\n // @ts-ignore: decorator\r\n @inline\r\n export const WINCH: signal = 27;\r\n // @ts-ignore: decorator\r\n @inline\r\n export const POLL: signal = 28;\r\n // @ts-ignore: decorator\r\n @inline\r\n export const PWR: signal = 29;\r\n /** Bad system call. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SYS: signal = 30;\r\n}\r\nexport type signal = u8;\r\n\r\n/** Flags determining how to interpret the timestamp provided in `subscription_t::u.clock.timeout. */\r\nexport namespace subclockflags {\r\n /** If set, treat the timestamp provided in `clocksubscription` as an absolute timestamp. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const ABSTIME: subclockflags = 1;\r\n}\r\nexport type subclockflags = u16;\r\n\r\n@unmanaged abstract class $subscription { // size=16/48\r\n /** User-provided value that is attached to the subscription. */\r\n userdata: userdata;\r\n /** The type of the event to which to subscribe. */\r\n type: eventtype;\r\n\r\n private __padding0: u32;\r\n}\r\n\r\n/** Subscription to an event. */\r\n@unmanaged export abstract class subscription extends $subscription {\r\n private __padding1: u64;\r\n private __padding2: u64;\r\n private __padding3: u64;\r\n private __padding4: u64;\r\n}\r\n\r\n/* Subscription to an event of type `eventtype.CLOCK`.**/\r\n@unmanaged export class subscription_clock extends $subscription {\r\n /** The clock against which to compare the timestamp. */\r\n clock_id: clockid;\r\n /** The absolute or relative timestamp. */\r\n timeout: timestamp;\r\n /** The amount of time that the implementation may wait additionally to coalesce with other events. */\r\n precision: timestamp;\r\n /** Flags specifying whether the timeout is absolute or relative. */\r\n flags: subclockflags;\r\n\r\n private __padding1: u32;\r\n}\r\n\r\n/* Subscription to an event of type `eventtype.FD_READ` or `eventtype.FD_WRITE`.**/\r\n@unmanaged export class subscription_fd_readwrite extends $subscription {\r\n /** The file descriptor on which to wait for it to become ready for reading or writing. */\r\n file_descriptor: fd;\r\n\r\n private __padding1: u64;\r\n private __padding2: u64;\r\n private __padding3: u64;\r\n}\r\n\r\n/** Timestamp in nanoseconds. */\r\nexport type timestamp = u64;\r\n\r\n/** User-provided value that may be attached to objects that is retained when extracted from the implementation. */\r\nexport type userdata = u64;\r\n\r\n/** The position relative to which to set the offset of the file descriptor. */\r\nexport namespace whence {\r\n /** Seek relative to start-of-file. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const SET: whence = 0;\r\n /** Seek relative to current position. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const CUR: whence = 1;\r\n /** Seek relative to end-of-file. */\r\n // @ts-ignore: decorator\r\n @inline\r\n export const END: whence = 2;\r\n}\r\n\r\nexport type whence = u8;\r\n","import { describe, endTest, expect, test } from \"../assembly\";\n\ndescribe(\"expect\", () => {\n test(\"< = >\", () => {\n let expectValue = expect(0);\n let eq = expectValue.equal;\n eq.call(expectValue, 1);\n expect(1).equal(1);\n expect(1).notEqual(0);\n expect(1.23).closeTo(1.230001, 0.01);\n expect(1).greaterThan(0);\n expect(1).greaterThanOrEqual(0);\n expect(1).greaterThanOrEqual(1);\n expect(1).lessThan(2);\n expect(1).lessThanOrEqual(2);\n expect(1).lessThanOrEqual(1);\n });\n test(\"null\", () => {\n expect(null).isNull();\n expect(\"test\").notNull();\n });\n});\n\nendTest();\n","import { Value } from \"./expect\";\nimport {\n describeImpl,\n mockImpl,\n remockImpl,\n testImpl,\n unmockImpl,\n} from \"./implement\";\nimport { output } from \"./output\";\nimport { MockFn } from \"./mockInstrument\";\nexport { MockFn } from \"./mockInstrument\";\n\n/**\n * describe a test group\n * @param description common description of each test inside\n * @param testsFunction can call multi-time test\n */\nexport function describe(description: string, testsFunction: () => void): void {\n describeImpl(description, testsFunction);\n}\n\n/**\n * run a test\n * @param description test description\n * @param testFunction main function of test\n */\nexport function test(description: string, testFunction: () => void): void {\n testImpl(description, testFunction);\n}\n\n/**\n * mock some function\n * @param oldFunction function you want to mock\n * @param newFunction the new function.\n * @returns Mock Status { callTime : u32}\n */\nexport function mock(\n oldFunction: T,\n newFunction: T,\n): MockFn {\n return mockImpl(oldFunction, newFunction);\n}\n/**\n * unmock this function, can only be used in mocked function\n */\nexport function unmock(oldFunction: T): void {\n unmockImpl(oldFunction);\n}\n/**\n * remock this function, can only be used in mocked function. Pair of {unmock}\n */\nexport function remock(oldFunction: T): void {\n remockImpl(oldFunction);\n}\n\nexport function expect(value: T): Value {\n return new Value(value);\n}\n\nexport function endTest(): void {\n output();\n}\n","export function isNull(a: T): bool {\n if (!isReference(a)) {\n ERROR(\"paramemter of isNull should be a reference type\");\n }\n if (!isNullable(a)) {\n ERROR(\"paramemter of isNull should be nullable\");\n }\n return a == null;\n}\n\nfunction includes(set: T[], value: T): bool {\n for (let i = 0; i < set.length; i++) {\n if (equal(set[i], value)) {\n return true;\n }\n }\n return false;\n}\n\nfunction equalArrayBuffer(a: T, b: T): bool {\n if (!(a instanceof ArrayBuffer) || !(b instanceof ArrayBuffer)) {\n return false;\n }\n if (a.byteLength != b.byteLength) {\n return false;\n }\n const aRef = changetype(a);\n const bRef = changetype(b);\n const wordSize = a.byteLength / 4;\n const remainder = a.byteLength % 4;\n for (let i = 0; i < wordSize; i++) {\n if (load(aRef + i * 4) != load(bRef + i * 4)) {\n return false;\n }\n }\n for (let i = 0; i < remainder; i++) {\n if (\n load(aRef + wordSize * 4 + i) != load(bRef + wordSize * 4 + i)\n ) {\n return false;\n }\n }\n return true;\n}\n\nfunction equalArrayLike(a: T, b: T): bool {\n if (!isArrayLike(a) || !isArrayLike(b)) {\n return false;\n }\n if (a.length != b.length) {\n return false;\n }\n for (let i = 0; i < a.length; i++) {\n if (!equal(a[i], b[i])) {\n return false;\n }\n }\n return true;\n}\n\nfunction equalMap(a: Map, b: Map): bool {\n const a_key: T[] = a.keys();\n const b_key: T[] = b.keys();\n if (a_key.length != b_key.length) {\n return false;\n }\n for (let i = 0; i < a_key.length; i++) {\n const k: T = a_key[i];\n if (!includes(b_key, k)) {\n return false;\n }\n if (!equal(a.get(k), b.get(k))) {\n return false;\n }\n }\n return true;\n}\n\nfunction equalSet(a: Set, b: Set): bool {\n if (a.size != b.size) {\n return false;\n }\n const va: T[] = a.values();\n const vb: T[] = b.values();\n for (let i = 0; i < va.length; i++) {\n if (!includes(vb, va[i])) {\n return false;\n }\n }\n return true;\n}\n\nexport function equal(a: T, b: T): bool {\n if (!isReference() || isString()) {\n return a == b;\n }\n if (isNullable(a) || isNullable(b)) {\n if (isNull(a) && isNull(b)) {\n return true;\n }\n if ((isNull(a) && !isNull(b)) || (!isNull(a) && isNull(b))) {\n return false;\n }\n }\n const nonnull_a = >a;\n const nonnull_b = >b;\n if (nonnull_a instanceof ArrayBuffer && nonnull_b instanceof ArrayBuffer) {\n return equalArrayBuffer>(nonnull_a, nonnull_b);\n }\n if (isArrayLike(nonnull_a) && isArrayLike(nonnull_b)) {\n return equalArrayLike>(nonnull_a, nonnull_b);\n }\n if (nonnull_a instanceof Map && nonnull_b instanceof Map) {\n return equalMap(nonnull_a, nonnull_b);\n }\n if (nonnull_a instanceof Set && nonnull_b instanceof Set) {\n return equalSet(nonnull_a, nonnull_b);\n }\n ERROR(\n \"type is not supported to equal, hint: cannot comparison user-defined object\",\n );\n return false;\n}\n","export function toJson(v: T): string {\n if (isNullable(v) && v == null) {\n return \"null\";\n }\n if (isBoolean(v)) {\n return v ? \"true\" : \"false\";\n }\n if (isInteger(v) || isFloat(v) || isFunction(v)) {\n return v.toString();\n }\n if (isString(v)) {\n const str: string = v.toString();\n const jsonchars: string[] = [];\n for (let i = 0; i < str.length; i++) {\n const charCode = str.charCodeAt(i);\n if (\n (charCode >= 0x20 && charCode <= 0x21) ||\n (charCode >= 0x23 && charCode <= 0x5b) ||\n (charCode >= 0x5d && charCode <= 0xffff)\n ) {\n jsonchars.push(str.charAt(i));\n } else {\n switch (charCode) {\n case 0x00:\n jsonchars.push(\"\\\\0\");\n break;\n case 0x07:\n jsonchars.push(\"\\\\a\");\n break;\n case 0x08:\n jsonchars.push(\"\\\\b\");\n break;\n case 0x09:\n jsonchars.push(\"\\\\t\");\n break;\n case 0x0a:\n jsonchars.push(\"\\\\n\");\n break;\n case 0x0b:\n jsonchars.push(\"\\\\v\");\n break;\n case 0x0c:\n jsonchars.push(\"\\\\f\");\n break;\n case 0x0d:\n jsonchars.push(\"\\\\r\");\n break;\n case 0x22:\n jsonchars.push('\\\\\"');\n break;\n case 0x5c:\n jsonchars.push(\"\\\\\\\\\");\n break;\n default: {\n // unknown control code\n const charCodeStr = charCode.toString();\n jsonchars.push(\"\\\\u\");\n for (let i = charCodeStr.length; i < 4; i++) {\n jsonchars.push(\"0\");\n }\n jsonchars.push(charCodeStr);\n }\n }\n }\n }\n return '\"' + jsonchars.join(\"\") + '\"';\n }\n if (v instanceof ArrayBuffer) {\n const tmpArray = Uint8Array.wrap(v);\n const tmpStrArray = new Array(tmpArray.length);\n for (let i = 0; i < tmpArray.length; i++) {\n tmpStrArray[i] = tmpArray[i].toString();\n }\n return `[${tmpStrArray.join(\", \")}]`;\n }\n if (isArray(v) || isArrayLike(v)) {\n const tempStrArray = new Array(v.length);\n for (let i = 0, k = v.length; i < k; i++) {\n tempStrArray[i] = toJson(v[i]);\n }\n return `[${tempStrArray.join(\", \")}]`;\n }\n if (v instanceof Set) {\n return toJson(v.values());\n }\n if (v instanceof Map) {\n const key = v.keys();\n const value = v.values();\n const tempStrArray = new Array();\n for (let i = 0; i < key.length; i++) {\n tempStrArray[i] = toJson(key[i]) + \" : \" + toJson(value[i]);\n }\n return `{ ${tempStrArray.join(\", \")} }`;\n }\n return \"[Object \" + nameof(v) + \"]\";\n}\n","import { itoa32, utoa32, itoa64, utoa64, dtoa } from \"./util/number\";\nimport { strtol, strtod } from \"./util/string\";\n\n// @ts-ignore: decorator\n@builtin @inline\nexport const NaN: f64 = 0 / 0; // context-aware\n\n// @ts-ignore: decorator\n@builtin @inline\nexport const Infinity: f64 = 1 / 0; // context-aware\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isNaN(value: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isFinite(value: T): bool;\n\n@final @unmanaged\nexport abstract class I8 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i8 = i8.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i8 = i8.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i8 {\n return strtol(value, radix);\n }\n\n toString(this: i8, radix: i32 = 10): String {\n return itoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class I16 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i16 = i16.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i16 = i16.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i16 {\n return strtol(value, radix);\n }\n\n toString(this: i16, radix: i32 = 10): String {\n return itoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class I32 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i32 = i32.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i32 = i32.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i32 {\n return strtol(value, radix);\n }\n\n toString(this: i32, radix: i32 = 10): String {\n return itoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class I64 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: i64 = i64.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: i64 = i64.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): i64 {\n return strtol(value, radix);\n }\n\n toString(this: i64, radix: i32 = 10): String {\n return itoa64(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class Isize {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: isize = isize.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: isize = isize.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): isize {\n return strtol(value, radix);\n }\n\n toString(this: isize, radix: i32 = 10): String {\n if (sizeof() == 4) {\n return itoa32(this, radix);\n } else {\n return itoa64(this, radix);\n }\n }\n}\n\n@final @unmanaged\nexport abstract class U8 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u8 = u8.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u8 = u8.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u8 {\n return strtol(value, radix);\n }\n\n toString(this: u8, radix: i32 = 10): String {\n return utoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class U16 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u16 = u16.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u16 = u16.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u16 {\n return strtol(value, radix);\n }\n\n toString(this: u16, radix: i32 = 10): String {\n return utoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class U32 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u32 = u32.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u32 = u32.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u32 {\n return strtol(value, radix);\n }\n\n toString(this: u32, radix: i32 = 10): String {\n return utoa32(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class U64 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: u64 = u64.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: u64 = u64.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): u64 {\n return strtol(value, radix);\n }\n\n toString(this: u64, radix: i32 = 10): String {\n return utoa64(this, radix);\n }\n}\n\n@final @unmanaged\nexport abstract class Usize {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: usize = usize.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: usize = usize.MAX_VALUE;\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): usize {\n return strtol(value, radix);\n }\n\n toString(this: usize, radix: i32 = 10): String {\n if (sizeof() == 4) {\n return utoa32(this, radix);\n } else {\n return utoa64(this, radix);\n }\n }\n}\n\n@final @unmanaged\nexport abstract class Bool {\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: bool = bool.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: bool = bool.MAX_VALUE;\n\n toString(this: bool, radix: i32 = 0): String {\n return this ? \"true\" : \"false\";\n }\n}\n\nexport { Bool as Boolean };\n\n@final @unmanaged\nexport abstract class F32 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly EPSILON: f32 = f32.EPSILON;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: f32 = f32.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: f32 = f32.MAX_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_SAFE_INTEGER: f32 = f32.MIN_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_SAFE_INTEGER: f32 = f32.MAX_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly POSITIVE_INFINITY: f32 = f32.POSITIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NEGATIVE_INFINITY: f32 = f32.NEGATIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NaN: f32 = f32.NaN;\n\n static isNaN(value: f32): bool {\n return isNaN(value);\n }\n\n static isFinite(value: f32): bool {\n return isFinite(value);\n }\n\n static isSafeInteger(value: f32): bool {\n return abs(value) <= f32.MAX_SAFE_INTEGER && trunc(value) == value;\n }\n\n static isInteger(value: f32): bool {\n return isFinite(value) && trunc(value) == value;\n }\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): f32 {\n return strtol(value, radix);\n }\n\n /** @deprecated */\n static parseFloat(value: string): f32 {\n return strtod(value);\n }\n\n toString(this: f32, radix: i32 = 0): String {\n return dtoa(this);\n }\n}\n\n@final @unmanaged\nexport abstract class F64 {\n\n // @ts-ignore: decorator\n @lazy\n static readonly EPSILON: f64 = f64.EPSILON;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_VALUE: f64 = f64.MIN_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_VALUE: f64 = f64.MAX_VALUE;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MIN_SAFE_INTEGER: f64 = f64.MIN_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly MAX_SAFE_INTEGER: f64 = f64.MAX_SAFE_INTEGER;\n\n // @ts-ignore: decorator\n @lazy\n static readonly POSITIVE_INFINITY: f64 = f64.POSITIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NEGATIVE_INFINITY: f64 = f64.NEGATIVE_INFINITY;\n\n // @ts-ignore: decorator\n @lazy\n static readonly NaN: f64 = f64.NaN;\n\n static isNaN(value: f64): bool {\n return isNaN(value);\n }\n\n static isFinite(value: f64): bool {\n return isFinite(value);\n }\n\n static isSafeInteger(value: f64): bool {\n return abs(value) <= f64.MAX_SAFE_INTEGER && trunc(value) == value;\n }\n\n static isInteger(value: f64): bool {\n return isFinite(value) && trunc(value) == value;\n }\n\n /** @deprecated */\n static parseInt(value: string, radix: i32 = 0): f64 {\n return strtol(value, radix);\n }\n\n /** @deprecated */\n static parseFloat(value: string): f64 {\n return strtod(value);\n }\n\n toString(this: f64, radix: i32 = 0): String {\n return dtoa(this);\n }\n}\n\nexport { F64 as Number };\n","import { compareImpl } from \"./string\";\n\ntype Comparator = (a: T, b: T) => i32;\n\n// @ts-ignore: decorator\n@lazy @inline const EMPTY = u32.MAX_VALUE;\n// @ts-ignore: decorator\n@inline const INSERTION_SORT_THRESHOLD = 48;\n// @ts-ignore: decorator\n@inline const MIN_RUN_LENGTH = 32;\n\n// @ts-ignore: decorator\n@inline\nfunction log2u(n: u32): u32 {\n return 31 - clz(n);\n}\n\n// @ts-ignore: decorator\n@inline\nexport function COMPARATOR(): Comparator {\n if (isInteger()) {\n if (isSigned() && sizeof() <= 4) {\n return (a, b) => i32(a) - i32(b);\n } else {\n return (a, b) => i32(a > b) - i32(a < b);\n }\n } else if (isFloat()) {\n if (sizeof() == 4) {\n return (a, b) => {\n let ia = reinterpret(f32(a));\n let ib = reinterpret(f32(b));\n ia ^= ia >> 31 >>> 1;\n ib ^= ib >> 31 >>> 1;\n return i32(ia > ib) - i32(ia < ib);\n };\n } else {\n return (a, b) => {\n let ia = reinterpret(f64(a));\n let ib = reinterpret(f64(b));\n ia ^= ia >> 63 >>> 1;\n ib ^= ib >> 63 >>> 1;\n return i32(ia > ib) - i32(ia < ib);\n };\n }\n } else if (isString()) {\n return (a, b) => {\n if (\n changetype(a) == changetype(b) ||\n changetype(a) == 0 ||\n changetype(b) == 0\n ) return 0;\n let alen = changetype(a).length;\n let blen = changetype(b).length;\n if (!(alen | blen)) return 0;\n if (!alen) return -1;\n if (!blen) return 1;\n let res = compareImpl(\n changetype(a), 0,\n changetype(b), 0,\n min(alen, blen)\n );\n return res ? res : alen - blen;\n };\n } else {\n return (a, b) => i32(a > b) - i32(a < b);\n }\n}\n\n// Power Sort implementation (stable) from paper \"Nearly-Optimal Mergesorts\"\n// https://arxiv.org/pdf/1805.04154.pdf\n// This method usually outperform TimSort.\n// TODO: refactor c >>> 31 to c < 0 when binaryen will support this opt\nexport function SORT(\n ptr: usize,\n len: i32,\n comparator: Comparator\n): void {\n if (len <= INSERTION_SORT_THRESHOLD) {\n if (len <= 1) return;\n if (ASC_SHRINK_LEVEL < 1) {\n switch (len) {\n case 3: {\n let a = load(ptr, 0);\n let b = load(ptr, 1 << alignof());\n let c = comparator(a, b) > 0;\n store(ptr, select(b, a, c), 0);\n a = select(a, b, c);\n b = load(ptr, 2 << alignof());\n c = comparator(a, b) > 0;\n store(ptr, select(b, a, c), 1 << alignof());\n store(ptr, select(a, b, c), 2 << alignof());\n }\n case 2: {\n let a = load(ptr, 0);\n let b = load(ptr, 1 << alignof());\n let c = comparator(a, b) > 0;\n store(ptr, select(b, a, c), 0);\n store(ptr, select(a, b, c), 1 << alignof());\n return;\n }\n }\n }\n insertionSort(ptr, 0, len - 1, 0, comparator);\n return;\n }\n\n let lgPlus2 = log2u(len) + 2;\n let lgPlus2Size = lgPlus2 << alignof();\n let leftRunStartBuf = __alloc(lgPlus2Size << 1);\n let leftRunEndBuf = leftRunStartBuf + lgPlus2Size;\n\n for (let i: u32 = 0; i < lgPlus2; ++i) {\n store(leftRunStartBuf + (i << alignof()), EMPTY);\n }\n\n let buffer = __alloc(len << alignof());\n\n let hi = len - 1;\n let endA = extendRunRight(ptr, 0, hi, comparator);\n let lenA = endA + 1;\n\n if (lenA < MIN_RUN_LENGTH) {\n endA = min(hi, MIN_RUN_LENGTH - 1);\n insertionSort(ptr, 0, endA, lenA, comparator);\n }\n\n let top: u32 = 0, startA = 0;\n while (endA < hi) {\n let startB = endA + 1;\n let endB = extendRunRight(ptr, startB, hi, comparator);\n let lenB = endB - startB + 1;\n\n if (lenB < MIN_RUN_LENGTH) {\n endB = min(hi, startB + MIN_RUN_LENGTH - 1);\n insertionSort(ptr, startB, endB, lenB, comparator);\n }\n\n let k = nodePower(0, hi, startA, startB, endB);\n\n for (let i = top; i > k; --i) {\n let start = load(leftRunStartBuf + (i << alignof()));\n if (start != EMPTY) {\n mergeRuns(\n ptr,\n start,\n load(leftRunEndBuf + (i << alignof())) + 1,\n endA,\n buffer,\n comparator\n );\n startA = start;\n store(leftRunStartBuf + (i << alignof()), EMPTY);\n }\n }\n\n store(leftRunStartBuf + (k << alignof()), startA);\n store(leftRunEndBuf + (k << alignof()), endA);\n startA = startB;\n endA = endB;\n top = k;\n }\n\n for (let i = top; i != 0; --i) {\n let start = load(leftRunStartBuf + (i << alignof()));\n if (start != EMPTY) {\n mergeRuns(\n ptr,\n start,\n load(leftRunEndBuf + (i << alignof())) + 1,\n hi,\n buffer,\n comparator\n );\n }\n }\n // dealloc aux buffers\n __free(buffer);\n __free(leftRunStartBuf);\n}\n\nfunction insertionSort(\n ptr: usize,\n left: i32,\n right: i32,\n presorted: i32,\n comparator: Comparator\n): void {\n if (ASC_SHRINK_LEVEL >= 1) {\n // slightly improved original insertion sort\n for (let i = left + presorted; i <= right; ++i) {\n let j = i - 1;\n let a = load(ptr + (i << alignof()));\n while (j >= left) {\n let b = load(ptr + (j << alignof()));\n if (comparator(a, b) < 0) {\n store(ptr + (j << alignof()), b, 1 << alignof()); --j;\n } else break;\n }\n store(ptr + (j << alignof()), a, 1 << alignof());\n }\n } else {\n // even-odd two-way insertion sort which allow increase minRunLen\n let range = right - left + 1;\n let i = left + select(range & 1, presorted - ((range - presorted) & 1), presorted == 0);\n for (; i <= right; i += 2) {\n let a = load(ptr + (i << alignof()), 0);\n let b = load(ptr + (i << alignof()), 1 << alignof());\n let min = b, max = a;\n if (comparator(a, b) <= 0) {\n min = a, max = b;\n }\n let j = i - 1;\n while (j >= left) {\n a = load(ptr + (j << alignof()));\n if (comparator(a, max) > 0) {\n store(ptr + (j << alignof()), a, 2 << alignof()); --j;\n } else break;\n }\n store(ptr + (j << alignof()), max, 2 << alignof());\n while (j >= left) {\n a = load(ptr + (j << alignof()));\n if (comparator(a, min) > 0) {\n store(ptr + (j << alignof()), a, 1 << alignof()); --j;\n } else break;\n }\n store(ptr + (j << alignof()), min, 1 << alignof());\n }\n }\n}\n\nfunction nodePower(left: u32, right: u32, startA: u32, startB: u32, endB: u32): u32 {\n let n: u64 = right - left + 1;\n let s = startB - (left << 1);\n let l = startA + s;\n let r = endB + s + 1;\n let a = (l << 30) / n;\n let b = (r << 30) / n;\n return clz((a ^ b));\n}\n\nfunction extendRunRight(\n ptr: usize,\n i: i32,\n right: i32,\n comparator: Comparator\n): i32 {\n if (i == right) return i;\n let j = i;\n if (comparator(\n load(ptr + ( j << alignof())),\n load(ptr + (++j << alignof()))\n ) > 0) {\n while (\n j < right &&\n (comparator(\n load(ptr + (j << alignof()), 1 << alignof()),\n load(ptr + (j << alignof()))\n ) >>> 31) // < 0\n ) ++j;\n // reverse\n let k = j;\n while (i < k) {\n let tmp = load(ptr + (i << alignof()));\n store(ptr + (i << alignof()), load(ptr + (k << alignof()))); ++i;\n store(ptr + (k << alignof()), tmp); --k;\n }\n } else {\n while (\n j < right &&\n comparator(\n load(ptr + (j << alignof()), 1 << alignof()),\n load(ptr + (j << alignof()))\n ) >= 0\n ) ++j;\n }\n return j;\n}\n\n// Merges arr[l..m - 1] and arr[m..r]\nfunction mergeRuns(\n ptr: usize,\n l: i32,\n m: i32,\n r: i32,\n buffer: usize,\n comparator: Comparator\n): void {\n --m;\n let i: i32, j: i32, t = r + m;\n for (i = m + 1; i > l; --i) {\n store(\n buffer + ((i - 1) << alignof()),\n load(ptr + ((i - 1) << alignof()))\n );\n }\n for (j = m; j < r; ++j) {\n store(\n buffer + ((t - j) << alignof()),\n load(ptr + (j << alignof()), 1 << alignof())\n );\n }\n for (let k = l; k <= r; ++k) {\n let a = load(buffer + (j << alignof()));\n let b = load(buffer + (i << alignof()));\n if (comparator(a, b) < 0) {\n store(ptr + (k << alignof()), a);\n --j;\n } else {\n store(ptr + (k << alignof()), b);\n ++i;\n }\n }\n}\n","/// \n\nimport { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from \"./rt/common\";\nimport { compareImpl, strtol, strtod, isSpace, isAscii, isFinalSigma, toLower8, toUpper8 } from \"./util/string\";\nimport { SPECIALS_UPPER, casemap, bsearch } from \"./util/casemap\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_UNPAIRED_SURROGATE } from \"./util/error\";\nimport { idof } from \"./builtins\";\nimport { Array } from \"./array\";\n\n@final export abstract class String {\n\n @lazy static readonly MAX_LENGTH: i32 = (BLOCK_MAXSIZE >>> alignof());\n\n static fromCharCode(unit: i32, surr: i32 = -1): String {\n let hasSur = surr > 0;\n let out = changetype(__new(2 << i32(hasSur), idof()));\n store(changetype(out), unit);\n if (hasSur) store(changetype(out), surr, 2);\n return out;\n }\n\n static fromCharCodes(units: Array): String {\n let length = units.length;\n let out = changetype(__new(length << 1, idof()));\n let ptr = units.dataStart;\n for (let i = 0; i < length; ++i) {\n store(changetype(out) + (i << 1), load(ptr + (i << 2)));\n }\n return out;\n }\n\n static fromCodePoint(code: i32): String {\n let hasSur = code > 0xFFFF;\n let out = changetype(__new(2 << i32(hasSur), idof()));\n if (!hasSur) {\n store(changetype(out), code);\n } else {\n // Checks valid code point range\n assert(code <= 0x10FFFF);\n code -= 0x10000;\n let hi = (code & 0x03FF) | 0xDC00;\n let lo = code >>> 10 | 0xD800;\n store(changetype(out), lo | hi << 16);\n }\n return out;\n }\n\n @builtin static raw(parts: TemplateStringsArray, ...args: unknown[]): string { return unreachable(); }\n\n get length(): i32 {\n return changetype(changetype(this) - TOTAL_OVERHEAD).rtSize >> 1;\n }\n\n at(pos: i32): String {\n let len = this.length;\n pos += select(0, len, pos >= 0);\n if (pos >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n let out = __new(2, idof());\n store(out, load(changetype(this) + (pos << 1)));\n return changetype(out); // retains\n }\n\n @operator(\"[]\") charAt(pos: i32): String {\n if (pos >= this.length) return changetype(\"\");\n let out = changetype(__new(2, idof()));\n store(changetype(out), load(changetype(this) + (pos << 1)));\n return out;\n }\n\n charCodeAt(pos: i32): i32 {\n if (pos >= this.length) return -1; // (NaN)\n return load(changetype(this) + (pos << 1));\n }\n\n codePointAt(pos: i32): i32 {\n let len = this.length;\n if (pos >= len) return -1; // (undefined)\n let first = load(changetype(this) + (pos << 1));\n if ((first & 0xFC00) != 0xD800 || pos + 1 == len) return first;\n let second = load(changetype(this) + (pos << 1), 2);\n if ((second & 0xFC00) != 0xDC00) return first;\n return (first - 0xD800 << 10) + (second - 0xDC00) + 0x10000;\n }\n\n @operator(\"+\") private static __concat(left: String, right: String): String {\n return left.concat(right);\n }\n\n concat(other: String): String {\n let thisSize: isize = this.length << 1;\n let otherSize: isize = other.length << 1;\n let outSize: usize = thisSize + otherSize;\n if (outSize == 0) return changetype(\"\");\n let out = changetype(__new(outSize, idof()));\n memory.copy(changetype(out), changetype(this), thisSize);\n memory.copy(changetype(out) + thisSize, changetype(other), otherSize);\n return out;\n }\n\n endsWith(search: String, end: i32 = String.MAX_LENGTH): bool {\n end = min(max(end, 0), this.length);\n let searchLength = search.length;\n let searchStart = end - searchLength;\n if (searchStart < 0) return false;\n // @ts-ignore: string <-> String\n return !compareImpl(this, searchStart, search, 0, searchLength);\n }\n\n @operator(\"==\") private static __eq(left: String | null, right: String | null): bool {\n if (changetype(left) == changetype(right)) return true;\n if (changetype(left) == 0 || changetype(right) == 0) return false;\n let leftLength = changetype(left).length;\n if (leftLength != changetype(right).length) return false;\n // @ts-ignore: string <-> String\n return !compareImpl(left, 0, right, 0, leftLength);\n }\n\n @operator.prefix(\"!\")\n private static __not(str: String | null): bool {\n return changetype(str) == 0 || !changetype(str).length;\n }\n\n @operator(\"!=\")\n private static __ne(left: String | null, right: String | null): bool {\n return !this.__eq(left, right);\n }\n\n @operator(\">\") private static __gt(left: String, right: String): bool {\n if (changetype(left) == changetype(right)) return false;\n let leftLength = left.length;\n if (!leftLength) return false;\n let rightLength = right.length;\n if (!rightLength) return true;\n // @ts-ignore: string <-> String\n let res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));\n return res ? res > 0 : leftLength > rightLength;\n }\n\n @operator(\">=\") private static __gte(left: String, right: String): bool {\n return !this.__lt(left, right);\n }\n\n @operator(\"<\") private static __lt(left: String, right: String): bool {\n if (changetype(left) == changetype(right)) return false;\n let rightLength = right.length;\n if (!rightLength) return false;\n let leftLength = left.length;\n if (!leftLength) return true;\n // @ts-ignore: string <-> String\n let res = compareImpl(left, 0, right, 0, min(leftLength, rightLength));\n return res ? res < 0 : leftLength < rightLength;\n }\n\n @operator(\"<=\") private static __lte(left: String, right: String): bool {\n return !this.__gt(left, right);\n }\n\n includes(search: String, start: i32 = 0): bool {\n return this.indexOf(search, start) != -1;\n }\n\n indexOf(search: String, start: i32 = 0): i32 {\n let searchLen = search.length;\n if (!searchLen) return 0;\n let len = this.length;\n if (!len) return -1;\n let searchStart = min(max(start, 0), len);\n for (len -= searchLen; searchStart <= len; ++searchStart) {\n // @ts-ignore: string <-> String\n if (!compareImpl(this, searchStart, search, 0, searchLen)) return searchStart;\n }\n return -1;\n }\n\n lastIndexOf(search: String, start: i32 = i32.MAX_VALUE): i32 {\n let searchLen = search.length;\n if (!searchLen) return this.length;\n let len = this.length;\n if (!len) return -1;\n let searchStart = min(max(start, 0), len - searchLen);\n for (; searchStart >= 0; --searchStart) {\n // @ts-ignore: string <-> String\n if (!compareImpl(this, searchStart, search, 0, searchLen)) return searchStart;\n }\n return -1;\n }\n\n // TODO: implement full locale comparison with locales and Collator options\n localeCompare(other: String): i32 {\n if (changetype(other) == changetype(this)) return 0;\n let alen = this.length;\n let blen = other.length;\n // @ts-ignore: string <-> String\n let res = compareImpl(this, 0, other, 0, min(alen, blen));\n res = res ? res : alen - blen;\n // normalize to [-1, 1] range\n return i32(res > 0) - i32(res < 0);\n }\n\n startsWith(search: String, start: i32 = 0): bool {\n let len = this.length;\n let searchStart = min(max(start, 0), len);\n let searchLength = search.length;\n if (searchLength + searchStart > len) return false;\n // @ts-ignore: string <-> String\n return !compareImpl(this, searchStart, search, 0, searchLength);\n }\n\n substr(start: i32, length: i32 = i32.MAX_VALUE): String { // legacy\n let intStart: isize = start;\n let end: isize = length;\n let len: isize = this.length;\n if (intStart < 0) intStart = max(len + intStart, 0);\n let size = min(max(end, 0), len - intStart) << 1;\n if (size <= 0) return changetype(\"\");\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + (intStart << 1), size);\n return out;\n }\n\n substring(start: i32, end: i32 = i32.MAX_VALUE): String {\n let len: isize = this.length;\n let finalStart = min(max(start, 0), len);\n let finalEnd = min(max(end, 0), len);\n let fromPos = min(finalStart, finalEnd) << 1;\n let toPos = max(finalStart, finalEnd) << 1;\n let size = toPos - fromPos;\n if (!size) return changetype(\"\");\n if (!fromPos && toPos == len << 1) return this;\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + fromPos, size);\n return out;\n }\n\n trim(): String {\n let len = this.length;\n let size: usize = len << 1;\n while (size && isSpace(load(changetype(this) + size - 2))) {\n size -= 2;\n }\n let offset: usize = 0;\n while (offset < size && isSpace(load(changetype(this) + offset))) {\n offset += 2; size -= 2;\n }\n if (!size) return changetype(\"\");\n if (!offset && size == len << 1) return this;\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + offset, size);\n return out;\n }\n\n @inline\n trimLeft(): String {\n return this.trimStart();\n }\n\n @inline\n trimRight(): String {\n return this.trimEnd();\n }\n\n trimStart(): String {\n let size = this.length << 1;\n let offset: usize = 0;\n while (offset < size && isSpace(load(changetype(this) + offset))) {\n offset += 2;\n }\n if (!offset) return this;\n size -= offset;\n if (!size) return changetype(\"\");\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this) + offset, size);\n return out;\n }\n\n trimEnd(): String {\n let originalSize = this.length << 1;\n let size = originalSize;\n while (size && isSpace(load(changetype(this) + size - 2))) {\n size -= 2;\n }\n if (!size) return changetype(\"\");\n if (size == originalSize) return this;\n let out = changetype(__new(size, idof()));\n memory.copy(changetype(out), changetype(this), size);\n return out;\n }\n\n padStart(length: i32, pad: string = \" \"): String {\n let thisSize = this.length << 1;\n let targetSize = length << 1;\n let padSize = pad.length << 1;\n if (targetSize < thisSize || !padSize) return this;\n let prependSize = targetSize - thisSize;\n let out = changetype(__new(targetSize, idof()));\n if (prependSize > padSize) {\n let repeatCount = (prependSize - 2) / padSize;\n let restBase = repeatCount * padSize;\n let restSize = prependSize - restBase;\n memory.repeat(changetype(out), changetype(pad), padSize, repeatCount);\n memory.copy(changetype(out) + restBase, changetype(pad), restSize);\n } else {\n memory.copy(changetype(out), changetype(pad), prependSize);\n }\n memory.copy(changetype(out) + prependSize, changetype(this), thisSize);\n return out;\n }\n\n padEnd(length: i32, pad: string = \" \"): String {\n let thisSize = this.length << 1;\n let targetSize = length << 1;\n let padSize = pad.length << 1;\n if (targetSize < thisSize || !padSize) return this;\n let appendSize = targetSize - thisSize;\n let out = changetype(__new(targetSize, idof()));\n memory.copy(changetype(out), changetype(this), thisSize);\n if (appendSize > padSize) {\n let repeatCount = (appendSize - 2) / padSize;\n let restBase = repeatCount * padSize;\n let restSize = appendSize - restBase;\n memory.repeat(changetype(out) + thisSize, changetype(pad), padSize, repeatCount);\n memory.copy(changetype(out) + thisSize + restBase, changetype(pad), restSize);\n } else {\n memory.copy(changetype(out) + thisSize, changetype(pad), appendSize);\n }\n return out;\n }\n\n repeat(count: i32 = 0): String {\n let length = this.length;\n\n // Most browsers can't handle strings 1 << 28 chars or longer\n if (count < 0 || length * count > (1 << 28)) {\n throw new RangeError(E_INVALIDLENGTH);\n }\n\n if (count == 0 || !length) return changetype(\"\");\n if (count == 1) return this;\n let out = changetype(__new((length * count) << 1, idof()));\n memory.repeat(changetype(out), changetype(this), length << 1, count);\n return out;\n }\n\n replace(search: String, replacement: String): String {\n let len: usize = this.length;\n let slen: usize = search.length;\n if (len <= slen) {\n return len < slen ? this : select(replacement, this, search == this);\n }\n let index: isize = this.indexOf(search);\n if (~index) {\n let rlen: usize = replacement.length;\n len -= slen;\n let olen = len + rlen;\n if (olen) {\n let out = changetype(__new(olen << 1, idof()));\n memory.copy(changetype(out), changetype(this), index << 1);\n memory.copy(\n changetype(out) + (index << 1),\n changetype(replacement),\n rlen << 1\n );\n memory.copy(\n changetype(out) + ((index + rlen) << 1),\n changetype(this) + ((index + slen) << 1),\n (len - index) << 1\n );\n return out;\n }\n }\n return this;\n }\n\n replaceAll(search: String, replacement: String): String {\n let thisLen: usize = this.length;\n let searchLen: usize = search.length;\n if (thisLen <= searchLen) {\n return thisLen < searchLen\n ? this\n : select(replacement, this, search == this);\n }\n let replaceLen: usize = replacement.length;\n if (!searchLen) {\n if (!replaceLen) return this;\n // Special case: 'abc'.replaceAll('', '-') -> '-a-b-c-'\n let out = changetype(__new((thisLen + (thisLen + 1) * replaceLen) << 1, idof()));\n memory.copy(changetype(out), changetype(replacement), replaceLen << 1);\n let offset = replaceLen;\n for (let i: usize = 0; i < thisLen; ++i) {\n store(\n changetype(out) + (offset++ << 1),\n load(changetype(this) + (i << 1))\n );\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(replacement),\n replaceLen << 1\n );\n offset += replaceLen;\n }\n return out;\n }\n let prev: isize = 0, next: isize = 0;\n if (searchLen == replaceLen) {\n // Fast path when search and replacement have same length\n let outSize = thisLen << 1;\n let out = changetype(__new(outSize, idof()));\n memory.copy(changetype(out), changetype(this), outSize);\n while (~(next = this.indexOf(search, prev))) {\n memory.copy(changetype(out) + (next << 1), changetype(replacement), replaceLen << 1);\n prev = next + searchLen;\n }\n return out;\n }\n let out: String | null = null, offset: usize = 0, outSize = thisLen;\n while (~(next = this.indexOf(search, prev))) {\n if (!out) out = changetype(__new(thisLen << 1, idof()));\n let chunk = next - prev;\n if (offset + chunk + replaceLen > outSize) {\n outSize <<= 1;\n out = changetype(__renew(changetype(out), outSize << 1));\n }\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(this) + (prev << 1),\n chunk << 1\n );\n offset += chunk;\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(replacement),\n replaceLen << 1\n );\n offset += replaceLen;\n prev = next + searchLen;\n }\n if (out) {\n let rest = thisLen - prev;\n if (offset + rest > outSize) {\n outSize <<= 1;\n out = changetype(__renew(changetype(out), outSize << 1));\n }\n if (rest) {\n memory.copy(\n changetype(out) + (offset << 1),\n changetype(this) + (prev << 1),\n rest << 1\n );\n }\n rest += offset;\n if (outSize > rest) {\n out = changetype(__renew(changetype(out), rest << 1));\n }\n return out;\n }\n return this;\n }\n\n slice(start: i32, end: i32 = i32.MAX_VALUE): String {\n let len = this.length;\n start = start < 0 ? max(start + len, 0) : min(start, len);\n end = end < 0 ? max(end + len, 0) : min(end, len);\n len = end - start;\n if (len <= 0) return changetype(\"\");\n let out = changetype(__new(len << 1, idof()));\n memory.copy(changetype(out), changetype(this) + (start << 1), len << 1);\n return out;\n }\n\n split(separator: String | null = null, limit: i32 = i32.MAX_VALUE): String[] {\n if (!limit) return changetype(__newArray(0, alignof(), idof>()));\n if (changetype(separator) == 0) return [ this ];\n let length: isize = this.length;\n let sepLen = changetype(separator).length;\n if (limit < 0) limit = i32.MAX_VALUE;\n if (!sepLen) {\n if (!length) return changetype(__newArray(0, alignof(), idof>()));\n // split by chars\n length = min(length, limit);\n let result = changetype(__newArray(length, alignof(), idof>()));\n // @ts-ignore: cast\n let resultStart = result.dataStart as usize;\n for (let i: isize = 0; i < length; ++i) {\n let charStr = changetype(__new(2, idof()));\n store(changetype(charStr), load(changetype(this) + (i << 1)));\n store(resultStart + (i << alignof()), changetype(charStr)); // result[i] = charStr\n __link(changetype(result), changetype(charStr), true);\n }\n return result;\n } else if (!length) {\n let result = changetype(__newArray(1, alignof(), idof>()));\n // @ts-ignore: cast\n store(result.dataStart as usize, changetype(\"\")); // static \"\"\n return result;\n }\n let result = changetype(__newArray(0, alignof(), idof>()));\n let end = 0, start = 0, i = 0;\n while (~(end = this.indexOf(changetype(separator), start))) {\n let len = end - start;\n if (len > 0) {\n let out = changetype(__new(len << 1, idof()));\n memory.copy(changetype(out), changetype(this) + (start << 1), len << 1);\n result.push(out);\n } else {\n result.push(changetype(\"\"));\n }\n if (++i == limit) return result;\n start = end + sepLen;\n }\n if (!start) { // also means: loop above didn't do anything\n result.push(this);\n return result;\n }\n let len = length - start;\n if (len > 0) {\n let out = changetype(__new(len << 1, idof()));\n memory.copy(changetype(out), changetype(this) + (start << 1), len << 1);\n result.push(out);\n } else {\n result.push(changetype(\"\")); // static \"\"\n }\n return result;\n }\n\n toLowerCase(): String {\n let len = this.length;\n if (!len) return this;\n let codes = changetype(__new(len * 2 * 2, idof()));\n let j: usize = 0;\n for (let i: usize = 0; i < len; ++i, ++j) {\n let c = load(changetype(this) + (i << 1));\n if (isAscii(c)) {\n store(changetype(codes) + (j << 1), toLower8(c));\n } else {\n // check and read surrogate pair\n if ((c - 0xD7FF < 0xDC00 - 0xD7FF) && i < len - 1) {\n let c1 = load(changetype(this) + (i << 1), 2);\n if (c1 - 0xDBFF < 0xE000 - 0xDBFF) {\n let c0 = c;\n c = (((c & 0x03FF) << 10) | (c1 & 0x03FF)) + 0x10000;\n ++i;\n if (c >= 0x20000) {\n store(changetype(codes) + (j << 1), c0 | (c1 << 16));\n ++j;\n continue;\n }\n }\n }\n // check special casing for lower table. It has one ently so instead lookup we just inline this.\n if (c == 0x0130) {\n // 0x0130 -> [0x0069, 0x0307]\n store(changetype(codes) + (j << 1), (0x0307 << 16) | 0x0069);\n ++j;\n } else if (c == 0x03A3) { // 'Σ'\n // Σ maps to σ but except at the end of a word where it maps to ς\n let sigma = 0x03C3; // σ\n if (len > 1 && isFinalSigma(changetype(this), i, len)) {\n sigma = 0x03C2; // ς\n }\n store(changetype(codes) + (j << 1), sigma);\n } else if (c - 0x24B6 <= 0x24CF - 0x24B6) {\n // Range 0x24B6 <= c <= 0x24CF not covered by casemap and require special early handling\n store(changetype(codes) + (j << 1), c + 26);\n } else {\n let code = casemap(c, 0) & 0x1FFFFF;\n if (code < 0x10000) {\n store(changetype(codes) + (j << 1), code);\n } else {\n // store as surrogare pair\n code -= 0x10000;\n let lo = (code >>> 10) | 0xD800;\n let hi = (code & 0x03FF) | 0xDC00;\n store(changetype(codes) + (j << 1), lo | (hi << 16));\n ++j;\n }\n }\n }\n }\n return changetype(__renew(changetype(codes), j << 1));\n }\n\n toUpperCase(): String {\n let len = this.length;\n if (!len) return this;\n let codes = changetype(__new(len * 3 * 2, idof()));\n let specialsPtr = changetype(SPECIALS_UPPER);\n let specialsLen = SPECIALS_UPPER.length;\n let j: usize = 0;\n for (let i: usize = 0; i < len; ++i, ++j) {\n let c = load(changetype(this) + (i << 1));\n if (isAscii(c)) {\n store(changetype(codes) + (j << 1), toUpper8(c));\n } else {\n // check and read surrogate pair\n if ((c - 0xD7FF < 0xDC00 - 0xD7FF) && i < len - 1) {\n let c1 = load(changetype(this) + (i << 1), 2);\n if (c1 - 0xDBFF < 0xE000 - 0xDBFF) {\n let c0 = c;\n c = (((c & 0x03FF) << 10) | (c1 & 0x03FF)) + 0x10000;\n ++i;\n if (c >= 0x20000) {\n store(changetype(codes) + (j << 1), c0 | (c1 << 16));\n ++j;\n continue;\n }\n }\n }\n // Range 0x24D0 <= c <= 0x24E9 not covered by casemap and require special early handling\n if (c - 0x24D0 <= 0x24E9 - 0x24D0) {\n // monkey patch\n store(changetype(codes) + (j << 1), c - 26);\n } else {\n let index: usize = -1;\n // Fast range check. See first and last rows in specialsUpper table\n if (c - 0x00DF <= 0xFB17 - 0x00DF) {\n index = bsearch(c, specialsPtr, specialsLen);\n }\n if (~index) {\n // load next 3 code points from row with `index` offset for specialsUpper table\n let ab = load(specialsPtr + (index << 1), 2);\n let cc = load(specialsPtr + (index << 1), 6);\n store(changetype(codes) + (j << 1), ab, 0);\n store(changetype(codes) + (j << 1), cc, 4);\n j += 1 + usize(cc != 0);\n } else {\n let code = casemap(c, 1) & 0x1FFFFF;\n if (code < 0x10000) {\n store(changetype(codes) + (j << 1), code);\n } else {\n // store as surrogare pair\n code -= 0x10000;\n let lo = (code >>> 10) | 0xD800;\n let hi = (code & 0x03FF) | 0xDC00;\n store(changetype(codes) + (j << 1), lo | (hi << 16));\n ++j;\n }\n }\n }\n }\n }\n return changetype(__renew(changetype(codes), j << 1));\n }\n\n toString(): String {\n return this;\n }\n}\n\n// @ts-ignore: nolib\nexport type string = String;\n\nexport function parseInt(str: string, radix: i32 = 0): f64 {\n return strtol(str, radix);\n}\n\nexport function parseFloat(str: string): f64 {\n return strtod(str);\n}\n\n// Encoding helpers\nexport namespace String {\n\n export namespace UTF8 {\n\n export const enum ErrorMode {\n WTF8,\n REPLACE,\n ERROR\n }\n\n export function byteLength(str: string, nullTerminated: bool = false): i32 {\n let strOff = changetype(str);\n let strEnd = strOff + changetype(changetype(str) - TOTAL_OVERHEAD).rtSize;\n let bufLen = i32(nullTerminated);\n while (strOff < strEnd) {\n let c1 = load(strOff);\n if (c1 < 128) {\n // @ts-ignore: cast\n if (nullTerminated & !c1) break;\n bufLen += 1;\n } else if (c1 < 2048) {\n bufLen += 2;\n } else {\n if ((c1 & 0xFC00) == 0xD800 && strOff + 2 < strEnd) {\n if ((load(strOff, 2) & 0xFC00) == 0xDC00) {\n bufLen += 4; strOff += 4;\n continue;\n }\n }\n bufLen += 3;\n }\n strOff += 2;\n }\n return bufLen;\n }\n\n export function encode(str: string, nullTerminated: bool = false, errorMode: ErrorMode = ErrorMode.WTF8): ArrayBuffer {\n let buf = changetype(__new(byteLength(str, nullTerminated), idof()));\n encodeUnsafe(changetype(str), str.length, changetype(buf), nullTerminated, errorMode);\n return buf;\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function encodeUnsafe(str: usize, len: i32, buf: usize, nullTerminated: bool = false, errorMode: ErrorMode = ErrorMode.WTF8): usize {\n let strEnd = str + (len << 1);\n let bufOff = buf;\n while (str < strEnd) {\n let c1 = load(str);\n if (c1 < 128) {\n store(bufOff, c1);\n bufOff++;\n // @ts-ignore: cast\n if (nullTerminated & !c1) return bufOff - buf;\n } else if (c1 < 2048) {\n let b0 = c1 >> 6 | 192;\n let b1 = c1 & 63 | 128;\n store(bufOff, b1 << 8 | b0);\n bufOff += 2;\n } else {\n // D800: 11011 0 0000000000 Lead\n // DBFF: 11011 0 1111111111\n // DC00: 11011 1 0000000000 Trail\n // DFFF: 11011 1 1111111111\n // F800: 11111 0 0000000000 Mask\n // FC00: 11111 1 0000000000\n if ((c1 & 0xF800) == 0xD800) {\n if (c1 < 0xDC00 && str + 2 < strEnd) {\n let c2 = load(str, 2);\n if ((c2 & 0xFC00) == 0xDC00) {\n c1 = 0x10000 + ((c1 & 0x03FF) << 10) | (c2 & 0x03FF);\n let b0 = c1 >> 18 | 240;\n let b1 = c1 >> 12 & 63 | 128;\n let b2 = c1 >> 6 & 63 | 128;\n let b3 = c1 & 63 | 128;\n store(bufOff, b3 << 24 | b2 << 16 | b1 << 8 | b0);\n bufOff += 4; str += 4;\n continue;\n }\n }\n if (errorMode != ErrorMode.WTF8) { // unlikely\n if (errorMode == ErrorMode.ERROR) throw new Error(E_UNPAIRED_SURROGATE);\n c1 = 0xFFFD;\n }\n }\n let b0 = c1 >> 12 | 224;\n let b1 = c1 >> 6 & 63 | 128;\n let b2 = c1 & 63 | 128;\n store(bufOff, b1 << 8 | b0);\n store(bufOff, b2, 2);\n bufOff += 3;\n }\n str += 2;\n }\n if (nullTerminated) {\n store(bufOff++, 0);\n }\n return bufOff - buf;\n }\n\n export function decode(buf: ArrayBuffer, nullTerminated: bool = false): String {\n return decodeUnsafe(changetype(buf), buf.byteLength, nullTerminated);\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function decodeUnsafe(buf: usize, len: usize, nullTerminated: bool = false): String {\n let bufOff = buf;\n let bufEnd = buf + len;\n assert(bufEnd >= bufOff); // guard wraparound\n let str = changetype(__new(len << 1, idof())); // max is one u16 char per u8 byte\n let strOff = changetype(str);\n while (bufOff < bufEnd) {\n let u0 = load(bufOff); ++bufOff;\n if (!(u0 & 128)) {\n // @ts-ignore: cast\n if (nullTerminated & !u0) break;\n store(strOff, u0);\n } else {\n if (bufEnd == bufOff) break;\n let u1 = load(bufOff) & 63; ++bufOff;\n if ((u0 & 224) == 192) {\n store(strOff, (u0 & 31) << 6 | u1);\n } else {\n if (bufEnd == bufOff) break;\n let u2 = load(bufOff) & 63; ++bufOff;\n if ((u0 & 240) == 224) {\n u0 = (u0 & 15) << 12 | u1 << 6 | u2;\n } else {\n if (bufEnd == bufOff) break;\n u0 = (u0 & 7) << 18 | u1 << 12 | u2 << 6 | load(bufOff) & 63;\n ++bufOff;\n }\n if (u0 < 0x10000) {\n store(strOff, u0);\n } else {\n u0 -= 0x10000;\n let lo = u0 >> 10 | 0xD800;\n let hi = (u0 & 0x03FF) | 0xDC00;\n store(strOff, lo | (hi << 16));\n strOff += 2;\n }\n }\n }\n strOff += 2;\n }\n return changetype(__renew(changetype(str), strOff - changetype(str)));\n }\n }\n\n export namespace UTF16 {\n\n export function byteLength(str: string): i32 {\n return changetype(changetype(str) - TOTAL_OVERHEAD).rtSize;\n }\n\n export function encode(str: string): ArrayBuffer {\n let buf = changetype(__new(byteLength(str), idof()));\n encodeUnsafe(changetype(str), str.length, changetype(buf));\n return buf;\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function encodeUnsafe(str: usize, len: i32, buf: usize): usize {\n let size = len << 1;\n memory.copy(buf, changetype(str), size);\n return size;\n }\n\n export function decode(buf: ArrayBuffer): String {\n return decodeUnsafe(changetype(buf), buf.byteLength);\n }\n\n // @ts-ignore: decorator\n @unsafe\n export function decodeUnsafe(buf: usize, len: usize): String {\n let str = changetype(__new(len &= ~1, idof()));\n memory.copy(changetype(str), buf, len);\n return str;\n }\n }\n}\n\nexport class TemplateStringsArray extends Array {\n readonly raw: string[];\n}\n","/// \n\nimport { BLOCK_MAXSIZE } from \"./rt/common\";\nimport { Runtime } from \"shared/runtime\";\nimport { COMPARATOR, SORT } from \"./util/sort\";\nimport { REVERSE, FILL } from \"./util/bytes\";\nimport { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinReferenceArray } from \"./util/string\";\nimport { idof, isArray as builtin_isArray } from \"./builtins\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_EMPTYARRAY, E_HOLEYARRAY } from \"./util/error\";\n\n// @ts-ignore: decorator\n@inline @lazy const MIN_SIZE: usize = 8;\n\n/** Ensures that the given array has _at least_ the specified backing size. */\nfunction ensureCapacity(array: usize, newSize: usize, alignLog2: u32, canGrow: bool = true): void {\n // Depends on the fact that Arrays mimic ArrayBufferView\n let oldCapacity = changetype(array).byteLength;\n if (newSize > oldCapacity >>> alignLog2) {\n if (newSize > BLOCK_MAXSIZE >>> alignLog2) throw new RangeError(E_INVALIDLENGTH);\n let oldData = changetype(changetype(array).buffer);\n // Grows old capacity by factor of two.\n // Make sure we don't reach BLOCK_MAXSIZE for new growed capacity.\n let newCapacity = max(newSize, MIN_SIZE) << alignLog2;\n if (canGrow) newCapacity = max(min(oldCapacity << 1, BLOCK_MAXSIZE), newCapacity);\n let newData = __renew(oldData, newCapacity);\n // __new / __renew already init memory range as zeros in Incremental runtime.\n // So try to avoid this.\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(newData + oldCapacity, 0, newCapacity - oldCapacity);\n }\n if (newData != oldData) { // oldData has been free'd\n store(array, newData, offsetof(\"buffer\"));\n store(array, newData, offsetof(\"dataStart\"));\n __link(array, changetype(newData), false);\n }\n store(array, newCapacity, offsetof(\"byteLength\"));\n }\n}\n\nexport class Array {\n [key: number]: T;\n\n // Mimicking ArrayBufferView isn't strictly necessary here but is done to allow glue code\n // to work with typed and normal arrays interchangeably. Technically, normal arrays do not need\n // `dataStart` (equals `buffer`) and `byteLength` (equals computed `buffer.byteLength`), but the\n // block is 16 bytes anyway so it's fine to have a couple extra fields in there.\n\n private buffer: ArrayBuffer;\n @unsafe readonly dataStart: usize;\n private byteLength: i32; // Uses here as capacity\n\n // Also note that Array with non-nullable T must guard against uninitialized null values\n // whenever an element is accessed. Otherwise, the compiler wouldn't be able to guarantee\n // type-safety anymore. For lack of a better word, such an array is \"holey\".\n\n private length_: i32;\n\n static isArray(value: U): bool {\n return isReference() ? changetype(value) != 0 && builtin_isArray(value) : false;\n }\n\n static create(capacity: i32 = 0): Array {\n WARNING(\"'Array.create' is deprecated. Use 'new Array' instead, making sure initial elements are initialized.\");\n let array = new Array(capacity);\n array.length = 0;\n return array;\n }\n\n constructor(length: i32 = 0) {\n if (length > BLOCK_MAXSIZE >>> alignof()) throw new RangeError(E_INVALIDLENGTH);\n // reserve capacity for at least MIN_SIZE elements\n let bufferSize = max(length, MIN_SIZE) << alignof();\n let buffer = changetype(__new(bufferSize, idof()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(buffer), 0, bufferSize);\n }\n this.buffer = buffer; // links\n this.dataStart = changetype(buffer);\n this.byteLength = bufferSize;\n this.length_ = length;\n }\n\n get length(): i32 {\n return this.length_;\n }\n\n set length(newLength: i32) {\n ensureCapacity(changetype(this), newLength, alignof(), false);\n this.length_ = newLength;\n }\n\n every(fn: (value: T, index: i32, array: Array) => bool): bool {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n if (!fn(load(this.dataStart + (i << alignof())), i, this)) return false;\n }\n return true;\n }\n\n findIndex(fn: (value: T, index: i32, array: Array) => bool): i32 {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n if (fn(load(this.dataStart + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n findLastIndex(fn: (value: T, index: i32, array: Array) => bool): i32 {\n for (let i = this.length_ - 1; i >= 0; --i) {\n if (fn(load(this.dataStart + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n @operator(\"[]\") private __get(index: i32): T {\n if (index >= this.length_) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(this.dataStart + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n @unsafe @operator(\"{}\") private __uget(index: i32): T {\n return load(this.dataStart + (index << alignof()));\n }\n\n @operator(\"[]=\") private __set(index: i32, value: T): void {\n if (index >= this.length_) {\n if (index < 0) throw new RangeError(E_INDEXOUTOFRANGE);\n ensureCapacity(changetype(this), index + 1, alignof());\n this.length_ = index + 1;\n }\n store(this.dataStart + (index << alignof()), value);\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n }\n\n at(index: i32): T {\n let len = this.length_;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(this.dataStart + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n fill(value: T, start: i32 = 0, end: i32 = i32.MAX_VALUE): Array {\n if (isManaged()) {\n FILL(this.dataStart, this.length_, changetype(value), start, end);\n __link(changetype(this), changetype(value), false);\n } else {\n FILL(this.dataStart, this.length_, value, start, end);\n }\n return this;\n }\n\n includes(value: T, fromIndex: i32 = 0): bool {\n if (isFloat()) {\n let len = this.length_;\n if (len == 0 || fromIndex >= len) return false;\n if (fromIndex < 0) fromIndex = max(len + fromIndex, 0);\n let ptr = this.dataStart;\n while (fromIndex < len) {\n let elem = load(ptr + (fromIndex << alignof()));\n // @ts-ignore\n if (elem == value || isNaN(elem) & isNaN(value)) return true;\n ++fromIndex;\n }\n return false;\n } else {\n return this.indexOf(value, fromIndex) >= 0;\n }\n }\n\n indexOf(value: T, fromIndex: i32 = 0): i32 {\n let len = this.length_;\n if (len == 0 || fromIndex >= len) return -1;\n if (fromIndex < 0) fromIndex = max(len + fromIndex, 0);\n let ptr = this.dataStart;\n while (fromIndex < len) {\n if (load(ptr + (fromIndex << alignof())) == value) return fromIndex;\n ++fromIndex;\n }\n return -1;\n }\n\n lastIndexOf(value: T, fromIndex: i32 = this.length_): i32 {\n let len = this.length_;\n if (len == 0) return -1;\n if (fromIndex < 0) fromIndex = len + fromIndex;\n else if (fromIndex >= len) fromIndex = len - 1;\n let ptr = this.dataStart;\n while (fromIndex >= 0) {\n if (load(ptr + (fromIndex << alignof())) == value) return fromIndex;\n --fromIndex;\n }\n return -1;\n }\n\n push(value: T): i32 {\n let oldLen = this.length_;\n let len = oldLen + 1;\n ensureCapacity(changetype(this), len, alignof());\n if (isManaged()) {\n store(this.dataStart + (oldLen << alignof()), changetype(value));\n __link(changetype(this), changetype(value), true);\n } else {\n store(this.dataStart + (oldLen << alignof()), value);\n }\n this.length_ = len;\n return len;\n }\n\n concat(other: Array): Array {\n let thisLen = this.length_;\n let otherLen = other.length_;\n let outLen = thisLen + otherLen;\n if (outLen > BLOCK_MAXSIZE >>> alignof()) throw new Error(E_INVALIDLENGTH);\n let out = changetype>(__newArray(outLen, alignof(), idof>()));\n let outStart = out.dataStart;\n let thisSize = thisLen << alignof();\n if (isManaged()) {\n let thisStart = this.dataStart;\n for (let offset: usize = 0; offset < thisSize; offset += sizeof()) {\n let ref = load(thisStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n outStart += thisSize;\n let otherStart = other.dataStart;\n let otherSize = otherLen << alignof();\n for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {\n let ref = load(otherStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(outStart, this.dataStart, thisSize);\n memory.copy(outStart + thisSize, other.dataStart, otherLen << alignof());\n }\n return out;\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): Array {\n let ptr = this.dataStart;\n let len = this.length_;\n\n end = min(end, len);\n\n let to = target < 0 ? max(len + target, 0) : min(target, len);\n let from = start < 0 ? max(len + start, 0) : min(start, len);\n let last = end < 0 ? max(len + end, 0) : min(end, len);\n let count = min(last - from, len - to);\n\n memory.copy( // is memmove\n ptr + (to << alignof()),\n ptr + (from << alignof()),\n count << alignof()\n );\n return this;\n }\n\n pop(): T {\n let len = this.length_;\n if (len < 1) throw new RangeError(E_EMPTYARRAY);\n let val = load(this.dataStart + ((--len) << alignof()));\n this.length_ = len;\n return val;\n }\n\n forEach(fn: (value: T, index: i32, array: Array) => void): void {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n fn(load(this.dataStart + (i << alignof())), i, this);\n }\n }\n\n map(fn: (value: T, index: i32, array: Array) => U): Array {\n let len = this.length_;\n let out = changetype>(__newArray(len, alignof(), idof>()));\n let outStart = out.dataStart;\n for (let i = 0; i < min(len, this.length_); ++i) {\n let result = fn(load(this.dataStart + (i << alignof())), i, this);\n store(outStart + (i << alignof()), result);\n if (isManaged()) {\n __link(changetype(out), changetype(result), true);\n }\n }\n return out;\n }\n\n filter(fn: (value: T, index: i32, array: Array) => bool): Array {\n let result = changetype>(__newArray(0, alignof(), idof>()));\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n let value = load(this.dataStart + (i << alignof()));\n if (fn(value, i, this)) result.push(value);\n }\n return result;\n }\n\n reduce(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n acc = fn(acc, load(this.dataStart + (i << alignof())), i, this);\n }\n return acc;\n }\n\n reduceRight(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: Array) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = this.length_ - 1; i >= 0; --i) {\n acc = fn(acc, load(this.dataStart + (i << alignof())), i, this);\n }\n return acc;\n }\n\n shift(): T {\n let len = this.length_;\n if (len < 1) throw new RangeError(E_EMPTYARRAY);\n let base = this.dataStart;\n let element = load(base);\n let lastIndex = len - 1;\n memory.copy(\n base,\n base + sizeof(),\n lastIndex << alignof()\n );\n if (isReference()) {\n store(base + (lastIndex << alignof()), 0);\n } else {\n // @ts-ignore\n store(base + (lastIndex << alignof()), 0);\n }\n this.length_ = lastIndex;\n return element;\n }\n\n some(fn: (value: T, index: i32, array: Array) => bool): bool {\n for (let i = 0, len = this.length_; i < min(len, this.length_); ++i) {\n if (fn(load(this.dataStart + (i << alignof())), i, this)) return true;\n }\n return false;\n }\n\n unshift(value: T): i32 {\n let len = this.length_ + 1;\n ensureCapacity(changetype(this), len, alignof());\n let ptr = this.dataStart;\n memory.copy(\n ptr + sizeof(),\n ptr,\n (len - 1) << alignof()\n );\n store(ptr, value);\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n this.length_ = len;\n return len;\n }\n\n slice(start: i32 = 0, end: i32 = i32.MAX_VALUE): Array {\n let len = this.length_;\n start = start < 0 ? max(start + len, 0) : min(start, len);\n end = end < 0 ? max(end + len, 0) : min(end , len);\n len = max(end - start, 0);\n let slice = changetype>(__newArray(len, alignof(), idof>()));\n let sliceBase = slice.dataStart;\n let thisBase = this.dataStart + (start << alignof());\n if (isManaged()) {\n let off = 0;\n let end = len << alignof();\n while (off < end) {\n let ref = load(thisBase + off);\n store(sliceBase + off, ref);\n __link(changetype(slice), ref, true);\n off += sizeof();\n }\n } else {\n memory.copy(sliceBase, thisBase, len << alignof());\n }\n return slice;\n }\n\n splice(start: i32, deleteCount: i32 = i32.MAX_VALUE): Array {\n let len = this.length_;\n start = start < 0 ? max(len + start, 0) : min(start, len);\n deleteCount = max(min(deleteCount, len - start), 0);\n let result = changetype>(__newArray(deleteCount, alignof(), idof>()));\n let resultStart = result.dataStart;\n let thisStart = this.dataStart;\n let thisBase = thisStart + (start << alignof());\n memory.copy(\n resultStart,\n thisBase,\n deleteCount << alignof()\n );\n let offset = start + deleteCount;\n if (len != offset) {\n memory.copy(\n thisBase,\n thisStart + (offset << alignof()),\n (len - offset) << alignof()\n );\n }\n this.length_ = len - deleteCount;\n return result;\n }\n\n reverse(): Array {\n REVERSE(this.dataStart, this.length_);\n return this;\n }\n\n sort(comparator: (a: T, b: T) => i32 = COMPARATOR()): Array {\n SORT(this.dataStart, this.length_, comparator);\n return this;\n }\n\n join(separator: string = \",\"): string {\n let ptr = this.dataStart;\n let len = this.length_;\n if (isBoolean()) return joinBooleanArray(ptr, len, separator);\n if (isInteger()) return joinIntegerArray(ptr, len, separator);\n if (isFloat()) return joinFloatArray(ptr, len, separator);\n\n if (ASC_SHRINK_LEVEL < 1) {\n if (isString()) return joinStringArray(ptr, len, separator);\n }\n // For rest objects and arrays use general join routine\n if (isReference()) return joinReferenceArray(ptr, len, separator);\n ERROR(\"unspported element type\");\n return unreachable();\n }\n\n flat(): T {\n if (!isArray()) {\n ERROR(\"Cannot call flat() on Array where T is not an Array.\");\n }\n // Get the length and data start values\n let ptr = this.dataStart;\n let len = this.length_;\n\n // calculate the end size with an initial pass\n let size = 0;\n for (let i = 0; i < len; ++i) {\n let child = load(ptr + (i << alignof()));\n size += child == 0 ? 0 : load(child, offsetof(\"length_\"));\n }\n\n // calculate the byteLength of the resulting backing ArrayBuffer\n const align = alignof>();\n let byteLength = size << align;\n let outBuffer = changetype(__new(byteLength, idof()));\n\n // create the return value and initialize it\n let outArray = changetype(__new(offsetof(), idof()));\n store(changetype(outArray), size, offsetof(\"length_\"));\n\n // byteLength, dataStart, and buffer are all readonly\n store(changetype(outArray), byteLength, offsetof(\"byteLength\"));\n store(changetype(outArray), changetype(outBuffer), offsetof(\"dataStart\"));\n store(changetype(outArray), changetype(outBuffer), offsetof(\"buffer\"));\n __link(changetype(outArray), changetype(outBuffer), false);\n\n // set the elements\n let resultOffset: usize = 0;\n for (let i = 0; i < len; ++i) { // for each child\n let child = load(ptr + (i << alignof()));\n\n // ignore null arrays\n if (!child) continue;\n\n // copy the underlying buffer data to the result buffer\n let childDataLength = load(child, offsetof(\"length_\")) << align;\n memory.copy(\n changetype(outBuffer) + resultOffset,\n load(child, offsetof(\"dataStart\")),\n childDataLength\n );\n\n // advance the result length\n resultOffset += childDataLength;\n }\n\n // if the `valueof` type is managed, we must link each reference\n if (isManaged>()) {\n for (let i = 0; i < size; ++i) {\n let ref = load(changetype(outBuffer) + (i << usize(alignof>())));\n __link(changetype(outBuffer), ref, true);\n }\n }\n\n return outArray;\n }\n\n toString(): string {\n return this.join();\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n if (isManaged()) {\n let cur = this.dataStart;\n let end = cur + (this.length_ << alignof());\n while (cur < end) {\n let val = load(cur);\n if (val) __visit(val, cookie);\n cur += sizeof();\n }\n }\n __visit(changetype(this.buffer), cookie);\n }\n}\n","import { assertResult } from \"./assertCollector\";\nimport { MockFn, mockFunctionStatus } from \"./mockInstrument\";\n\nexport function describeImpl(\n description: string,\n testsFunction: () => void,\n): void {\n assertResult.addDescription(description);\n testsFunction();\n assertResult.removeDescription();\n}\nexport function testImpl(description: string, testFunction: () => void): void {\n assertResult.addDescription(description);\n testFunction();\n assertResult.removeDescription();\n mockFunctionStatus.clear();\n}\n\nexport function mockImpl(\n oldFunction: T,\n newFunction: T,\n): MockFn {\n if (!isFunction(oldFunction) || !isFunction(newFunction)) {\n ERROR(\"mock paramemter receive a function\");\n }\n const mockFn = new MockFn(oldFunction.index, newFunction.index);\n mockFunctionStatus.set(oldFunction.index, newFunction.index);\n return mockFn;\n}\nexport function unmockImpl(oldFunction: T): void {\n mockFunctionStatus.setIgnore(oldFunction.index, true);\n}\nexport function remockImpl(oldFunction: T): void {\n mockFunctionStatus.setIgnore(oldFunction.index, false);\n}\n","import { assertResult } from \"./assertCollector\";\nimport { outputTrace } from \"./covInstrument\";\n\nimport {\n args_sizes_get,\n args_get,\n errno,\n errnoToString,\n fd,\n path_open,\n lookupflags,\n rights,\n oflags,\n fdflags,\n iovec,\n fd_write,\n fd_close,\n} from \"@assemblyscript/wasi-shim/assembly/bindings/wasi_snapshot_preview1\";\n\nexport function output(): void {\n const kvPair: string[] = [];\n kvPair.push(assertResult.totalString());\n kvPair.push(assertResult.failString());\n kvPair.push(assertResult.failInfoString());\n assertResult.clear();\n\n outputTrace();\n\n const outputString = \"{\" + kvPair.join(\",\") + \"}\";\n\n const outputFileName = getArgs()[1].slice(0, -5) + \".assert.log\";\n writeFile(outputFileName, outputString);\n}\n\nlet ret: errno;\n\nfunction perror(msg: string): void {\n if (ret == errno.SUCCESS) {\n return;\n }\n assert(false, errnoToString(ret) + \" \" + msg);\n}\n\nfunction checkMemory(offset: usize): void {\n assert(offset < usize(i32.MAX_VALUE), \"OOM\");\n}\n\nfunction fromCString(cstring: usize): string {\n let size = 0;\n while (load(cstring + size) !== 0) {\n size++;\n }\n return String.UTF8.decodeUnsafe(cstring, size);\n}\n\nfunction getArgs(): string[] {\n const args: string[] = [];\n\n const count_and_size = memory.data(sizeof() * 2);\n checkMemory(count_and_size + sizeof() * 2);\n ret = args_sizes_get(count_and_size, count_and_size + 4);\n perror(\"args_sizes_get\");\n const argc = load(count_and_size, 0);\n const argv_total_size = load(count_and_size, sizeof());\n\n const argv_ptr_array = new ArrayBuffer(i32((argc + 1) * sizeof()));\n const argv_total_string = new ArrayBuffer(i32(argv_total_size));\n checkMemory(changetype(argv_ptr_array) + (argc + 1) * sizeof());\n checkMemory(changetype(argv_total_string) + argv_total_size);\n ret = args_get(\n changetype(argv_ptr_array),\n changetype(argv_total_string),\n );\n perror(\"args_get\");\n for (let i: usize = 0; i < argc; i++) {\n const argv_ptr = load(\n changetype(argv_ptr_array) + i * sizeof(),\n );\n const arg = fromCString(argv_ptr);\n args.push(arg);\n }\n\n return args;\n}\n\nfunction writeFile(path: string, data: string): void {\n if (data.length == 0) return;\n // open\n const utf8path = String.UTF8.encode(path);\n const fdptr = memory.data(sizeof());\n checkMemory(changetype(utf8path) + utf8path.byteLength);\n ret = path_open(\n 3,\n lookupflags.SYMLINK_FOLLOW,\n changetype(utf8path),\n utf8path.byteLength,\n oflags.CREAT | oflags.TRUNC,\n rights.FD_WRITE |\n rights.FD_SEEK |\n rights.FD_TELL |\n rights.FD_FILESTAT_GET |\n rights.PATH_CREATE_FILE,\n rights.FD_WRITE |\n rights.FD_SEEK |\n rights.FD_TELL |\n rights.FD_FILESTAT_GET |\n rights.PATH_CREATE_FILE,\n fdflags.SYNC,\n fdptr,\n );\n perror(\"path_open\");\n const fileDescriptor: fd = load(fdptr);\n\n // write\n const buf = String.UTF8.encode(data);\n const iov = changetype(memory.data(sizeof()));\n iov.buf = changetype(buf);\n iov.buf_len = buf.byteLength;\n const written_ptr = memory.data(sizeof());\n checkMemory(changetype(buf) + buf.byteLength);\n do {\n ret = fd_write(fileDescriptor, changetype(iov), 1, written_ptr);\n perror(\"fd_write\");\n iov.buf_len -= load(written_ptr);\n iov.buf += load(written_ptr);\n } while (iov.buf_len > 0);\n fd_close(fileDescriptor);\n}\n","/// \n\nimport { OBJECT, BLOCK_MAXSIZE, TOTAL_OVERHEAD } from \"./rt/common\";\nimport { Runtime } from \"shared/runtime\";\nimport { COMPARATOR, SORT } from \"./util/sort\";\nimport { REVERSE, FILL } from \"./util/bytes\";\nimport { idof } from \"./builtins\";\nimport { Array } from \"./array\";\nimport { E_INDEXOUTOFRANGE, E_INVALIDLENGTH, E_HOLEYARRAY } from \"./util/error\";\nimport { joinBooleanArray, joinIntegerArray, joinFloatArray, joinStringArray, joinReferenceArray } from \"./util/string\";\n\n@final\nexport class StaticArray {\n [key: number]: T;\n\n // Note that the interface of StaticArray instances must be a semantically\n // compatible subset of Array in order for syntax highlighting to work\n // properly, for instance when creating static arrays from array literals.\n // The additionally provided static methods take care of dealing with static\n // arrays exclusively, without having to convert to Array first.\n\n static fromArray(source: Array): StaticArray {\n let length = source.length;\n let outSize = length << alignof();\n let out = changetype>(__new(outSize, idof>()));\n if (isManaged()) {\n let sourcePtr = source.dataStart;\n for (let i = 0; i < length; ++i) {\n let off = i << alignof();\n let ref = load(sourcePtr + off);\n store(changetype(out) + off, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(changetype(out), source.dataStart, outSize);\n }\n return out;\n }\n\n /** @deprecated Please use source.concat> instead. */\n static concat(source: StaticArray, other: StaticArray): StaticArray {\n return source.concat>(other);\n }\n\n /** @deprecated Please use source.slice> instead. */\n static slice(source: StaticArray, start: i32 = 0, end: i32 = i32.MAX_VALUE): StaticArray {\n return source.slice>(start, end);\n }\n\n constructor(length: i32) {\n if (length > BLOCK_MAXSIZE >>> alignof()) throw new RangeError(E_INVALIDLENGTH);\n let outSize = length << alignof();\n let out = changetype>(__new(outSize, idof>()));\n if (ASC_RUNTIME != Runtime.Incremental) {\n memory.fill(changetype(out), 0, outSize);\n }\n return out;\n }\n\n get length(): i32 {\n return changetype(changetype(this) - TOTAL_OVERHEAD).rtSize >>> alignof();\n }\n\n at(index: i32): T {\n let len = this.length;\n index += select(0, len, index >= 0);\n if (index >= len) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(changetype(this) + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n @operator(\"[]\") private __get(index: i32): T {\n if (index >= this.length) throw new RangeError(E_INDEXOUTOFRANGE);\n let value = load(changetype(this) + (index << alignof()));\n if (isReference()) {\n if (!isNullable()) {\n if (!changetype(value)) throw new Error(E_HOLEYARRAY);\n }\n }\n return value;\n }\n\n @unsafe @operator(\"{}\") private __uget(index: i32): T {\n return load(changetype(this) + (index << alignof()));\n }\n\n @operator(\"[]=\") private __set(index: i32, value: T): void {\n if (index >= this.length) throw new RangeError(E_INDEXOUTOFRANGE);\n this.__uset(index, value);\n }\n\n @unsafe @operator(\"{}=\") private __uset(index: i32, value: T): void {\n store(changetype(this) + (index << alignof()), value);\n if (isManaged()) {\n __link(changetype(this), changetype(value), true);\n }\n }\n\n fill(value: T, start: i32 = 0, end: i32 = i32.MAX_VALUE): StaticArray {\n if (isManaged()) {\n FILL(changetype(this), this.length, changetype(value), start, end);\n __link(changetype(this), changetype(value), false);\n } else {\n FILL(changetype(this), this.length, value, start, end);\n }\n return this;\n }\n\n copyWithin(target: i32, start: i32, end: i32 = i32.MAX_VALUE): StaticArray {\n let ptr = changetype(this);\n let len = this.length;\n\n end = min(end, len);\n\n let to = target < 0 ? max(len + target, 0) : min(target, len);\n let from = start < 0 ? max(len + start, 0) : min(start, len);\n let last = end < 0 ? max(len + end, 0) : min(end, len);\n let count = min(last - from, len - to);\n\n memory.copy( // is memmove\n ptr + (to << alignof()),\n ptr + (from << alignof()),\n count << alignof()\n );\n return this;\n }\n\n includes(value: T, fromIndex: i32 = 0): bool {\n if (isFloat()) {\n let length = this.length;\n if (length == 0 || fromIndex >= length) return false;\n if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);\n while (fromIndex < length) {\n let elem = load(changetype(this) + (fromIndex << alignof()));\n // @ts-ignore\n if (elem == value || isNaN(elem) & isNaN(value)) return true;\n ++fromIndex;\n }\n return false;\n } else {\n return this.indexOf(value, fromIndex) >= 0;\n }\n }\n\n indexOf(value: T, fromIndex: i32 = 0): i32 {\n let length = this.length;\n if (length == 0 || fromIndex >= length) return -1;\n if (fromIndex < 0) fromIndex = max(length + fromIndex, 0);\n while (fromIndex < length) {\n if (load(changetype(this) + (fromIndex << alignof())) == value) return fromIndex;\n ++fromIndex;\n }\n return -1;\n }\n\n lastIndexOf(value: T, fromIndex: i32 = this.length): i32 {\n let length = this.length;\n if (length == 0) return -1;\n if (fromIndex < 0) fromIndex = length + fromIndex;\n else if (fromIndex >= length) fromIndex = length - 1;\n while (fromIndex >= 0) {\n if (load(changetype(this) + (fromIndex << alignof())) == value) return fromIndex;\n --fromIndex;\n }\n return -1;\n }\n\n concat = Array>(other: U): U {\n let sourceLen = this.length;\n let otherLen = other.length;\n let outLen = sourceLen + otherLen;\n if (outLen > BLOCK_MAXSIZE >>> alignof()) {\n throw new Error(E_INVALIDLENGTH);\n }\n let sourceSize = sourceLen << alignof();\n let out = changetype(this); // FIXME: instanceof needs *some* value\n\n if (out instanceof Array) {\n out = changetype(__newArray(outLen, alignof(), idof>()));\n // ^ FIXME: Function returns type U, but can't __newArray(U extends Array)\n let outStart = changetype>(out).dataStart;\n let otherStart = changetype>(other).dataStart;\n let thisStart = changetype(this);\n\n if (isManaged()) {\n for (let offset: usize = 0; offset < sourceSize; offset += sizeof()) {\n let ref = load(thisStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n outStart += sourceSize;\n let otherSize = otherLen << alignof();\n for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {\n let ref = load(otherStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(outStart, thisStart, sourceSize);\n memory.copy(outStart + sourceSize, otherStart, otherLen << alignof());\n }\n } else if (out instanceof StaticArray) {\n out = changetype(__new(outLen << alignof(), idof>()));\n let outStart = changetype(out);\n let otherStart = changetype(other);\n let thisStart = changetype(this);\n\n if (isManaged()) {\n for (let offset: usize = 0; offset < sourceSize; offset += sizeof()) {\n let ref = load(thisStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n outStart += sourceSize;\n let otherSize = otherLen << alignof();\n for (let offset: usize = 0; offset < otherSize; offset += sizeof()) {\n let ref = load(otherStart + offset);\n store(outStart + offset, ref);\n __link(changetype(out), ref, true);\n }\n } else {\n memory.copy(outStart, thisStart, sourceSize);\n memory.copy(outStart + sourceSize, otherStart, otherLen << alignof());\n }\n } else {\n ERROR(\"Only Array and StaticArray accept for 'U' parameter\");\n }\n return out;\n }\n\n slice = Array>(start: i32 = 0, end: i32 = i32.MAX_VALUE): U {\n let length = this.length;\n start = start < 0 ? max(start + length, 0) : min(start, length);\n end = end < 0 ? max(end + length, 0) : min(end, length);\n length = max(end - start, 0);\n\n let sourceStart = changetype(this) + (start << alignof());\n let size = length << alignof();\n let out = changetype(this); // FIXME: instanceof needs *some* value\n\n if (out instanceof Array) {\n // return Array\n out = changetype(__newArray(length, alignof(), idof>()));\n // ^ FIXME: Function returns type U, but can't __newArray(U extends Array)\n let outStart = changetype>(out).dataStart;\n if (isManaged()) {\n let off: usize = 0;\n while (off < size) {\n let ref = load(sourceStart + off);\n store(outStart + off, ref);\n __link(changetype(out), ref, true);\n off += sizeof();\n }\n } else {\n memory.copy(outStart, sourceStart, size);\n }\n } else if (out instanceof StaticArray) {\n // return StaticArray\n out = changetype(__new(size, idof>()));\n let outStart = changetype(out);\n if (isManaged()) {\n let off: usize = 0;\n while (off < size) {\n let ref = load(sourceStart + off);\n store(outStart + off, ref);\n __link(outStart, ref, true);\n off += sizeof();\n }\n } else {\n memory.copy(outStart, sourceStart, size);\n }\n } else {\n ERROR(\"Only Array and StaticArray accept for 'U' parameter\");\n }\n return out;\n }\n\n findIndex(fn: (value: T, index: i32, array: StaticArray) => bool): i32 {\n for (let i = 0, len = this.length; i < len; ++i) {\n if (fn(load(changetype(this) + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n findLastIndex(fn: (value: T, index: i32, array: StaticArray) => bool): i32 {\n for (let i = this.length - 1; i >= 0; --i) {\n if (fn(load(changetype(this) + (i << alignof())), i, this)) return i;\n }\n return -1;\n }\n\n forEach(fn: (value: T, index: i32, array: StaticArray) => void): void {\n for (let i = 0, len = this.length; i < len; ++i) {\n fn(load(changetype(this) + (i << alignof())), i, this);\n }\n }\n\n map(fn: (value: T, index: i32, array: StaticArray) => U): Array {\n let len = this.length;\n let out = changetype>(__newArray(len, alignof(), idof>()));\n let outStart = out.dataStart;\n for (let i = 0; i < len; ++i) {\n let result = fn(load(changetype(this) + (i << alignof())), i, this);\n store(outStart + (i << alignof()), result);\n if (isManaged()) {\n __link(changetype(out), changetype(result), true);\n }\n }\n return out;\n }\n\n filter(fn: (value: T, index: i32, array: StaticArray) => bool): Array {\n let result = changetype>(__newArray(0, alignof(), idof>()));\n for (let i = 0, len = this.length; i < len; ++i) {\n let value = load(changetype(this) + (i << alignof()));\n if (fn(value, i, this)) result.push(value);\n }\n return result;\n }\n\n reduce(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: StaticArray) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = 0, len = this.length; i < len; ++i) {\n acc = fn(acc, load(changetype(this) + (i << alignof())), i, this);\n }\n return acc;\n }\n\n reduceRight(\n fn: (previousValue: U, currentValue: T, currentIndex: i32, array: StaticArray) => U,\n initialValue: U\n ): U {\n let acc = initialValue;\n for (let i = this.length - 1; i >= 0; --i) {\n acc = fn(acc, load(changetype(this) + (i << alignof())), i, this);\n }\n return acc;\n }\n\n every(fn: (value: T, index: i32, array: StaticArray) => bool): bool {\n for (let i = 0, len = this.length; i < len; ++i) {\n if (!fn(load(changetype(this) + (i << alignof())), i, this)) return false;\n }\n return true;\n }\n\n some(fn: (value: T, index: i32, array: StaticArray) => bool): bool {\n for (let i = 0, len = this.length; i < len; ++i) {\n if (fn(load(changetype(this) + (i << alignof())), i, this)) return true;\n }\n return false;\n }\n\n sort(comparator: (a: T, b: T) => i32 = COMPARATOR()): StaticArray {\n SORT(changetype(this), this.length, comparator);\n return this;\n }\n\n join(separator: string = \",\"): string {\n if (isBoolean()) return joinBooleanArray(changetype(this), this.length, separator);\n if (isInteger()) return joinIntegerArray(changetype(this), this.length, separator);\n if (isFloat()) return joinFloatArray(changetype(this), this.length, separator);\n if (ASC_SHRINK_LEVEL < 1) {\n if (isString()) return joinStringArray(changetype(this), this.length, separator);\n }\n if (isReference()) return joinReferenceArray(changetype(this), this.length, separator);\n ERROR(\"unspported element type\");\n return unreachable();\n }\n\n reverse(): StaticArray {\n REVERSE(changetype(this), this.length);\n return this;\n }\n\n toString(): string {\n return this.join();\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n if (isManaged()) {\n let cur = changetype(this);\n let end = cur + changetype(changetype(this) - TOTAL_OVERHEAD).rtSize;\n while (cur < end) {\n let val = load(cur);\n if (val) __visit(val, cookie);\n cur += sizeof();\n }\n }\n }\n}\n","import { strtol, strtod, strtob } from \"./util/string\";\n\ntype auto = i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isBoolean(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isInteger(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isSigned(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isFloat(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isVector(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isReference(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isString(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isArray(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isArrayLike(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isFunction(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isNullable(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isDefined(expression: auto): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isConstant(expression: auto): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isManaged(value?: T): bool;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isVoid(): bool;\n\n// @ts-ignore\n@builtin\nexport declare function lengthof(func?: T): i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function clz(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function ctz(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function popcnt(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function rotl(value: T, shift: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function rotr(value: T, shift: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function abs(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function max(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function min(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function ceil(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function floor(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function copysign(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function nearest(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function reinterpret(value: number): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function sqrt(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function trunc(value: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function add(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function sub(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function mul(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function div(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function eq(left: T, right: T): i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function ne(left: T, right: T): i32;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function rem(left: T, right: T): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function store(ptr: usize, value: auto, immOffset?: usize, immAlign?: usize): void;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function sizeof(): usize; // | u32 / u64\n\n// @ts-ignore: decorator\n@builtin\nexport declare function alignof(): usize; // | u32 / u64\n\n// @ts-ignore: decorator\n@builtin\nexport declare function offsetof(fieldName?: string): usize; // | u32 / u64\n\n// @ts-ignore: decorator\n@builtin\nexport declare function idof(): u32;\n\n// @ts-ignore\n@builtin\nexport declare function nameof(): string;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function select(ifTrue: T, ifFalse: T, condition: bool): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function unreachable(): auto;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function changetype(value: auto): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function assert(isTrueish: T, message?: string): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function unchecked(expr: T): T;\n\n// @ts-ignore: decorator\n@unsafe @builtin\nexport declare function call_indirect(index: u32, ...args: auto[]): T;\n\n// @ts-ignore: decorator\n@builtin\nexport declare function instantiate(...args: auto[]): T;\n\nexport namespace atomic {\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load(ptr: usize, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: T, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg(ptr: usize, value: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg(ptr: usize, expected: T, replacement: T, immOffset?: usize): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function wait(ptr: usize, expected: T, timeout: i64): AtomicWaitResult;\n\n // @ts-ignore: decorator\n @builtin\n export declare function notify(ptr: usize, count: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function fence(): void;\n}\n\n// @ts-ignore: decorator\n@lazy\nexport const enum AtomicWaitResult {\n OK = 0,\n NOT_EQUAL = 1,\n TIMED_OUT = 2\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i8(value: auto): i8;\n\nexport namespace i8 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i8 = -128;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i8 = 127;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i8 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i16(value: auto): i16;\n\nexport namespace i16 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i16 = -32768;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i16 = 32767;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i16 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i32(value: auto): i32;\n\nexport namespace i32 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i32 = -2147483648;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i32 = 2147483647;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i32 {\n return strtol(value, radix);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function clz(value: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ctz(value: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(value: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_s(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_u(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotl(value: i32, shift: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotr(value: i32, shift: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: i32, right:i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_s(left: i32, right: i32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_u(left: u32, right: u32): u32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_f32(value: f32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_s(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_s(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i32, immOffset?: usize, immAlign?: usize): void;\n\n export namespace atomic {\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i32, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i32, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i32, immOffset?: usize): void;\n\n export namespace rmw8 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i32, replacement: i32, immOffset?: usize): i32;\n }\n\n export namespace rmw16 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i32, replacement: i32, immOffset?: usize): i32;\n }\n\n export namespace rmw {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg(ptr: usize, value: i32, immOffset?: usize): i32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg(ptr: usize, expected: i32, replacement: i32, immOffset?: usize): i32;\n }\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i64(value: auto): i64;\n\nexport namespace i64 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: i64 = -9223372036854775808;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: i64 = 9223372036854775807;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): i64 {\n return strtol(value, radix);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function clz(value: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ctz(value: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_s(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div_u(left: i64, right:i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_s(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_s(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32_s(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32_u(ptr: usize, immOffset?: usize, immAlign?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(value: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotl(value: i64, shift: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rotr(value: i64, shift: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: i64, right:i64): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: i64, right:i64): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_s(left: i64, right: i64): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function rem_u(left: u64, right: u64): u64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_f64(value: f64): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store32(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i64, immOffset?: usize, immAlign?: usize): void;\n\n export namespace atomic {\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8_u(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16_u(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32_u(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8(ptr: usize, value: i64, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16(ptr: usize, value: i64, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store32(ptr: usize, value: i64, immOffset?: usize): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: i64, immOffset?: usize): void;\n\n export namespace rmw8 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n\n export namespace rmw16 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n\n export namespace rmw32 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg_u(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg_u(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n\n export namespace rmw {\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function xchg(ptr: usize, value: i64, immOffset?: usize): i64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function cmpxchg(ptr: usize, expected: i64, replacement: i64, immOffset?: usize): i64;\n }\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function isize(value: auto): isize;\n\nexport namespace isize {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: isize = sizeof() == sizeof()\n ? -2147483648\n : -9223372036854775808;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: isize = sizeof() == sizeof()\n ? 2147483647\n : 9223372036854775807;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): isize {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u8(value: auto): u8;\n\nexport namespace u8 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u8 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u8 = 255;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u8 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u16(value: auto): u16;\n\nexport namespace u16 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u16 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u16 = 65535;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u16 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u32(value: auto): u32;\n\nexport namespace u32 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u32 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u32 = 4294967295;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u32 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function u64(value: auto): u64;\n\nexport namespace u64 {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: u64 = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: u64 = 18446744073709551615;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): u64 {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function usize(value: auto): usize;\n\nexport namespace usize {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: usize = 0;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: usize = sizeof() == sizeof()\n ? 4294967295\n : 18446744073709551615;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string, radix: i32 = 0): usize {\n return strtol(value, radix);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function bool(value: auto): bool;\n\nexport namespace bool {\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE: bool = false;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE: bool = true;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string): bool {\n return strtob(value);\n }\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f32(value: auto): f32;\n\nexport namespace f32 {\n\n // @ts-ignore: decorator\n @lazy\n export const EPSILON = reinterpret(0x34000000); // 0x1p-23f\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE = reinterpret(0x00000001); // 0x0.000001p+0f\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE = reinterpret(0x7F7FFFFF); // 0x1.fffffep+127f\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_NORMAL_VALUE = reinterpret(0x00800000); // 0x1p-126f\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_SAFE_INTEGER: f32 = -16777215;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_SAFE_INTEGER: f32 = 16777215;\n\n // @ts-ignore: decorator\n @lazy\n export const POSITIVE_INFINITY: f32 = Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NEGATIVE_INFINITY: f32 = -Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NaN: f32 = 0.0 / 0.0;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string): f32 {\n return strtod(value);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function copysign(x: f32, y: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_i32(value: i32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(value: f32): f32;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: f32, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(value: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(left: f32, right: f32): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: f32, right: f32): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: f32, right: f32): i32;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f64(value: auto): f64;\n\nexport namespace f64 {\n\n // @ts-ignore: decorator\n @lazy\n export const EPSILON = reinterpret(0x3CB0000000000000); // 0x1p-52\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_VALUE = reinterpret(0x0000000000000001); // 0x0.0000000000001p+0\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_VALUE = reinterpret(0x7FEFFFFFFFFFFFFF); // 0x1.fffffffffffffp+1023\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_NORMAL_VALUE = reinterpret(0x0010000000000000); // 0x1p-1022\n\n // @ts-ignore: decorator\n @lazy\n export const MIN_SAFE_INTEGER: f64 = -9007199254740991;\n\n // @ts-ignore: decorator\n @lazy\n export const MAX_SAFE_INTEGER: f64 = 9007199254740991;\n\n // @ts-ignore: decorator\n @lazy\n export const POSITIVE_INFINITY: f64 = Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NEGATIVE_INFINITY: f64 = -Infinity;\n\n // @ts-ignore: decorator\n @lazy\n export const NaN: f64 = 0.0 / 0.0;\n\n // @ts-ignore: decorator\n @inline\n export function parse(value: string): f64 {\n return strtod(value);\n }\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function copysign(x: f64, y: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function reinterpret_i64(value: i64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(value: f64): f64;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: f64, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(value: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(left: f64, right: f64): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(left: f64, right: f64): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(left: f64, right: f64): i32;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function v128(\n a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8,\n i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8\n): v128;\n\nexport namespace v128 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: T): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): T;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: T): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, ...lanes: u8[]): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_ext(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_zero(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_lane(ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store_lane(ptr: usize, vec: v128, idx: u8, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8x8_s(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load8x8_u(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16x4_s(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load16x4_u(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32x2_s(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function load32x2_u(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load_splat(ptr: usize, immOffset?: usize, immAlign?: usize): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load8_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load16_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load32_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load64_splat(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load32_zero(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load64_zero(ptr: usize, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load8_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load16_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load32_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function load64_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): v128;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store8_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store16_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store32_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store64_lane(ptr: usize, vec: v128, idx: u8, immOffset?: u32, immAlign?: u32): void;\n\n // @ts-ignore: decorator\n @unsafe @builtin\n export declare function store(ptr: usize, value: v128, immOffset?: usize, immAlign?: usize): void;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(a: v128, b: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function and(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function or(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function xor(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function andnot(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function not(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitselect(v1: v128, v2: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function any_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmin(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmax(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function dot(a: v128, b: v128): v128; // i16 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function avgr(a: v128, b: v128): v128; // u8, u16 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(a: v128): v128; // f32, f64 only\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_low(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function demote_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function promote_low(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function q15mulr_sat(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_swizzle(a: v128, s: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_trunc(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_trunc_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_madd(a: v128, b: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_nmadd(a: v128, b: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_laneselect(a: v128, b: v128, m: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_q15mulr(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_dot(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_dot_add(a: v128, b: v128, c: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i8x16(\n a: i8, b: i8, c: i8, d: i8, e: i8, f: i8, g: i8, h: i8,\n i: i8, j: i8, k: i8, l: i8, m: i8, n: i8, o: i8, p: i8\n): v128;\n\nexport namespace i8x16 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_s(x: v128, idx: u8): i8;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_u(x: v128, idx: u8): u8;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function avgr_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function popcnt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i16x8_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(\n a: v128, b: v128,\n l0: u8, l1: u8, l2: u8, l3: u8, l4: u8, l5: u8, l6: u8, l7: u8,\n l8: u8, l9: u8, l10: u8, l11: u8, l12: u8, l13: u8, l14: u8, l15: u8\n ): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function swizzle(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_swizzle(a: v128, s: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_laneselect(a: v128, b: v128, m: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i16x8(a: i16, b: i16, c: i16, d: i16, e: i16, f: i16, g: i16, h: i16): v128;\n\nexport namespace i16x8 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i16): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_s(x: v128, idx: u8): i16;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane_u(x: v128, idx: u8): u16;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i16): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function avgr_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub_sat_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i32x4_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function narrow_i32x4_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i8x16_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i8x16_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i8x16_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i8x16_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i8x16_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i8x16_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function q15mulr_sat_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i8x16_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i8x16_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i8x16_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i8x16_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(\n a: v128, b: v128,\n l0: u8, l1: u8, l2: u8, l3: u8, l4: u8, l5: u8, l6: u8, l7: u8\n ): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_laneselect(a: v128, b: v128, m: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_q15mulr_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_dot_i8x16_i7x16_s(a: v128, b: v128, c: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i32x4(a: i32, b: i32, c: i32, d: i32): v128;\n\nexport namespace i32x4 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function dot_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f64x2_s_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc_sat_f64x2_u_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i16x8_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i16x8_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i16x8_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i16x8_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i16x8_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extadd_pairwise_i16x8_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i16x8_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i16x8_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i16x8_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8, l2: u8, l3: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_trunc_f32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_trunc_f32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_trunc_f64x2_s_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_trunc_f64x2_u_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_laneselect(a: v128, b: v128, m: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_dot_i8x16_i7x16_add_s(a: v128, b: v128, c: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function i64x2(a: i64, b: i64): v128;\n\nexport namespace i64x2 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: i64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): i64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: i64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shl(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_s(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shr_u(a: v128, b: i32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function all_true(a: v128): bool;\n\n // @ts-ignore: decorator\n @builtin\n export declare function bitmask(a: v128): i32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_low_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extend_high_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i32x4_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_low_i32x4_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i32x4_s(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extmul_high_i32x4_u(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_laneselect(a: v128, b: v128, m: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f32x4(a: f32, b: f32, c: f32, d: f32): v128;\n\nexport namespace f32x4 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: f32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): f32;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: f32): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmin(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmax(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function demote_f64x2_zero(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8, l2: u8, l3: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_madd(a: v128, b: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_nmadd(a: v128, b: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_max(a: v128, b: v128): v128;\n}\n\n// @ts-ignore: decorator\n@builtin\nexport declare function f64x2(a: f64, b: f64): v128;\n\nexport namespace f64x2 {\n\n // @ts-ignore: decorator\n @builtin\n export declare function splat(x: f64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function extract_lane(x: v128, idx: u8): f64;\n\n // @ts-ignore: decorator\n @builtin\n export declare function replace_lane(x: v128, idx: u8, value: f64): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function add(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sub(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function mul(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function div(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function neg(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function max(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmin(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function pmax(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function abs(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function sqrt(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ceil(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function floor(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function trunc(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function nearest(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function eq(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ne(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function lt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function le(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function gt(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function ge(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_low_i32x4_s(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function convert_low_i32x4_u(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function promote_low_f32x4(a: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function shuffle(a: v128, b: v128, l0: u8, l1: u8): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_madd(a: v128, b: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_nmadd(a: v128, b: v128, c: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_min(a: v128, b: v128): v128;\n\n // @ts-ignore: decorator\n @builtin\n export declare function relaxed_max(a: v128, b: v128): v128;\n}\n\n@final\nexport abstract class i31 { // FIXME: usage of 'new' requires a class :(\n\n // @ts-ignore: decorator\n @builtin\n static new(value: i32): i31ref { return changetype(unreachable()); }\n\n // @ts-ignore: decorator\n @builtin\n static get(i31expr: i31ref): i32 { return unreachable(); }\n}\n\n/* eslint-disable @typescript-eslint/no-unused-vars */\n\n// @ts-ignore: decorator\n@external(\"env\", \"abort\")\n@external.js(\"throw Error(`${message} in ${fileName}:${lineNumber}:${columnNumber}`);\")\ndeclare function abort(\n message?: string | null,\n fileName?: string | null,\n lineNumber?: u32,\n columnNumber?: u32\n): void;\n\n// @ts-ignore: decorator\n@external(\"env\", \"trace\")\n@external.js(\"console.log(message, ...[a0, a1, a2, a3, a4].slice(0, n));\")\ndeclare function trace(\n message: string,\n n?: i32,\n a0?: f64,\n a1?: f64,\n a2?: f64,\n a3?: f64,\n a4?: f64\n): void;\n\n// @ts-ignore: decorator\n@external(\"env\", \"seed\")\n@external.js(\"return Date.now() * Math.random();\")\ndeclare function seed(): f64;\n\n/* eslint-enable @typescript-eslint/no-unused-vars */\n","type auto = i32;\n\n@final export abstract class Function {\n private _index: u32;\n private _env: usize;\n\n // @ts-ignore: this on getter\n get index(this: T): u32 {\n return load(changetype(this), offsetof>(\"_index\"));\n }\n\n // @ts-ignore: this on getter\n get name(this: T): string {\n return \"\";\n }\n\n // @ts-ignore: this on getter\n get length(this: T): i32 {\n // @ts-ignore: T is function\n return lengthof();\n }\n\n // @ts-ignore: T is function\n @builtin call(thisArg: thisof | null, ...args: auto[]): returnof {\n return unreachable();\n }\n\n toString(this: T): string {\n return \"function() { [native code] }\";\n }\n\n // RT integration\n\n @unsafe private __visit(cookie: u32): void {\n // Env is either `null` (nop) or compiler-generated\n __visit(this._env, cookie);\n }\n}\n"]} \ No newline at end of file diff --git a/tests/cpp/lit/run.cjs b/tests/cpp/lit/run.cjs new file mode 100644 index 0000000..a14ef65 --- /dev/null +++ b/tests/cpp/lit/run.cjs @@ -0,0 +1,110 @@ +const fs = require('fs'); +const wasmBuffer = fs.readFileSync(process.argv[2]); +const mockInstruFunc = { + // isCall = true, return -1 if not mocked; + // isCall = false, return oldIndex if not mocked. + checkMock(index, isCall) { + if (mockInstruFunc["mockFunctionStatus.has"](index)) { + return mockInstruFunc["mockFunctionStatus.get"](index); + } + return isCall ? -1 : index; + }, + "mockFunctionStatus.last": 0, + "mockFunctionStatus.state": new Map(), + "mockFunctionStatus.clear": function () { + mockInstruFunc["mockFunctionStatus.state"].clear(); + }, + "mockFunctionStatus.set": function (k, v) { + const value = { + calls: 0, + ignore: false, + newIndex: v, + }; + mockInstruFunc["mockFunctionStatus.state"].set(k, value); + }, + "mockFunctionStatus.get": function (k) { + const fn = mockInstruFunc["mockFunctionStatus.state"].get(k); + assert(fn); + fn.calls++; + mockInstruFunc["mockFunctionStatus.last"] = k; + return fn.newIndex; + }, + "mockFunctionStatus.lastGet": function () { + return mockInstruFunc["mockFunctionStatus.last"]; + }, + "mockFunctionStatus.has": function (k) { + const fn = mockInstruFunc["mockFunctionStatus.state"].get(k); + if (fn === undefined) { + return false; + } + return !fn.ignore; + }, + "mockFunctionStatus.getCalls": function (oldIndex, newIndex) { + const fn = mockInstruFunc["mockFunctionStatus.state"].get(oldIndex); + if (fn === undefined || fn.newIndex !== newIndex) { + return 0; + } + return fn.calls; + }, + "mockFunctionStatus.setIgnore": function (k, v) { + const fn = mockInstruFunc["mockFunctionStatus.state"].get(k); + if (fn === undefined) { + return; + } + fn.ignore = v; + }, +}; +const imports = { + "mockInstrument": mockInstruFunc, + "covInstrument": { + traceExpression(functionIndex, index, type) { + // console.log(consumer); + switch (type) { + case 1: // call in + console.log(`make directly call to function index=${functionIndex}`); + break; + case 2: // call out + console.log(`exit from function call index=${functionIndex}`); + break; + default: + console.log(`basic block entry trace to: function=${functionIndex}, basic block=${index}`); + break; + } + } + }, + "env": { + memory: sharedMemory, + abort(_msg, _file, line, column) { + console.error("abort called at index.ts:" + line + ":" + column); + }, + seed: function () { + return 0xA5534817; // make tests deterministic + }, + log(ptr) { console.log(getString(ptr)); }, + logi(i) { console.log(i); }, + "Date.now": function () { + return new Date().getTime(); + }, + trace(msg, n, ...args) { + const memory = sharedMemory; + console.log(`trace: ${getString(msg)}${n ? " " : ""}${args.slice(0, n).join(", ")}`); + }, + } +}; +function getString(ptr) { + if (!ptr) return "null"; + var U32 = new Uint32Array(sharedMemory.buffer); + var U16 = new Uint16Array(sharedMemory.buffer); + var length = U32[(ptr - 4) >>> 2] >>> 1; + var offset = ptr >>> 1; + return String.fromCharCode.apply(String, U16.subarray(offset, offset + length)); +} + +var sharedMemory = new WebAssembly.Memory({ initial: 1 }); + +WebAssembly.instantiate(wasmBuffer, imports).then(wasmModule => { + wasmExample = wasmModule; + const { main, memory } = wasmModule.instance.exports; + sharedMemory = memory; + main(); +}); \ No newline at end of file diff --git a/tests/cpp/main.cpp b/tests/cpp/main.cpp new file mode 100644 index 0000000..4483c91 --- /dev/null +++ b/tests/cpp/main.cpp @@ -0,0 +1,6 @@ +#include "gtest/gtest.h" + +int main(int argc, char **argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/tests/cpp/test-asc/asconfig.json b/tests/cpp/test-asc/asconfig.json new file mode 100644 index 0000000..a813b17 --- /dev/null +++ b/tests/cpp/test-asc/asconfig.json @@ -0,0 +1,15 @@ +{ + "targets": { + "debug": { + "outFile": "build/debug.wasm", + "textFile": "build/debug.wat", + "sourceMap": true, + "debug": true, + "disable":["nontrapping-f2i", "bulk-memory"], + "target": 2 + } + }, + "options": { + "bindings": "esm" + } +} \ No newline at end of file diff --git a/tests/cpp/test-asc/assembly/index.ts b/tests/cpp/test-asc/assembly/index.ts new file mode 100644 index 0000000..8fed477 --- /dev/null +++ b/tests/cpp/test-asc/assembly/index.ts @@ -0,0 +1,8 @@ +class A{ + a:i32 +} +export function add(a:i32): i32 { + let aInstance = new A(); + aInstance.a = 42; + return aInstance.a; +} diff --git a/tests/cpp/test-asc/package.json b/tests/cpp/test-asc/package.json new file mode 100644 index 0000000..3ee27b9 --- /dev/null +++ b/tests/cpp/test-asc/package.json @@ -0,0 +1,15 @@ +{ + "name": "test-asc", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "ascbuild": "npx asc assembly/index.ts --config ./asconfig.json --target debug --debug" + }, + "author": "", + "license": "ISC", + "dependencies": { + "assemblyscript": "^0.27.22", + "source-map": "^0.7.4" + } +} diff --git a/tests/cpp/test-asc/run.cjs b/tests/cpp/test-asc/run.cjs new file mode 100644 index 0000000..07a0b8e --- /dev/null +++ b/tests/cpp/test-asc/run.cjs @@ -0,0 +1,110 @@ +const fs = require('fs'); +const sourceMap = require("source-map"); + +const wasmBuffer = fs.readFileSync('./build/debug.wasm.instrumented.wasm'); +const wasmMap = JSON.parse(fs.readFileSync('build/debug.wasm.map')); + +promise = new sourceMap.SourceMapConsumer(wasmMap); +promise.then((consumer) => { + const mock = { + checkMock(index) { + if (mock["mockFunctionStatus.has"](index)) { + return mock["mockFunctionStatus.get"](index); + } + return -1; + }, + "mockFunctionStatus.last": 0, + "mockFunctionStatus.state": new Map(), + "mockFunctionStatus.clear": function () { + mock["mockFunctionStatus.state"].clear(); + }, + "mockFunctionStatus.set": function (k, v) { + const value = { + calls: 0, + ignore: false, + newIndex: v + } + mock["mockFunctionStatus.state"].set(k, value); + }, + "mockFunctionStatus.get": function (k) { + const fn = mock["mockFunctionStatus.state"].get(k); + fn.calls++; + mock["mockFunctionStatus.last"] = k; + return fn.newIndex; + }, + "mockFunctionStatus.lastGet": function () { + return mock["mockFunctionStatus.last"]; + }, + "mockFunctionStatus.has": function (k) { + if (mock["mockFunctionStatus.state"].has(k)) { + const fn = mock["mockFunctionStatus.state"].get(k); + return !fn.ignore; + } + return false; + }, + "mockFunctionStatus.getCalls": function (k) { + const fn = mock["mockFunctionStatus.state"].get(k); + return fn.calls; + }, + "mockFunctionStatus.setIgnore": function (k, v) { + const fn = mock["mockFunctionStatus.state"].get(k); + fn.ignore = v; + } + }; + const imports = { + mock, + "env": { + memory: sharedMemory, + abort(_msg, _file, line, column) { + console.error("abort called at index.ts:" + line + ":" + column); + }, + seed: function () { + return 0xA5534817; // make tests deterministic + }, + log(ptr) { console.log(getString(ptr)); }, + logi(i) { console.log(i); }, + "Date.now": function () { + return new Date().getTime(); + }, + trace(msg, n, ...args) { + const memory = sharedMemory; + console.log(`trace: ${getString(msg)}${n ? " " : ""}${args.slice(0, n).join(", ")}`); + }, + traceExpression(functionIndex, index, type) { + // console.log(consumer); + switch (type) { + case 1: // call in + console.log(`make directly call to function index=${functionIndex}`); + break; + case 2: // call out + console.log(`exit from function call index=${functionIndex}`); + break; + default: + console.log(`basic block entry trace to: function=${functionIndex}, basic block=${index}`); + break; + } + } + } + }; + function getString(ptr) { + if (!ptr) return "null"; + var U32 = new Uint32Array(sharedMemory.buffer); + var U16 = new Uint16Array(sharedMemory.buffer); + var length = U32[(ptr - 4) >>> 2] >>> 1; + var offset = ptr >>> 1; + return String.fromCharCode.apply(String, U16.subarray(offset, offset + length)); + } + + var sharedMemory = new WebAssembly.Memory({ initial: 1 }); + + WebAssembly.instantiate(wasmBuffer, imports).then(wasmModule => { + wasmExample = wasmModule; + const { memory, add } = wasmModule.instance.exports; + sharedMemory = memory; + add(); + console.log("finished"); + }); + +}); + + diff --git a/tests/cpp/utils/utils.cpp b/tests/cpp/utils/utils.cpp new file mode 100644 index 0000000..cbe7114 --- /dev/null +++ b/tests/cpp/utils/utils.cpp @@ -0,0 +1,65 @@ +#include "utils.h" + +namespace testUtils { + +bool compareDebugInfoJson(Json::Value &debugInfoJson1, Json::Value &debugInfoJson2) noexcept { + + if ((!debugInfoJson1.isObject()) && (!debugInfoJson2.isObject())) { + std::cerr << "Not same with types\n"; + return false; + } + + // compare debug files + const auto &files1 = debugInfoJson1["debugFiles"]; + const auto &files2 = debugInfoJson2["debugFiles"]; + if (!(files1 == files2)) { + std::cerr << "Not same with files\n"; + return false; + } + + // compare function debug info + const Json::Value &debugInfos1 = debugInfoJson1["debugInfos"]; + const Json::Value &debugInfos2 = debugInfoJson2["debugInfos"]; + const Json::Value::Members &functionNames = debugInfos1.getMemberNames(); + const Json::Value::Members &compareFunctionNames = debugInfos2.getMemberNames(); + if (functionNames != compareFunctionNames) { + std::cerr << "Not same with function names\n"; + return false; + } + for (const std::string_view functionName : functionNames) { + const Json::Value &functionDebugInfo = debugInfos1[functionName.data()]; + const Json::Value &compareFunctionDebugInfo = debugInfos2[functionName.data()]; + if (functionDebugInfo["index"] != compareFunctionDebugInfo["index"]) { + std::cerr << "Not same with function index\n"; + return false; + } + + if (functionDebugInfo["lineInfo"] != compareFunctionDebugInfo["lineInfo"]) { + std::cerr << "Not same with function line info\n"; + return false; + } + + // for branch info, compare without order + std::unordered_map> branchInfos; + if (functionDebugInfo["branchInfo"].size() != compareFunctionDebugInfo["branchInfo"].size()) { + std::cerr << "Not same with function branch info size\n"; + return false; + } + for (const Json::Value &branchPair : functionDebugInfo["branchInfo"]) { + branchInfos[branchPair[0U].asUInt()].insert(branchPair[1U].asUInt()); + } + for (const Json::Value &branchPair : compareFunctionDebugInfo["branchInfo"]) { + const auto &findIterator = branchInfos.find(branchPair[0U].asUInt()); + if (findIterator == branchInfos.cend()) { + std::cerr << "Not same with function branch info\n"; + return false; + } + if (findIterator->second.find(branchPair[1U].asUInt()) == findIterator->second.cend()) { + std::cerr << "Not same with function branch info\n"; + return false; + } + } + } + return true; +} +} // namespace testUtils diff --git a/tests/cpp/utils/utils.h b/tests/cpp/utils/utils.h new file mode 100644 index 0000000..ad2d340 --- /dev/null +++ b/tests/cpp/utils/utils.h @@ -0,0 +1,36 @@ +#ifndef __TEST_UTILS_UTILS_H__ +#define __TEST_UTILS_UTILS_H__ +#include "json/value.h" +#include +#include +#include +#include +#include +#include +#include + +namespace testUtils { + +constexpr std::string_view PROJECT_NAME("wasm-instrumentation"); + +/// +/// @brief Get the project path +/// +/// @return path of project +inline const std::filesystem::path getProjectPath() noexcept { + const std::filesystem::path currentFile = std::filesystem::current_path(); + const std::string currentPath = currentFile.string(); + return currentPath.substr(0U, currentPath.rfind(PROJECT_NAME) + PROJECT_NAME.size()); +} + +/// +/// @brief Compare two debug info json object +/// +/// @param debugInfoJson1 +/// @param debugInfoJson2 +/// @return Return true if the are same debug info json object +bool compareDebugInfoJson(Json::Value &debugInfoJson1, Json::Value &debugInfoJson2) noexcept; + +} // namespace testUtils + +#endif // __TEST_UTILS_UTILS_H__ From 6aa39e058b954b3c678fd29a8c9b477756bed4ab Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 18:13:29 +0800 Subject: [PATCH 07/14] finish --- instrumentation/CMakeLists.txt | 11 +-- tests/cpp/CMakeLists.txt | 5 +- tests/cpp/e2e.cpp | 60 --------------- tests/cpp/fuzz.cpp | 8 +- tests/cpp/lit.cpp | 18 +++-- tests/cpp/test-asc/asconfig.json | 15 ---- tests/cpp/test-asc/assembly/index.ts | 8 -- tests/cpp/test-asc/package.json | 15 ---- tests/cpp/test-asc/run.cjs | 110 --------------------------- tests/cpp/utils/utils.h | 2 +- 10 files changed, 23 insertions(+), 229 deletions(-) delete mode 100644 tests/cpp/e2e.cpp delete mode 100644 tests/cpp/test-asc/asconfig.json delete mode 100644 tests/cpp/test-asc/assembly/index.ts delete mode 100644 tests/cpp/test-asc/package.json delete mode 100644 tests/cpp/test-asc/run.cjs diff --git a/instrumentation/CMakeLists.txt b/instrumentation/CMakeLists.txt index 94c669b..310f133 100644 --- a/instrumentation/CMakeLists.txt +++ b/instrumentation/CMakeLists.txt @@ -1,11 +1,8 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} sources) -add_executable(wasm-instrumentation ${sources}) - -target_link_libraries(wasm-instrumentation binaryen jsoncpp_static) -target_include_directories(wasm-instrumentation SYSTEM PRIVATE ${PROJECT_SOURCE_DIR}/third_party/binaryen/src ${PROJECT_SOURCE_DIR}/third_party/jsoncpp/include) - if(EMSCRIPTEN) + add_executable(wasm-instrumentation ${sources}) + target_link_libraries(wasm-instrumentation "-sSINGLE_FILE") target_link_libraries(wasm-instrumentation "-sFORCE_FILESYSTEM") target_link_libraries(wasm-instrumentation "-sALLOW_MEMORY_GROWTH") @@ -20,4 +17,8 @@ if(EMSCRIPTEN) target_link_libraries(wasm-instrumentation "-sEXPORTED_RUNTIME_METHODS=allocateUTF8") target_link_libraries(wasm-instrumentation "-sEXPORTED_FUNCTIONS=_malloc,_free") else() + add_library(wasm-instrumentation ${sources}) endif() + +target_link_libraries(wasm-instrumentation PUBLIC binaryen jsoncpp_static) +target_include_directories(wasm-instrumentation SYSTEM PUBLIC ${PROJECT_SOURCE_DIR}/third_party/binaryen/src ${PROJECT_SOURCE_DIR}/third_party/jsoncpp/include) diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index 73679bf..8072c76 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -9,13 +9,12 @@ add_executable( ) target_link_libraries( wasm-instrumentation-test + PUBLIC + wasm-instrumentation GTest::gtest_main binaryen jsoncpp_static ) -file(GLOB sources CONFIGURE_DEPENDS ${PROJECT_SOURCE_DIR}/instrumentation/*.cpp ${PROJECT_SOURCE_DIR}/instrumentation/*.hpp) -target_sources(wasm-instrumentation-test PUBLIC ${sources}) -target_include_directories(wasm-instrumentation-test PUBLIC ${PROJECT_SOURCE_DIR}/third_party/binaryen/src ${PROJECT_SOURCE_DIR}/third_party/jsoncpp/include) include(GoogleTest) gtest_discover_tests(wasm-instrumentation-test) diff --git a/tests/cpp/e2e.cpp b/tests/cpp/e2e.cpp deleted file mode 100644 index 3e0f53f..0000000 --- a/tests/cpp/e2e.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include -#include -#include -#include "../../instrumentation/CoverageInstru.hpp" -#include "../../instrumentation/InstrumentResponse.hpp" -#include "utils/utils.h" - -TEST(e2e, asc) { - const std::filesystem::path project_path = testUtils::getProjectPath(); - const std::filesystem::path build_path = project_path / "build"; - const std::filesystem::path wasmPath = - project_path / "test" / "test-asc" / "build" / "debug.wasm"; - const std::filesystem::path mapPath = - project_path / "test" / "test-asc" / "build" / "debug.wasm.map"; - const std::filesystem::path targetPath = wasmPath.parent_path() / "debug.wasm.instrumented.wasm"; - const std::filesystem::path targetDebugInfoPath = - wasmPath.parent_path() / "debug.wasm.debuginfo.json"; - const std::filesystem::path targetExpectInfoPath = - wasmPath.parent_path() / "debug.wasm.expectInfo.json"; - const char *reportName = "assembly/env/traceExpression"; - wasmInstrumentation::InstrumentationConfig config; - config.fileName = wasmPath.c_str(); - config.debugInfoOutputFilePath = targetDebugInfoPath.c_str(); - config.sourceMap = mapPath.c_str(); - config.targetName = targetPath.c_str(); - config.reportFunction = reportName; - config.expectInfoOutputFilePath = targetExpectInfoPath.c_str(); - wasmInstrumentation::CoverageInstru instrumentor(&config); - ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::NORMAL); -} -TEST(e2e, empty_config) { - wasmInstrumentation::InstrumentationConfig config; - wasmInstrumentation::CoverageInstru instrumentor(&config); - ASSERT_EQ(instrumentor.instrument(), wasmInstrumentation::InstrumentationResponse::CONFIG_ERROR); -} - -TEST(e2e, illegal_path_config) { - const std::filesystem::path project_path = testUtils::getProjectPath(); - const std::filesystem::path build_path = project_path / "build"; - const std::filesystem::path wasmPath = - project_path / "test" / "test-asc" / "build" / "debug.wasm"; - const std::filesystem::path mapPath = - project_path / "test" / "test-asc" / "build" / "debug.wasm.map"; - const std::filesystem::path targetPath = wasmPath.parent_path() / "debug.wasm.instrumented.wasm"; - const std::filesystem::path targetExpectInfoPath = - wasmPath.parent_path() / "debug.wasm.expectInfo.json"; - const char *reportName = "assembly/env/traceExpression"; - wasmInstrumentation::InstrumentationConfig config; - config.fileName = wasmPath.c_str(); - config.debugInfoOutputFilePath = "this path will not be existed"; - config.sourceMap = mapPath.c_str(); - config.targetName = targetPath.c_str(); - config.reportFunction = reportName; - config.expectInfoOutputFilePath = targetExpectInfoPath.c_str(); - wasmInstrumentation::CoverageInstru instrumentor(&config); - ASSERT_EQ(instrumentor.instrument(), - wasmInstrumentation::InstrumentationResponse::CONFIG_FILEPATH_ERROR); -} diff --git a/tests/cpp/fuzz.cpp b/tests/cpp/fuzz.cpp index c59ff7f..c3077a6 100644 --- a/tests/cpp/fuzz.cpp +++ b/tests/cpp/fuzz.cpp @@ -9,12 +9,12 @@ #include "utils/utils.h" TEST(fuzz, asc) { - const std::filesystem::path project_path = testUtils::getProjectPath(); - const std::filesystem::path build_path = project_path / "build"; + const std::filesystem::path projectPath = testUtils::getProjectPath(); + const std::filesystem::path build_path = projectPath / "build"; const std::filesystem::path wasmPath = - project_path / "test" / "fuzz" / "assemblyscript.debug.wasm"; + projectPath / "tests" / "cpp" / "fuzz" / "assemblyscript.debug.wasm"; const std::filesystem::path mapPath = - project_path / "test" / "fuzz" / "assemblyscript.debug.wasm.map"; + projectPath / "tests" / "cpp" / "fuzz" / "assemblyscript.debug.wasm.map"; const std::filesystem::path targetPath = build_path / "assemblyscript.debug.wasm.instrumented.wasm"; const std::filesystem::path targetDebugInfoPath = diff --git a/tests/cpp/lit.cpp b/tests/cpp/lit.cpp index 27aff00..c897670 100644 --- a/tests/cpp/lit.cpp +++ b/tests/cpp/lit.cpp @@ -16,11 +16,12 @@ TEST(lit, coverageInstrumentation) { // step 1, prepare const std::filesystem::path projectPath = testUtils::getProjectPath(); const std::filesystem::path wasmOptPath = - projectPath / "build" / "thirdparty" / "binaryen" / "bin" / "wasm-opt"; - const std::filesystem::path fixtureFolder = projectPath / "test" / "lit" / "covInstrument"; - const std::filesystem::path tmpDir = projectPath / "test" / "lit" / "build"; - const std::filesystem::path executor = projectPath / "test" / "lit" / "run.cjs"; - const std::filesystem::path checkPy = projectPath / "test" / "check.py"; + projectPath / "build" / "third_party" / "binaryen" / "bin" / "wasm-opt"; + const std::filesystem::path fixtureFolder = + projectPath / "tests" / "cpp" / "lit" / "covInstrument"; + const std::filesystem::path tmpDir = projectPath / "tests" / "cpp" / "lit" / "build"; + const std::filesystem::path executor = projectPath / "tests" / "cpp" / "lit" / "run.cjs"; + const std::filesystem::path checkPy = projectPath / "tests" / "cpp" / "check.py"; if (!exists(tmpDir)) { create_directory(tmpDir); @@ -85,9 +86,10 @@ TEST(lit, coverageInstrumentation) { TEST(lit, expectInstrumentation) { const std::filesystem::path projectPath = testUtils::getProjectPath(); - const std::filesystem::path fixtureFolder = projectPath / "test" / "lit" / "expectInstrument"; - const std::filesystem::path tmpDir = projectPath / "test" / "lit" / "build"; - const std::filesystem::path checkPy = projectPath / "test" / "check.py"; + const std::filesystem::path fixtureFolder = + projectPath / "tests" / "cpp" / "lit" / "expectInstrument"; + const std::filesystem::path tmpDir = projectPath / "tests" / "cpp" / "lit" / "build"; + const std::filesystem::path checkPy = projectPath / "tests" / "cpp" / "check.py"; if (!exists(tmpDir)) { create_directory(tmpDir); diff --git a/tests/cpp/test-asc/asconfig.json b/tests/cpp/test-asc/asconfig.json deleted file mode 100644 index a813b17..0000000 --- a/tests/cpp/test-asc/asconfig.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "targets": { - "debug": { - "outFile": "build/debug.wasm", - "textFile": "build/debug.wat", - "sourceMap": true, - "debug": true, - "disable":["nontrapping-f2i", "bulk-memory"], - "target": 2 - } - }, - "options": { - "bindings": "esm" - } -} \ No newline at end of file diff --git a/tests/cpp/test-asc/assembly/index.ts b/tests/cpp/test-asc/assembly/index.ts deleted file mode 100644 index 8fed477..0000000 --- a/tests/cpp/test-asc/assembly/index.ts +++ /dev/null @@ -1,8 +0,0 @@ -class A{ - a:i32 -} -export function add(a:i32): i32 { - let aInstance = new A(); - aInstance.a = 42; - return aInstance.a; -} diff --git a/tests/cpp/test-asc/package.json b/tests/cpp/test-asc/package.json deleted file mode 100644 index 3ee27b9..0000000 --- a/tests/cpp/test-asc/package.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "test-asc", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "ascbuild": "npx asc assembly/index.ts --config ./asconfig.json --target debug --debug" - }, - "author": "", - "license": "ISC", - "dependencies": { - "assemblyscript": "^0.27.22", - "source-map": "^0.7.4" - } -} diff --git a/tests/cpp/test-asc/run.cjs b/tests/cpp/test-asc/run.cjs deleted file mode 100644 index 07a0b8e..0000000 --- a/tests/cpp/test-asc/run.cjs +++ /dev/null @@ -1,110 +0,0 @@ -const fs = require('fs'); -const sourceMap = require("source-map"); - -const wasmBuffer = fs.readFileSync('./build/debug.wasm.instrumented.wasm'); -const wasmMap = JSON.parse(fs.readFileSync('build/debug.wasm.map')); - -promise = new sourceMap.SourceMapConsumer(wasmMap); -promise.then((consumer) => { - const mock = { - checkMock(index) { - if (mock["mockFunctionStatus.has"](index)) { - return mock["mockFunctionStatus.get"](index); - } - return -1; - }, - "mockFunctionStatus.last": 0, - "mockFunctionStatus.state": new Map(), - "mockFunctionStatus.clear": function () { - mock["mockFunctionStatus.state"].clear(); - }, - "mockFunctionStatus.set": function (k, v) { - const value = { - calls: 0, - ignore: false, - newIndex: v - } - mock["mockFunctionStatus.state"].set(k, value); - }, - "mockFunctionStatus.get": function (k) { - const fn = mock["mockFunctionStatus.state"].get(k); - fn.calls++; - mock["mockFunctionStatus.last"] = k; - return fn.newIndex; - }, - "mockFunctionStatus.lastGet": function () { - return mock["mockFunctionStatus.last"]; - }, - "mockFunctionStatus.has": function (k) { - if (mock["mockFunctionStatus.state"].has(k)) { - const fn = mock["mockFunctionStatus.state"].get(k); - return !fn.ignore; - } - return false; - }, - "mockFunctionStatus.getCalls": function (k) { - const fn = mock["mockFunctionStatus.state"].get(k); - return fn.calls; - }, - "mockFunctionStatus.setIgnore": function (k, v) { - const fn = mock["mockFunctionStatus.state"].get(k); - fn.ignore = v; - } - }; - const imports = { - mock, - "env": { - memory: sharedMemory, - abort(_msg, _file, line, column) { - console.error("abort called at index.ts:" + line + ":" + column); - }, - seed: function () { - return 0xA5534817; // make tests deterministic - }, - log(ptr) { console.log(getString(ptr)); }, - logi(i) { console.log(i); }, - "Date.now": function () { - return new Date().getTime(); - }, - trace(msg, n, ...args) { - const memory = sharedMemory; - console.log(`trace: ${getString(msg)}${n ? " " : ""}${args.slice(0, n).join(", ")}`); - }, - traceExpression(functionIndex, index, type) { - // console.log(consumer); - switch (type) { - case 1: // call in - console.log(`make directly call to function index=${functionIndex}`); - break; - case 2: // call out - console.log(`exit from function call index=${functionIndex}`); - break; - default: - console.log(`basic block entry trace to: function=${functionIndex}, basic block=${index}`); - break; - } - } - } - }; - function getString(ptr) { - if (!ptr) return "null"; - var U32 = new Uint32Array(sharedMemory.buffer); - var U16 = new Uint16Array(sharedMemory.buffer); - var length = U32[(ptr - 4) >>> 2] >>> 1; - var offset = ptr >>> 1; - return String.fromCharCode.apply(String, U16.subarray(offset, offset + length)); - } - - var sharedMemory = new WebAssembly.Memory({ initial: 1 }); - - WebAssembly.instantiate(wasmBuffer, imports).then(wasmModule => { - wasmExample = wasmModule; - const { memory, add } = wasmModule.instance.exports; - sharedMemory = memory; - add(); - console.log("finished"); - }); - -}); - - diff --git a/tests/cpp/utils/utils.h b/tests/cpp/utils/utils.h index ad2d340..ddf13d4 100644 --- a/tests/cpp/utils/utils.h +++ b/tests/cpp/utils/utils.h @@ -11,7 +11,7 @@ namespace testUtils { -constexpr std::string_view PROJECT_NAME("wasm-instrumentation"); +constexpr std::string_view PROJECT_NAME("assemblyscript-unittest-framework"); /// /// @brief Get the project path From 4c7f5088d83249045e1014342ea64f4790305b9e Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 18:54:42 +0800 Subject: [PATCH 08/14] fix --- .clang-format | 82 ++-- .clang-tidy | 357 +++++++++--------- .eslintrc.cjs | 7 +- .github/workflows/ci-test.yml | 14 +- .github/workflows/publish.yml | 8 +- .gitmodules | 3 + .prettierignore | 2 + instrumentation/CMakeLists.txt | 24 +- package.json | 5 +- scripts/esbuild.js | 23 +- .../covInstrument/do_while.wast.debug.json | 68 +--- .../do_while_break.wast.debug.json | 106 +----- .../do_while_continue.wast.debug.json | 106 +----- .../do_while_once.wast.debug.json | 154 ++------ .../exit_basicBlock.wast.debug.json | 66 +--- .../covInstrument/for_loop.wast.debug.json | 90 +---- .../for_loop_break.wast.debug.json | 118 +----- .../for_loop_continue.wast.debug.json | 124 ++---- .../for_loop_return.wast.debug.json | 110 +----- .../lit/covInstrument/if_else.wast.debug.json | 23 +- .../if_elseif_else.wast.debug.json | 40 +- .../if_elseif_empty_else.wast.debug.json | 36 +- .../if_empty_else.wast.debug.json | 22 +- .../if_multi_condition.wast.debug.json | 124 ++---- .../include_exclude.wast.debug.json | 29 +- .../covInstrument/multi_func.wast.debug.json | 26 +- .../multi_if_else.wast.debug.json | 46 ++- .../covInstrument/switch_case.wast.debug.json | 156 ++------ .../switch_case_fallthrough.wast.debug.json | 144 ++----- .../switch_case_rdefault.wast.debug.json | 54 ++- .../lit/covInstrument/while.wast.debug.json | 84 +---- .../covInstrument/while_break.wast.debug.json | 118 +----- .../while_continue.wast.debug.json | 114 +----- tests/cpp/lit/run.cjs | 30 +- third_party/emsdk | 1 + 35 files changed, 846 insertions(+), 1668 deletions(-) create mode 160000 third_party/emsdk diff --git a/.clang-format b/.clang-format index c2e5bf7..5af0327 100644 --- a/.clang-format +++ b/.clang-format @@ -1,5 +1,5 @@ --- -Language: Cpp +Language: Cpp # BasedOnStyle: LLVM AccessModifierOffset: -2 AlignAfterOpenBracket: Align @@ -7,7 +7,7 @@ AlignConsecutiveMacros: false AlignConsecutiveAssignments: false AlignConsecutiveDeclarations: false AlignEscapedNewlines: Right -AlignOperands: true +AlignOperands: true AlignTrailingComments: true AllowAllArgumentsOnNextLine: true AllowAllConstructorInitializersOnNextLine: true @@ -25,19 +25,19 @@ AlwaysBreakTemplateDeclarations: Yes BinPackArguments: true BinPackParameters: true BraceWrapping: - AfterCaseLabel: false - AfterClass: false + AfterCaseLabel: false + AfterClass: false AfterControlStatement: false - AfterEnum: false - AfterFunction: false - AfterNamespace: false + AfterEnum: false + AfterFunction: false + AfterNamespace: false AfterObjCDeclaration: false - AfterStruct: false - AfterUnion: false + AfterStruct: false + AfterUnion: false AfterExternBlock: false - BeforeCatch: false - BeforeElse: false - IndentBraces: false + BeforeCatch: false + BeforeElse: false + IndentBraces: false SplitEmptyFunction: true SplitEmptyRecord: true SplitEmptyNamespace: true @@ -50,8 +50,8 @@ BreakConstructorInitializersBeforeComma: false BreakConstructorInitializers: BeforeColon BreakAfterJavaFieldAnnotations: false BreakStringLiterals: true -ColumnLimit: 100 -CommentPragmas: '^ IWYU pragma:' +ColumnLimit: 100 +CommentPragmas: "^ IWYU pragma:" CompactNamespaces: false ConstructorInitializerAllOnOneLineOrOnePerLine: false ConstructorInitializerIndentWidth: 4 @@ -59,39 +59,39 @@ ContinuationIndentWidth: 4 Cpp11BracedListStyle: true DeriveLineEnding: true DerivePointerAlignment: false -DisableFormat: false +DisableFormat: false ExperimentalAutoDetectBinPacking: false FixNamespaceComments: true ForEachMacros: - foreach - Q_FOREACH - BOOST_FOREACH -IncludeBlocks: Preserve +IncludeBlocks: Preserve IncludeCategories: - - Regex: '^"(llvm|llvm-c|clang|clang-c)/' - Priority: 2 - SortPriority: 0 - - Regex: '^(<|"(gtest|gmock|isl|json)/)' - Priority: 1 - SortPriority: 0 - - Regex: '.*' - Priority: 3 - SortPriority: 0 - - Regex: '^(src|wasm-compiler)/' - Priority: 4 - SortPriority: 0 -IncludeIsMainRegex: '(Test)?$' -IncludeIsMainSourceRegex: '' + - Regex: '^"(llvm|llvm-c|clang|clang-c)/' + Priority: 2 + SortPriority: 0 + - Regex: '^(<|"(gtest|gmock|isl|json)/)' + Priority: 1 + SortPriority: 0 + - Regex: ".*" + Priority: 3 + SortPriority: 0 + - Regex: "^(src|wasm-compiler)/" + Priority: 4 + SortPriority: 0 +IncludeIsMainRegex: "(Test)?$" +IncludeIsMainSourceRegex: "" IndentCaseLabels: false IndentGotoLabels: true IndentPPDirectives: None -IndentWidth: 2 +IndentWidth: 2 IndentWrappedFunctionNames: false JavaScriptQuotes: Leave JavaScriptWrapImports: true KeepEmptyLinesAtTheStartOfBlocks: true -MacroBlockBegin: '' -MacroBlockEnd: '' +MacroBlockBegin: "" +MacroBlockEnd: "" MaxEmptyLinesToKeep: 1 NamespaceIndentation: None ObjCBinPackProtocolList: Auto @@ -107,8 +107,8 @@ PenaltyBreakTemplateDeclaration: 10 PenaltyExcessCharacter: 1000000 PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Right -ReflowComments: true -SortIncludes: true +ReflowComments: true +SortIncludes: true SortUsingDeclarations: true SpaceAfterCStyleCast: false SpaceAfterLogicalNot: false @@ -122,19 +122,19 @@ SpaceBeforeRangeBasedForLoopColon: true SpaceInEmptyBlock: false SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 1 -SpacesInAngles: false +SpacesInAngles: false SpacesInConditionalStatement: false SpacesInContainerLiterals: true SpacesInCStyleCastParentheses: false SpacesInParentheses: false SpacesInSquareBrackets: false SpaceBeforeSquareBrackets: false -Standard: Latest +Standard: Latest StatementMacros: - Q_UNUSED - QT_REQUIRE_VERSION -TabWidth: 8 -UseCRLF: false -UseTab: Never -... +TabWidth: 8 +UseCRLF: false +UseTab: Never +--- diff --git a/.clang-tidy b/.clang-tidy index a99d78a..f83eeb9 100644 --- a/.clang-tidy +++ b/.clang-tidy @@ -1,180 +1,179 @@ -Checks: -'-*, - -bugprone-lambda-function-name, -bugprone-macro-parentheses, -bugprone-macro-repeated-side-effects, -bugprone-misplaced-widening-cast, -bugprone-move-forwarding-reference, -bugprone-multiple-statement-macro, -bugprone-parent-virtual-call, -bugprone-sizeof-container, -bugprone-sizeof-expression, -bugprone-string-integer-assignment, -bugprone-string-literal-with-embedded-nul, -bugprone-suspicious-memset-usage, -bugprone-suspicious-missing-comma, -bugprone-suspicious-semicolon, -bugprone-suspicious-string-compare, -bugprone-undelegated-constructor, -bugprone-unused-raii, -bugprone-unused-return-value, -bugprone-assert-side-effect, -bugprone-bool-pointer-implicit-conversion, -bugprone-copy-constructor-init, -bugprone-dangling-handle, -bugprone-fold-init-type, -bugprone-forward-declaration-namespace, -bugprone-forward-reference-overload, -bugprone-inaccurate-erase, -bugprone-incorrect-roundings, -bugprone-integer-division, -bugprone-misplaced-operator-in-strlen-in-alloc, -bugprone-string-constructor, -bugprone-suspicious-enum-usage, -bugprone-swapped-arguments, -bugprone-terminating-continue, -bugprone-throw-keyword-missing, -bugprone-too-small-loop-variable, -bugprone-undefined-memory-manipulation, -bugprone-use-after-move, -bugprone-unhandled-self-assignment, - -hicpp-multiway-paths-covered, - -clang-analyzer-core.builtin.NoRetmodernize-deprecated-headersurnFunctions, -clang-analyzer-core.CallAndMessage, -clang-analyzer-core.DivideZero, -clang-analyzer-core.DynamicTypePropagation, -clang-analyzer-core.NonnilStringConstants, -clang-analyzer-core.NonNullParamChecker, -clang-analyzer-core.NullDereference, -clang-analyzer-core.StackAddressEscape, -clang-analyzer-core.UndefinedBinaryOperatorResult, -clang-analyzer-core.uninitialized.ArraySubscript, -clang-analyzer-core.uninitializedmodernize-deprecated-headers.Assign, -clang-analyzer-core.uninitialized.Branch, -clang-analyzer-core.uninitialized.CapturedBlockVariable, -clang-analyzer-core.uninitialized.UndefReturn, -clang-analyzer-core.VLASize, - -clang-analyzer-cplusplus.NewDelete, -clang-analyzer-cplusplus.NewDeleteLeaks, -clang-analyzer-cplusplus.SelfAssignment, - -clang-analyzer-deadcode.DeadStores, - -clang-analyzer-optin.cplusplus.VirtualCall, -clang-analyzer-optin.performance.Padding, - -clang-analyzer-security.FloatLoopCounter, -clang-analyzer-security.insecureAmodernize-deprecated-headersPI.getpw, -clang-analyzer-security.insecureAPI.gets, -clang-analyzer-security.insecureAPI.mkstemp, -clang-analyzer-security.insecureAPI.mktemp, -clang-analyzer-security.insecureAPI.rand, -clang-analyzer-security.insecureAPI.strcpy, -clang-analyzer-security.insecuremodernize-deprecated-headersAPI.UncheckedReturn, -clang-analyzer-security.insecureAPI.vfork, - -clang-analyzer-unix.API, -clang-analyzer-unix.cstring.BadSizeArg, -clang-analyzer-unix.cstring.NullArg, -clang-analyzer-unix.Malloc, -clang-analyzer-unix.MallocSizeof, -clang-analyzer-unix.MismatchedDeallocator, -clang-analyzer-unix.StdCLibraryFunctions, -clang-analyzer-unix.Vfork, -clang-analyzer-valist.CopyToSelf, -clang-analyzer-valist.Uninitialized, -clang-analyzer-valist.Unterminated, -clang-analyzer-nullability.NullablePassedToNonnull, - -cert-dcl03-c, -cert-dcl21-cpp, -cert-dcl54-cpp, -cert-dcl58-cpp, -cert-err09-cpp, -cert-err34-c, -cert-err52-cpp, -cert-err58-cpp, -cert-err60-cpp, -cert-fio38-c, -cert-flp30-c, -cert-oop11-cpp, - -cppcoreguidelines-c-copy-assignment-signature, -cppcoreguidelines-explicit-virtual-functions, -cppcoreguidelines-interfaces-global-init, -cppcoreguidelines-narrowing-conversions, -cppcoreguidelines-pro-type-const-cast, -cppcoreguidelines-pro-type-cstyle-cast, -cppcoreguidelines-pro-type-member-init, -cppcoreguidelines-pro-type-static-cast-downcast, -cppcoreguidelines-slicing, -cppcoreguidelines-pro-type-vararg, -cppcoreguidelines-special-member-functions, -cppcoreguidelines-avoid-goto, -cppcoreguidelines-pro-type-reinterpret-cast, - -google-default-arguments, -google-explicit-constructor, -google-global-names-in-headers, -google-readability-casting, -google-readability-todo, -google-runtime-operator, -google-runtime-int, - -hicpp-exception-baseclass, -hicpp-move-const-arg, -hicpp-named-parameter, -hicpp-no-assembler, -hicpp-noexcept-move, -hicpp-signed-bitwise, -hicpp-use-nullptr, - - -misc-definitions-in-headers, -misc-misplaced-const, -misc-redundant-expression, -misc-unused-alias-decls, -misc-unused-parameters, -misc-unused-using-decls, -misc-unconventional-assign-operator, - - -readability-delete-null-pointer, -readability-implicit-bool-conversion, -readability-inconsistent-declaration-parameter-name, -readability-redundant-non-const-parameter, -readability-redundant-control-flow, -readability-redundant-declaration, -readability-redundant-function-ptr-dereference, -readability-redundant-member-init, -readability-redundant-smartptr-get, -readability-redundant-string-cstr, -readability-redundant-string-init, -readability-simplify-subscript-expr, -readability-static-accessed-through-instance, -readability-static-definition-in-anonymous-namespace, -readability-string-compare, -readability-uniqueptr-delete-release, -readability-uppercase-literal-suffix, -readability-braces-around-statements, -readability-non-const-parameter, -readability-isolate-declaration, - -modernize-loop-convert, -modernize-use-using, -modernize-use-nullptr, -modernize-use-noexcept, -modernize-deprecated-headers, -modernize-avoid-c-arrays, - -performance-move-const-arg -' - -WarningsAsErrors: '' -HeaderFilterRegex: '' +Checks: > + -*, + + bugprone-lambda-function-name, + bugprone-macro-parentheses, + bugprone-macro-repeated-side-effects, + bugprone-misplaced-widening-cast, + bugprone-move-forwarding-reference, + bugprone-multiple-statement-macro, + bugprone-parent-virtual-call, + bugprone-sizeof-container, + bugprone-sizeof-expression, + bugprone-string-integer-assignment, + bugprone-string-literal-with-embedded-nul, + bugprone-suspicious-memset-usage, + bugprone-suspicious-missing-comma, + bugprone-suspicious-semicolon, + bugprone-suspicious-string-compare, + bugprone-undelegated-constructor, + bugprone-unused-raii, + bugprone-unused-return-value, + bugprone-assert-side-effect, + bugprone-bool-pointer-implicit-conversion, + bugprone-copy-constructor-init, + bugprone-dangling-handle, + bugprone-fold-init-type, + bugprone-forward-declaration-namespace, + bugprone-forward-reference-overload, + bugprone-inaccurate-erase, + bugprone-incorrect-roundings, + bugprone-integer-division, + bugprone-misplaced-operator-in-strlen-in-alloc, + bugprone-string-constructor, + bugprone-suspicious-enum-usage, + bugprone-swapped-arguments, + bugprone-terminating-continue, + bugprone-throw-keyword-missing, + bugprone-too-small-loop-variable, + bugprone-undefined-memory-manipulation, + bugprone-use-after-move, + bugprone-unhandled-self-assignment, + + hicpp-multiway-paths-covered, + + clang-analyzer-core.builtin.NoRetmodernize-deprecated-headersurnFunctions, + clang-analyzer-core.CallAndMessage, + clang-analyzer-core.DivideZero, + clang-analyzer-core.DynamicTypePropagation, + clang-analyzer-core.NonnilStringConstants, + clang-analyzer-core.NonNullParamChecker, + clang-analyzer-core.NullDereference, + clang-analyzer-core.StackAddressEscape, + clang-analyzer-core.UndefinedBinaryOperatorResult, + clang-analyzer-core.uninitialized.ArraySubscript, + clang-analyzer-core.uninitializedmodernize-deprecated-headers.Assign, + clang-analyzer-core.uninitialized.Branch, + clang-analyzer-core.uninitialized.CapturedBlockVariable, + clang-analyzer-core.uninitialized.UndefReturn, + clang-analyzer-core.VLASize, + + clang-analyzer-cplusplus.NewDelete, + clang-analyzer-cplusplus.NewDeleteLeaks, + clang-analyzer-cplusplus.SelfAssignment, + + clang-analyzer-deadcode.DeadStores, + + clang-analyzer-optin.cplusplus.VirtualCall, + clang-analyzer-optin.performance.Padding, + + clang-analyzer-security.FloatLoopCounter, + clang-analyzer-security.insecureAmodernize-deprecated-headersPI.getpw, + clang-analyzer-security.insecureAPI.gets, + clang-analyzer-security.insecureAPI.mkstemp, + clang-analyzer-security.insecureAPI.mktemp, + clang-analyzer-security.insecureAPI.rand, + clang-analyzer-security.insecureAPI.strcpy, + clang-analyzer-security.insecuremodernize-deprecated-headersAPI.UncheckedReturn, + clang-analyzer-security.insecureAPI.vfork, + + clang-analyzer-unix.API, + clang-analyzer-unix.cstring.BadSizeArg, + clang-analyzer-unix.cstring.NullArg, + clang-analyzer-unix.Malloc, + clang-analyzer-unix.MallocSizeof, + clang-analyzer-unix.MismatchedDeallocator, + clang-analyzer-unix.StdCLibraryFunctions, + clang-analyzer-unix.Vfork, + clang-analyzer-valist.CopyToSelf, + clang-analyzer-valist.Uninitialized, + clang-analyzer-valist.Unterminated, + clang-analyzer-nullability.NullablePassedToNonnull, + + cert-dcl03-c, + cert-dcl21-cpp, + cert-dcl54-cpp, + cert-dcl58-cpp, + cert-err09-cpp, + cert-err34-c, + cert-err52-cpp, + cert-err58-cpp, + cert-err60-cpp, + cert-fio38-c, + cert-flp30-c, + cert-oop11-cpp, + + cppcoreguidelines-c-copy-assignment-signature, + cppcoreguidelines-explicit-virtual-functions, + cppcoreguidelines-interfaces-global-init, + cppcoreguidelines-narrowing-conversions, + cppcoreguidelines-pro-type-const-cast, + cppcoreguidelines-pro-type-cstyle-cast, + cppcoreguidelines-pro-type-member-init, + cppcoreguidelines-pro-type-static-cast-downcast, + cppcoreguidelines-slicing, + cppcoreguidelines-pro-type-vararg, + cppcoreguidelines-special-member-functions, + cppcoreguidelines-avoid-goto, + cppcoreguidelines-pro-type-reinterpret-cast, + + google-default-arguments, + google-explicit-constructor, + google-global-names-in-headers, + google-readability-casting, + google-readability-todo, + google-runtime-operator, + google-runtime-int, + + hicpp-exception-baseclass, + hicpp-move-const-arg, + hicpp-named-parameter, + hicpp-no-assembler, + hicpp-noexcept-move, + hicpp-signed-bitwise, + hicpp-use-nullptr, + + + misc-definitions-in-headers, + misc-misplaced-const, + misc-redundant-expression, + misc-unused-alias-decls, + misc-unused-parameters, + misc-unused-using-decls, + misc-unconventional-assign-operator, + + + readability-delete-null-pointer, + readability-implicit-bool-conversion, + readability-inconsistent-declaration-parameter-name, + readability-redundant-non-const-parameter, + readability-redundant-control-flow, + readability-redundant-declaration, + readability-redundant-function-ptr-dereference, + readability-redundant-member-init, + readability-redundant-smartptr-get, + readability-redundant-string-cstr, + readability-redundant-string-init, + readability-simplify-subscript-expr, + readability-static-accessed-through-instance, + readability-static-definition-in-anonymous-namespace, + readability-string-compare, + readability-uniqueptr-delete-release, + readability-uppercase-literal-suffix, + readability-braces-around-statements, + readability-non-const-parameter, + readability-isolate-declaration, + + modernize-loop-convert, + modernize-use-using, + modernize-use-nullptr, + modernize-use-noexcept, + modernize-deprecated-headers, + modernize-avoid-c-arrays, + + performance-move-const-arg + +WarningsAsErrors: "" +HeaderFilterRegex: "" AnalyzeTemporaryDtors: false -FormatStyle: none \ No newline at end of file +FormatStyle: none diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 385ea3c..bf3ffaf 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -10,5 +10,10 @@ module.exports = { }, ], }, - ignorePatterns: ["src/core/instrument.ts", "src/utils/import.js", "src/generator/html-generator/resource/*"], + ignorePatterns: [ + "src/core/instrument.ts", + "src/utils/import.js", + "src/generator/html-generator/resource/*", + "third_party/*", + ], }; diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 4774c71..9da6079 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -6,22 +6,18 @@ on: - "main" jobs: - build: + test: runs-on: ubuntu-latest - strategy: - matrix: - node: [16, 18, 20] steps: - - name: Checkout repository - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + submodules: true - uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node }} + node-version: 20 - run: npm ci - run: npm run build - - run: npm run lint - - run: npm run test diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 0978620..7544559 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -9,7 +9,9 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 + with: + submodules: true - uses: actions/setup-node@v3 with: node-version: 20 @@ -18,10 +20,6 @@ jobs: - run: npm run build - - run: npm run lint - - - run: npm run test - - run: npm version $(echo "${GITHUB_REF}" | sed 's/refs\/tags\///') --git-tag-version false - run: echo "//registry.npmjs.org/:_authToken=${NODE_AUTH_TOKEN}" >> .npmrc env: diff --git a/.gitmodules b/.gitmodules index 0d05ad3..9a8388f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ url = https://github.com/WebAssembly/binaryen.git [submodule "third_party/jsoncpp"] path = third_party/jsoncpp url = https://github.com/open-source-parsers/jsoncpp.git +[submodule "third_party/emsdk"] + path = third_party/emsdk + url = https://github.com/emscripten-core/emsdk.git diff --git a/.prettierignore b/.prettierignore index e3b01c0..ba0b250 100644 --- a/.prettierignore +++ b/.prettierignore @@ -4,3 +4,5 @@ /node_modules /transform/*.mjs /tests/ts/fixture +/third_party +/tests/cpp/lit/expectInstrument/expect.test.expect.json diff --git a/instrumentation/CMakeLists.txt b/instrumentation/CMakeLists.txt index 310f133..d9bc067 100644 --- a/instrumentation/CMakeLists.txt +++ b/instrumentation/CMakeLists.txt @@ -3,19 +3,19 @@ aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR} sources) if(EMSCRIPTEN) add_executable(wasm-instrumentation ${sources}) - target_link_libraries(wasm-instrumentation "-sSINGLE_FILE") - target_link_libraries(wasm-instrumentation "-sFORCE_FILESYSTEM") - target_link_libraries(wasm-instrumentation "-sALLOW_MEMORY_GROWTH") + target_link_libraries(wasm-instrumentation PUBLIC "-sSINGLE_FILE") + target_link_libraries(wasm-instrumentation PUBLIC "-sFORCE_FILESYSTEM") + target_link_libraries(wasm-instrumentation PUBLIC "-sALLOW_MEMORY_GROWTH") - # target_link_libraries(wasm-instrumentation "-sINITIAL_MEMORY=33554432") - target_link_libraries(wasm-instrumentation "-sNODERAWFS=1") - target_link_libraries(wasm-instrumentation "-sENVIRONMENT=node") - target_link_libraries(wasm-instrumentation "-sSTACK_SIZE=4mb") - target_link_libraries(wasm-instrumentation "-sMODULARIZE=1") - target_link_libraries(wasm-instrumentation "-sEXPORT_NAME=initInstrumenter") - target_link_libraries(wasm-instrumentation "-sEXPORT_ES6=1") - target_link_libraries(wasm-instrumentation "-sEXPORTED_RUNTIME_METHODS=allocateUTF8") - target_link_libraries(wasm-instrumentation "-sEXPORTED_FUNCTIONS=_malloc,_free") + # target_link_libraries(wasm-instrumentation PUBLIC "-sINITIAL_MEMORY=33554432") + target_link_libraries(wasm-instrumentation PUBLIC "-sNODERAWFS=1") + target_link_libraries(wasm-instrumentation PUBLIC "-sENVIRONMENT=node") + target_link_libraries(wasm-instrumentation PUBLIC "-sSTACK_SIZE=4mb") + target_link_libraries(wasm-instrumentation PUBLIC "-sMODULARIZE=1") + target_link_libraries(wasm-instrumentation PUBLIC "-sEXPORT_NAME=initInstrumenter") + target_link_libraries(wasm-instrumentation PUBLIC "-sEXPORT_ES6=1") + target_link_libraries(wasm-instrumentation PUBLIC "-sEXPORTED_RUNTIME_METHODS=allocateUTF8") + target_link_libraries(wasm-instrumentation PUBLIC "-sEXPORTED_FUNCTIONS=_malloc,_free") else() add_library(wasm-instrumentation ${sources}) endif() diff --git a/package.json b/package.json index f596481..496475a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,10 @@ "prettier": "@schleifner/prettier-config", "scripts": { "build": "tsc --build ./transform/tsconfig.json && node ./scripts/esbuild.js", - "test": "node bin/as-test.js && cross-env NODE_OPTIONS=--experimental-vm-modules jest", + "test:as": "node bin/as-test.js", + "test:ts": "cross-env NODE_OPTIONS=--experimental-vm-modules jest", + "test:cpp": "cmake -B build -S . && cmake --build build && build/bin/wasm-instrumentation-test", + "test": "npm run test:as && npm run test:ts && npm run test:cpp", "lint": "eslint src assembly tests/ts/test --max-warnings=0 && prettier -c .", "lint:fix": "eslint src assembly --fix && npx prettier --write .", "example": "node bin/as-test.js --config example/as-test.config.cjs ; node bin/as-test.js --config example/as-test.config.js" diff --git a/scripts/esbuild.js b/scripts/esbuild.js index 5b7e3c9..55559d1 100644 --- a/scripts/esbuild.js +++ b/scripts/esbuild.js @@ -3,24 +3,33 @@ import * as esbuild from "esbuild"; import { fileURLToPath, URL } from "url"; import { execSync } from "node:child_process"; import pkg from "@sprout2000/esbuild-copy-plugin"; +import { existsSync } from "node:fs"; const { copyPlugin } = pkg; const __dirname = fileURLToPath(new URL(".", import.meta.url)); execSync("tsc --build ./transform/tsconfig.json"); -function emsdkEnv() { - return { - env: "/Users/q540239/dev/emsdk:/Users/q540239/dev/emsdk/upstream/emscripten:" + process.env["PATH"], - ...process.env, - }; +const env = process.env; + +function initEmscripten() { + const sdkPath = "third_party/emsdk/"; + + env["PATH"] = `${sdkPath}:` + env["PATH"]; + if (!existsSync(`${sdkPath}upstream/emscripten`)) { + execSync("emsdk install 3.1.32", { encoding: "utf8", stdio: "inherit", env }); + execSync("emsdk activate 3.1.32", { encoding: "utf8", stdio: "inherit", env }); + } + env["PATH"] = `${sdkPath}upstream/emscripten:` + env["PATH"]; } -execSync("emcmake cmake -B build_wasm -S .", { encoding: "utf8", stdio: "inherit", env: emsdkEnv() }); +initEmscripten(); + +execSync("emcmake cmake -B build_wasm -S .", { encoding: "utf8", stdio: "inherit", env }); execSync("cmake --build build_wasm --target wasm-instrumentation", { encoding: "utf8", stdio: "inherit", - env: emsdkEnv(), + env, }); execSync( "tsc build_wasm/bin/wasm-instrumentation.js --declaration --allowJs --emitDeclarationOnly --outDir build_wasm/bin" diff --git a/tests/cpp/lit/covInstrument/do_while.wast.debug.json b/tests/cpp/lit/covInstrument/do_while.wast.debug.json index 2be21a6..cad40f1 100644 --- a/tests/cpp/lit/covInstrument/do_while.wast.debug.json +++ b/tests/cpp/lit/covInstrument/do_while.wast.debug.json @@ -1,70 +1,26 @@ { - "debugFiles": [ - "fixture/do-while.ts" - ], + "debugFiles": ["fixture/do-while.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 1 - ] + [1, 2], + [1, 1] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 3, - 25 - ] + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] ], [ - [ - 0, - 5, - 4 - ], - [ - 0, - 6, - 10 - ], - [ - 0, - 6, - 18 - ] + [0, 5, 4], + [0, 6, 10], + [0, 6, 18] ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 7, - 9 - ] - ] + [[0, 4, 2]], + [[0, 7, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json b/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json index e89c871..b5c0fec 100644 --- a/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json +++ b/tests/cpp/lit/covInstrument/do_while_break.wast.debug.json @@ -1,104 +1,34 @@ { - "debugFiles": [ - "fixture/do-while-break.ts" - ], + "debugFiles": ["fixture/do-while-break.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 3 - ], - [ - 3, - 4 - ], - [ - 3, - 1 - ] + [1, 2], + [1, 3], + [3, 4], + [3, 1] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 3, - 25 - ] + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] ], [ - [ - 0, - 5, - 4 - ], - [ - 0, - 6, - 8 - ], - [ - 0, - 6, - 16 - ] + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] ], + [[0, 6, 19]], [ - [ - 0, - 6, - 19 - ] + [0, 7, 10], + [0, 7, 18] ], - [ - [ - 0, - 7, - 10 - ], - [ - 0, - 7, - 18 - ] - ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 8, - 9 - ] - ] + [[0, 4, 2]], + [[0, 4, 2]], + [[0, 8, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json b/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json index a66211a..e283660 100644 --- a/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json +++ b/tests/cpp/lit/covInstrument/do_while_continue.wast.debug.json @@ -1,104 +1,34 @@ { - "debugFiles": [ - "fixture/do-while-continue.ts" - ], + "debugFiles": ["fixture/do-while-continue.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 3 - ], - [ - 4, - 5 - ], - [ - 4, - 1 - ] + [1, 2], + [1, 3], + [4, 5], + [4, 1] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 3, - 25 - ] + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] ], [ - [ - 0, - 5, - 4 - ], - [ - 0, - 6, - 8 - ], - [ - 0, - 6, - 16 - ] + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] ], + [[0, 6, 19]], + [[0, 4, 2]], [ - [ - 0, - 6, - 19 - ] + [0, 7, 10], + [0, 7, 18] ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 7, - 10 - ], - [ - 0, - 7, - 18 - ] - ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 8, - 9 - ] - ] + [[0, 4, 2]], + [[0, 8, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json b/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json index 4df6bb5..5abcf4c 100644 --- a/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json +++ b/tests/cpp/lit/covInstrument/do_while_once.wast.debug.json @@ -1,148 +1,46 @@ { - "debugFiles": [ - "fixture/do-while-once.ts" - ], + "debugFiles": ["fixture/do-while-once.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 3 - ], - [ - 3, - 4 - ], - [ - 3, - 5 - ], - [ - 6, - 7 - ], - [ - 6, - 1 - ] + [1, 2], + [1, 3], + [3, 4], + [3, 5], + [6, 7], + [6, 1] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ] - ], - [ - [ - 0, - 5, - 4 - ], - [ - 0, - 5, - 13 - ], - [ - 0, - 6, - 8 - ], - [ - 0, - 6, - 16 - ] - ], - [ - [ - 0, - 6, - 22 - ] - ], - [ - [ - 0, - 7, - 4 - ], - [ - 0, - 8, - 8 - ], - [ - 0, - 8, - 16 - ] - ], - [ - [ - 0, - 8, - 20 - ] - ], - [ - [ - 0, - 4, - 2 - ], - [ - 0, - 9, - 4 - ] + [0, 2, 14], + [0, 3, 14] ], [ - [ - 0, - 10, - 11 - ] + [0, 5, 4], + [0, 5, 13], + [0, 6, 8], + [0, 6, 16] ], + [[0, 6, 22]], [ - [ - 0, - 4, - 2 - ] + [0, 7, 4], + [0, 8, 8], + [0, 8, 16] ], + [[0, 8, 20]], [ - [ - 0, - 4, - 2 - ] + [0, 4, 2], + [0, 9, 4] ], + [[0, 10, 11]], + [[0, 4, 2]], + [[0, 4, 2]], [ - [ - 0, - 11, - 9 - ], - [ - 0, - 11, - 17 - ] + [0, 11, 9], + [0, 11, 17] ] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json b/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json index ce50b83..7553dc1 100644 --- a/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json +++ b/tests/cpp/lit/covInstrument/exit_basicBlock.wast.debug.json @@ -1,70 +1,28 @@ { - "debugFiles": [ - "fixture/exit-basicBlock.ts" - ], + "debugFiles": ["fixture/exit-basicBlock.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 0, - 1 - ], - [ - 0, - 2 - ], - [ - 3, - 4 - ], - [ - 3, - 5 - ] + [0, 1], + [0, 2], + [3, 4], + [3, 5] ], "index": 0, "lineInfo": [ [ - [ - 0, - 4, - 6 - ], - [ - 0, - 4, - 14 - ] - ], - [ - [ - 0, - 4, - 14 - ] + [0, 4, 6], + [0, 4, 14] ], + [[0, 4, 14]], [ - [ - 0, - 4, - 19 - ], - [ - 0, - 4, - 27 - ] + [0, 4, 19], + [0, 4, 27] ], [], - [ - [ - 0, - 5, - 17 - ] - ], + [[0, 5, 17]], [] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/for_loop.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop.wast.debug.json index 3e7a717..59e17c7 100644 --- a/tests/cpp/lit/covInstrument/for_loop.wast.debug.json +++ b/tests/cpp/lit/covInstrument/for_loop.wast.debug.json @@ -1,92 +1,34 @@ { - "debugFiles": [ - "fixture/for-loop.ts" - ], + "debugFiles": ["fixture/for-loop.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 3 - ] + [1, 2], + [1, 3] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 4, - 19 - ] - ], - [ - [ - 0, - 4, - 22 - ], - [ - 0, - 4, - 30 - ] + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] ], [ - [ - 0, - 4, - 37 - ], - [ - 0, - 5, - 4 - ], - [ - 0, - 5, - 13 - ] + [0, 4, 22], + [0, 4, 30] ], [ - [ - 0, - 4, - 19 - ] + [0, 4, 37], + [0, 5, 4], + [0, 5, 13] ], + [[0, 4, 19]], [ - [ - 0, - 7, - 2 - ], - [ - 0, - 7, - 11 - ], - [ - 0, - 8, - 9 - ] + [0, 7, 2], + [0, 7, 11], + [0, 8, 9] ] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json index b5ec18b..a7956dd 100644 --- a/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json +++ b/tests/cpp/lit/covInstrument/for_loop_break.wast.debug.json @@ -1,116 +1,38 @@ { - "debugFiles": [ - "fixture/for-loop-break.ts" - ], + "debugFiles": ["fixture/for-loop-break.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 5 - ], - [ - 2, - 3 - ], - [ - 2, - 4 - ] + [1, 2], + [1, 5], + [2, 3], + [2, 4] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 4, - 19 - ] + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] ], [ - [ - 0, - 4, - 22 - ], - [ - 0, - 4, - 30 - ] + [0, 4, 22], + [0, 4, 30] ], [ - [ - 0, - 5, - 8 - ], - [ - 0, - 5, - 16 - ] + [0, 5, 8], + [0, 5, 16] ], + [[0, 5, 19]], [ - [ - 0, - 5, - 19 - ] + [0, 4, 37], + [0, 6, 4], + [0, 6, 13] ], - [ - [ - 0, - 4, - 37 - ], - [ - 0, - 6, - 4 - ], - [ - 0, - 6, - 13 - ] - ], - [ - [ - 0, - 4, - 19 - ] - ], - [ - [ - 0, - 4, - 19 - ] - ], - [ - [ - 0, - 8, - 9 - ] - ] + [[0, 4, 19]], + [[0, 4, 19]], + [[0, 8, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json index ae9e642..3cc31e6 100644 --- a/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json +++ b/tests/cpp/lit/covInstrument/for_loop_continue.wast.debug.json @@ -1,121 +1,39 @@ { - "debugFiles": [ - "fixture/for-loop-continue.ts" - ], + "debugFiles": ["fixture/for-loop-continue.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 6 - ], - [ - 2, - 3 - ], - [ - 2, - 4 - ] + [1, 2], + [1, 6], + [2, 3], + [2, 4] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 4, - 19 - ] + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] ], [ - [ - 0, - 4, - 22 - ], - [ - 0, - 4, - 30 - ] + [0, 4, 22], + [0, 4, 30] ], [ - [ - 0, - 5, - 8 - ], - [ - 0, - 5, - 16 - ], - [ - 0, - 5, - 21 - ] + [0, 5, 8], + [0, 5, 16], + [0, 5, 21] ], + [[0, 5, 24]], [ - [ - 0, - 5, - 24 - ] + [0, 4, 30], + [0, 6, 4], + [0, 6, 13] ], - [ - [ - 0, - 4, - 30 - ], - [ - 0, - 6, - 4 - ], - [ - 0, - 6, - 13 - ] - ], - [ - [ - 0, - 4, - 37 - ] - ], - [ - [ - 0, - 4, - 19 - ] - ], - [ - [ - 0, - 8, - 9 - ] - ] + [[0, 4, 37]], + [[0, 4, 19]], + [[0, 8, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json b/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json index 65489db..af38d18 100644 --- a/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json +++ b/tests/cpp/lit/covInstrument/for_loop_return.wast.debug.json @@ -1,109 +1,37 @@ { - "debugFiles": [ - "fixture/for-loop-return.ts" - ], + "debugFiles": ["fixture/for-loop-return.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 5 - ], - [ - 2, - 3 - ], - [ - 2, - 4 - ] + [1, 2], + [1, 5], + [2, 3], + [2, 4] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 4, - 19 - ] - ], - [ - [ - 0, - 4, - 22 - ], - [ - 0, - 4, - 30 - ] + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] ], [ - [ - 0, - 5, - 8 - ], - [ - 0, - 5, - 16 - ] + [0, 4, 22], + [0, 4, 30] ], [ - [ - 0, - 5, - 26 - ] + [0, 5, 8], + [0, 5, 16] ], + [[0, 5, 26]], [ - [ - 0, - 4, - 37 - ], - [ - 0, - 6, - 4 - ], - [ - 0, - 6, - 13 - ] + [0, 4, 37], + [0, 6, 4], + [0, 6, 13] ], - [ - [ - 0, - 4, - 19 - ] - ], - [ - [ - 0, - 8, - 9 - ] - ] + [[0, 4, 19]], + [[0, 8, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/if_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_else.wast.debug.json index 2bdea0a..ad38ee2 100644 --- a/tests/cpp/lit/covInstrument/if_else.wast.debug.json +++ b/tests/cpp/lit/covInstrument/if_else.wast.debug.json @@ -1 +1,22 @@ -{"debugFiles":["fixture/if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6]],[[0,5,13]],[[0,7,13]],[[0,9,2]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6] + ], + [[0, 5, 13]], + [[0, 7, 13]], + [[0, 9, 2]] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json index 9d85273..47202dd 100644 --- a/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json +++ b/tests/cpp/lit/covInstrument/if_elseif_else.wast.debug.json @@ -1 +1,39 @@ -{"debugFiles":["fixture/if-elseif-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,4],[0,9,14]],[[0,11,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-elseif-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6], + [0, 4, 13] + ], + [ + [0, 5, 4], + [0, 5, 14] + ], + [ + [0, 6, 13], + [0, 6, 20] + ], + [ + [0, 7, 4], + [0, 7, 14] + ], + [ + [0, 9, 4], + [0, 9, 14] + ], + [[0, 11, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json index 2f6aa47..bed0cb5 100644 --- a/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json +++ b/tests/cpp/lit/covInstrument/if_elseif_empty_else.wast.debug.json @@ -1 +1,35 @@ -{"debugFiles":["fixture/if-elseif-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,20],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-elseif-empty-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 20], + [0, 4, 6], + [0, 4, 13] + ], + [ + [0, 5, 4], + [0, 5, 14] + ], + [ + [0, 6, 13], + [0, 6, 20] + ], + [ + [0, 7, 4], + [0, 7, 14] + ], + [[0, 9, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json b/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json index a72518d..dc227ea 100644 --- a/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json +++ b/tests/cpp/lit/covInstrument/if_empty_else.wast.debug.json @@ -1 +1,21 @@ -{"debugFiles":["fixture/if-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,16],[0,4,6]],[[0,5,13]],[[0,7,2]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-empty-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 16], + [0, 4, 6] + ], + [[0, 5, 13]], + [[0, 7, 2]] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json b/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json index 72079a5..ed4bd6a 100644 --- a/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json +++ b/tests/cpp/lit/covInstrument/if_multi_condition.wast.debug.json @@ -1,121 +1,39 @@ { - "debugFiles": [ - "fixture/if-multi-condition.ts" - ], + "debugFiles": ["fixture/if-multi-condition.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 0, - 1 - ], - [ - 0, - 2 - ], - [ - 3, - 4 - ], - [ - 3, - 5 - ], - [ - 6, - 7 - ], - [ - 6, - 8 - ] + [0, 1], + [0, 2], + [3, 4], + [3, 5], + [6, 7], + [6, 8] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 13 - ], - [ - 0, - 3, - 15 - ], - [ - 0, - 4, - 6 - ], - [ - 0, - 4, - 14 - ] - ], - [ - [ - 0, - 4, - 14 - ] + [0, 2, 13], + [0, 3, 15], + [0, 4, 6], + [0, 4, 14] ], + [[0, 4, 14]], [ - [ - 0, - 4, - 19 - ], - [ - 0, - 4, - 27 - ] + [0, 4, 19], + [0, 4, 27] ], [], + [[0, 4, 14]], [ - [ - 0, - 4, - 14 - ] - ], - [ - [ - 0, - 4, - 33 - ], - [ - 0, - 4, - 41 - ] + [0, 4, 33], + [0, 4, 41] ], [], - [ - [ - 0, - 5, - 13 - ] - ], - [ - [ - 0, - 7, - 13 - ] - ], - [ - [ - 0, - 9, - 9 - ] - ] + [[0, 5, 13]], + [[0, 7, 13]], + [[0, 9, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json b/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json index 5791c54..ec1abbf 100644 --- a/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json +++ b/tests/cpp/lit/covInstrument/include_exclude.wast.debug.json @@ -1 +1,28 @@ -{"debugFiles":["index.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,1,1],[0,2,1],[0,3,1]],[[0,4,1],[0,5,1]],[[0,6,1],[0,7,1]],[[0,8,1]]]}}} \ No newline at end of file +{ + "debugFiles": ["index.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 0, + "lineInfo": [ + [ + [0, 1, 1], + [0, 2, 1], + [0, 3, 1] + ], + [ + [0, 4, 1], + [0, 5, 1] + ], + [ + [0, 6, 1], + [0, 7, 1] + ], + [[0, 8, 1]] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/multi_func.wast.debug.json b/tests/cpp/lit/covInstrument/multi_func.wast.debug.json index ca8f1ae..c82edfe 100644 --- a/tests/cpp/lit/covInstrument/multi_func.wast.debug.json +++ b/tests/cpp/lit/covInstrument/multi_func.wast.debug.json @@ -1 +1,25 @@ -{"debugFiles":["assembly/add.ts"],"debugInfos":{"assembly/add/add":{"branchInfo":[],"index":2,"lineInfo":[[[0,3,11]]]},"assembly/add/genA":{"branchInfo":[],"index":0,"lineInfo":[[[0,11,11]]]},"assembly/add/main":{"branchInfo":[[0,1],[0,2]],"index":3,"lineInfo":[[[0,15,12],[0,16,8],[0,16,12]],[[0,17,12]],[[0,19,12]],[]]},"assembly/add/min":{"branchInfo":[],"index":1,"lineInfo":[[[0,7,11]]]}}} \ No newline at end of file +{ + "debugFiles": ["assembly/add.ts"], + "debugInfos": { + "assembly/add/add": { "branchInfo": [], "index": 2, "lineInfo": [[[0, 3, 11]]] }, + "assembly/add/genA": { "branchInfo": [], "index": 0, "lineInfo": [[[0, 11, 11]]] }, + "assembly/add/main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 3, + "lineInfo": [ + [ + [0, 15, 12], + [0, 16, 8], + [0, 16, 12] + ], + [[0, 17, 12]], + [[0, 19, 12]], + [] + ] + }, + "assembly/add/min": { "branchInfo": [], "index": 1, "lineInfo": [[[0, 7, 11]]] } + } +} diff --git a/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json b/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json index 6c1c53c..4a80a0a 100644 --- a/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json +++ b/tests/cpp/lit/covInstrument/multi_if_else.wast.debug.json @@ -1 +1,45 @@ -{"debugFiles":["fixture/multi-if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4],[4,5],[4,6]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,7,8],[0,7,15]],[[0,8,6],[0,8,16]],[[0,9,15],[0,9,22]],[[0,10,6],[0,10,16]],[]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/multi-if-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4], + [4, 5], + [4, 6] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6], + [0, 4, 13] + ], + [ + [0, 5, 4], + [0, 5, 14] + ], + [ + [0, 7, 8], + [0, 7, 15] + ], + [ + [0, 8, 6], + [0, 8, 16] + ], + [ + [0, 9, 15], + [0, 9, 22] + ], + [ + [0, 10, 6], + [0, 10, 16] + ], + [] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/switch_case.wast.debug.json b/tests/cpp/lit/covInstrument/switch_case.wast.debug.json index 8dd5688..9b1141a 100644 --- a/tests/cpp/lit/covInstrument/switch_case.wast.debug.json +++ b/tests/cpp/lit/covInstrument/switch_case.wast.debug.json @@ -1,151 +1,49 @@ { - "debugFiles": [ - "fixture/switch-case.ts" - ], + "debugFiles": ["fixture/switch-case.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 0, - 1 - ], - [ - 0, - 4 - ], - [ - 1, - 2 - ], - [ - 1, - 5 - ], - [ - 2, - 3 - ], - [ - 2, - 6 - ] + [0, 1], + [0, 4], + [1, 2], + [1, 5], + [2, 3], + [2, 6] ], "index": 0, "lineInfo": [ [ - [ - 0, - 8, - 13 - ], - [ - 0, - 9, - 14 - ], - [ - 0, - 10, - 10 - ], - [ - 0, - 11, - 9 - ] - ], - [ - [ - 0, - 11, - 9 - ], - [ - 0, - 15, - 9 - ] - ], - [ - [ - 0, - 15, - 9 - ], - [ - 0, - 18, - 9 - ] + [0, 8, 13], + [0, 9, 14], + [0, 10, 10], + [0, 11, 9] ], [ - [ - 0, - 18, - 9 - ] + [0, 11, 9], + [0, 15, 9] ], [ - [ - 0, - 12, - 6 - ], - [ - 0, - 12, - 15 - ], - [ - 0, - 13, - 6 - ] + [0, 15, 9], + [0, 18, 9] ], + [[0, 18, 9]], [ - [ - 0, - 16, - 13 - ], - [ - 0, - 16, - 21 - ] + [0, 12, 6], + [0, 12, 15], + [0, 13, 6] ], [ - [ - 0, - 19, - 6 - ], - [ - 0, - 19, - 15 - ], - [ - 0, - 20, - 6 - ] + [0, 16, 13], + [0, 16, 21] ], [ - [ - 0, - 23, - 13 - ] + [0, 19, 6], + [0, 19, 15], + [0, 20, 6] ], - [ - [ - 0, - 26, - 9 - ] - ] + [[0, 23, 13]], + [[0, 26, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json index 389aa97..4ff1773 100644 --- a/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json +++ b/tests/cpp/lit/covInstrument/switch_case_fallthrough.wast.debug.json @@ -1,139 +1,45 @@ { - "debugFiles": [ - "fixture/switch-case-fallthrough.ts" - ], + "debugFiles": ["fixture/switch-case-fallthrough.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 0, - 1 - ], - [ - 0, - 4 - ], - [ - 1, - 2 - ], - [ - 1, - 5 - ], - [ - 2, - 3 - ], - [ - 2, - 6 - ] + [0, 1], + [0, 4], + [1, 2], + [1, 5], + [2, 3], + [2, 6] ], "index": 0, "lineInfo": [ [ - [ - 0, - 8, - 13 - ], - [ - 0, - 9, - 14 - ], - [ - 0, - 10, - 10 - ], - [ - 0, - 11, - 9 - ] - ], - [ - [ - 0, - 11, - 9 - ], - [ - 0, - 15, - 9 - ] - ], - [ - [ - 0, - 15, - 9 - ], - [ - 0, - 16, - 9 - ] + [0, 8, 13], + [0, 9, 14], + [0, 10, 10], + [0, 11, 9] ], [ - [ - 0, - 16, - 9 - ] + [0, 11, 9], + [0, 15, 9] ], [ - [ - 0, - 12, - 6 - ], - [ - 0, - 12, - 15 - ], - [ - 0, - 13, - 6 - ] + [0, 15, 9], + [0, 16, 9] ], + [[0, 16, 9]], [ - [ - 0, - 10, - 2 - ] + [0, 12, 6], + [0, 12, 15], + [0, 13, 6] ], + [[0, 10, 2]], [ - [ - 0, - 17, - 6 - ], - [ - 0, - 17, - 15 - ], - [ - 0, - 18, - 6 - ] + [0, 17, 6], + [0, 17, 15], + [0, 18, 6] ], - [ - [ - 0, - 21, - 9 - ] - ] + [[0, 21, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json index 9d9927f..280a716 100644 --- a/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json +++ b/tests/cpp/lit/covInstrument/switch_case_rdefault.wast.debug.json @@ -1 +1,53 @@ -{"debugFiles":["fixture/switch-case-rdefault.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,5],[1,2],[1,6],[2,3],[2,7]],"index":0,"lineInfo":[[[0,8,13],[0,9,14],[0,10,10],[0,14,9]],[[0,14,9],[0,18,9]],[[0,18,9],[0,22,9]],[[0,22,9]],[[0,12,13],[0,12,21]],[[0,15,6],[0,15,15],[0,16,6]],[[0,19,6],[0,19,15],[0,20,6]],[[0,23,6],[0,23,15],[0,24,6]],[[0,27,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/switch-case-rdefault.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 5], + [1, 2], + [1, 6], + [2, 3], + [2, 7] + ], + "index": 0, + "lineInfo": [ + [ + [0, 8, 13], + [0, 9, 14], + [0, 10, 10], + [0, 14, 9] + ], + [ + [0, 14, 9], + [0, 18, 9] + ], + [ + [0, 18, 9], + [0, 22, 9] + ], + [[0, 22, 9]], + [ + [0, 12, 13], + [0, 12, 21] + ], + [ + [0, 15, 6], + [0, 15, 15], + [0, 16, 6] + ], + [ + [0, 19, 6], + [0, 19, 15], + [0, 20, 6] + ], + [ + [0, 23, 6], + [0, 23, 15], + [0, 24, 6] + ], + [[0, 27, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/covInstrument/while.wast.debug.json b/tests/cpp/lit/covInstrument/while.wast.debug.json index 0052e2c..f57c598 100644 --- a/tests/cpp/lit/covInstrument/while.wast.debug.json +++ b/tests/cpp/lit/covInstrument/while.wast.debug.json @@ -1,87 +1,33 @@ { - "debugFiles": [ - "fixture/while.ts" - ], + "debugFiles": ["fixture/while.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 3 - ] + [1, 2], + [1, 3] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 3, - 25 - ] - ], - [ - [ - 0, - 4, - 9 - ], - [ - 0, - 4, - 17 - ] + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] ], [ - [ - 0, - 5, - 4 - ], - [ - 0, - 6, - 4 - ], - [ - 0, - 6, - 13 - ] + [0, 4, 9], + [0, 4, 17] ], [ - [ - 0, - 4, - 2 - ] + [0, 5, 4], + [0, 6, 4], + [0, 6, 13] ], + [[0, 4, 2]], [ - [ - 0, - 4, - 2 - ], - [ - 0, - 8, - 9 - ] + [0, 4, 2], + [0, 8, 9] ] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/while_break.wast.debug.json b/tests/cpp/lit/covInstrument/while_break.wast.debug.json index 20bc3dc..be4d6e2 100644 --- a/tests/cpp/lit/covInstrument/while_break.wast.debug.json +++ b/tests/cpp/lit/covInstrument/while_break.wast.debug.json @@ -1,116 +1,38 @@ { - "debugFiles": [ - "fixture/while-break.ts" - ], + "debugFiles": ["fixture/while-break.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 5 - ], - [ - 2, - 3 - ], - [ - 2, - 4 - ] + [1, 2], + [1, 5], + [2, 3], + [2, 4] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 3, - 25 - ] + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] ], [ - [ - 0, - 4, - 9 - ], - [ - 0, - 4, - 17 - ] + [0, 4, 9], + [0, 4, 17] ], [ - [ - 0, - 5, - 4 - ], - [ - 0, - 6, - 8 - ], - [ - 0, - 6, - 16 - ] + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] ], + [[0, 6, 19]], [ - [ - 0, - 6, - 19 - ] + [0, 7, 4], + [0, 7, 13] ], - [ - [ - 0, - 7, - 4 - ], - [ - 0, - 7, - 13 - ] - ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 4, - 2 - ] - ], - [ - [ - 0, - 9, - 9 - ] - ] + [[0, 4, 2]], + [[0, 4, 2]], + [[0, 9, 9]] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/covInstrument/while_continue.wast.debug.json b/tests/cpp/lit/covInstrument/while_continue.wast.debug.json index 418a833..3d2032a 100644 --- a/tests/cpp/lit/covInstrument/while_continue.wast.debug.json +++ b/tests/cpp/lit/covInstrument/while_continue.wast.debug.json @@ -1,114 +1,40 @@ { - "debugFiles": [ - "fixture/while-continue.ts" - ], + "debugFiles": ["fixture/while-continue.ts"], "debugInfos": { "main": { "branchInfo": [ - [ - 1, - 2 - ], - [ - 1, - 5 - ], - [ - 2, - 3 - ], - [ - 2, - 4 - ] + [1, 2], + [1, 5], + [2, 3], + [2, 4] ], "index": 0, "lineInfo": [ [ - [ - 0, - 2, - 14 - ], - [ - 0, - 3, - 14 - ], - [ - 0, - 3, - 25 - ] - ], - [ - [ - 0, - 4, - 9 - ], - [ - 0, - 4, - 17 - ] - ], - [ - [ - 0, - 5, - 4 - ], - [ - 0, - 6, - 8 - ], - [ - 0, - 6, - 16 - ] + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] ], [ - [ - 0, - 6, - 19 - ] + [0, 4, 9], + [0, 4, 17] ], [ - [ - 0, - 7, - 4 - ], - [ - 0, - 7, - 13 - ] + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] ], + [[0, 6, 19]], [ - [ - 0, - 4, - 2 - ] + [0, 7, 4], + [0, 7, 13] ], + [[0, 4, 2]], [ - [ - 0, - 4, - 2 - ], - [ - 0, - 9, - 9 - ] + [0, 4, 2], + [0, 9, 9] ] ] } } -} \ No newline at end of file +} diff --git a/tests/cpp/lit/run.cjs b/tests/cpp/lit/run.cjs index a14ef65..067729f 100644 --- a/tests/cpp/lit/run.cjs +++ b/tests/cpp/lit/run.cjs @@ -1,4 +1,4 @@ -const fs = require('fs'); +const fs = require("fs"); const wasmBuffer = fs.readFileSync(process.argv[2]); const mockInstruFunc = { // isCall = true, return -1 if not mocked; @@ -55,33 +55,37 @@ const mockInstruFunc = { }, }; const imports = { - "mockInstrument": mockInstruFunc, - "covInstrument": { + mockInstrument: mockInstruFunc, + covInstrument: { traceExpression(functionIndex, index, type) { // console.log(consumer); switch (type) { - case 1: // call in + case 1: // call in console.log(`make directly call to function index=${functionIndex}`); break; - case 2: // call out + case 2: // call out console.log(`exit from function call index=${functionIndex}`); break; default: console.log(`basic block entry trace to: function=${functionIndex}, basic block=${index}`); break; } - } + }, }, - "env": { + env: { memory: sharedMemory, abort(_msg, _file, line, column) { console.error("abort called at index.ts:" + line + ":" + column); }, seed: function () { - return 0xA5534817; // make tests deterministic + return 0xa5534817; // make tests deterministic + }, + log(ptr) { + console.log(getString(ptr)); + }, + logi(i) { + console.log(i); }, - log(ptr) { console.log(getString(ptr)); }, - logi(i) { console.log(i); }, "Date.now": function () { return new Date().getTime(); }, @@ -89,7 +93,7 @@ const imports = { const memory = sharedMemory; console.log(`trace: ${getString(msg)}${n ? " " : ""}${args.slice(0, n).join(", ")}`); }, - } + }, }; function getString(ptr) { if (!ptr) return "null"; @@ -102,9 +106,9 @@ function getString(ptr) { var sharedMemory = new WebAssembly.Memory({ initial: 1 }); -WebAssembly.instantiate(wasmBuffer, imports).then(wasmModule => { +WebAssembly.instantiate(wasmBuffer, imports).then((wasmModule) => { wasmExample = wasmModule; const { main, memory } = wasmModule.instance.exports; sharedMemory = memory; main(); -}); \ No newline at end of file +}); diff --git a/third_party/emsdk b/third_party/emsdk new file mode 160000 index 0000000..85390ce --- /dev/null +++ b/third_party/emsdk @@ -0,0 +1 @@ +Subproject commit 85390ce88465e18c1c5d2f8d7f6ed21f3e8e8678 From 4fe823e5c5a564777a322f83ac2d448482ef5c9f Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 21:08:38 +0800 Subject: [PATCH 09/14] fix lint --- .github/workflows/ci-test.yml | 2 +- tests/cpp/lit/build/do_while.wast.debug.json | 27 +- tests/cpp/lit/build/do_while.wast.expect.json | 2 +- .../lit/build/do_while_break.wast.debug.json | 35 +- .../lit/build/do_while_break.wast.expect.json | 2 +- .../build/do_while_continue.wast.debug.json | 35 +- .../build/do_while_continue.wast.expect.json | 2 +- .../lit/build/do_while_once.wast.debug.json | 47 +- .../lit/build/do_while_once.wast.expect.json | 2 +- .../lit/build/exit_basicBlock.wast.debug.json | 29 +- .../build/exit_basicBlock.wast.expect.json | 2 +- tests/cpp/lit/build/expect.test.debug.json | 1337 ++++++++++++++++- tests/cpp/lit/build/expect.test.expect.json | 14 +- tests/cpp/lit/build/for_loop.wast.debug.json | 35 +- tests/cpp/lit/build/for_loop.wast.expect.json | 2 +- .../lit/build/for_loop_break.wast.debug.json | 39 +- .../lit/build/for_loop_break.wast.expect.json | 2 +- .../build/for_loop_continue.wast.debug.json | 40 +- .../build/for_loop_continue.wast.expect.json | 2 +- .../lit/build/for_loop_return.wast.debug.json | 38 +- .../build/for_loop_return.wast.expect.json | 2 +- tests/cpp/lit/build/if_else.wast.debug.json | 23 +- tests/cpp/lit/build/if_else.wast.expect.json | 2 +- .../lit/build/if_elseif_else.wast.debug.json | 40 +- .../lit/build/if_elseif_else.wast.expect.json | 2 +- .../if_elseif_empty_else.wast.debug.json | 36 +- .../if_elseif_empty_else.wast.expect.json | 2 +- .../lit/build/if_empty_else.wast.debug.json | 22 +- .../lit/build/if_empty_else.wast.expect.json | 2 +- .../build/if_multi_condition.wast.debug.json | 40 +- .../build/if_multi_condition.wast.expect.json | 2 +- .../lit/build/include_exclude.wast.debug.json | 29 +- .../build/include_exclude.wast.expect.json | 2 +- .../cpp/lit/build/multi_func.wast.debug.json | 26 +- .../cpp/lit/build/multi_func.wast.expect.json | 2 +- .../lit/build/multi_if_else.wast.debug.json | 46 +- .../lit/build/multi_if_else.wast.expect.json | 2 +- .../cpp/lit/build/switch_case.wast.debug.json | 50 +- .../lit/build/switch_case.wast.expect.json | 2 +- .../switch_case_fallthrough.wast.debug.json | 46 +- .../switch_case_fallthrough.wast.expect.json | 2 +- .../switch_case_rdefault.wast.debug.json | 54 +- .../switch_case_rdefault.wast.expect.json | 2 +- tests/cpp/lit/build/while.wast.debug.json | 34 +- tests/cpp/lit/build/while.wast.expect.json | 2 +- .../cpp/lit/build/while_break.wast.debug.json | 39 +- .../lit/build/while_break.wast.expect.json | 2 +- .../lit/build/while_continue.wast.debug.json | 41 +- .../lit/build/while_continue.wast.expect.json | 2 +- 49 files changed, 2201 insertions(+), 49 deletions(-) diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index 9da6079..c925472 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -18,6 +18,6 @@ jobs: - run: npm ci - - run: npm run build - run: npm run lint + - run: npm run build - run: npm run test diff --git a/tests/cpp/lit/build/do_while.wast.debug.json b/tests/cpp/lit/build/do_while.wast.debug.json index d214a55..cad40f1 100644 --- a/tests/cpp/lit/build/do_while.wast.debug.json +++ b/tests/cpp/lit/build/do_while.wast.debug.json @@ -1 +1,26 @@ -{"debugFiles":["fixture/do-while.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,1]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,5,4],[0,6,10],[0,6,18]],[[0,4,2]],[[0,7,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/do-while.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 1] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] + ], + [ + [0, 5, 4], + [0, 6, 10], + [0, 6, 18] + ], + [[0, 4, 2]], + [[0, 7, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/do_while.wast.expect.json b/tests/cpp/lit/build/do_while.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/do_while.wast.expect.json +++ b/tests/cpp/lit/build/do_while.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/do_while_break.wast.debug.json b/tests/cpp/lit/build/do_while_break.wast.debug.json index 168ce35..b5c0fec 100644 --- a/tests/cpp/lit/build/do_while_break.wast.debug.json +++ b/tests/cpp/lit/build/do_while_break.wast.debug.json @@ -1 +1,34 @@ -{"debugFiles":["fixture/do-while-break.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3],[3,4],[3,1]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,5,4],[0,6,8],[0,6,16]],[[0,6,19]],[[0,7,10],[0,7,18]],[[0,4,2]],[[0,4,2]],[[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/do-while-break.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 3], + [3, 4], + [3, 1] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] + ], + [ + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] + ], + [[0, 6, 19]], + [ + [0, 7, 10], + [0, 7, 18] + ], + [[0, 4, 2]], + [[0, 4, 2]], + [[0, 8, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/do_while_break.wast.expect.json b/tests/cpp/lit/build/do_while_break.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/do_while_break.wast.expect.json +++ b/tests/cpp/lit/build/do_while_break.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/do_while_continue.wast.debug.json b/tests/cpp/lit/build/do_while_continue.wast.debug.json index 5407e59..e283660 100644 --- a/tests/cpp/lit/build/do_while_continue.wast.debug.json +++ b/tests/cpp/lit/build/do_while_continue.wast.debug.json @@ -1 +1,34 @@ -{"debugFiles":["fixture/do-while-continue.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3],[4,5],[4,1]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,5,4],[0,6,8],[0,6,16]],[[0,6,19]],[[0,4,2]],[[0,7,10],[0,7,18]],[[0,4,2]],[[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/do-while-continue.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 3], + [4, 5], + [4, 1] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] + ], + [ + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] + ], + [[0, 6, 19]], + [[0, 4, 2]], + [ + [0, 7, 10], + [0, 7, 18] + ], + [[0, 4, 2]], + [[0, 8, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/do_while_continue.wast.expect.json b/tests/cpp/lit/build/do_while_continue.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/do_while_continue.wast.expect.json +++ b/tests/cpp/lit/build/do_while_continue.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/do_while_once.wast.debug.json b/tests/cpp/lit/build/do_while_once.wast.debug.json index 2cc8037..5abcf4c 100644 --- a/tests/cpp/lit/build/do_while_once.wast.debug.json +++ b/tests/cpp/lit/build/do_while_once.wast.debug.json @@ -1 +1,46 @@ -{"debugFiles":["fixture/do-while-once.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3],[3,4],[3,5],[6,7],[6,1]],"index":0,"lineInfo":[[[0,2,14],[0,3,14]],[[0,5,4],[0,5,13],[0,6,8],[0,6,16]],[[0,6,22]],[[0,7,4],[0,8,8],[0,8,16]],[[0,8,20]],[[0,4,2],[0,9,4]],[[0,10,11]],[[0,4,2]],[[0,4,2]],[[0,11,9],[0,11,17]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/do-while-once.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 3], + [3, 4], + [3, 5], + [6, 7], + [6, 1] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14] + ], + [ + [0, 5, 4], + [0, 5, 13], + [0, 6, 8], + [0, 6, 16] + ], + [[0, 6, 22]], + [ + [0, 7, 4], + [0, 8, 8], + [0, 8, 16] + ], + [[0, 8, 20]], + [ + [0, 4, 2], + [0, 9, 4] + ], + [[0, 10, 11]], + [[0, 4, 2]], + [[0, 4, 2]], + [ + [0, 11, 9], + [0, 11, 17] + ] + ] + } + } +} diff --git a/tests/cpp/lit/build/do_while_once.wast.expect.json b/tests/cpp/lit/build/do_while_once.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/do_while_once.wast.expect.json +++ b/tests/cpp/lit/build/do_while_once.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.debug.json b/tests/cpp/lit/build/exit_basicBlock.wast.debug.json index 3cea1a8..7553dc1 100644 --- a/tests/cpp/lit/build/exit_basicBlock.wast.debug.json +++ b/tests/cpp/lit/build/exit_basicBlock.wast.debug.json @@ -1 +1,28 @@ -{"debugFiles":["fixture/exit-basicBlock.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[3,4],[3,5]],"index":0,"lineInfo":[[[0,4,6],[0,4,14]],[[0,4,14]],[[0,4,19],[0,4,27]],[],[[0,5,17]],[]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/exit-basicBlock.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [3, 4], + [3, 5] + ], + "index": 0, + "lineInfo": [ + [ + [0, 4, 6], + [0, 4, 14] + ], + [[0, 4, 14]], + [ + [0, 4, 19], + [0, 4, 27] + ], + [], + [[0, 5, 17]], + [] + ] + } + } +} diff --git a/tests/cpp/lit/build/exit_basicBlock.wast.expect.json b/tests/cpp/lit/build/exit_basicBlock.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/exit_basicBlock.wast.expect.json +++ b/tests/cpp/lit/build/exit_basicBlock.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/expect.test.debug.json b/tests/cpp/lit/build/expect.test.debug.json index 399cd82..86d17c0 100644 --- a/tests/cpp/lit/build/expect.test.debug.json +++ b/tests/cpp/lit/build/expect.test.debug.json @@ -1 +1,1336 @@ -{"debugFiles":["~lib/rt/common.ts","~lib/rt/tlsf.ts","~lib/shared/typeinfo.ts","~lib/rt/itcms.ts","~lib/util/error.ts","~lib/shared/runtime.ts","~lib/util/number.ts","~lib/util/math.ts","~lib/util/string.ts","~lib/rt.ts","assembly/assertCollector.ts","~lib/arraybuffer.ts","~lib/util/hash.ts","~lib/map.ts","assembly/expect.ts","~lib/@assemblyscript/wasi-shim/assembly/bindings/wasi_snapshot_preview1.ts","tests-as/expect.test.ts","assembly/index.ts","assembly/comparison.ts","assembly/formatPrint.ts","~lib/number.ts","~lib/util/sort.ts","~lib/string.ts","~lib/array.ts","assembly/implement.ts","assembly/output.ts","~lib/staticarray.ts","~lib/builtins.ts","~lib/function.ts"],"debugInfos":{"assembly/assertCollector/AssertResultCollector#addDescription":{"branchInfo":[],"index":19,"lineInfo":[[[10,10,4],[10,10,38]]]},"assembly/assertCollector/AssertResultCollector#clear":{"branchInfo":[],"index":38,"lineInfo":[[[10,39,4],[10,39,23],[10,40,4],[10,40,35],[10,41,4]]]},"assembly/assertCollector/AssertResultCollector#collectCheckResult":{"branchInfo":[[0,1],[0,5],[1,2],[1,3]],"index":10,"lineInfo":[[[10,21,4],[10,22,8],[10,22,9]],[[10,23,6],[10,24,31],[10,24,65],[10,25,28],[10,26,8],[10,27,8],[10,28,8],[10,30,10],[10,30,31],[20,187,35]],[[10,31,8],[10,31,29],[10,31,52]],[[10,33,8],[10,33,29],[10,33,47],[10,33,48]],[],[]]},"assembly/assertCollector/AssertResultCollector#constructor":{"branchInfo":[[0,1],[0,2]],"index":8,"lineInfo":[[],[],[[10,4,15],[10,5,14],[10,6,41],[10,7,38]]]},"assembly/assertCollector/AssertResultCollector#failInfoString":{"branchInfo":[],"index":37,"lineInfo":[[[10,51,4],[10,51,11],[10,51,30],[10,51,37]]]},"assembly/assertCollector/AssertResultCollector#failString":{"branchInfo":[],"index":32,"lineInfo":[[[10,48,4],[10,48,11],[10,48,23],[20,187,35]]]},"assembly/assertCollector/AssertResultCollector#removeDescription":{"branchInfo":[],"index":20,"lineInfo":[[[10,13,4]]]},"assembly/assertCollector/AssertResultCollector#totalString":{"branchInfo":[],"index":31,"lineInfo":[[[10,45,4],[10,45,11],[10,45,24],[20,187,35]]]},"assembly/comparison/equal":{"branchInfo":[],"index":1,"lineInfo":[[[18,94,6],[18,94,7],[18,94,42],[18,95,11],[18,95,16]]]},"assembly/comparison/isNull<~lib/string/String|null>":{"branchInfo":[],"index":25,"lineInfo":[[[18,2,2],[18,2,6],[18,2,7],[18,5,2],[18,5,6],[18,5,7],[18,8,2],[18,8,9],[18,8,14]]]},"assembly/expect/Value#closeTo":{"branchInfo":[],"index":14,"lineInfo":[[[14,100,4],[14,100,17],[14,101,8],[14,101,52],[14,102,6],[14,103,8],[14,103,12],[14,103,19],[14,103,33],[14,104,8],[14,105,8],[14,105,15],[14,106,8],[14,106,22],[14,106,29],[14,111,4],[14,111,11]]]},"assembly/expect/Value#constructor":{"branchInfo":[[0,1],[0,2]],"index":13,"lineInfo":[[],[],[[14,12,4],[14,12,16]]]},"assembly/expect/Value#constructor":{"branchInfo":[[0,1],[0,2]],"index":9,"lineInfo":[[],[],[[14,12,4],[14,12,16]]]},"assembly/expect/Value#equal":{"branchInfo":[],"index":11,"lineInfo":[[[14,34,4],[14,35,6],[14,35,15],[14,35,26],[14,36,6],[14,37,6],[14,37,13],[14,38,6],[14,38,13],[14,38,20],[14,40,4],[14,40,11]]]},"assembly/expect/Value#equal@varargs":{"branchInfo":[[0,1],[0,2],[0,3]],"index":43,"lineInfo":[[],[],[[14,33,44]],[]]},"assembly/expect/Value#greaterThan":{"branchInfo":[],"index":15,"lineInfo":[[[14,53,4],[14,54,6],[14,54,18],[14,55,6],[14,56,6],[14,56,13],[14,57,6],[14,57,14],[14,57,21],[14,59,4],[14,59,11]]]},"assembly/expect/Value#greaterThanOrEqual":{"branchInfo":[],"index":16,"lineInfo":[[[14,65,4],[14,66,6],[14,66,19],[14,67,6],[14,68,6],[14,68,13],[14,69,6],[14,69,15],[14,69,22],[14,71,4],[14,71,11]]]},"assembly/expect/Value#lessThan":{"branchInfo":[],"index":17,"lineInfo":[[[14,74,4],[14,75,6],[14,75,18],[14,76,6],[14,77,6],[14,77,13],[14,78,6],[14,78,14],[14,78,21],[14,80,4],[14,80,11]]]},"assembly/expect/Value#lessThanOrEqual":{"branchInfo":[],"index":18,"lineInfo":[[[14,86,4],[14,87,6],[14,87,19],[14,88,6],[14,89,6],[14,89,13],[14,90,6],[14,90,15],[14,90,22],[14,92,4],[14,92,11]]]},"assembly/expect/Value#notEqual":{"branchInfo":[],"index":12,"lineInfo":[[[14,43,4],[14,44,6],[14,44,7],[14,44,16],[14,44,27],[14,45,6],[14,46,6],[14,46,13],[14,47,6],[14,47,15],[14,47,22],[14,49,4],[14,49,11]]]},"assembly/expect/Value<~lib/string/String|null>#constructor":{"branchInfo":[[0,1],[0,2]],"index":23,"lineInfo":[[],[],[[14,12,4],[14,12,16]]]},"assembly/expect/Value<~lib/string/String|null>#isNull":{"branchInfo":[],"index":27,"lineInfo":[[[14,15,4],[14,16,6],[14,16,16],[14,17,6],[14,18,6],[14,18,13],[14,19,6],[14,21,4],[14,21,11]]]},"assembly/expect/Value<~lib/string/String|null>#notNull":{"branchInfo":[],"index":28,"lineInfo":[[[14,24,4],[14,25,6],[14,25,7],[14,25,17],[14,26,6],[14,27,6],[14,27,13],[14,28,6],[14,30,4],[14,30,11]]]},"assembly/formatPrint/toJson":{"branchInfo":[],"index":4,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,6],[19,8,60],[19,9,11],[20,383,35]]]},"assembly/formatPrint/toJson":{"branchInfo":[],"index":2,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,6],[19,8,60],[19,9,11],[20,78,35]]]},"assembly/formatPrint/toJson<~lib/array/Array<~lib/array/Array<~lib/string/String>>>":{"branchInfo":[[1,2],[1,3]],"index":35,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,2],[19,11,6],[19,68,2],[19,68,6],[19,76,6],[19,76,42],[19,77,25],[19,77,43],[19,78,17],[19,78,24]],[[19,78,34],[19,78,38]],[[19,78,41],[19,79,6],[19,79,19],[19,79,24],[19,79,31],[19,79,33]],[],[[19,81,4],[19,81,11],[19,81,15],[19,81,33]]]},"assembly/formatPrint/toJson<~lib/array/Array<~lib/string/String>>":{"branchInfo":[[1,2],[1,3]],"index":34,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,2],[19,11,6],[19,68,2],[19,68,6],[19,76,6],[19,76,42],[19,77,25],[19,77,43],[19,78,17],[19,78,24]],[[19,78,34],[19,78,38]],[[19,78,41],[19,79,6],[19,79,19],[19,79,24],[19,79,31],[19,79,33]],[],[[19,81,4],[19,81,11],[19,81,15],[19,81,33]]]},"assembly/formatPrint/toJson<~lib/map/Map<~lib/string/String\\2c~lib/array/Array<~lib/array/Array<~lib/string/String>>>>":{"branchInfo":[[1,2],[1,3]],"index":36,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,2],[19,11,6],[19,68,2],[19,68,6],[19,76,2],[19,76,6],[19,83,2],[19,83,6],[19,86,6],[19,86,24],[19,87,16],[19,88,18],[19,89,25],[19,90,9],[19,90,17],[23,69,28]],[[19,90,20],[19,90,24]],[[19,90,36],[19,91,6],[19,91,19],[19,91,24],[19,91,31],[19,91,35],[19,91,41],[19,91,49],[19,91,56],[19,91,62]],[],[[19,93,4],[19,93,11],[19,93,16],[19,93,34]]]},"assembly/formatPrint/toJson<~lib/string/String>":{"branchInfo":[[1,2],[1,44],[2,3],[2,4],[5,6],[5,7],[7,8],[7,9],[10,11],[10,12],[12,13],[12,14],[15,16],[15,17],[17,18],[17,28],[18,19],[18,29],[19,20],[19,30],[20,21],[20,31],[21,22],[21,32],[22,23],[22,33],[23,24],[23,34],[24,25],[24,35],[25,26],[25,36],[26,27],[26,37],[39,40],[39,41]],"index":33,"lineInfo":[[[19,2,2],[19,2,6],[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,6],[19,11,22],[19,12,24],[19,13,32],[19,14,9],[19,14,17]],[[19,14,20],[19,14,24]],[[19,15,6],[19,15,23],[19,15,38],[19,17,9],[19,17,21]],[[19,17,29],[19,17,41]],[],[],[],[[19,18,9],[19,18,21]],[[19,18,29],[19,18,41]],[],[],[],[[19,19,9],[19,19,21]],[[19,19,29],[19,19,41]],[],[],[[19,21,8],[19,21,23],[19,21,34]],[[19,23,16],[19,24,15]],[[19,27,15]],[[19,30,15]],[[19,33,15]],[[19,36,15]],[[19,39,15]],[[19,42,15]],[[19,45,15]],[[19,48,15]],[[19,51,15]],[],[[19,25,12],[19,25,27],[19,26,12]],[[19,28,12],[19,28,27],[19,29,12]],[[19,31,12],[19,31,27],[19,32,12]],[[19,34,12],[19,34,27],[19,35,12]],[[19,37,12],[19,37,27],[19,38,12]],[[19,40,12],[19,40,27],[19,41,12]],[[19,43,12],[19,43,27],[19,44,12]],[[19,46,12],[19,46,27],[19,47,12]],[[19,49,12],[19,49,27],[19,50,12]],[[19,52,12],[19,52,27],[19,53,12]],[[19,54,19],[19,56,32],[19,57,12],[19,57,27],[19,58,17],[19,58,25],[20,78,35]],[[19,58,45],[19,58,49]],[[19,58,52],[19,59,14],[19,59,29]],[],[[19,23,8],[19,61,12],[19,61,27]],[[19,14,36]],[],[[19,66,4],[19,66,11],[19,66,17],[19,66,32],[19,66,38]]]},"assembly/formatPrint/toJson<~lib/string/String|null>":{"branchInfo":[[0,1],[0,2],[3,4],[3,46],[4,5],[4,6],[7,8],[7,9],[9,10],[9,11],[12,13],[12,14],[14,15],[14,16],[17,18],[17,19],[19,20],[19,30],[20,21],[20,31],[21,22],[21,32],[22,23],[22,33],[23,24],[23,34],[24,25],[24,35],[25,26],[25,36],[26,27],[26,37],[27,28],[27,38],[28,29],[28,39],[41,42],[41,43]],"index":26,"lineInfo":[[[19,2,6],[19,2,23],[19,2,28]],[[19,3,4],[19,3,11]],[[19,5,2],[19,5,6],[19,8,2],[19,8,6],[19,11,6],[19,11,22],[19,12,24],[19,13,32],[19,14,9],[19,14,17]],[[19,14,20],[19,14,24]],[[19,15,6],[19,15,23],[19,15,38],[19,17,9],[19,17,21]],[[19,17,29],[19,17,41]],[],[],[],[[19,18,9],[19,18,21]],[[19,18,29],[19,18,41]],[],[],[],[[19,19,9],[19,19,21]],[[19,19,29],[19,19,41]],[],[],[[19,21,8],[19,21,23],[19,21,34]],[[19,23,16],[19,24,15]],[[19,27,15]],[[19,30,15]],[[19,33,15]],[[19,36,15]],[[19,39,15]],[[19,42,15]],[[19,45,15]],[[19,48,15]],[[19,51,15]],[],[[19,25,12],[19,25,27],[19,26,12]],[[19,28,12],[19,28,27],[19,29,12]],[[19,31,12],[19,31,27],[19,32,12]],[[19,34,12],[19,34,27],[19,35,12]],[[19,37,12],[19,37,27],[19,38,12]],[[19,40,12],[19,40,27],[19,41,12]],[[19,43,12],[19,43,27],[19,44,12]],[[19,46,12],[19,46,27],[19,47,12]],[[19,49,12],[19,49,27],[19,50,12]],[[19,52,12],[19,52,27],[19,53,12]],[[19,54,19],[19,56,32],[19,57,12],[19,57,27],[19,58,17],[19,58,25],[20,78,35]],[[19,58,45],[19,58,49]],[[19,58,52],[19,59,14],[19,59,29]],[],[[19,23,8],[19,61,12],[19,61,27]],[[19,14,36]],[],[[19,66,4],[19,66,11],[19,66,17],[19,66,32],[19,66,38]]]},"assembly/implement/describeImpl":{"branchInfo":[],"index":29,"lineInfo":[[[24,8,2],[24,8,30],[24,9,2],[24,10,2]]]},"assembly/implement/testImpl":{"branchInfo":[],"index":21,"lineInfo":[[[24,13,2],[24,13,30],[24,14,2],[24,15,2],[24,16,2]]]},"assembly/index/describe":{"branchInfo":[],"index":30,"lineInfo":[[[17,19,2],[17,19,15],[17,19,28]]]},"assembly/index/endTest":{"branchInfo":[],"index":7,"lineInfo":[[[17,61,2]]]},"assembly/index/expect":{"branchInfo":[],"index":3,"lineInfo":[[[17,57,2],[17,57,9],[17,57,22]]]},"assembly/index/expect":{"branchInfo":[],"index":0,"lineInfo":[[[17,57,2],[17,57,9],[17,57,22]]]},"assembly/index/expect<~lib/string/String|null>":{"branchInfo":[],"index":24,"lineInfo":[[[17,57,2],[17,57,9],[17,57,22]]]},"assembly/index/test":{"branchInfo":[],"index":22,"lineInfo":[[[17,28,2],[17,28,11],[17,28,24]]]},"assembly/output/checkMemory":{"branchInfo":[[0,1],[0,2]],"index":5,"lineInfo":[[[25,45,9],[25,45,18]],[[25,45,40]],[]]},"assembly/output/fromCString":{"branchInfo":[[1,2],[1,3]],"index":6,"lineInfo":[[[25,49,2],[25,49,13]],[[25,50,9],[25,50,18],[25,50,28],[25,50,38]],[[25,51,4]],[],[[22,767,80],[25,50,2],[25,53,2],[25,53,9],[25,53,34],[25,53,43]]]},"assembly/output/getArgs":{"branchInfo":[[1,2],[1,3]],"index":40,"lineInfo":[[[25,57,25],[25,60,2],[25,60,14],[25,60,31],[25,60,49],[25,61,2],[25,61,8],[25,61,23],[25,61,39],[25,61,56],[25,62,2],[25,62,9],[25,63,2],[25,63,15],[25,63,27],[25,64,2],[25,64,26],[25,64,38],[25,66,25],[25,66,41],[25,66,46],[25,66,53],[25,66,58],[25,67,28],[25,67,44],[25,68,2],[25,68,14],[25,68,50],[25,68,51],[25,68,58],[25,68,63],[25,69,2],[25,69,14],[25,69,53],[25,70,2],[25,70,8],[25,71,4],[25,72,4],[25,74,2],[25,74,9],[25,75,7],[25,75,22]],[[25,75,25],[25,75,29]],[[25,75,35],[25,76,4],[25,76,21],[25,77,6],[25,77,42],[25,77,46],[25,79,16],[25,79,28],[25,80,4],[25,80,14]],[],[[25,83,2],[25,83,9]]]},"assembly/output/output":{"branchInfo":[],"index":42,"lineInfo":[[[25,21,27],[25,22,2],[25,22,14],[25,23,2],[25,23,14],[25,24,2],[25,24,14],[25,25,2],[25,27,2],[25,29,23],[25,29,29],[25,29,41],[25,29,48],[25,31,25],[25,31,35],[25,31,44],[25,31,47],[25,31,53],[25,32,2],[25,32,12],[25,32,28]]]},"assembly/output/perror":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":39,"lineInfo":[[[25,38,6],[25,38,13]],[[25,39,4]],[[25,41,9]],[[25,41,16],[25,41,30],[25,41,37],[25,41,43]],[]]},"assembly/output/writeFile":{"branchInfo":[[0,1],[0,2],[3,4],[3,3]],"index":41,"lineInfo":[[[25,87,6],[25,87,21]],[[25,87,24]],[[22,697,63],[25,89,19],[25,89,38],[25,91,2],[25,91,14],[25,91,44],[25,92,2],[25,92,8],[25,93,4],[25,94,4],[25,95,4],[25,96,4],[25,97,4],[25,97,19],[25,98,4],[25,99,6],[25,100,6],[25,101,6],[25,102,6],[25,103,4],[25,104,6],[25,105,6],[25,106,6],[25,107,6],[25,108,4],[25,109,4],[25,111,2],[25,111,9],[25,112,2],[25,112,29],[25,112,38],[25,115,14],[25,115,33],[25,117,2],[25,117,12],[25,118,2],[25,118,16],[25,120,2],[25,120,14],[25,120,39]],[[25,122,4],[25,122,10],[25,122,19],[25,122,35],[25,122,59],[25,122,62],[25,123,4],[25,123,11],[25,124,4],[25,124,19],[25,124,31],[25,125,4],[25,125,15],[25,125,27],[25,126,11],[25,126,25]],[[25,121,2]],[[25,127,2],[25,127,11]]]}}} \ No newline at end of file +{ + "debugFiles": [ + "~lib/rt/common.ts", + "~lib/rt/tlsf.ts", + "~lib/shared/typeinfo.ts", + "~lib/rt/itcms.ts", + "~lib/util/error.ts", + "~lib/shared/runtime.ts", + "~lib/util/number.ts", + "~lib/util/math.ts", + "~lib/util/string.ts", + "~lib/rt.ts", + "assembly/assertCollector.ts", + "~lib/arraybuffer.ts", + "~lib/util/hash.ts", + "~lib/map.ts", + "assembly/expect.ts", + "~lib/@assemblyscript/wasi-shim/assembly/bindings/wasi_snapshot_preview1.ts", + "tests-as/expect.test.ts", + "assembly/index.ts", + "assembly/comparison.ts", + "assembly/formatPrint.ts", + "~lib/number.ts", + "~lib/util/sort.ts", + "~lib/string.ts", + "~lib/array.ts", + "assembly/implement.ts", + "assembly/output.ts", + "~lib/staticarray.ts", + "~lib/builtins.ts", + "~lib/function.ts" + ], + "debugInfos": { + "assembly/assertCollector/AssertResultCollector#addDescription": { + "branchInfo": [], + "index": 19, + "lineInfo": [ + [ + [10, 10, 4], + [10, 10, 38] + ] + ] + }, + "assembly/assertCollector/AssertResultCollector#clear": { + "branchInfo": [], + "index": 38, + "lineInfo": [ + [ + [10, 39, 4], + [10, 39, 23], + [10, 40, 4], + [10, 40, 35], + [10, 41, 4] + ] + ] + }, + "assembly/assertCollector/AssertResultCollector#collectCheckResult": { + "branchInfo": [ + [0, 1], + [0, 5], + [1, 2], + [1, 3] + ], + "index": 10, + "lineInfo": [ + [ + [10, 21, 4], + [10, 22, 8], + [10, 22, 9] + ], + [ + [10, 23, 6], + [10, 24, 31], + [10, 24, 65], + [10, 25, 28], + [10, 26, 8], + [10, 27, 8], + [10, 28, 8], + [10, 30, 10], + [10, 30, 31], + [20, 187, 35] + ], + [ + [10, 31, 8], + [10, 31, 29], + [10, 31, 52] + ], + [ + [10, 33, 8], + [10, 33, 29], + [10, 33, 47], + [10, 33, 48] + ], + [], + [] + ] + }, + "assembly/assertCollector/AssertResultCollector#constructor": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 8, + "lineInfo": [ + [], + [], + [ + [10, 4, 15], + [10, 5, 14], + [10, 6, 41], + [10, 7, 38] + ] + ] + }, + "assembly/assertCollector/AssertResultCollector#failInfoString": { + "branchInfo": [], + "index": 37, + "lineInfo": [ + [ + [10, 51, 4], + [10, 51, 11], + [10, 51, 30], + [10, 51, 37] + ] + ] + }, + "assembly/assertCollector/AssertResultCollector#failString": { + "branchInfo": [], + "index": 32, + "lineInfo": [ + [ + [10, 48, 4], + [10, 48, 11], + [10, 48, 23], + [20, 187, 35] + ] + ] + }, + "assembly/assertCollector/AssertResultCollector#removeDescription": { + "branchInfo": [], + "index": 20, + "lineInfo": [[[10, 13, 4]]] + }, + "assembly/assertCollector/AssertResultCollector#totalString": { + "branchInfo": [], + "index": 31, + "lineInfo": [ + [ + [10, 45, 4], + [10, 45, 11], + [10, 45, 24], + [20, 187, 35] + ] + ] + }, + "assembly/comparison/equal": { + "branchInfo": [], + "index": 1, + "lineInfo": [ + [ + [18, 94, 6], + [18, 94, 7], + [18, 94, 42], + [18, 95, 11], + [18, 95, 16] + ] + ] + }, + "assembly/comparison/isNull<~lib/string/String|null>": { + "branchInfo": [], + "index": 25, + "lineInfo": [ + [ + [18, 2, 2], + [18, 2, 6], + [18, 2, 7], + [18, 5, 2], + [18, 5, 6], + [18, 5, 7], + [18, 8, 2], + [18, 8, 9], + [18, 8, 14] + ] + ] + }, + "assembly/expect/Value#closeTo": { + "branchInfo": [], + "index": 14, + "lineInfo": [ + [ + [14, 100, 4], + [14, 100, 17], + [14, 101, 8], + [14, 101, 52], + [14, 102, 6], + [14, 103, 8], + [14, 103, 12], + [14, 103, 19], + [14, 103, 33], + [14, 104, 8], + [14, 105, 8], + [14, 105, 15], + [14, 106, 8], + [14, 106, 22], + [14, 106, 29], + [14, 111, 4], + [14, 111, 11] + ] + ] + }, + "assembly/expect/Value#constructor": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 13, + "lineInfo": [ + [], + [], + [ + [14, 12, 4], + [14, 12, 16] + ] + ] + }, + "assembly/expect/Value#constructor": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 9, + "lineInfo": [ + [], + [], + [ + [14, 12, 4], + [14, 12, 16] + ] + ] + }, + "assembly/expect/Value#equal": { + "branchInfo": [], + "index": 11, + "lineInfo": [ + [ + [14, 34, 4], + [14, 35, 6], + [14, 35, 15], + [14, 35, 26], + [14, 36, 6], + [14, 37, 6], + [14, 37, 13], + [14, 38, 6], + [14, 38, 13], + [14, 38, 20], + [14, 40, 4], + [14, 40, 11] + ] + ] + }, + "assembly/expect/Value#equal@varargs": { + "branchInfo": [ + [0, 1], + [0, 2], + [0, 3] + ], + "index": 43, + "lineInfo": [[], [], [[14, 33, 44]], []] + }, + "assembly/expect/Value#greaterThan": { + "branchInfo": [], + "index": 15, + "lineInfo": [ + [ + [14, 53, 4], + [14, 54, 6], + [14, 54, 18], + [14, 55, 6], + [14, 56, 6], + [14, 56, 13], + [14, 57, 6], + [14, 57, 14], + [14, 57, 21], + [14, 59, 4], + [14, 59, 11] + ] + ] + }, + "assembly/expect/Value#greaterThanOrEqual": { + "branchInfo": [], + "index": 16, + "lineInfo": [ + [ + [14, 65, 4], + [14, 66, 6], + [14, 66, 19], + [14, 67, 6], + [14, 68, 6], + [14, 68, 13], + [14, 69, 6], + [14, 69, 15], + [14, 69, 22], + [14, 71, 4], + [14, 71, 11] + ] + ] + }, + "assembly/expect/Value#lessThan": { + "branchInfo": [], + "index": 17, + "lineInfo": [ + [ + [14, 74, 4], + [14, 75, 6], + [14, 75, 18], + [14, 76, 6], + [14, 77, 6], + [14, 77, 13], + [14, 78, 6], + [14, 78, 14], + [14, 78, 21], + [14, 80, 4], + [14, 80, 11] + ] + ] + }, + "assembly/expect/Value#lessThanOrEqual": { + "branchInfo": [], + "index": 18, + "lineInfo": [ + [ + [14, 86, 4], + [14, 87, 6], + [14, 87, 19], + [14, 88, 6], + [14, 89, 6], + [14, 89, 13], + [14, 90, 6], + [14, 90, 15], + [14, 90, 22], + [14, 92, 4], + [14, 92, 11] + ] + ] + }, + "assembly/expect/Value#notEqual": { + "branchInfo": [], + "index": 12, + "lineInfo": [ + [ + [14, 43, 4], + [14, 44, 6], + [14, 44, 7], + [14, 44, 16], + [14, 44, 27], + [14, 45, 6], + [14, 46, 6], + [14, 46, 13], + [14, 47, 6], + [14, 47, 15], + [14, 47, 22], + [14, 49, 4], + [14, 49, 11] + ] + ] + }, + "assembly/expect/Value<~lib/string/String|null>#constructor": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 23, + "lineInfo": [ + [], + [], + [ + [14, 12, 4], + [14, 12, 16] + ] + ] + }, + "assembly/expect/Value<~lib/string/String|null>#isNull": { + "branchInfo": [], + "index": 27, + "lineInfo": [ + [ + [14, 15, 4], + [14, 16, 6], + [14, 16, 16], + [14, 17, 6], + [14, 18, 6], + [14, 18, 13], + [14, 19, 6], + [14, 21, 4], + [14, 21, 11] + ] + ] + }, + "assembly/expect/Value<~lib/string/String|null>#notNull": { + "branchInfo": [], + "index": 28, + "lineInfo": [ + [ + [14, 24, 4], + [14, 25, 6], + [14, 25, 7], + [14, 25, 17], + [14, 26, 6], + [14, 27, 6], + [14, 27, 13], + [14, 28, 6], + [14, 30, 4], + [14, 30, 11] + ] + ] + }, + "assembly/formatPrint/toJson": { + "branchInfo": [], + "index": 4, + "lineInfo": [ + [ + [19, 2, 2], + [19, 2, 6], + [19, 5, 2], + [19, 5, 6], + [19, 8, 6], + [19, 8, 60], + [19, 9, 11], + [20, 383, 35] + ] + ] + }, + "assembly/formatPrint/toJson": { + "branchInfo": [], + "index": 2, + "lineInfo": [ + [ + [19, 2, 2], + [19, 2, 6], + [19, 5, 2], + [19, 5, 6], + [19, 8, 6], + [19, 8, 60], + [19, 9, 11], + [20, 78, 35] + ] + ] + }, + "assembly/formatPrint/toJson<~lib/array/Array<~lib/array/Array<~lib/string/String>>>": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 35, + "lineInfo": [ + [ + [19, 2, 2], + [19, 2, 6], + [19, 5, 2], + [19, 5, 6], + [19, 8, 2], + [19, 8, 6], + [19, 11, 2], + [19, 11, 6], + [19, 68, 2], + [19, 68, 6], + [19, 76, 6], + [19, 76, 42], + [19, 77, 25], + [19, 77, 43], + [19, 78, 17], + [19, 78, 24] + ], + [ + [19, 78, 34], + [19, 78, 38] + ], + [ + [19, 78, 41], + [19, 79, 6], + [19, 79, 19], + [19, 79, 24], + [19, 79, 31], + [19, 79, 33] + ], + [], + [ + [19, 81, 4], + [19, 81, 11], + [19, 81, 15], + [19, 81, 33] + ] + ] + }, + "assembly/formatPrint/toJson<~lib/array/Array<~lib/string/String>>": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 34, + "lineInfo": [ + [ + [19, 2, 2], + [19, 2, 6], + [19, 5, 2], + [19, 5, 6], + [19, 8, 2], + [19, 8, 6], + [19, 11, 2], + [19, 11, 6], + [19, 68, 2], + [19, 68, 6], + [19, 76, 6], + [19, 76, 42], + [19, 77, 25], + [19, 77, 43], + [19, 78, 17], + [19, 78, 24] + ], + [ + [19, 78, 34], + [19, 78, 38] + ], + [ + [19, 78, 41], + [19, 79, 6], + [19, 79, 19], + [19, 79, 24], + [19, 79, 31], + [19, 79, 33] + ], + [], + [ + [19, 81, 4], + [19, 81, 11], + [19, 81, 15], + [19, 81, 33] + ] + ] + }, + "assembly/formatPrint/toJson<~lib/map/Map<~lib/string/String\\2c~lib/array/Array<~lib/array/Array<~lib/string/String>>>>": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 36, + "lineInfo": [ + [ + [19, 2, 2], + [19, 2, 6], + [19, 5, 2], + [19, 5, 6], + [19, 8, 2], + [19, 8, 6], + [19, 11, 2], + [19, 11, 6], + [19, 68, 2], + [19, 68, 6], + [19, 76, 2], + [19, 76, 6], + [19, 83, 2], + [19, 83, 6], + [19, 86, 6], + [19, 86, 24], + [19, 87, 16], + [19, 88, 18], + [19, 89, 25], + [19, 90, 9], + [19, 90, 17], + [23, 69, 28] + ], + [ + [19, 90, 20], + [19, 90, 24] + ], + [ + [19, 90, 36], + [19, 91, 6], + [19, 91, 19], + [19, 91, 24], + [19, 91, 31], + [19, 91, 35], + [19, 91, 41], + [19, 91, 49], + [19, 91, 56], + [19, 91, 62] + ], + [], + [ + [19, 93, 4], + [19, 93, 11], + [19, 93, 16], + [19, 93, 34] + ] + ] + }, + "assembly/formatPrint/toJson<~lib/string/String>": { + "branchInfo": [ + [1, 2], + [1, 44], + [2, 3], + [2, 4], + [5, 6], + [5, 7], + [7, 8], + [7, 9], + [10, 11], + [10, 12], + [12, 13], + [12, 14], + [15, 16], + [15, 17], + [17, 18], + [17, 28], + [18, 19], + [18, 29], + [19, 20], + [19, 30], + [20, 21], + [20, 31], + [21, 22], + [21, 32], + [22, 23], + [22, 33], + [23, 24], + [23, 34], + [24, 25], + [24, 35], + [25, 26], + [25, 36], + [26, 27], + [26, 37], + [39, 40], + [39, 41] + ], + "index": 33, + "lineInfo": [ + [ + [19, 2, 2], + [19, 2, 6], + [19, 5, 2], + [19, 5, 6], + [19, 8, 2], + [19, 8, 6], + [19, 11, 6], + [19, 11, 22], + [19, 12, 24], + [19, 13, 32], + [19, 14, 9], + [19, 14, 17] + ], + [ + [19, 14, 20], + [19, 14, 24] + ], + [ + [19, 15, 6], + [19, 15, 23], + [19, 15, 38], + [19, 17, 9], + [19, 17, 21] + ], + [ + [19, 17, 29], + [19, 17, 41] + ], + [], + [], + [], + [ + [19, 18, 9], + [19, 18, 21] + ], + [ + [19, 18, 29], + [19, 18, 41] + ], + [], + [], + [], + [ + [19, 19, 9], + [19, 19, 21] + ], + [ + [19, 19, 29], + [19, 19, 41] + ], + [], + [], + [ + [19, 21, 8], + [19, 21, 23], + [19, 21, 34] + ], + [ + [19, 23, 16], + [19, 24, 15] + ], + [[19, 27, 15]], + [[19, 30, 15]], + [[19, 33, 15]], + [[19, 36, 15]], + [[19, 39, 15]], + [[19, 42, 15]], + [[19, 45, 15]], + [[19, 48, 15]], + [[19, 51, 15]], + [], + [ + [19, 25, 12], + [19, 25, 27], + [19, 26, 12] + ], + [ + [19, 28, 12], + [19, 28, 27], + [19, 29, 12] + ], + [ + [19, 31, 12], + [19, 31, 27], + [19, 32, 12] + ], + [ + [19, 34, 12], + [19, 34, 27], + [19, 35, 12] + ], + [ + [19, 37, 12], + [19, 37, 27], + [19, 38, 12] + ], + [ + [19, 40, 12], + [19, 40, 27], + [19, 41, 12] + ], + [ + [19, 43, 12], + [19, 43, 27], + [19, 44, 12] + ], + [ + [19, 46, 12], + [19, 46, 27], + [19, 47, 12] + ], + [ + [19, 49, 12], + [19, 49, 27], + [19, 50, 12] + ], + [ + [19, 52, 12], + [19, 52, 27], + [19, 53, 12] + ], + [ + [19, 54, 19], + [19, 56, 32], + [19, 57, 12], + [19, 57, 27], + [19, 58, 17], + [19, 58, 25], + [20, 78, 35] + ], + [ + [19, 58, 45], + [19, 58, 49] + ], + [ + [19, 58, 52], + [19, 59, 14], + [19, 59, 29] + ], + [], + [ + [19, 23, 8], + [19, 61, 12], + [19, 61, 27] + ], + [[19, 14, 36]], + [], + [ + [19, 66, 4], + [19, 66, 11], + [19, 66, 17], + [19, 66, 32], + [19, 66, 38] + ] + ] + }, + "assembly/formatPrint/toJson<~lib/string/String|null>": { + "branchInfo": [ + [0, 1], + [0, 2], + [3, 4], + [3, 46], + [4, 5], + [4, 6], + [7, 8], + [7, 9], + [9, 10], + [9, 11], + [12, 13], + [12, 14], + [14, 15], + [14, 16], + [17, 18], + [17, 19], + [19, 20], + [19, 30], + [20, 21], + [20, 31], + [21, 22], + [21, 32], + [22, 23], + [22, 33], + [23, 24], + [23, 34], + [24, 25], + [24, 35], + [25, 26], + [25, 36], + [26, 27], + [26, 37], + [27, 28], + [27, 38], + [28, 29], + [28, 39], + [41, 42], + [41, 43] + ], + "index": 26, + "lineInfo": [ + [ + [19, 2, 6], + [19, 2, 23], + [19, 2, 28] + ], + [ + [19, 3, 4], + [19, 3, 11] + ], + [ + [19, 5, 2], + [19, 5, 6], + [19, 8, 2], + [19, 8, 6], + [19, 11, 6], + [19, 11, 22], + [19, 12, 24], + [19, 13, 32], + [19, 14, 9], + [19, 14, 17] + ], + [ + [19, 14, 20], + [19, 14, 24] + ], + [ + [19, 15, 6], + [19, 15, 23], + [19, 15, 38], + [19, 17, 9], + [19, 17, 21] + ], + [ + [19, 17, 29], + [19, 17, 41] + ], + [], + [], + [], + [ + [19, 18, 9], + [19, 18, 21] + ], + [ + [19, 18, 29], + [19, 18, 41] + ], + [], + [], + [], + [ + [19, 19, 9], + [19, 19, 21] + ], + [ + [19, 19, 29], + [19, 19, 41] + ], + [], + [], + [ + [19, 21, 8], + [19, 21, 23], + [19, 21, 34] + ], + [ + [19, 23, 16], + [19, 24, 15] + ], + [[19, 27, 15]], + [[19, 30, 15]], + [[19, 33, 15]], + [[19, 36, 15]], + [[19, 39, 15]], + [[19, 42, 15]], + [[19, 45, 15]], + [[19, 48, 15]], + [[19, 51, 15]], + [], + [ + [19, 25, 12], + [19, 25, 27], + [19, 26, 12] + ], + [ + [19, 28, 12], + [19, 28, 27], + [19, 29, 12] + ], + [ + [19, 31, 12], + [19, 31, 27], + [19, 32, 12] + ], + [ + [19, 34, 12], + [19, 34, 27], + [19, 35, 12] + ], + [ + [19, 37, 12], + [19, 37, 27], + [19, 38, 12] + ], + [ + [19, 40, 12], + [19, 40, 27], + [19, 41, 12] + ], + [ + [19, 43, 12], + [19, 43, 27], + [19, 44, 12] + ], + [ + [19, 46, 12], + [19, 46, 27], + [19, 47, 12] + ], + [ + [19, 49, 12], + [19, 49, 27], + [19, 50, 12] + ], + [ + [19, 52, 12], + [19, 52, 27], + [19, 53, 12] + ], + [ + [19, 54, 19], + [19, 56, 32], + [19, 57, 12], + [19, 57, 27], + [19, 58, 17], + [19, 58, 25], + [20, 78, 35] + ], + [ + [19, 58, 45], + [19, 58, 49] + ], + [ + [19, 58, 52], + [19, 59, 14], + [19, 59, 29] + ], + [], + [ + [19, 23, 8], + [19, 61, 12], + [19, 61, 27] + ], + [[19, 14, 36]], + [], + [ + [19, 66, 4], + [19, 66, 11], + [19, 66, 17], + [19, 66, 32], + [19, 66, 38] + ] + ] + }, + "assembly/implement/describeImpl": { + "branchInfo": [], + "index": 29, + "lineInfo": [ + [ + [24, 8, 2], + [24, 8, 30], + [24, 9, 2], + [24, 10, 2] + ] + ] + }, + "assembly/implement/testImpl": { + "branchInfo": [], + "index": 21, + "lineInfo": [ + [ + [24, 13, 2], + [24, 13, 30], + [24, 14, 2], + [24, 15, 2], + [24, 16, 2] + ] + ] + }, + "assembly/index/describe": { + "branchInfo": [], + "index": 30, + "lineInfo": [ + [ + [17, 19, 2], + [17, 19, 15], + [17, 19, 28] + ] + ] + }, + "assembly/index/endTest": { "branchInfo": [], "index": 7, "lineInfo": [[[17, 61, 2]]] }, + "assembly/index/expect": { + "branchInfo": [], + "index": 3, + "lineInfo": [ + [ + [17, 57, 2], + [17, 57, 9], + [17, 57, 22] + ] + ] + }, + "assembly/index/expect": { + "branchInfo": [], + "index": 0, + "lineInfo": [ + [ + [17, 57, 2], + [17, 57, 9], + [17, 57, 22] + ] + ] + }, + "assembly/index/expect<~lib/string/String|null>": { + "branchInfo": [], + "index": 24, + "lineInfo": [ + [ + [17, 57, 2], + [17, 57, 9], + [17, 57, 22] + ] + ] + }, + "assembly/index/test": { + "branchInfo": [], + "index": 22, + "lineInfo": [ + [ + [17, 28, 2], + [17, 28, 11], + [17, 28, 24] + ] + ] + }, + "assembly/output/checkMemory": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 5, + "lineInfo": [ + [ + [25, 45, 9], + [25, 45, 18] + ], + [[25, 45, 40]], + [] + ] + }, + "assembly/output/fromCString": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 6, + "lineInfo": [ + [ + [25, 49, 2], + [25, 49, 13] + ], + [ + [25, 50, 9], + [25, 50, 18], + [25, 50, 28], + [25, 50, 38] + ], + [[25, 51, 4]], + [], + [ + [22, 767, 80], + [25, 50, 2], + [25, 53, 2], + [25, 53, 9], + [25, 53, 34], + [25, 53, 43] + ] + ] + }, + "assembly/output/getArgs": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 40, + "lineInfo": [ + [ + [25, 57, 25], + [25, 60, 2], + [25, 60, 14], + [25, 60, 31], + [25, 60, 49], + [25, 61, 2], + [25, 61, 8], + [25, 61, 23], + [25, 61, 39], + [25, 61, 56], + [25, 62, 2], + [25, 62, 9], + [25, 63, 2], + [25, 63, 15], + [25, 63, 27], + [25, 64, 2], + [25, 64, 26], + [25, 64, 38], + [25, 66, 25], + [25, 66, 41], + [25, 66, 46], + [25, 66, 53], + [25, 66, 58], + [25, 67, 28], + [25, 67, 44], + [25, 68, 2], + [25, 68, 14], + [25, 68, 50], + [25, 68, 51], + [25, 68, 58], + [25, 68, 63], + [25, 69, 2], + [25, 69, 14], + [25, 69, 53], + [25, 70, 2], + [25, 70, 8], + [25, 71, 4], + [25, 72, 4], + [25, 74, 2], + [25, 74, 9], + [25, 75, 7], + [25, 75, 22] + ], + [ + [25, 75, 25], + [25, 75, 29] + ], + [ + [25, 75, 35], + [25, 76, 4], + [25, 76, 21], + [25, 77, 6], + [25, 77, 42], + [25, 77, 46], + [25, 79, 16], + [25, 79, 28], + [25, 80, 4], + [25, 80, 14] + ], + [], + [ + [25, 83, 2], + [25, 83, 9] + ] + ] + }, + "assembly/output/output": { + "branchInfo": [], + "index": 42, + "lineInfo": [ + [ + [25, 21, 27], + [25, 22, 2], + [25, 22, 14], + [25, 23, 2], + [25, 23, 14], + [25, 24, 2], + [25, 24, 14], + [25, 25, 2], + [25, 27, 2], + [25, 29, 23], + [25, 29, 29], + [25, 29, 41], + [25, 29, 48], + [25, 31, 25], + [25, 31, 35], + [25, 31, 44], + [25, 31, 47], + [25, 31, 53], + [25, 32, 2], + [25, 32, 12], + [25, 32, 28] + ] + ] + }, + "assembly/output/perror": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4] + ], + "index": 39, + "lineInfo": [ + [ + [25, 38, 6], + [25, 38, 13] + ], + [[25, 39, 4]], + [[25, 41, 9]], + [ + [25, 41, 16], + [25, 41, 30], + [25, 41, 37], + [25, 41, 43] + ], + [] + ] + }, + "assembly/output/writeFile": { + "branchInfo": [ + [0, 1], + [0, 2], + [3, 4], + [3, 3] + ], + "index": 41, + "lineInfo": [ + [ + [25, 87, 6], + [25, 87, 21] + ], + [[25, 87, 24]], + [ + [22, 697, 63], + [25, 89, 19], + [25, 89, 38], + [25, 91, 2], + [25, 91, 14], + [25, 91, 44], + [25, 92, 2], + [25, 92, 8], + [25, 93, 4], + [25, 94, 4], + [25, 95, 4], + [25, 96, 4], + [25, 97, 4], + [25, 97, 19], + [25, 98, 4], + [25, 99, 6], + [25, 100, 6], + [25, 101, 6], + [25, 102, 6], + [25, 103, 4], + [25, 104, 6], + [25, 105, 6], + [25, 106, 6], + [25, 107, 6], + [25, 108, 4], + [25, 109, 4], + [25, 111, 2], + [25, 111, 9], + [25, 112, 2], + [25, 112, 29], + [25, 112, 38], + [25, 115, 14], + [25, 115, 33], + [25, 117, 2], + [25, 117, 12], + [25, 118, 2], + [25, 118, 16], + [25, 120, 2], + [25, 120, 14], + [25, 120, 39] + ], + [ + [25, 122, 4], + [25, 122, 10], + [25, 122, 19], + [25, 122, 35], + [25, 122, 59], + [25, 122, 62], + [25, 123, 4], + [25, 123, 11], + [25, 124, 4], + [25, 124, 19], + [25, 124, 31], + [25, 125, 4], + [25, 125, 15], + [25, 125, 27], + [25, 126, 11], + [25, 126, 25] + ], + [[25, 121, 2]], + [ + [25, 127, 2], + [25, 127, 11] + ] + ] + } + } +} diff --git a/tests/cpp/lit/build/expect.test.expect.json b/tests/cpp/lit/build/expect.test.expect.json index 57f50bf..5ea750f 100644 --- a/tests/cpp/lit/build/expect.test.expect.json +++ b/tests/cpp/lit/build/expect.test.expect.json @@ -1 +1,13 @@ -{"0":"tests-as/expect.test.ts:8:4","1":"tests-as/expect.test.ts:9:4","10":"tests-as/expect.test.ts:20:4","2":"tests-as/expect.test.ts:10:4","3":"tests-as/expect.test.ts:11:4","4":"tests-as/expect.test.ts:12:4","5":"tests-as/expect.test.ts:13:4","6":"tests-as/expect.test.ts:14:4","7":"tests-as/expect.test.ts:15:4","8":"tests-as/expect.test.ts:16:4","9":"tests-as/expect.test.ts:19:4"} \ No newline at end of file +{ + "0": "tests-as/expect.test.ts:8:4", + "1": "tests-as/expect.test.ts:9:4", + "10": "tests-as/expect.test.ts:20:4", + "2": "tests-as/expect.test.ts:10:4", + "3": "tests-as/expect.test.ts:11:4", + "4": "tests-as/expect.test.ts:12:4", + "5": "tests-as/expect.test.ts:13:4", + "6": "tests-as/expect.test.ts:14:4", + "7": "tests-as/expect.test.ts:15:4", + "8": "tests-as/expect.test.ts:16:4", + "9": "tests-as/expect.test.ts:19:4" +} diff --git a/tests/cpp/lit/build/for_loop.wast.debug.json b/tests/cpp/lit/build/for_loop.wast.debug.json index d66f010..59e17c7 100644 --- a/tests/cpp/lit/build/for_loop.wast.debug.json +++ b/tests/cpp/lit/build/for_loop.wast.debug.json @@ -1 +1,34 @@ -{"debugFiles":["fixture/for-loop.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,4,19]],[[0,4,22],[0,4,30]],[[0,4,37],[0,5,4],[0,5,13]],[[0,4,19]],[[0,7,2],[0,7,11],[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/for-loop.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] + ], + [ + [0, 4, 22], + [0, 4, 30] + ], + [ + [0, 4, 37], + [0, 5, 4], + [0, 5, 13] + ], + [[0, 4, 19]], + [ + [0, 7, 2], + [0, 7, 11], + [0, 8, 9] + ] + ] + } + } +} diff --git a/tests/cpp/lit/build/for_loop.wast.expect.json b/tests/cpp/lit/build/for_loop.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/for_loop.wast.expect.json +++ b/tests/cpp/lit/build/for_loop.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/for_loop_break.wast.debug.json b/tests/cpp/lit/build/for_loop_break.wast.debug.json index 073e44b..a7956dd 100644 --- a/tests/cpp/lit/build/for_loop_break.wast.debug.json +++ b/tests/cpp/lit/build/for_loop_break.wast.debug.json @@ -1 +1,38 @@ -{"debugFiles":["fixture/for-loop-break.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,5],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,4,19]],[[0,4,22],[0,4,30]],[[0,5,8],[0,5,16]],[[0,5,19]],[[0,4,37],[0,6,4],[0,6,13]],[[0,4,19]],[[0,4,19]],[[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/for-loop-break.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 5], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] + ], + [ + [0, 4, 22], + [0, 4, 30] + ], + [ + [0, 5, 8], + [0, 5, 16] + ], + [[0, 5, 19]], + [ + [0, 4, 37], + [0, 6, 4], + [0, 6, 13] + ], + [[0, 4, 19]], + [[0, 4, 19]], + [[0, 8, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/for_loop_break.wast.expect.json b/tests/cpp/lit/build/for_loop_break.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/for_loop_break.wast.expect.json +++ b/tests/cpp/lit/build/for_loop_break.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/for_loop_continue.wast.debug.json b/tests/cpp/lit/build/for_loop_continue.wast.debug.json index 3c23ea8..3cc31e6 100644 --- a/tests/cpp/lit/build/for_loop_continue.wast.debug.json +++ b/tests/cpp/lit/build/for_loop_continue.wast.debug.json @@ -1 +1,39 @@ -{"debugFiles":["fixture/for-loop-continue.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,6],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,4,19]],[[0,4,22],[0,4,30]],[[0,5,8],[0,5,16],[0,5,21]],[[0,5,24]],[[0,4,30],[0,6,4],[0,6,13]],[[0,4,37]],[[0,4,19]],[[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/for-loop-continue.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 6], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] + ], + [ + [0, 4, 22], + [0, 4, 30] + ], + [ + [0, 5, 8], + [0, 5, 16], + [0, 5, 21] + ], + [[0, 5, 24]], + [ + [0, 4, 30], + [0, 6, 4], + [0, 6, 13] + ], + [[0, 4, 37]], + [[0, 4, 19]], + [[0, 8, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/for_loop_continue.wast.expect.json b/tests/cpp/lit/build/for_loop_continue.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/for_loop_continue.wast.expect.json +++ b/tests/cpp/lit/build/for_loop_continue.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/for_loop_return.wast.debug.json b/tests/cpp/lit/build/for_loop_return.wast.debug.json index 3e20712..af38d18 100644 --- a/tests/cpp/lit/build/for_loop_return.wast.debug.json +++ b/tests/cpp/lit/build/for_loop_return.wast.debug.json @@ -1 +1,37 @@ -{"debugFiles":["fixture/for-loop-return.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,5],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,4,19]],[[0,4,22],[0,4,30]],[[0,5,8],[0,5,16]],[[0,5,26]],[[0,4,37],[0,6,4],[0,6,13]],[[0,4,19]],[[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/for-loop-return.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 5], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 4, 19] + ], + [ + [0, 4, 22], + [0, 4, 30] + ], + [ + [0, 5, 8], + [0, 5, 16] + ], + [[0, 5, 26]], + [ + [0, 4, 37], + [0, 6, 4], + [0, 6, 13] + ], + [[0, 4, 19]], + [[0, 8, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/for_loop_return.wast.expect.json b/tests/cpp/lit/build/for_loop_return.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/for_loop_return.wast.expect.json +++ b/tests/cpp/lit/build/for_loop_return.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/if_else.wast.debug.json b/tests/cpp/lit/build/if_else.wast.debug.json index 2bdea0a..ad38ee2 100644 --- a/tests/cpp/lit/build/if_else.wast.debug.json +++ b/tests/cpp/lit/build/if_else.wast.debug.json @@ -1 +1,22 @@ -{"debugFiles":["fixture/if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6]],[[0,5,13]],[[0,7,13]],[[0,9,2]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6] + ], + [[0, 5, 13]], + [[0, 7, 13]], + [[0, 9, 2]] + ] + } + } +} diff --git a/tests/cpp/lit/build/if_else.wast.expect.json b/tests/cpp/lit/build/if_else.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/if_else.wast.expect.json +++ b/tests/cpp/lit/build/if_else.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/if_elseif_else.wast.debug.json b/tests/cpp/lit/build/if_elseif_else.wast.debug.json index 9d85273..47202dd 100644 --- a/tests/cpp/lit/build/if_elseif_else.wast.debug.json +++ b/tests/cpp/lit/build/if_elseif_else.wast.debug.json @@ -1 +1,39 @@ -{"debugFiles":["fixture/if-elseif-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,4],[0,9,14]],[[0,11,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-elseif-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6], + [0, 4, 13] + ], + [ + [0, 5, 4], + [0, 5, 14] + ], + [ + [0, 6, 13], + [0, 6, 20] + ], + [ + [0, 7, 4], + [0, 7, 14] + ], + [ + [0, 9, 4], + [0, 9, 14] + ], + [[0, 11, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/if_elseif_else.wast.expect.json b/tests/cpp/lit/build/if_elseif_else.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/if_elseif_else.wast.expect.json +++ b/tests/cpp/lit/build/if_elseif_else.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json b/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json index 2f6aa47..bed0cb5 100644 --- a/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json +++ b/tests/cpp/lit/build/if_elseif_empty_else.wast.debug.json @@ -1 +1,35 @@ -{"debugFiles":["fixture/if-elseif-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,13],[0,3,20],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,6,13],[0,6,20]],[[0,7,4],[0,7,14]],[[0,9,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-elseif-empty-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 20], + [0, 4, 6], + [0, 4, 13] + ], + [ + [0, 5, 4], + [0, 5, 14] + ], + [ + [0, 6, 13], + [0, 6, 20] + ], + [ + [0, 7, 4], + [0, 7, 14] + ], + [[0, 9, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json b/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json +++ b/tests/cpp/lit/build/if_elseif_empty_else.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/if_empty_else.wast.debug.json b/tests/cpp/lit/build/if_empty_else.wast.debug.json index a72518d..dc227ea 100644 --- a/tests/cpp/lit/build/if_empty_else.wast.debug.json +++ b/tests/cpp/lit/build/if_empty_else.wast.debug.json @@ -1 +1,21 @@ -{"debugFiles":["fixture/if-empty-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,2,13],[0,3,16],[0,4,6]],[[0,5,13]],[[0,7,2]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-empty-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 16], + [0, 4, 6] + ], + [[0, 5, 13]], + [[0, 7, 2]] + ] + } + } +} diff --git a/tests/cpp/lit/build/if_empty_else.wast.expect.json b/tests/cpp/lit/build/if_empty_else.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/if_empty_else.wast.expect.json +++ b/tests/cpp/lit/build/if_empty_else.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/if_multi_condition.wast.debug.json b/tests/cpp/lit/build/if_multi_condition.wast.debug.json index b58a441..ed4bd6a 100644 --- a/tests/cpp/lit/build/if_multi_condition.wast.debug.json +++ b/tests/cpp/lit/build/if_multi_condition.wast.debug.json @@ -1 +1,39 @@ -{"debugFiles":["fixture/if-multi-condition.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[3,4],[3,5],[6,7],[6,8]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,14]],[[0,4,14]],[[0,4,19],[0,4,27]],[],[[0,4,14]],[[0,4,33],[0,4,41]],[],[[0,5,13]],[[0,7,13]],[[0,9,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/if-multi-condition.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [3, 4], + [3, 5], + [6, 7], + [6, 8] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6], + [0, 4, 14] + ], + [[0, 4, 14]], + [ + [0, 4, 19], + [0, 4, 27] + ], + [], + [[0, 4, 14]], + [ + [0, 4, 33], + [0, 4, 41] + ], + [], + [[0, 5, 13]], + [[0, 7, 13]], + [[0, 9, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/if_multi_condition.wast.expect.json b/tests/cpp/lit/build/if_multi_condition.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/if_multi_condition.wast.expect.json +++ b/tests/cpp/lit/build/if_multi_condition.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/include_exclude.wast.debug.json b/tests/cpp/lit/build/include_exclude.wast.debug.json index 5791c54..ec1abbf 100644 --- a/tests/cpp/lit/build/include_exclude.wast.debug.json +++ b/tests/cpp/lit/build/include_exclude.wast.debug.json @@ -1 +1,28 @@ -{"debugFiles":["index.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2]],"index":0,"lineInfo":[[[0,1,1],[0,2,1],[0,3,1]],[[0,4,1],[0,5,1]],[[0,6,1],[0,7,1]],[[0,8,1]]]}}} \ No newline at end of file +{ + "debugFiles": ["index.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 0, + "lineInfo": [ + [ + [0, 1, 1], + [0, 2, 1], + [0, 3, 1] + ], + [ + [0, 4, 1], + [0, 5, 1] + ], + [ + [0, 6, 1], + [0, 7, 1] + ], + [[0, 8, 1]] + ] + } + } +} diff --git a/tests/cpp/lit/build/include_exclude.wast.expect.json b/tests/cpp/lit/build/include_exclude.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/include_exclude.wast.expect.json +++ b/tests/cpp/lit/build/include_exclude.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/multi_func.wast.debug.json b/tests/cpp/lit/build/multi_func.wast.debug.json index ca8f1ae..c82edfe 100644 --- a/tests/cpp/lit/build/multi_func.wast.debug.json +++ b/tests/cpp/lit/build/multi_func.wast.debug.json @@ -1 +1,25 @@ -{"debugFiles":["assembly/add.ts"],"debugInfos":{"assembly/add/add":{"branchInfo":[],"index":2,"lineInfo":[[[0,3,11]]]},"assembly/add/genA":{"branchInfo":[],"index":0,"lineInfo":[[[0,11,11]]]},"assembly/add/main":{"branchInfo":[[0,1],[0,2]],"index":3,"lineInfo":[[[0,15,12],[0,16,8],[0,16,12]],[[0,17,12]],[[0,19,12]],[]]},"assembly/add/min":{"branchInfo":[],"index":1,"lineInfo":[[[0,7,11]]]}}} \ No newline at end of file +{ + "debugFiles": ["assembly/add.ts"], + "debugInfos": { + "assembly/add/add": { "branchInfo": [], "index": 2, "lineInfo": [[[0, 3, 11]]] }, + "assembly/add/genA": { "branchInfo": [], "index": 0, "lineInfo": [[[0, 11, 11]]] }, + "assembly/add/main": { + "branchInfo": [ + [0, 1], + [0, 2] + ], + "index": 3, + "lineInfo": [ + [ + [0, 15, 12], + [0, 16, 8], + [0, 16, 12] + ], + [[0, 17, 12]], + [[0, 19, 12]], + [] + ] + }, + "assembly/add/min": { "branchInfo": [], "index": 1, "lineInfo": [[[0, 7, 11]]] } + } +} diff --git a/tests/cpp/lit/build/multi_func.wast.expect.json b/tests/cpp/lit/build/multi_func.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/multi_func.wast.expect.json +++ b/tests/cpp/lit/build/multi_func.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/multi_if_else.wast.debug.json b/tests/cpp/lit/build/multi_if_else.wast.debug.json index 6c1c53c..4a80a0a 100644 --- a/tests/cpp/lit/build/multi_if_else.wast.debug.json +++ b/tests/cpp/lit/build/multi_if_else.wast.debug.json @@ -1 +1,45 @@ -{"debugFiles":["fixture/multi-if-else.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,2],[2,3],[2,4],[4,5],[4,6]],"index":0,"lineInfo":[[[0,2,13],[0,3,15],[0,4,6],[0,4,13]],[[0,5,4],[0,5,14]],[[0,7,8],[0,7,15]],[[0,8,6],[0,8,16]],[[0,9,15],[0,9,22]],[[0,10,6],[0,10,16]],[]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/multi-if-else.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 2], + [2, 3], + [2, 4], + [4, 5], + [4, 6] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 13], + [0, 3, 15], + [0, 4, 6], + [0, 4, 13] + ], + [ + [0, 5, 4], + [0, 5, 14] + ], + [ + [0, 7, 8], + [0, 7, 15] + ], + [ + [0, 8, 6], + [0, 8, 16] + ], + [ + [0, 9, 15], + [0, 9, 22] + ], + [ + [0, 10, 6], + [0, 10, 16] + ], + [] + ] + } + } +} diff --git a/tests/cpp/lit/build/multi_if_else.wast.expect.json b/tests/cpp/lit/build/multi_if_else.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/multi_if_else.wast.expect.json +++ b/tests/cpp/lit/build/multi_if_else.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/switch_case.wast.debug.json b/tests/cpp/lit/build/switch_case.wast.debug.json index dc110ea..9b1141a 100644 --- a/tests/cpp/lit/build/switch_case.wast.debug.json +++ b/tests/cpp/lit/build/switch_case.wast.debug.json @@ -1 +1,49 @@ -{"debugFiles":["fixture/switch-case.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,4],[1,2],[1,5],[2,3],[2,6]],"index":0,"lineInfo":[[[0,8,13],[0,9,14],[0,10,10],[0,11,9]],[[0,11,9],[0,15,9]],[[0,15,9],[0,18,9]],[[0,18,9]],[[0,12,6],[0,12,15],[0,13,6]],[[0,16,13],[0,16,21]],[[0,19,6],[0,19,15],[0,20,6]],[[0,23,13]],[[0,26,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/switch-case.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 4], + [1, 2], + [1, 5], + [2, 3], + [2, 6] + ], + "index": 0, + "lineInfo": [ + [ + [0, 8, 13], + [0, 9, 14], + [0, 10, 10], + [0, 11, 9] + ], + [ + [0, 11, 9], + [0, 15, 9] + ], + [ + [0, 15, 9], + [0, 18, 9] + ], + [[0, 18, 9]], + [ + [0, 12, 6], + [0, 12, 15], + [0, 13, 6] + ], + [ + [0, 16, 13], + [0, 16, 21] + ], + [ + [0, 19, 6], + [0, 19, 15], + [0, 20, 6] + ], + [[0, 23, 13]], + [[0, 26, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/switch_case.wast.expect.json b/tests/cpp/lit/build/switch_case.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/switch_case.wast.expect.json +++ b/tests/cpp/lit/build/switch_case.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json b/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json index 725d2c8..4ff1773 100644 --- a/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json +++ b/tests/cpp/lit/build/switch_case_fallthrough.wast.debug.json @@ -1 +1,45 @@ -{"debugFiles":["fixture/switch-case-fallthrough.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,4],[1,2],[1,5],[2,3],[2,6]],"index":0,"lineInfo":[[[0,8,13],[0,9,14],[0,10,10],[0,11,9]],[[0,11,9],[0,15,9]],[[0,15,9],[0,16,9]],[[0,16,9]],[[0,12,6],[0,12,15],[0,13,6]],[[0,10,2]],[[0,17,6],[0,17,15],[0,18,6]],[[0,21,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/switch-case-fallthrough.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 4], + [1, 2], + [1, 5], + [2, 3], + [2, 6] + ], + "index": 0, + "lineInfo": [ + [ + [0, 8, 13], + [0, 9, 14], + [0, 10, 10], + [0, 11, 9] + ], + [ + [0, 11, 9], + [0, 15, 9] + ], + [ + [0, 15, 9], + [0, 16, 9] + ], + [[0, 16, 9]], + [ + [0, 12, 6], + [0, 12, 15], + [0, 13, 6] + ], + [[0, 10, 2]], + [ + [0, 17, 6], + [0, 17, 15], + [0, 18, 6] + ], + [[0, 21, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json b/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json +++ b/tests/cpp/lit/build/switch_case_fallthrough.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/switch_case_rdefault.wast.debug.json b/tests/cpp/lit/build/switch_case_rdefault.wast.debug.json index 9d9927f..280a716 100644 --- a/tests/cpp/lit/build/switch_case_rdefault.wast.debug.json +++ b/tests/cpp/lit/build/switch_case_rdefault.wast.debug.json @@ -1 +1,53 @@ -{"debugFiles":["fixture/switch-case-rdefault.ts"],"debugInfos":{"main":{"branchInfo":[[0,1],[0,5],[1,2],[1,6],[2,3],[2,7]],"index":0,"lineInfo":[[[0,8,13],[0,9,14],[0,10,10],[0,14,9]],[[0,14,9],[0,18,9]],[[0,18,9],[0,22,9]],[[0,22,9]],[[0,12,13],[0,12,21]],[[0,15,6],[0,15,15],[0,16,6]],[[0,19,6],[0,19,15],[0,20,6]],[[0,23,6],[0,23,15],[0,24,6]],[[0,27,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/switch-case-rdefault.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [0, 1], + [0, 5], + [1, 2], + [1, 6], + [2, 3], + [2, 7] + ], + "index": 0, + "lineInfo": [ + [ + [0, 8, 13], + [0, 9, 14], + [0, 10, 10], + [0, 14, 9] + ], + [ + [0, 14, 9], + [0, 18, 9] + ], + [ + [0, 18, 9], + [0, 22, 9] + ], + [[0, 22, 9]], + [ + [0, 12, 13], + [0, 12, 21] + ], + [ + [0, 15, 6], + [0, 15, 15], + [0, 16, 6] + ], + [ + [0, 19, 6], + [0, 19, 15], + [0, 20, 6] + ], + [ + [0, 23, 6], + [0, 23, 15], + [0, 24, 6] + ], + [[0, 27, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/switch_case_rdefault.wast.expect.json b/tests/cpp/lit/build/switch_case_rdefault.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/switch_case_rdefault.wast.expect.json +++ b/tests/cpp/lit/build/switch_case_rdefault.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/while.wast.debug.json b/tests/cpp/lit/build/while.wast.debug.json index f84f7df..f57c598 100644 --- a/tests/cpp/lit/build/while.wast.debug.json +++ b/tests/cpp/lit/build/while.wast.debug.json @@ -1 +1,33 @@ -{"debugFiles":["fixture/while.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,3]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,4,9],[0,4,17]],[[0,5,4],[0,6,4],[0,6,13]],[[0,4,2]],[[0,4,2],[0,8,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/while.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 3] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] + ], + [ + [0, 4, 9], + [0, 4, 17] + ], + [ + [0, 5, 4], + [0, 6, 4], + [0, 6, 13] + ], + [[0, 4, 2]], + [ + [0, 4, 2], + [0, 8, 9] + ] + ] + } + } +} diff --git a/tests/cpp/lit/build/while.wast.expect.json b/tests/cpp/lit/build/while.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/while.wast.expect.json +++ b/tests/cpp/lit/build/while.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/while_break.wast.debug.json b/tests/cpp/lit/build/while_break.wast.debug.json index eacf70a..be4d6e2 100644 --- a/tests/cpp/lit/build/while_break.wast.debug.json +++ b/tests/cpp/lit/build/while_break.wast.debug.json @@ -1 +1,38 @@ -{"debugFiles":["fixture/while-break.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,5],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,4,9],[0,4,17]],[[0,5,4],[0,6,8],[0,6,16]],[[0,6,19]],[[0,7,4],[0,7,13]],[[0,4,2]],[[0,4,2]],[[0,9,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/while-break.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 5], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] + ], + [ + [0, 4, 9], + [0, 4, 17] + ], + [ + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] + ], + [[0, 6, 19]], + [ + [0, 7, 4], + [0, 7, 13] + ], + [[0, 4, 2]], + [[0, 4, 2]], + [[0, 9, 9]] + ] + } + } +} diff --git a/tests/cpp/lit/build/while_break.wast.expect.json b/tests/cpp/lit/build/while_break.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/while_break.wast.expect.json +++ b/tests/cpp/lit/build/while_break.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null diff --git a/tests/cpp/lit/build/while_continue.wast.debug.json b/tests/cpp/lit/build/while_continue.wast.debug.json index 44cdebe..3d2032a 100644 --- a/tests/cpp/lit/build/while_continue.wast.debug.json +++ b/tests/cpp/lit/build/while_continue.wast.debug.json @@ -1 +1,40 @@ -{"debugFiles":["fixture/while-continue.ts"],"debugInfos":{"main":{"branchInfo":[[1,2],[1,5],[2,3],[2,4]],"index":0,"lineInfo":[[[0,2,14],[0,3,14],[0,3,25]],[[0,4,9],[0,4,17]],[[0,5,4],[0,6,8],[0,6,16]],[[0,6,19]],[[0,7,4],[0,7,13]],[[0,4,2]],[[0,4,2],[0,9,9]]]}}} \ No newline at end of file +{ + "debugFiles": ["fixture/while-continue.ts"], + "debugInfos": { + "main": { + "branchInfo": [ + [1, 2], + [1, 5], + [2, 3], + [2, 4] + ], + "index": 0, + "lineInfo": [ + [ + [0, 2, 14], + [0, 3, 14], + [0, 3, 25] + ], + [ + [0, 4, 9], + [0, 4, 17] + ], + [ + [0, 5, 4], + [0, 6, 8], + [0, 6, 16] + ], + [[0, 6, 19]], + [ + [0, 7, 4], + [0, 7, 13] + ], + [[0, 4, 2]], + [ + [0, 4, 2], + [0, 9, 9] + ] + ] + } + } +} diff --git a/tests/cpp/lit/build/while_continue.wast.expect.json b/tests/cpp/lit/build/while_continue.wast.expect.json index ec747fa..19765bd 100644 --- a/tests/cpp/lit/build/while_continue.wast.expect.json +++ b/tests/cpp/lit/build/while_continue.wast.expect.json @@ -1 +1 @@ -null \ No newline at end of file +null From 5f3ca351c678cc14a766ac101ae07c4f954f7f8d Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 21:24:47 +0800 Subject: [PATCH 10/14] install gtest --- .github/workflows/publish.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 7544559..5be9290 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,6 +12,8 @@ jobs: - uses: actions/checkout@v4 with: submodules: true + - run: sudo apt-get install libgtest-dev + - uses: actions/setup-node@v3 with: node-version: 20 From f0cbe475fccde2d9ba69cc08dccafefbfee27b8b Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 21:25:33 +0800 Subject: [PATCH 11/14] install gtest --- .github/workflows/ci-test.yml | 1 + .github/workflows/publish.yml | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-test.yml b/.github/workflows/ci-test.yml index c925472..ff9822f 100644 --- a/.github/workflows/ci-test.yml +++ b/.github/workflows/ci-test.yml @@ -17,6 +17,7 @@ jobs: node-version: 20 - run: npm ci + - run: sudo apt-get install libgtest-dev - run: npm run lint - run: npm run build diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 5be9290..417afdb 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,7 +12,6 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - - run: sudo apt-get install libgtest-dev - uses: actions/setup-node@v3 with: From 79799cdc4ae72aee66df608f8daccebacbfeb166 Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 21:26:47 +0800 Subject: [PATCH 12/14] fix --- .github/workflows/publish.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 417afdb..dba6188 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: true - + - uses: actions/setup-node@v3 with: node-version: 20 From 0c346367a1ee3c76e3608907eedc03bc6ed3c64c Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 21:49:56 +0800 Subject: [PATCH 13/14] fix --- tests/cpp/CMakeLists.txt | 34 ---------------------------------- 1 file changed, 34 deletions(-) diff --git a/tests/cpp/CMakeLists.txt b/tests/cpp/CMakeLists.txt index 8072c76..614a74b 100644 --- a/tests/cpp/CMakeLists.txt +++ b/tests/cpp/CMakeLists.txt @@ -17,37 +17,3 @@ target_link_libraries( ) include(GoogleTest) gtest_discover_tests(wasm-instrumentation-test) - -if(ENABLE_E2E) - add_custom_target(npm-install ALL - COMMAND npm install - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test-asc - ) - add_custom_target(compile-asc ALL - DEPENDS npm-install - COMMAND npm run ascbuild - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test-asc - ) - add_dependencies(wasm-instrumentation-test copy-files) - add_custom_target(copy-files ALL - DEPENDS compile-asc - COMMAND ${CMAKE_COMMAND} -E copy_directory - ${CMAKE_CURRENT_SOURCE_DIR}/test-asc/build - ${CMAKE_CURRENT_BINARY_DIR}/test-asc/build - ) -endif() - -if(CMAKE_COMPILER_IS_GNUCXX) - LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) - include(CodeCoverage) - APPEND_COVERAGE_COMPILER_FLAGS() - setup_target_for_coverage_gcovr_xml(NAME cov - EXECUTABLE wasm-instrumentation-test - DEPENDENCIES wasm-instrumentation-test - BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/instrumentation") - - setup_target_for_coverage_gcovr_html(NAME cov_html - EXECUTABLE wasm-instrumentation-test - DEPENDENCIES wasm-instrumentation-test - BASE_DIRECTORY "${PROJECT_SOURCE_DIR}/instrumentation") -endif() From 6ed353c4f71ca6cbae9b66f7d0e7d34b2b21b48a Mon Sep 17 00:00:00 2001 From: Congcong Cai Date: Mon, 17 Feb 2025 22:23:46 +0800 Subject: [PATCH 14/14] fix include --- tests/cpp/utils/utils.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/tests/cpp/utils/utils.cpp b/tests/cpp/utils/utils.cpp index cbe7114..27ff53a 100644 --- a/tests/cpp/utils/utils.cpp +++ b/tests/cpp/utils/utils.cpp @@ -1,4 +1,7 @@ #include "utils.h" +#include "json/value.h" +#include +#include namespace testUtils {