Extract portable AS to its own definition and polyfill; Try running flatten/ssa before default optimizations, see WebAssembly/binaryen#1331

This commit is contained in:
dcodeIO 2017-12-08 19:08:03 +01:00
parent d6b94d4c33
commit 0ebb99a33c
23 changed files with 1515 additions and 1231 deletions

12
assembly.d.ts vendored
View File

@ -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<T = i32 | i64>(value: T): T;
@ -84,10 +86,10 @@ declare function changetype<T1,T2>(value: T1): T2;
declare function isNaN<T = f32 | f64>(value: T): bool;
/** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */
declare function isFinite<T = f32 | f64>(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
/// <reference path="./std/carray.d.ts" />
/// <reference path="./std/cstring.d.ts" />

48
portable-assembly.d.ts vendored Normal file
View File

@ -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 `<u8>(someI32 & 0xff)` will yield the same
// result when compiling to WebAssembly or JS while `<u8>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<T = i32>(value: T): T;
/** Computes the absolute value of an integer or float. */
declare function abs<T = i32 | f32 | f64>(value: T): T;
/** Determines the maximum of two integers or floats. If either operand is `NaN`, returns `NaN`. */
declare function max<T = i32 | f32 | f64>(left: T, right: T): T;
/** Determines the minimum of two integers or floats. If either operand is `NaN`, returns `NaN`. */
declare function min<T = i32 | f32 | f64>(left: T, right: T): T;
/** Performs the ceiling operation on a 32-bit or 64-bit float. */
declare function ceil<T = f32 | f64>(value: T): T;
/** Performs the floor operation on a 32-bit or 64-bit float. */
declare function floor<T = f32 | f64>(value: T): T;
/** Selects one of two pre-evaluated values depending on the condition. */
declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;
/** Calculates the square root of a 32-bit or 64-bit float. */
declare function sqrt<T = f32 | f64>(value: T): T;
/** Rounds to the nearest integer towards zero of a 32-bit or 64-bit float. */
declare function trunc<T = f32 | f64>(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;

29
portable-assembly.js Normal file
View File

@ -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(); };

View File

@ -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

20
src/glue/js.d.ts vendored
View File

@ -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;
/// <reference path="../../portable-assembly.d.ts" />
/// <reference path="./binaryen-c.d.ts" />
// Raw memory access (here: Binaryen memory)
// Raw memory accesses to Binaryen memory
declare function store<T = u8>(ptr: usize, val: T): void;
declare function load<T = u8>(ptr: usize): T;
declare function assert(isTrue: bool): void;
// Other things that might or might not be useful
declare function select<T>(ifTrue: T, ifFalse: T, condition: bool): T;

42
src/glue/js.js Normal file
View File

@ -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;
}

View File

@ -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<T>(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 = (<any>binaryen)["print"];
let ret: string = "";
binaryen["print"] = function(x: string): void { ret += x + "\n" };
this.print();
binaryen["print"] = previousPrint;
return ret;
}

View File

View File

@ -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 {

View File

@ -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"
]
}
}

View File

@ -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<u8>(dst++, load<u8>(src++));
n--;
}

View File

@ -1,4 +1,4 @@
/// <reference path="../src/glue/binaryen.d.ts" />
/// <reference path="../lib/binaryen.d.ts" />
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())

View File

@ -1,5 +1,3 @@
/// <reference path="../src/glue/binaryen.d.ts" />
import * as fs from "fs";
import * as path from "path";
import * as chalk from "chalk";

View File

@ -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)
)
)
)

View File

@ -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

View File

@ -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)

File diff suppressed because it is too large Load Diff

View File

@ -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)

View File

@ -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)
)
)
)

View File

@ -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)
)
)
)

View File

@ -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)

View File

@ -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: [
{