diff --git a/assembly.d.ts b/assembly.d.ts index a29e6547..7c3fa266 100644 --- a/assembly.d.ts +++ b/assembly.d.ts @@ -1,4 +1,6 @@ -// types +// Definitions for the "AssemblyScript" subset. + +// Types /** An 8-bit signed integer. */ declare type i8 = number; @@ -27,7 +29,7 @@ declare type f32 = number; /** A 64-bit float. */ declare type f64 = number; -// built-ins +// Built-ins /** Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero. */ declare function clz(value: T): T; @@ -84,10 +86,10 @@ declare function changetype(value: T1): T2; declare function isNaN(value: T): bool; /** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */ declare function isFinite(value: T): bool; -/** Traps if the specified value is `false`. */ +/** Traps if the specified value evaluates to `false`. */ declare function assert(isTrue: bool): void; -// internal decorators +// Internal decorators /** Annotates an element being part of the global namespace. */ declare function global(): any; @@ -96,7 +98,7 @@ declare function inline(): any; /** Annotates a class using a C-style memory layout. */ declare function struct(): any; -// standard library +// Standard library /// /// diff --git a/portable-assembly.d.ts b/portable-assembly.d.ts new file mode 100644 index 00000000..5f1f102d --- /dev/null +++ b/portable-assembly.d.ts @@ -0,0 +1,48 @@ +// Definitions for the "portable AssemblyScript" subset. + +// Portable types + +// Note that semantics differences require additional explicit conversions for full compatibility. +// For example, when casting an i32 to an u8, doing `(someI32 & 0xff)` will yield the same +// result when compiling to WebAssembly or JS while `someI32` alone does nothing in JS. + +// Note that i64's are not portable (JS numbers are IEEE754 doubles with a maximum safe integer value +// of 2^53-1) and instead require a compatibility layer to work in JS as well. See: src/util/i64.ts + +declare type i8 = number; +declare type u8 = number; +declare type i16 = number; +declare type u16 = number; +declare type i32 = number; +declare type u32 = number; +declare type isize = number; +declare type usize = number; +declare type f32 = number; +declare type f64 = number; +declare type bool = boolean; + +// Portable built-ins + +/** Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero. */ +declare function clz(value: T): T; +/** Computes the absolute value of an integer or float. */ +declare function abs(value: T): T; +/** Determines the maximum of two integers or floats. If either operand is `NaN`, returns `NaN`. */ +declare function max(left: T, right: T): T; +/** Determines the minimum of two integers or floats. If either operand is `NaN`, returns `NaN`. */ +declare function min(left: T, right: T): T; +/** Performs the ceiling operation on a 32-bit or 64-bit float. */ +declare function ceil(value: T): T; +/** Performs the floor operation on a 32-bit or 64-bit float. */ +declare function floor(value: T): T; +/** Selects one of two pre-evaluated values depending on the condition. */ +declare function select(ifTrue: T, ifFalse: T, condition: bool): T; +/** Calculates the square root of a 32-bit or 64-bit float. */ +declare function sqrt(value: T): T; +/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */ +declare function trunc(value: T): T; +/** Emits an unreachable operation that results in a runtime error when executed. */ +declare function unreachable(): any; // sic + +/** Traps if the specified value evaluates to `false`. */ +declare function assert(isTrue: bool): void; diff --git a/portable-assembly.js b/portable-assembly.js new file mode 100644 index 00000000..1c0e6c1f --- /dev/null +++ b/portable-assembly.js @@ -0,0 +1,29 @@ +var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self; + +globalScope["clz"] = Math.clz32; +globalScope["abs"] = Math.abs; +globalScope["max"] = Math.max; +globalScope["min"] = Math.min; +globalScope["ceil"] = Math.ceil; +globalScope["floor"] = Math.floor; +globalScope["select"] = function select(ifTrue, ifFalse, condition) { return condition ? ifTrue : ifFalse; }; +globalScope["sqrt"] = Math.sqrt; +globalScope["trunc"] = Math.trunc; + +function UnreachableError() { + this.stack = new Error().stack; +} +UnreachableError.prototype = new Error; +UnreachableError.prototype.name = "UnreachableError"; +UnreachableError.prototype.message = "unreachable"; + +globalScope["unreachable"] = function unreachable() { throw new UnreachableError(); }; + +function AssertionError() { + this.stack = new Error().stack; +} +AssertionError.prototype = new Error; +AssertionError.prototype.name = "AssertionError"; +AssertionError.prototype.message = "assertion failed"; + +globalScope["assert"] = function assert(isTrue) { if (!isTrue) throw new AssertionError(); }; diff --git a/src/compiler.ts b/src/compiler.ts index 5781904d..9fff4bc8 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1424,6 +1424,7 @@ export class Compiler extends DiagnosticEmitter { case Token.AMPERSAND_AMPERSAND: // left && right left = this.compileExpression(expression.left, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT); right = this.compileExpression(expression.right, this.currentType); + // TODO: once it's possible to clone 'left', we could check if it is a Const, GetLocal, GetGlobal or Load and avoid the tempLocal tempLocal = this.currentFunction.addLocal(this.currentType); return this.module.createIf( this.currentType.isLongInteger @@ -1440,6 +1441,7 @@ export class Compiler extends DiagnosticEmitter { case Token.BAR_BAR: // left || right left = this.compileExpression(expression.left, contextualType, contextualType == Type.void ? ConversionKind.NONE : ConversionKind.IMPLICIT); right = this.compileExpression(expression.right, this.currentType); + // TODO: same as above tempLocal = this.currentFunction.addLocal(this.currentType); return this.module.createIf( this.currentType.isLongInteger diff --git a/src/glue/binaryen.d.ts b/src/glue/binaryen-c.d.ts similarity index 100% rename from src/glue/binaryen.d.ts rename to src/glue/binaryen-c.d.ts diff --git a/src/glue/js.d.ts b/src/glue/js.d.ts index 7fb052f5..6f07721b 100644 --- a/src/glue/js.d.ts +++ b/src/glue/js.d.ts @@ -1,20 +1,6 @@ -// Aliased AssemblyScript types. Beware of semantic differences. -declare type i8 = number; -declare type u8 = number; -declare type i16 = number; -declare type u16 = number; -declare type i32 = number; -declare type u32 = number; -declare type isize = number; -declare type usize = number; -declare type f32 = number; -declare type f64 = number; -declare type bool = boolean; +/// +/// -// Raw memory access (here: Binaryen memory) +// Raw memory accesses to Binaryen memory declare function store(ptr: usize, val: T): void; declare function load(ptr: usize): T; -declare function assert(isTrue: bool): void; - -// Other things that might or might not be useful -declare function select(ifTrue: T, ifFalse: T, condition: bool): T; diff --git a/src/glue/js.js b/src/glue/js.js new file mode 100644 index 00000000..78803912 --- /dev/null +++ b/src/glue/js.js @@ -0,0 +1,42 @@ +require("../../portable-assembly"); + +var globalScope = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self; + +var binaryen; +try { + binaryen = require("binaryen"); +} catch (e) { + binaryen = globalScope["Binaryen"]; +} +for (var key in binaryen) + if (/^_(?:Binaryen|Relooper|malloc$|free$)/.test(key)) + globalScope[key] = binaryen[key]; + +globalScope["store"] = function store(ptr, val) { + binaryen.HEAPU8[ptr] = val; +}; + +globalScope["load"] = function load_u8(ptr) { + return binaryen.HEAPU8[ptr]; +}; + +var Module = require("../module").Module; + +Module.prototype.toBinary = function toBinary(bufferSize) { + if (!bufferSize) bufferSize = 1024 * 1024; + var ptr = _malloc(bufferSize); + var len = this.write(ptr, bufferSize); + var ret = new Uint8Array(len); + ret.set(binaryen.HEAPU8.subarray(ptr, ptr + len)); + _free(ptr); + return ret; +} + +Module.prototype.toText = function toText() { + var previousPrint = binaryen.print; + var ret = ""; + binaryen.print = function print(x) { ret += x + "\n" }; + this.print(); + binaryen.print = previousPrint; + return ret; +} diff --git a/src/glue/js.ts b/src/glue/js.ts deleted file mode 100644 index fe6b7801..00000000 --- a/src/glue/js.ts +++ /dev/null @@ -1,47 +0,0 @@ -const globalScope: any = typeof window !== "undefined" && window || typeof global !== "undefined" && global || self; - -globalScope["store"] = function store_u8(ptr: number, val: number) { - binaryen.HEAPU8[ptr] = val; -}; - -globalScope["load"] = function load_u8(ptr: number) { - return binaryen.HEAPU8[ptr]; -}; - -globalScope["select"] = function select(ifTrue: T, ifFalse: T, condition: bool): T { - return condition ? ifTrue : ifFalse; -}; - -globalScope["assert"] = function(isTrue: bool): void { - if (!isTrue) throw new Error("assertion failed"); -}; - -let binaryen: any; -try { - binaryen = require("binaryen"); -} catch (e) { - binaryen = globalScope["Binaryen"]; -} -for (const key in binaryen) - if (/^_(?:Binaryen|Relooper|malloc$|free$)/.test(key)) - globalScope[key] = binaryen[key]; - -import { Module } from "../module"; - -Module.prototype.toBinary = function(bufferSize = 1048576): Uint8Array { - const ptr = _malloc(bufferSize); - const len = this.write(ptr, bufferSize); - const ret = new Uint8Array(len); - ret.set(binaryen.HEAPU8.subarray(ptr, ptr + len)); - _free(ptr); - return ret; -} - -Module.prototype.toText = function(): string { - let previousPrint: any = (binaryen)["print"]; - let ret: string = ""; - binaryen["print"] = function(x: string): void { ret += x + "\n" }; - this.print(); - binaryen["print"] = previousPrint; - return ret; -} diff --git a/src/glue/wasm.ts b/src/glue/wasm.ts deleted file mode 100644 index e69de29b..00000000 diff --git a/src/module.ts b/src/module.ts index 9f033fa8..15fa61b3 100644 --- a/src/module.ts +++ b/src/module.ts @@ -701,10 +701,13 @@ export class Module { } optimize(func: FunctionRef = 0): void { - if (func) + // see: https://github.com/WebAssembly/binaryen/issues/1331#issuecomment-350328175 + this.runPasses([ "flatten", "ssa" ], func); + if (func) { _BinaryenFunctionOptimize(func, this.ref); - else + } else { _BinaryenModuleOptimize(this.ref); + } } runPasses(passes: string[], func: FunctionRef = 0): void { diff --git a/src/tsconfig.json b/src/tsconfig.json index 1f0bb019..01693dcb 100644 --- a/src/tsconfig.json +++ b/src/tsconfig.json @@ -27,9 +27,7 @@ "diagnosticMessages.generated.ts", "diagnostics.ts", "evaluator.ts", - "glue/binaryen.d.ts", "glue/js.d.ts", - "glue/js.ts", "index.ts", "module.ts", "parser.ts", @@ -43,11 +41,7 @@ ], "assembly": { "exclude": [ - "glue/js.d.ts", - "glue/js.ts" - ], - "include": [ - "glue/wasm.ts" + "glue/js.d.ts" ] } } diff --git a/std/impl/heap.ts b/std/impl/heap.ts index 25be5ca4..aa351d8b 100644 --- a/std/impl/heap.ts +++ b/std/impl/heap.ts @@ -42,7 +42,7 @@ class Heap { let w: u32, x: u32; // copy 1 byte each until src is aligned to 4 bytes - while (n != 0 && src % 4 != 0) { + while (n && src % 4) { store(dst++, load(src++)); n--; } diff --git a/tests/binaryen.ts b/tests/binaryen.ts index 68e740f8..1c597094 100644 --- a/tests/binaryen.ts +++ b/tests/binaryen.ts @@ -1,4 +1,4 @@ -/// +/// import "../src/glue/js"; import { NativeType, Module, MemorySegment, BinaryOp } from "../src/module"; @@ -19,13 +19,13 @@ mod.addFunction("add", add, [], mod.createReturn( mod.createGetLocal(1, NativeType.I32) ) )); -mod.addExport("add", "add"); +mod.addFunctionExport("add", "add"); const lit = mod.addFunctionType("I", NativeType.I64, []); mod.addFunction("lit", lit, [], mod.createReturn( mod.createI64(0, 0x80000000) // I64_MIN )); -mod.addExport("lit", "lit"); +mod.addFunctionExport("lit", "lit"); mod.addGlobal("42", NativeType.I32, false, mod.createI32(42)); @@ -42,7 +42,7 @@ mod.addFunction("aSwitch", aSwitch, [ NativeType.I32 ], mod.createBlock(null, [ rl.renderAndDispose(b0, 1), mod.createUnreachable() ])); -mod.addExport("aSwitch", "aSwitch"); +mod.addFunctionExport("aSwitch", "aSwitch"); // mod.optimize(); if (mod.validate()) diff --git a/tests/compiler.ts b/tests/compiler.ts index 1232a54f..e5486ed9 100644 --- a/tests/compiler.ts +++ b/tests/compiler.ts @@ -1,5 +1,3 @@ -/// - import * as fs from "fs"; import * as path from "path"; import * as chalk from "chalk"; diff --git a/tests/compiler/do.optimized.wast b/tests/compiler/do.optimized.wast index 9d4d7f5e..279653c0 100644 --- a/tests/compiler/do.optimized.wast +++ b/tests/compiler/do.optimized.wast @@ -5,11 +5,15 @@ (export "loopDoInDo" (func $do/loopDoInDo)) (export "memory" (memory $0)) (func $do/loopDo (; 0 ;) (type $iv) (param $0 i32) + (local $1 i32) + (set_local $1 + (get_local $0) + ) (loop $continue|0 (br_if $continue|0 - (tee_local $0 + (tee_local $1 (i32.sub - (get_local $0) + (get_local $1) (i32.const 1) ) ) @@ -17,8 +21,10 @@ ) ) (func $do/loopDoInDo (; 1 ;) (type $iv) (param $0 i32) + (local $1 i32) + (local $2 i32) (loop $continue|0 - (set_local $0 + (set_local $1 (i32.sub (get_local $0) (i32.const 1) @@ -26,16 +32,20 @@ ) (loop $continue|1 (br_if $continue|1 - (tee_local $0 - (i32.sub - (get_local $0) - (i32.const 1) + (tee_local $2 + (tee_local $1 + (tee_local $0 + (i32.sub + (get_local $1) + (i32.const 1) + ) + ) ) ) ) ) (br_if $continue|0 - (get_local $0) + (get_local $2) ) ) ) diff --git a/tests/compiler/game-of-life.optimized.wast b/tests/compiler/game-of-life.optimized.wast index 3078cae6..35b9922a 100644 --- a/tests/compiler/game-of-life.optimized.wast +++ b/tests/compiler/game-of-life.optimized.wast @@ -100,7 +100,7 @@ (get_local $4) (get_global $game-of-life/w) ) - (tee_local $2 + (tee_local $3 (select (i32.sub (get_local $1) @@ -128,7 +128,7 @@ (get_local $4) (get_global $game-of-life/w) ) - (tee_local $3 + (tee_local $2 (select (i32.const 0) (i32.add @@ -150,7 +150,7 @@ (get_local $0) (get_global $game-of-life/w) ) - (get_local $2) + (get_local $3) ) ) ) @@ -160,7 +160,7 @@ (get_local $0) (get_global $game-of-life/w) ) - (get_local $3) + (get_local $2) ) ) ) @@ -170,7 +170,7 @@ (get_local $5) (get_global $game-of-life/w) ) - (get_local $2) + (get_local $3) ) ) ) @@ -190,7 +190,7 @@ (get_local $5) (get_global $game-of-life/w) ) - (get_local $3) + (get_local $2) ) ) ) @@ -205,32 +205,38 @@ (get_local $1) ) ) - (if - (if (result i32) - (tee_local $3 - (i32.lt_s - (get_local $2) - (i32.const 2) - ) - ) - (get_local $3) - (i32.gt_s - (get_local $2) - (i32.const 3) - ) - ) - (i32.store8 - (i32.add - (i32.add - (get_global $game-of-life/s) - (i32.mul - (get_local $0) - (get_global $game-of-life/w) + (block + (if + (i32.eqz + (tee_local $3 + (i32.lt_s + (get_local $2) + (i32.const 2) ) ) - (get_local $1) ) - (i32.const 0) + (set_local $3 + (i32.gt_s + (get_local $2) + (i32.const 3) + ) + ) + ) + (if + (get_local $3) + (i32.store8 + (i32.add + (i32.add + (get_global $game-of-life/s) + (i32.mul + (get_local $0) + (get_global $game-of-life/w) + ) + ) + (get_local $1) + ) + (i32.const 0) + ) ) ) (if diff --git a/tests/compiler/logical.optimized.wast b/tests/compiler/logical.optimized.wast index 3c0bd69b..0b2f268e 100644 --- a/tests/compiler/logical.optimized.wast +++ b/tests/compiler/logical.optimized.wast @@ -44,46 +44,48 @@ ) (unreachable) ) + (if + (tee_local $0 + (i32.const 1) + ) + (set_local $0 + (i32.const 2) + ) + ) (if (i32.eqz - (if (result i32) - (tee_local $0 - (i32.const 1) - ) - (tee_local $0 - (i32.const 2) - ) - (get_local $0) - ) + (get_local $0) ) (unreachable) ) (if - (f64.eq - (if (result f64) - (f64.ne - (tee_local $1 - (f64.const 1) - ) - (f64.const 0) - ) - (tee_local $1 - (f64.const 2) - ) - (get_local $1) + (f64.ne + (tee_local $1 + (f64.const 1) ) (f64.const 0) ) + (set_local $1 + (f64.const 2) + ) + ) + (if + (f64.eq + (get_local $1) + (f64.const 0) + ) (unreachable) ) - (set_global $logical/i - (if (result i32) - (tee_local $0 - (i32.const 1) - ) - (i32.const 2) - (get_local $0) + (if + (tee_local $0 + (i32.const 1) ) + (set_local $0 + (i32.const 2) + ) + ) + (set_global $logical/i + (get_local $0) ) (if (i32.ne @@ -92,15 +94,19 @@ ) (unreachable) ) - (set_global $logical/i - (if (result i32) + (if + (i32.eqz (tee_local $0 (i32.const 0) ) - (get_local $0) + ) + (set_local $0 (i32.const 1) ) ) + (set_global $logical/i + (get_local $0) + ) (if (i32.ne (get_global $logical/i) @@ -108,17 +114,19 @@ ) (unreachable) ) - (set_global $logical/I - (if (result i64) - (i64.ne - (tee_local $2 - (i64.const 1) - ) - (i64.const 0) + (if + (i64.ne + (tee_local $2 + (i64.const 1) ) - (i64.const 2) - (get_local $2) + (i64.const 0) ) + (set_local $2 + (i64.const 2) + ) + ) + (set_global $logical/I + (get_local $2) ) (if (i64.ne @@ -127,18 +135,20 @@ ) (unreachable) ) - (set_global $logical/I - (if (result i64) - (i64.ne - (tee_local $2 - (i64.const 0) - ) + (if + (i64.eq + (tee_local $2 (i64.const 0) ) - (get_local $2) + (i64.const 0) + ) + (set_local $2 (i64.const 1) ) ) + (set_global $logical/I + (get_local $2) + ) (if (i64.ne (get_global $logical/I) @@ -146,17 +156,19 @@ ) (unreachable) ) - (set_global $logical/f - (if (result f32) - (f32.ne - (tee_local $3 - (f32.const 1) - ) - (f32.const 0) + (if + (f32.ne + (tee_local $3 + (f32.const 1) ) - (f32.const 2) - (get_local $3) + (f32.const 0) ) + (set_local $3 + (f32.const 2) + ) + ) + (set_global $logical/f + (get_local $3) ) (if (f32.ne @@ -165,18 +177,20 @@ ) (unreachable) ) - (set_global $logical/f - (if (result f32) - (f32.ne - (tee_local $3 - (f32.const 0) - ) + (if + (f32.eq + (tee_local $3 (f32.const 0) ) - (get_local $3) + (f32.const 0) + ) + (set_local $3 (f32.const 1) ) ) + (set_global $logical/f + (get_local $3) + ) (if (f32.ne (get_global $logical/f) @@ -184,17 +198,19 @@ ) (unreachable) ) + (if + (f64.ne + (tee_local $1 + (f64.const 1) + ) + (f64.const 0) + ) + (set_local $1 + (f64.const 2) + ) + ) (set_global $logical/F - (if (result f64) - (f64.ne - (tee_local $1 - (f64.const 1) - ) - (f64.const 0) - ) - (f64.const 2) - (get_local $1) - ) + (get_local $1) ) (if (f64.ne @@ -203,18 +219,20 @@ ) (unreachable) ) - (set_global $logical/F - (if (result f64) - (f64.ne - (tee_local $1 - (f64.const 0) - ) + (if + (f64.eq + (tee_local $1 (f64.const 0) ) - (get_local $1) + (f64.const 0) + ) + (set_local $1 (f64.const 1) ) ) + (set_global $logical/F + (get_local $1) + ) (if (f64.ne (get_global $logical/F) diff --git a/tests/compiler/memcpy.optimized.wast b/tests/compiler/memcpy.optimized.wast index dcfb3e07..02ab6bb0 100644 --- a/tests/compiler/memcpy.optimized.wast +++ b/tests/compiler/memcpy.optimized.wast @@ -10,50 +10,248 @@ (local $3 i32) (local $4 i32) (local $5 i32) - (set_local $4 - (get_local $0) + (local $6 i32) + (local $7 i32) + (local $8 i32) + (local $9 i32) + (local $10 i32) + (local $11 i32) + (local $12 i32) + (local $13 i32) + (local $14 i32) + (local $15 i32) + (local $16 i32) + (local $17 i32) + (local $18 i32) + (local $19 i32) + (local $20 i32) + (local $21 i32) + (local $22 i32) + (local $23 i32) + (local $24 i32) + (local $25 i32) + (local $26 i32) + (local $27 i32) + (local $28 i32) + (local $29 i32) + (local $30 i32) + (local $31 i32) + (local $32 i32) + (local $33 i32) + (local $34 i32) + (local $35 i32) + (local $36 i32) + (local $37 i32) + (local $38 i32) + (local $39 i32) + (set_local $23 + (get_local $2) + ) + (set_local $16 + (get_local $2) + ) + (set_local $30 + (get_local $2) + ) + (set_local $31 + (get_local $2) + ) + (set_local $32 + (get_local $2) + ) + (set_local $33 + (get_local $2) + ) + (set_local $34 + (get_local $2) + ) + (set_local $35 + (get_local $2) + ) + (set_local $36 + (get_local $2) + ) + (set_local $37 + (get_local $2) + ) + (set_local $38 + (get_local $2) + ) + (set_local $39 + (get_local $2) + ) + (set_local $11 + (get_local $2) + ) + (set_local $19 + (get_local $2) + ) + (set_local $20 + (get_local $2) + ) + (set_local $21 + (get_local $2) + ) + (set_local $22 + (get_local $2) + ) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $2 + (tee_local $25 + (tee_local $24 + (tee_local $28 + (tee_local $12 + (tee_local $4 + (get_local $0) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $1 + (tee_local $27 + (tee_local $26 + (tee_local $29 + (tee_local $14 + (tee_local $3 + (get_local $1) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) ) (loop $continue|0 (if - (if (result i32) - (tee_local $3 - (get_local $2) - ) + (get_local $23) + (set_local $23 (i32.rem_s - (get_local $1) + (get_local $3) (i32.const 4) ) - (get_local $3) ) + ) + (if + (get_local $23) (block - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $2 + (tee_local $25 + (tee_local $24 + (tee_local $28 + (tee_local $12 + (tee_local $4 + (i32.add + (tee_local $23 + (get_local $4) + ) + (i32.const 1) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $1 + (tee_local $27 + (tee_local $26 + (tee_local $29 + (tee_local $14 + (tee_local $3 + (i32.add + (tee_local $11 + (get_local $3) + ) + (i32.const 1) + ) + ) + ) + ) + ) + ) + ) + ) + ) ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) + (get_local $23) + (i32.load8_u + (get_local $11) ) ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 1) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $39 + (tee_local $38 + (tee_local $37 + (tee_local $36 + (tee_local $35 + (tee_local $34 + (tee_local $33 + (tee_local $32 + (tee_local $31 + (tee_local $30 + (tee_local $16 + (tee_local $23 + (i32.sub + (get_local $16) + (i32.const 1) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) + ) ) ) (br $continue|0) @@ -71,68 +269,90 @@ (loop $continue|1 (if (i32.ge_s - (get_local $2) + (get_local $30) (i32.const 16) ) (block (i32.store - (get_local $4) + (get_local $12) (i32.load - (get_local $1) + (get_local $14) ) ) (i32.store (i32.add - (get_local $4) + (get_local $12) (i32.const 4) ) (i32.load (i32.add - (get_local $1) + (get_local $14) (i32.const 4) ) ) ) (i32.store (i32.add - (get_local $4) + (get_local $12) (i32.const 8) ) (i32.load (i32.add - (get_local $1) + (get_local $14) (i32.const 8) ) ) ) (i32.store (i32.add - (get_local $4) + (get_local $12) (i32.const 12) ) (i32.load (i32.add - (get_local $1) + (get_local $14) (i32.const 12) ) ) ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 16) + (set_local $27 + (tee_local $26 + (tee_local $29 + (tee_local $14 + (i32.add + (get_local $14) + (i32.const 16) + ) + ) + ) ) ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 16) + (set_local $25 + (tee_local $24 + (tee_local $28 + (tee_local $12 + (i32.add + (get_local $12) + (i32.const 16) + ) + ) + ) ) ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 16) + (set_local $35 + (tee_local $34 + (tee_local $33 + (tee_local $32 + (tee_local $31 + (tee_local $30 + (i32.sub + (get_local $31) + (i32.const 16) + ) + ) + ) + ) + ) ) ) (br $continue|1) @@ -141,89 +361,101 @@ ) (if (i32.and - (get_local $2) + (get_local $32) (i32.const 8) ) (block (i32.store - (get_local $4) + (get_local $12) (i32.load - (get_local $1) + (get_local $14) ) ) (i32.store (i32.add - (get_local $4) + (get_local $12) (i32.const 4) ) (i32.load (i32.add - (get_local $1) + (get_local $14) (i32.const 4) ) ) ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 8) + (set_local $25 + (tee_local $24 + (tee_local $28 + (i32.add + (get_local $12) + (i32.const 8) + ) + ) ) ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 8) + (set_local $27 + (tee_local $26 + (tee_local $29 + (i32.add + (get_local $14) + (i32.const 8) + ) + ) ) ) ) ) (if (i32.and - (get_local $2) + (get_local $33) (i32.const 4) ) (block (i32.store - (get_local $4) + (get_local $28) (i32.load - (get_local $1) + (get_local $29) ) ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 4) + (set_local $25 + (tee_local $24 + (i32.add + (get_local $28) + (i32.const 4) + ) ) ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 4) + (set_local $27 + (tee_local $26 + (i32.add + (get_local $29) + (i32.const 4) + ) ) ) ) ) (if (i32.and - (get_local $2) + (get_local $34) (i32.const 2) ) (block (i32.store16 - (get_local $4) + (get_local $24) (i32.load16_u - (get_local $1) + (get_local $26) ) ) - (set_local $4 + (set_local $25 (i32.add - (get_local $4) + (get_local $24) (i32.const 2) ) ) - (set_local $1 + (set_local $27 (i32.add - (get_local $1) + (get_local $26) (i32.const 2) ) ) @@ -231,13 +463,13 @@ ) (if (i32.and - (get_local $2) + (get_local $35) (i32.const 1) ) (i32.store8 - (get_local $4) + (get_local $25) (i32.load8_u - (get_local $1) + (get_local $27) ) ) ) @@ -248,128 +480,148 @@ ) (if (i32.ge_s - (get_local $2) + (get_local $36) (i32.const 32) ) (block $break|2 (block $case2|2 (block $case1|2 - (block $case0|2 - (block $tablify|0 - (br_table $case0|2 $case1|2 $case2|2 $tablify|0 - (i32.sub - (i32.rem_s - (get_local $4) - (i32.const 4) - ) - (i32.const 1) + (if + (i32.ne + (tee_local $4 + (i32.rem_s + (get_local $2) + (i32.const 4) ) ) + (i32.const 1) + ) + (block + (br_if $case1|2 + (i32.eq + (get_local $4) + (i32.const 2) + ) + ) + (br_if $case2|2 + (i32.eq + (get_local $4) + (i32.const 3) + ) + ) + (br $break|2) ) - (br $break|2) ) - (set_local $5 + (set_local $3 (i32.load (get_local $1) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) + (i32.store8 + (get_local $2) + (i32.load8_u + (get_local $1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $4 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $1) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) + ) + ) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $1 + (i32.add + (tee_local $16 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) + ) + ) ) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $2 + (i32.add + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) + ) + ) ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) + (get_local $16) + (i32.load8_u + (get_local $4) + ) + ) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $4 + (i32.sub + (get_local $37) + (i32.const 3) + ) + ) ) - (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 3) ) ) (loop $continue|3 (if (i32.ge_s - (get_local $2) + (get_local $4) (i32.const 17) ) (block (i32.store - (get_local $4) + (get_local $1) (i32.or (i32.shr_u - (get_local $5) + (get_local $3) (i32.const 24) ) (i32.shl (tee_local $3 (i32.load (i32.add - (get_local $1) + (get_local $2) (i32.const 1) ) ) @@ -380,7 +632,7 @@ ) (i32.store (i32.add - (get_local $4) + (get_local $1) (i32.const 4) ) (i32.or @@ -389,10 +641,10 @@ (i32.const 24) ) (i32.shl - (tee_local $5 + (tee_local $3 (i32.load (i32.add - (get_local $1) + (get_local $2) (i32.const 5) ) ) @@ -403,19 +655,19 @@ ) (i32.store (i32.add - (get_local $4) + (get_local $1) (i32.const 8) ) (i32.or (i32.shr_u - (get_local $5) + (get_local $3) (i32.const 24) ) (i32.shl (tee_local $3 (i32.load (i32.add - (get_local $1) + (get_local $2) (i32.const 9) ) ) @@ -426,7 +678,7 @@ ) (i32.store (i32.add - (get_local $4) + (get_local $1) (i32.const 12) ) (i32.or @@ -435,10 +687,10 @@ (i32.const 24) ) (i32.shl - (tee_local $5 + (tee_local $3 (i32.load (i32.add - (get_local $1) + (get_local $2) (i32.const 13) ) ) @@ -447,22 +699,52 @@ ) ) ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 16) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + ) + ) ) ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 16) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + ) ) ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 16) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $4 + (i32.sub + (get_local $4) + (i32.const 16) + ) + ) + ) + ) + ) ) ) (br $continue|3) @@ -471,77 +753,93 @@ ) (br $break|2) ) - (set_local $5 + (set_local $3 (i32.load (get_local $1) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) + (i32.store8 + (get_local $2) + (i32.load8_u + (get_local $1) + ) + ) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $2 + (i32.add + (tee_local $4 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) + ) + ) + ) + ) + ) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $1 + (i32.add + (tee_local $16 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) + ) + ) ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) + (get_local $4) + (i32.load8_u + (get_local $16) + ) + ) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $4 + (i32.sub + (get_local $38) + (i32.const 2) + ) + ) ) - (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 2) ) ) (loop $continue|4 (if (i32.ge_s - (get_local $2) + (get_local $4) (i32.const 18) ) (block (i32.store - (get_local $4) + (get_local $2) (i32.or (i32.shr_u - (get_local $5) + (get_local $3) (i32.const 16) ) (i32.shl @@ -559,7 +857,7 @@ ) (i32.store (i32.add - (get_local $4) + (get_local $2) (i32.const 4) ) (i32.or @@ -568,7 +866,7 @@ (i32.const 16) ) (i32.shl - (tee_local $5 + (tee_local $3 (i32.load (i32.add (get_local $1) @@ -582,12 +880,12 @@ ) (i32.store (i32.add - (get_local $4) + (get_local $2) (i32.const 8) ) (i32.or (i32.shr_u - (get_local $5) + (get_local $3) (i32.const 16) ) (i32.shl @@ -605,7 +903,7 @@ ) (i32.store (i32.add - (get_local $4) + (get_local $2) (i32.const 12) ) (i32.or @@ -614,7 +912,7 @@ (i32.const 16) ) (i32.shl - (tee_local $5 + (tee_local $3 (i32.load (i32.add (get_local $1) @@ -626,22 +924,52 @@ ) ) ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 16) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + ) ) ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 16) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 16) + ) + ) + ) + ) + ) ) ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 16) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $4 + (i32.sub + (get_local $4) + (i32.const 16) + ) + ) + ) + ) + ) ) ) (br $continue|4) @@ -650,45 +978,69 @@ ) (br $break|2) ) - (set_local $5 + (set_local $16 (i32.load (get_local $1) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $4 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + ) + ) + ) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $3 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + ) + ) ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) + (get_local $2) + (i32.load8_u + (get_local $1) ) ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 1) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $1 + (i32.sub + (get_local $39) + (i32.const 1) + ) + ) + ) + ) + ) ) ) (loop $continue|5 (if (i32.ge_s - (get_local $2) + (get_local $1) (i32.const 19) ) (block @@ -696,14 +1048,14 @@ (get_local $4) (i32.or (i32.shr_u - (get_local $5) + (get_local $16) (i32.const 8) ) (i32.shl - (tee_local $3 + (tee_local $2 (i32.load (i32.add - (get_local $1) + (get_local $3) (i32.const 3) ) ) @@ -719,14 +1071,14 @@ ) (i32.or (i32.shr_u - (get_local $3) + (get_local $2) (i32.const 8) ) (i32.shl - (tee_local $5 + (tee_local $2 (i32.load (i32.add - (get_local $1) + (get_local $3) (i32.const 7) ) ) @@ -742,14 +1094,14 @@ ) (i32.or (i32.shr_u - (get_local $5) + (get_local $2) (i32.const 8) ) (i32.shl - (tee_local $3 + (tee_local $2 (i32.load (i32.add - (get_local $1) + (get_local $3) (i32.const 11) ) ) @@ -765,14 +1117,14 @@ ) (i32.or (i32.shr_u - (get_local $3) + (get_local $2) (i32.const 8) ) (i32.shl - (tee_local $5 + (tee_local $16 (i32.load (i32.add - (get_local $1) + (get_local $3) (i32.const 15) ) ) @@ -781,22 +1133,52 @@ ) ) ) - (set_local $1 - (i32.add - (get_local $1) - (i32.const 16) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (tee_local $18 + (tee_local $3 + (i32.add + (get_local $3) + (i32.const 16) + ) + ) + ) + ) + ) ) ) - (set_local $4 - (i32.add - (get_local $4) - (i32.const 16) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (tee_local $17 + (tee_local $4 + (i32.add + (get_local $4) + (i32.const 16) + ) + ) + ) + ) + ) ) ) - (set_local $2 - (i32.sub - (get_local $2) - (i32.const 16) + (set_local $22 + (tee_local $21 + (tee_local $20 + (tee_local $19 + (tee_local $11 + (tee_local $1 + (i32.sub + (get_local $1) + (i32.const 16) + ) + ) + ) + ) + ) ) ) (br $continue|5) @@ -807,765 +1189,557 @@ ) (if (i32.and - (get_local $2) + (get_local $11) (i32.const 16) ) (block - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) + (i32.store8 + (get_local $17) + (i32.load8_u + (get_local $18) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $17) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $18) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) + ) + ) + (set_local $6 + (tee_local $5 + (tee_local $9 + (tee_local $13 + (i32.add + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) ) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) + (set_local $8 + (tee_local $7 + (tee_local $10 + (tee_local $15 + (i32.add + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) + (get_local $1) + (i32.load8_u + (get_local $2) ) ) ) ) (if (i32.and - (get_local $2) + (get_local $19) (i32.const 8) ) (block - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) + (i32.store8 + (get_local $13) + (i32.load8_u + (get_local $15) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $13) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) + (get_local $15) + (i32.const 1) + ) + ) + ) + ) + (i32.store8 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + (i32.store8 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + (i32.store8 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + (i32.store8 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + (i32.store8 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + ) + ) + (set_local $6 + (tee_local $5 + (tee_local $9 + (i32.add + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) ) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (set_local $8 + (tee_local $7 + (tee_local $10 (i32.add - (tee_local $3 - (get_local $1) + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) ) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) + (get_local $1) + (i32.load8_u + (get_local $2) ) ) ) ) (if (i32.and - (get_local $2) + (get_local $20) (i32.const 4) ) (block - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) + (i32.store8 + (get_local $9) + (i32.load8_u + (get_local $10) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $9) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $10) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.load8_u + (tee_local $2 (i32.add - (tee_local $3 - (get_local $1) - ) + (get_local $2) (i32.const 1) ) ) - (i32.load8_u - (get_local $3) + ) + ) + (set_local $6 + (tee_local $5 + (i32.add + (tee_local $1 + (i32.add + (get_local $1) + (i32.const 1) + ) + ) + (i32.const 1) ) ) ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) + (set_local $8 + (tee_local $7 + (i32.add + (tee_local $2 + (i32.add + (get_local $2) + (i32.const 1) + ) + ) + (i32.const 1) ) - (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) + (get_local $1) + (i32.load8_u + (get_local $2) ) ) ) ) (if (i32.and - (get_local $2) + (get_local $21) (i32.const 2) ) (block - (set_local $4 + (i32.store8 + (get_local $5) + (i32.load8_u + (get_local $7) + ) + ) + (set_local $6 (i32.add - (tee_local $3 - (get_local $4) + (tee_local $1 + (i32.add + (get_local $5) + (i32.const 1) + ) + ) + (i32.const 1) + ) + ) + (set_local $8 + (i32.add + (tee_local $2 + (i32.add + (get_local $7) + (i32.const 1) + ) ) (i32.const 1) ) ) (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) - ) - ) - (set_local $4 - (i32.add - (tee_local $3 - (get_local $4) - ) - (i32.const 1) - ) - ) - (i32.store8 - (get_local $3) - (block (result i32) - (set_local $1 - (i32.add - (tee_local $3 - (get_local $1) - ) - (i32.const 1) - ) - ) - (i32.load8_u - (get_local $3) - ) + (get_local $1) + (i32.load8_u + (get_local $2) ) ) ) ) (if (i32.and - (get_local $2) + (get_local $22) (i32.const 1) ) (i32.store8 - (get_local $4) + (get_local $6) (i32.load8_u - (get_local $1) + (get_local $8) ) ) ) diff --git a/tests/compiler/switch.optimized.wast b/tests/compiler/switch.optimized.wast index 094ada85..bff092c8 100644 --- a/tests/compiler/switch.optimized.wast +++ b/tests/compiler/switch.optimized.wast @@ -6,15 +6,36 @@ (export "doSwitchDefaultOmitted" (func $switch/doSwitchDefaultOmitted)) (export "memory" (memory $0)) (func $switch/doSwitch (; 0 ;) (type $ii) (param $0 i32) (result i32) + (local $1 i32) (block $case4|0 (block $case2|0 - (block $case0|0 - (block $tablify|0 - (br_table $case2|0 $case0|0 $case4|0 $case4|0 $tablify|0 + (if + (i32.ne + (tee_local $1 (get_local $0) ) + (i32.const 1) + ) + (block + (br_if $case2|0 + (i32.eqz + (get_local $1) + ) + ) + (br_if $case4|0 + (i32.eq + (get_local $1) + (i32.const 2) + ) + ) + (br_if $case4|0 + (i32.eq + (get_local $1) + (i32.const 3) + ) + ) + (br $case2|0) ) - (br $case2|0) ) (return (i32.const 1) @@ -27,18 +48,31 @@ (i32.const 23) ) (func $switch/doSwitchDefaultFirst (; 1 ;) (type $ii) (param $0 i32) (result i32) + (local $1 i32) (block $case3|0 - (block $case1|0 - (block $tablify|0 - (br_table $case1|0 $case3|0 $case3|0 $tablify|0 - (i32.sub - (get_local $0) - (i32.const 1) + (if + (i32.ne + (tee_local $1 + (get_local $0) + ) + (i32.const 1) + ) + (block + (br_if $case3|0 + (i32.eq + (get_local $1) + (i32.const 2) ) ) - ) - (return - (i32.const 0) + (br_if $case3|0 + (i32.eq + (get_local $1) + (i32.const 3) + ) + ) + (return + (i32.const 0) + ) ) ) (return @@ -48,18 +82,31 @@ (i32.const 23) ) (func $switch/doSwitchDefaultOmitted (; 2 ;) (type $ii) (param $0 i32) (result i32) + (local $1 i32) (block $break|0 (block $case2|0 - (block $case0|0 - (block $tablify|0 - (br_table $case0|0 $case2|0 $case2|0 $tablify|0 - (i32.sub - (get_local $0) - (i32.const 1) + (if + (i32.ne + (tee_local $1 + (get_local $0) + ) + (i32.const 1) + ) + (block + (br_if $case2|0 + (i32.eq + (get_local $1) + (i32.const 2) ) ) + (br_if $case2|0 + (i32.eq + (get_local $1) + (i32.const 3) + ) + ) + (br $break|0) ) - (br $break|0) ) (return (i32.const 1) diff --git a/tests/compiler/ternary.optimized.wast b/tests/compiler/ternary.optimized.wast index d0d8d5ae..a558589b 100644 --- a/tests/compiler/ternary.optimized.wast +++ b/tests/compiler/ternary.optimized.wast @@ -5,14 +5,28 @@ (export "memory" (memory $0)) (start $start) (func $start (; 0 ;) (type $v) + (local $0 i32) (set_global $ternary/a - (i32.const 1) + (tee_local $0 + (i32.const 1) + ) ) (set_global $ternary/a - (i32.const 1) + (tee_local $0 + (i32.const 1) + ) + ) + (if + (tee_local $0 + (i32.const 1) + ) + (set_local $0 + (i32.const 1) + ) + (unreachable) ) (set_global $ternary/a - (i32.const 1) + (get_local $0) ) ) ) diff --git a/tests/compiler/unary.optimized.wast b/tests/compiler/unary.optimized.wast index 7c28bb5b..382e59d5 100644 --- a/tests/compiler/unary.optimized.wast +++ b/tests/compiler/unary.optimized.wast @@ -66,53 +66,39 @@ ) ) (set_global $unary/i - (block (result i32) - (set_global $unary/i - (i32.add - (get_global $unary/i) - (i32.const 1) - ) - ) + (i32.add (get_global $unary/i) + (i32.const 1) ) ) (set_global $unary/i - (block (result i32) - (set_global $unary/i - (i32.sub - (get_global $unary/i) - (i32.const 1) - ) - ) + (i32.sub (get_global $unary/i) + (i32.const 1) ) ) (set_global $unary/i - (block (result i32) - (set_global $unary/i - (i32.add - (tee_local $0 - (get_global $unary/i) - ) - (i32.const 1) - ) + (i32.add + (tee_local $0 + (get_global $unary/i) ) - (get_local $0) + (i32.const 1) ) ) (set_global $unary/i - (block (result i32) - (set_global $unary/i - (i32.sub - (tee_local $0 - (get_global $unary/i) - ) - (i32.const 1) - ) + (get_local $0) + ) + (set_global $unary/i + (i32.sub + (tee_local $0 + (get_global $unary/i) ) - (get_local $0) + (i32.const 1) ) ) + (set_global $unary/i + (get_local $0) + ) (set_global $unary/I (i64.add (get_global $unary/I) @@ -169,53 +155,39 @@ ) ) (set_global $unary/I - (block (result i64) - (set_global $unary/I - (i64.add - (get_global $unary/I) - (i64.const 1) - ) - ) + (i64.add (get_global $unary/I) + (i64.const 1) ) ) (set_global $unary/I - (block (result i64) - (set_global $unary/I - (i64.sub - (get_global $unary/I) - (i64.const 1) - ) - ) + (i64.sub (get_global $unary/I) + (i64.const 1) ) ) (set_global $unary/I - (block (result i64) - (set_global $unary/I - (i64.add - (tee_local $1 - (get_global $unary/I) - ) - (i64.const 1) - ) + (i64.add + (tee_local $1 + (get_global $unary/I) ) - (get_local $1) + (i64.const 1) ) ) (set_global $unary/I - (block (result i64) - (set_global $unary/I - (i64.sub - (tee_local $1 - (get_global $unary/I) - ) - (i64.const 1) - ) + (get_local $1) + ) + (set_global $unary/I + (i64.sub + (tee_local $1 + (get_global $unary/I) ) - (get_local $1) + (i64.const 1) ) ) + (set_global $unary/I + (get_local $1) + ) (set_global $unary/f (f32.add (get_global $unary/f) @@ -261,53 +233,39 @@ ) ) (set_global $unary/f - (block (result f32) - (set_global $unary/f - (f32.add - (get_global $unary/f) - (f32.const 1) - ) - ) + (f32.add (get_global $unary/f) + (f32.const 1) ) ) (set_global $unary/f - (block (result f32) - (set_global $unary/f - (f32.sub - (get_global $unary/f) - (f32.const 1) - ) - ) + (f32.sub (get_global $unary/f) + (f32.const 1) ) ) (set_global $unary/f - (block (result f32) - (set_global $unary/f - (f32.add - (tee_local $2 - (get_global $unary/f) - ) - (f32.const 1) - ) + (f32.add + (tee_local $2 + (get_global $unary/f) ) - (get_local $2) + (f32.const 1) ) ) (set_global $unary/f - (block (result f32) - (set_global $unary/f - (f32.sub - (tee_local $2 - (get_global $unary/f) - ) - (f32.const 1) - ) + (get_local $2) + ) + (set_global $unary/f + (f32.sub + (tee_local $2 + (get_global $unary/f) ) - (get_local $2) + (f32.const 1) ) ) + (set_global $unary/f + (get_local $2) + ) (set_global $unary/F (f64.add (get_global $unary/F) @@ -355,52 +313,38 @@ ) ) (set_global $unary/F - (block (result f64) - (set_global $unary/F - (f64.add - (get_global $unary/F) - (f64.const 1) - ) - ) + (f64.add (get_global $unary/F) + (f64.const 1) ) ) (set_global $unary/F - (block (result f64) - (set_global $unary/F - (f64.sub - (get_global $unary/F) - (f64.const 1) - ) - ) + (f64.sub (get_global $unary/F) + (f64.const 1) ) ) (set_global $unary/F - (block (result f64) - (set_global $unary/F - (f64.add - (tee_local $3 - (get_global $unary/F) - ) - (f64.const 1) - ) + (f64.add + (tee_local $3 + (get_global $unary/F) ) - (get_local $3) + (f64.const 1) ) ) (set_global $unary/F - (block (result f64) - (set_global $unary/F - (f64.sub - (tee_local $3 - (get_global $unary/F) - ) - (f64.const 1) - ) + (get_local $3) + ) + (set_global $unary/F + (f64.sub + (tee_local $3 + (get_global $unary/F) ) - (get_local $3) + (f64.const 1) ) ) + (set_global $unary/F + (get_local $3) + ) ) ) diff --git a/tests/compiler/while.optimized.wast b/tests/compiler/while.optimized.wast index d7dfbaf4..fb50bea0 100644 --- a/tests/compiler/while.optimized.wast +++ b/tests/compiler/while.optimized.wast @@ -5,14 +5,20 @@ (export "loopWhileInWhile" (func $while/loopWhileInWhile)) (export "memory" (memory $0)) (func $while/loopWhile (; 0 ;) (type $iv) (param $0 i32) + (local $1 i32) + (set_local $1 + (get_local $0) + ) (loop $continue|0 (if - (get_local $0) + (get_local $1) (block (set_local $0 - (i32.sub - (get_local $0) - (i32.const 1) + (tee_local $1 + (i32.sub + (get_local $0) + (i32.const 1) + ) ) ) (br $continue|0) @@ -21,24 +27,32 @@ ) ) (func $while/loopWhileInWhile (; 1 ;) (type $iv) (param $0 i32) + (local $1 i32) + (set_local $1 + (get_local $0) + ) (loop $continue|0 (if - (get_local $0) + (get_local $1) (block (set_local $0 - (i32.sub - (get_local $0) - (i32.const 1) + (tee_local $1 + (i32.sub + (get_local $0) + (i32.const 1) + ) ) ) (loop $continue|1 (if - (get_local $0) + (get_local $1) (block (set_local $0 - (i32.sub - (get_local $0) - (i32.const 1) + (tee_local $1 + (i32.sub + (get_local $1) + (i32.const 1) + ) ) ) (br $continue|1) diff --git a/webpack.config.js b/webpack.config.js index c35d7c4e..76a2f25d 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,7 +2,7 @@ var path = require("path"); var webpack = require("webpack"); module.exports = { - entry: [ "./src/glue/js.ts", "./src/index.ts" ], + entry: [ "./src/glue/js.js", "./src/index.ts" ], module: { rules: [ {