diff --git a/README.md b/README.md
index 2e78bac1..20018864 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
[](https://travis-ci.org/AssemblyScript/assemblyscript)
-**AssemblyScript** compiles strictly typed [TypeScript](http://www.typescriptlang.org) to [WebAssembly](http://webassembly.org) using [Binaryen](https://github.com/WebAssembly/binaryen). Unlike more complex toolchains, `asc` generates minimal WebAssembly modules while being just an `npm install` away.
+**AssemblyScript** compiles strictly typed [TypeScript](http://www.typescriptlang.org) to [WebAssembly](http://webassembly.org) using [Binaryen](https://github.com/WebAssembly/binaryen). Unlike other toolchains, `asc` generates minimal WebAssembly modules while being just an `npm install` away.
Examples
--------
@@ -16,6 +16,9 @@ A few early examples to get an idea:
* **[i64 polyfill](./examples/i64-polyfill)**
Exposes WebAssembly's i64 operations to JavaScript using 32-bit integers (low and high bits).
+* **[PSON decoder](./examples/pson)**
+ A PSON decoder implemented in AssemblyScript.
+
Or browse the [compiler tests](./tests/compiler) for a more in-depth overview of what's supported already.
Getting started
diff --git a/examples/.gitignore b/examples/.gitignore
index 2a0c6b29..55fb3e2f 100644
--- a/examples/.gitignore
+++ b/examples/.gitignore
@@ -1,3 +1,5 @@
*.wast
*.wasm
node_modules/
+npm-debug.log
+package-lock.json
diff --git a/examples/game-of-life/assembly/game-of-life.ts b/examples/game-of-life/assembly/game-of-life.ts
index bd4c7baf..d400fcce 100644
--- a/examples/game-of-life/assembly/game-of-life.ts
+++ b/examples/game-of-life/assembly/game-of-life.ts
@@ -1,8 +1,8 @@
// A simplified version of the game of life as seen on http://dcode.io
-var w: u32; // width
-var h: u32; // height
-var s: u32; // total size
+var w: u32, // width
+ h: u32, // height
+ s: u32; // total size
/** Initializes width and height. */
export function init(w_: u32, h_: u32): void {
@@ -13,21 +13,18 @@ export function init(w_: u32, h_: u32): void {
/** Performs one step. */
export function step(): void {
- var y: u32, ym1: u32, yp1: u32; // y, y-1 and y+1
- var x: u32, xm1: u32, xp1: u32; // x, x-1 and x+1
- var hm1: u32 = h - 1, wm1: u32 = w - 1;
- var n: u32, v: u8, c: u32 = 0;
- for (y = 0; y < h; ++y) {
- ym1 = select(hm1, y - 1, y == 0);
- yp1 = select(0, y + 1, y == hm1);
- for (x = 0; x < w; ++x) {
- xm1 = select(wm1, x - 1, x == 0);
- xp1 = select(0, x + 1, x == wm1);
- n = load(ym1 * w + xm1) + load(ym1 * w + x) + load(ym1 * w + xp1)
- + load(y * w + xm1) + load(y * w + xp1)
- + load(yp1 * w + xm1) + load(yp1 * w + x) + load(yp1 * w + xp1);
- v = load(y * w + x);
- if (v) {
+ var hm1 = h - 1,
+ wm1 = w - 1;
+ for (var y: u32 = 0; y < h; ++y) {
+ var ym1 = select(hm1, y - 1, y == 0),
+ yp1 = select(0, y + 1, y == hm1);
+ for (var x: u32 = 0; x < w; ++x) {
+ var xm1 = select(wm1, x - 1, x == 0),
+ xp1 = select(0, x + 1, x == wm1);
+ var n = load(ym1 * w + xm1) + load(ym1 * w + x) + load(ym1 * w + xp1)
+ + load(y * w + xm1) + load(y * w + xp1)
+ + load(yp1 * w + xm1) + load(yp1 * w + x) + load(yp1 * w + xp1);
+ if (load(y * w + x)) {
if (n < 2 || n > 3)
store(s + y * w + x, 0);
} else if (n == 3)
diff --git a/examples/i64-polyfill/assembly/i64.ts b/examples/i64-polyfill/assembly/i64.ts
index 769ca810..36e26b90 100644
--- a/examples/i64-polyfill/assembly/i64.ts
+++ b/examples/i64-polyfill/assembly/i64.ts
@@ -1,5 +1,5 @@
-let lo: u32;
-let hi: u32;
+var lo: u32,
+ hi: u32;
export function getLo(): u32 {
return lo;
diff --git a/examples/pson/README.md b/examples/pson/README.md
new file mode 100644
index 00000000..776ec5aa
--- /dev/null
+++ b/examples/pson/README.md
@@ -0,0 +1,19 @@
+PSON decoder in WebAssembly
+===========================
+
+An [AssemblyScript](http://assemblyscript.org) example. Decodes a [PSON](https://github.com/dcodeIO/PSON) encoded buffer.
+
+Instructions
+------------
+
+To build [assembly/pson.ts](./assembly/pson.ts) to an untouched and an optimized `.wasm` including their respective `.wast` representations, run:
+
+```
+$> npm run build
+```
+
+Afterwards, to run the included test, do:
+
+```
+$> npm test
+```
diff --git a/examples/pson/assembly/pson.ts b/examples/pson/assembly/pson.ts
new file mode 100644
index 00000000..fc6ca112
--- /dev/null
+++ b/examples/pson/assembly/pson.ts
@@ -0,0 +1,156 @@
+const enum Token {
+ ZERO = 0x00,
+ MAX = 0xEF,
+ NULL = 0xf0,
+ TRUE = 0xf1,
+ FALSE = 0xf2,
+ EOBJECT = 0xf3,
+ EARRAY = 0xf4,
+ ESTRING = 0xf5,
+ OBJECT = 0xf6,
+ ARRAY = 0xf7,
+ INTEGER = 0xf8,
+ LONG = 0xf9,
+ FLOAT = 0xfa,
+ DOUBLE = 0xfb,
+ STRING = 0xfc,
+ STRING_ADD = 0xfd,
+ STRING_GET = 0xfe,
+ BINARY = 0xff
+}
+
+namespace pson {
+ export declare function onNull(): void;
+ export declare function onTrue(): void;
+ export declare function onFalse(): void;
+ export declare function onEObject(): void;
+ export declare function onEArray(): void;
+ export declare function onEString(): void;
+ export declare function onObject(size: u32): void;
+ export declare function onArray(size: u32): void;
+ export declare function onInteger(value: i32): void;
+ export declare function onLong(valueLow: i32, valueHigh: i32): void;
+ export declare function onFloat(value: f32): void;
+ export declare function onDouble(value: f64): void;
+ export declare function onString(offset: usize, length: u32): void;
+ export declare function onBinary(offset: usize, length: u32): void;
+ export declare function onTruncated(): void;
+}
+
+var offset: usize = 0;
+
+export function decode(length: usize): void {
+ offset = 0;
+ while (offset < length)
+ decodeValue();
+ if (offset != length)
+ pson.onTruncated();
+}
+
+function decodeValue(): void {
+ var token: u32 = load(offset++);
+ var size: u32;
+ var long: u64;
+ switch (token) {
+
+ case Token.NULL:
+ pson.onNull();
+ break;
+
+ case Token.TRUE:
+ pson.onTrue();
+ break;
+
+ case Token.FALSE:
+ pson.onFalse();
+ break;
+
+ case Token.EOBJECT:
+ pson.onEObject();
+ break;
+
+ case Token.EARRAY:
+ pson.onEArray();
+ break;
+
+ case Token.ESTRING:
+ pson.onEString();
+ break;
+
+ case Token.OBJECT:
+ pson.onObject(size = readVarint32());
+ while (size--) {
+ decodeValue();
+ decodeValue();
+ }
+ break;
+
+ case Token.ARRAY:
+ pson.onArray(size = readVarint32());
+ while (size--)
+ decodeValue();
+ break;
+
+ case Token.INTEGER:
+ pson.onInteger(((size = readVarint32()) >> 1) ^ -(size & 1));
+ break;
+
+ case Token.LONG:
+ long = ((long = readVarint64()) >> 1) ^ -(long & 1);
+ pson.onLong(long, (long >>> 32));
+ break;
+
+ case Token.FLOAT:
+ pson.onFloat(load(offset));
+ offset += 4;
+ break;
+
+ case Token.DOUBLE:
+ pson.onDouble(load(offset));
+ offset += 8;
+ break;
+
+ case Token.STRING:
+ size = readVarint32();
+ pson.onString(offset, size);
+ offset += size;
+ break;
+
+ case Token.STRING_ADD:
+ case Token.STRING_GET:
+ // could be implemented via imports as well, but isn't necessary for this example
+ throw new Error("not implemented");
+
+ case Token.BINARY:
+ size = readVarint32();
+ pson.onBinary(offset, size);
+ offset += size;
+ break;
+
+ default: // small integer?
+ if (token > Token.MAX)
+ throw new Error("unexpected token");
+ pson.onInteger((token >> 1) ^ -(token & 1));
+ break;
+ }
+}
+
+function readVarint32(): u32 {
+ var value: u32 = 0;
+ var shift: u32 = 0;
+ do {
+ var b = load(offset++);
+ value |= (b & 0x7f) << (7 * shift++);
+ } while (b & 0x80);
+ return value;
+}
+
+function readVarint64(): u64 {
+ var value: u64 = 0;
+ var shift: u64 = 0;
+ do {
+ var b = load(offset++);
+ value |= (b & 0x7f) << (7 * shift++);
+ } while (b & 0x80);
+ return value;
+}
diff --git a/examples/pson/assembly/tsconfig.json b/examples/pson/assembly/tsconfig.json
new file mode 100644
index 00000000..6e52b21c
--- /dev/null
+++ b/examples/pson/assembly/tsconfig.json
@@ -0,0 +1,6 @@
+{
+ "extends": "../../../std/assembly.json",
+ "include": [
+ "./**/*.ts"
+ ]
+}
diff --git a/examples/pson/index.js b/examples/pson/index.js
new file mode 100644
index 00000000..e0a94256
--- /dev/null
+++ b/examples/pson/index.js
@@ -0,0 +1,71 @@
+var fs = require("fs");
+
+// Define imports. Just logs to console for the sake of this example.
+var pson = {
+ onNull: function() {
+ console.log("null");
+ },
+ onTrue: function() {
+ console.log("true");
+ },
+ onFalse: function() {
+ console.log("false");
+ },
+ onEObject: function() {
+ console.log("{}");
+ },
+ onEArray: function() {
+ console.log("[]");
+ },
+ onEString: function() {
+ console.log("\"\"");
+ },
+ onObject: function(size) {
+ console.log("{" + size + "}")
+ },
+ onArray: function(size) {
+ console.log("[" + size + "]");
+ },
+ onInteger: function(value) {
+ console.log("integer: " + value);
+ },
+ onLong: function(valueLow, valueHigh) {
+ console.log("long: " + valueLow + ", " + valueHigh);
+ },
+ onFloat: function(value) {
+ console.log("float: " + value);
+ },
+ onDouble: function(value) {
+ console.log("double: " + value);
+ },
+ onString: function(offset, length) {
+ console.log("string(length=" + length + "): " + new Buffer(mem.slice(offset, offset + length)).toString());
+ },
+ onBinary: function(offset, length) {
+ console.log("binary(length=" + length + "): " + mem.slice(offset, offset + length));
+ },
+ onTruncated: function() {
+ console.log("buffer is truncated :-(");
+ }
+};
+
+// Instantiate the module
+var mod = new WebAssembly.Module(fs.readFileSync(__dirname + "/pson.optimized.wasm"));
+var ins = new WebAssembly.Instance(mod, { pson: pson });
+var mem = new Uint8Array(ins.exports.memory.buffer);
+
+// Export API
+exports.decode = function(buffer) {
+
+ // grow memory if necessary
+ if (mem.length < buffer.length) {
+ ins.exports.memory.grow(Math.ceil((buffer.length - mem.length) / 65536));
+ mem = new Uint8Array(ins.exports.memory.buffer);
+ }
+
+ // copy buffer to memory
+ mem.set(buffer);
+
+ // start decoding (calls the imports defined above)
+ ins.exports.decode(buffer.length);
+}
diff --git a/examples/pson/package.json b/examples/pson/package.json
new file mode 100644
index 00000000..6499903d
--- /dev/null
+++ b/examples/pson/package.json
@@ -0,0 +1,14 @@
+{
+ "name": "@assemblyscript/pson-example",
+ "version": "1.0.0",
+ "private": true,
+ "scripts": {
+ "build": "npm run build:untouched && npm run build:optimized",
+ "build:untouched": "asc assembly/pson.ts -b pson.untouched.wasm -t pson.untouched.wast --validate",
+ "build:optimized": "asc -O assembly/pson.ts -b pson.optimized.wasm -t pson.optimized.wast --validate",
+ "test": "node tests"
+ },
+ "devDependencies": {
+ "pson": "^2.0.0"
+ }
+}
diff --git a/examples/pson/tests/index.js b/examples/pson/tests/index.js
new file mode 100644
index 00000000..8110f5b2
--- /dev/null
+++ b/examples/pson/tests/index.js
@@ -0,0 +1,24 @@
+var Long = require("long");
+
+var psonJS = require("pson");
+var psonWASM = require("..");
+
+// encode in JS
+var buf = new psonJS.Encoder().encode({
+ emptyObject: {},
+ emptyArray: [],
+ emptyString: "",
+ object: {
+ aSmallInt: 42,
+ anInt: 9000,
+ aLong: Long.MIN_VALUE.add(1)
+ },
+ array: [
+ 0.25, // fits into float
+ 0.1 // always a double
+ ],
+ binary: Buffer.from([1, 2, 3])
+}).toBuffer();
+
+// decode in WASM
+psonWASM.decode(buf);
diff --git a/src/ast.ts b/src/ast.ts
index e822d19d..59e9865f 100644
--- a/src/ast.ts
+++ b/src/ast.ts
@@ -2182,7 +2182,7 @@ function builderEndsWith(sb: string[], code: CharCode): bool {
}
/** Converts a string to its literal representation including quotes. */
-export function stringToLiteral(str: string): string {
+export function stringToLiteral(str: string, singleQuoted: bool = false): string {
var ret = new Array();
var off = 0;
for (var i = 0, k = str.length; i < k;) {
@@ -2263,11 +2263,12 @@ export function stringToLiteral(str: string): string {
break;
}
}
+ var quote = singleQuoted ? "'" : "\"";
if (off == 0) {
assert(ret.length == 0);
- return "\"" + str + "\"";
+ return quote + str + quote;
}
if (i > off)
ret.push(str.substring(off, i));
- return "\"" + ret.join("") + "\"";
+ return quote + ret.join("") + quote;
}
diff --git a/src/compiler.ts b/src/compiler.ts
index 5dcf651b..fe84e48c 100644
--- a/src/compiler.ts
+++ b/src/compiler.ts
@@ -840,8 +840,8 @@ export class Compiler extends DiagnosticEmitter {
compileDoStatement(statement: DoStatement): ExpressionRef {
var label = this.currentFunction.enterBreakContext();
- var condition = this.compileExpression(statement.condition, Type.i32);
var body = this.compileStatement(statement.statement);
+ var condition = this.compileExpression(statement.condition, Type.i32);
this.currentFunction.leaveBreakContext();
var breakLabel = "break|" + label;
var continueLabel = "continue|" + label;
@@ -1494,8 +1494,11 @@ export class Compiler extends DiagnosticEmitter {
case Token.PERCENT:
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
right = this.compileExpression(expression.right, this.currentType);
- if (this.currentType.isAnyFloat)
- throw new Error("not implemented"); // TODO: internal fmod, possibly simply imported from JS
+ if (this.currentType.isAnyFloat) {
+ // TODO: internal fmod, possibly simply imported from JS
+ this.error(DiagnosticCode.Operation_not_supported, expression.range);
+ return this.module.createUnreachable();
+ }
op = this.currentType.isSignedInteger
? this.currentType.isLongInteger
? BinaryOp.RemI64
diff --git a/src/module.ts b/src/module.ts
index e4531792..6b1d9804 100644
--- a/src/module.ts
+++ b/src/module.ts
@@ -15,7 +15,7 @@ export type ImportRef = usize;
export type ExportRef = usize;
export type Index = u32;
- export enum NativeType {
+export enum NativeType {
None = _BinaryenTypeNone(),
I32 = _BinaryenTypeInt32(),
I64 = _BinaryenTypeInt64(),
@@ -796,7 +796,7 @@ export class Module {
}
// currently supports side effect free expressions only
- cloneExpression(expr: ExpressionRef, noSideEffects: bool = false, maxDepth: i32 = 0x7fffffff): ExpressionRef {
+ cloneExpression(expr: ExpressionRef, noSideEffects: bool = false, maxDepth: i32 = i32.MAX_VALUE): ExpressionRef {
if (this.noEmit || maxDepth < 0) return 0;
var nested1: ExpressionRef,
@@ -900,28 +900,24 @@ export class Relooper {
}
}
-export function setAPITracing(on: bool): void {
- _BinaryenSetAPITracing(on ? 1 : 0);
-}
-
// helpers
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js
function allocU8Array(u8s: Uint8Array | null): usize {
if (!u8s) return 0;
- var ptr = Heap.allocate((u8s).length);
+ var ptr = Heap.allocate(u8s.length);
var idx = ptr;
- for (var i = 0, k = (u8s).length; i < k; ++i)
- store(idx++, (u8s)[i]);
+ for (var i = 0, k = u8s.length; i < k; ++i)
+ store(idx++, u8s[i]);
return ptr;
}
function allocI32Array(i32s: i32[] | null): usize {
if (!i32s) return 0;
- var ptr = Heap.allocate((i32s).length << 2);
+ var ptr = Heap.allocate(i32s.length << 2);
var idx = ptr;
- for (var i = 0, k = (i32s).length; i < k; ++i) {
- var val = (i32s)[i];
+ for (var i = 0, k = i32s.length; i < k; ++i) {
+ var val = i32s[i];
// store(idx, val) is not portable
store(idx , ( val & 0xff) as u8);
store(idx + 1, ((val >> 8) & 0xff) as u8);
@@ -956,12 +952,12 @@ function stringLengthUTF8(str: string): usize {
function allocString(str: string | null): usize {
if (str == null) return 0;
- var ptr = Heap.allocate(stringLengthUTF8((str)) + 1);
+ var ptr = Heap.allocate(stringLengthUTF8(str) + 1);
var idx = ptr;
- for (var i = 0, k = (str).length; i < k; ++i) {
- var u = (str).charCodeAt(i);
+ for (var i = 0, k = str.length; i < k; ++i) {
+ var u = str.charCodeAt(i);
if (u >= 0xD800 && u <= 0xDFFF && i + 1 < k)
- u = 0x10000 + ((u & 0x3FF) << 10) | ((str).charCodeAt(++i) & 0x3FF);
+ u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
if (u <= 0x7F)
store(idx++, u as u8);
else if (u <= 0x7FF) {
diff --git a/tests/compiler/assert.ts b/tests/compiler/assert.ts
index 4d1656bd..5dfd0d5f 100644
--- a/tests/compiler/assert.ts
+++ b/tests/compiler/assert.ts
@@ -1 +1,3 @@
assert(true);
+assert(1 == 1);
+assert(0.5 > 0.4);
diff --git a/tests/compiler/assert.wast b/tests/compiler/assert.wast
index 0d7ca8ee..79f48403 100644
--- a/tests/compiler/assert.wast
+++ b/tests/compiler/assert.wast
@@ -11,6 +11,24 @@
)
(unreachable)
)
+ (if
+ (i32.eqz
+ (i32.eq
+ (i32.const 1)
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (f64.gt
+ (f64.const 0.5)
+ (f64.const 0.4)
+ )
+ )
+ (unreachable)
+ )
)
)
(;
diff --git a/tests/compiler/binary.ts b/tests/compiler/binary.ts
index 9a5f872c..74398742 100644
--- a/tests/compiler/binary.ts
+++ b/tests/compiler/binary.ts
@@ -1,6 +1,6 @@
-let b: bool = false;
+var b = false;
-let i: i32 = 0;
+var i: i32 = 0;
i < 1;
i > 1;
@@ -49,7 +49,7 @@ i &= 1;
i |= 1;
i ^= 1;
-let I: i64 = 0;
+var I: i64 = 0;
I < 1;
I > 1;
@@ -98,7 +98,7 @@ I &= 1;
I |= 1;
I ^= 1;
-let f: f32 = 0;
+var f: f32 = 0;
f < 1;
f > 1;
@@ -129,7 +129,7 @@ f -= 1;
f *= 1;
// f %= 1;
-let F: f64 = 0;
+var F: f64 = 0;
F < 1;
F > 1;
diff --git a/tests/compiler/builtins.optimized.wast b/tests/compiler/builtins.optimized.wast
index ed3daf84..b9262be6 100644
--- a/tests/compiler/builtins.optimized.wast
+++ b/tests/compiler/builtins.optimized.wast
@@ -7,9 +7,13 @@
(global $builtins/F (mut f64) (f64.const 0))
(global $builtins/s (mut i32) (i32.const 0))
(memory $0 1)
+ (export "test" (func $builtins/test))
(export "memory" (memory $0))
(start $start)
- (func $start (; 0 ;) (type $v)
+ (func $builtins/test (; 0 ;) (type $v)
+ (nop)
+ )
+ (func $start (; 1 ;) (type $v)
(local $0 f32)
(local $1 f64)
(local $2 i32)
diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts
index da7ace9d..d7b00df0 100644
--- a/tests/compiler/builtins.ts
+++ b/tests/compiler/builtins.ts
@@ -1,8 +1,8 @@
-let b: bool;
+var b: bool;
// integers
-let i: i32;
+var i: i32;
clz(1);
ctz(1);
@@ -22,7 +22,7 @@ i = abs(-42); assert(i == 42);
i = max(1, 2); assert(i == 2);
i = min(1, 2); assert(i == 1);
-let I: i64;
+var I: i64;
clz(1);
ctz(1);
@@ -42,7 +42,7 @@ I = min(1, 2); assert(i == 1);
// floats
-let f: f32;
+var f: f32;
NaN;
Infinity;
@@ -72,7 +72,7 @@ f = trunc(1.25);
b = isNaN(1.25);
b = isFinite(1.25);
-let F: f64;
+var F: f64;
NaN;
Infinity;
@@ -129,7 +129,7 @@ F = reinterpret(25);
// host
-let s: usize;
+var s: usize;
current_memory();
grow_memory(1);
@@ -179,8 +179,9 @@ assert(isFinite(0));
// imported
-// TODO: Can't be interpreted due to 'Fatal: callImport: unknown import: env.parseInt'
-
-// parseInt(0);
-// parseInt(0, 10);
-// parseFloat(0);
+export function test(): void {
+ // cannot be interpreted
+ // parseInt("01");
+ // parseInt("1", 10);
+ // parseFloat("1.0");
+}
diff --git a/tests/compiler/builtins.wast b/tests/compiler/builtins.wast
index 854d6257..2c0c363f 100644
--- a/tests/compiler/builtins.wast
+++ b/tests/compiler/builtins.wast
@@ -8,9 +8,12 @@
(global $builtins/s (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
+ (export "test" (func $builtins/test))
(export "memory" (memory $0))
(start $start)
- (func $start (; 0 ;) (type $v)
+ (func $builtins/test (; 0 ;) (type $v)
+ )
+ (func $start (; 1 ;) (type $v)
(local $0 i32)
(local $1 i32)
(local $2 i64)
@@ -1085,6 +1088,7 @@
GLOBAL: builtins/f
GLOBAL: builtins/F
GLOBAL: builtins/s
+ FUNCTION_PROTOTYPE: builtins/test
[program.exports]
-
+ FUNCTION_PROTOTYPE: builtins/test
;)
diff --git a/tests/compiler/do.optimized.wast b/tests/compiler/do.optimized.wast
index 9d4d7f5e..44389967 100644
--- a/tests/compiler/do.optimized.wast
+++ b/tests/compiler/do.optimized.wast
@@ -1,42 +1,132 @@
(module
- (type $iv (func (param i32)))
+ (type $v (func))
+ (global $do/n (mut i32) (i32.const 10))
+ (global $do/m (mut i32) (i32.const 0))
+ (global $do/o (mut i32) (i32.const 0))
(memory $0 1)
- (export "loopDo" (func $do/loopDo))
- (export "loopDoInDo" (func $do/loopDoInDo))
(export "memory" (memory $0))
- (func $do/loopDo (; 0 ;) (type $iv) (param $0 i32)
+ (start $start)
+ (func $start (; 0 ;) (type $v)
+ (local $0 i32)
(loop $continue|0
- (br_if $continue|0
- (tee_local $0
- (i32.sub
- (get_local $0)
- (i32.const 1)
- )
- )
- )
- )
- )
- (func $do/loopDoInDo (; 1 ;) (type $iv) (param $0 i32)
- (loop $continue|0
- (set_local $0
+ (set_global $do/n
(i32.sub
- (get_local $0)
+ (get_global $do/n)
(i32.const 1)
)
)
- (loop $continue|1
- (br_if $continue|1
- (tee_local $0
- (i32.sub
- (get_local $0)
- (i32.const 1)
- )
- )
+ (set_global $do/m
+ (i32.add
+ (get_global $do/m)
+ (i32.const 1)
)
)
(br_if $continue|0
+ (get_global $do/n)
+ )
+ )
+ (if
+ (get_global $do/n)
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $do/m)
+ (i32.const 10)
+ )
+ (unreachable)
+ )
+ (set_global $do/n
+ (i32.const 10)
+ )
+ (loop $continue|1
+ (set_global $do/n
+ (i32.sub
+ (tee_local $0
+ (get_global $do/n)
+ )
+ (i32.const 1)
+ )
+ )
+ (br_if $continue|1
(get_local $0)
)
)
+ (if
+ (i32.ne
+ (get_global $do/n)
+ (i32.const -1)
+ )
+ (unreachable)
+ )
+ (set_global $do/n
+ (i32.const 10)
+ )
+ (set_global $do/m
+ (i32.const 0)
+ )
+ (loop $continue|2
+ (set_global $do/n
+ (i32.sub
+ (get_global $do/n)
+ (i32.const 1)
+ )
+ )
+ (set_global $do/m
+ (i32.add
+ (get_global $do/m)
+ (i32.const 1)
+ )
+ )
+ (loop $continue|3
+ (set_global $do/n
+ (i32.sub
+ (get_global $do/n)
+ (i32.const 1)
+ )
+ )
+ (set_global $do/o
+ (i32.add
+ (get_global $do/o)
+ (i32.const 1)
+ )
+ )
+ (br_if $continue|3
+ (get_global $do/n)
+ )
+ )
+ (if
+ (get_global $do/n)
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $do/o)
+ (i32.const 9)
+ )
+ (unreachable)
+ )
+ (br_if $continue|2
+ (get_global $do/n)
+ )
+ )
+ (if
+ (get_global $do/n)
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $do/m)
+ (i32.const 1)
+ )
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $do/o)
+ (i32.const 9)
+ )
+ (unreachable)
+ )
)
)
diff --git a/tests/compiler/do.ts b/tests/compiler/do.ts
index 38c9425b..38091a7e 100644
--- a/tests/compiler/do.ts
+++ b/tests/compiler/do.ts
@@ -1,14 +1,29 @@
-export function loopDo(n: i32): void {
- do {
- n = n - 1;
- } while (n);
-}
+var n = 10;
+var m = 0;
+do {
+ n--;
+ m++;
+} while (n);
+assert(n == 0);
+assert(m == 10);
-export function loopDoInDo(n: i32): void {
+n = 10;
+do; while(n--);
+assert(n == -1);
+
+n = 10;
+m = 0;
+var o = 0;
+do {
+ n--;
+ m++;
do {
- n = n - 1;
- do {
- n = n - 1;
- } while (n);
+ n--;
+ o++;
} while (n);
-}
+ assert(n == 0);
+ assert(o == 9);
+} while (n);
+assert(n == 0);
+assert(m == 1);
+assert(o == 9);
diff --git a/tests/compiler/do.wast b/tests/compiler/do.wast
index 864e2154..96ce67a7 100644
--- a/tests/compiler/do.wast
+++ b/tests/compiler/do.wast
@@ -1,54 +1,228 @@
(module
- (type $iv (func (param i32)))
+ (type $v (func))
+ (global $do/n (mut i32) (i32.const 10))
+ (global $do/m (mut i32) (i32.const 0))
+ (global $do/o (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
- (export "loopDo" (func $do/loopDo))
- (export "loopDoInDo" (func $do/loopDoInDo))
(export "memory" (memory $0))
- (func $do/loopDo (; 0 ;) (type $iv) (param $0 i32)
- (block $break|0
- (loop $continue|0
- (set_local $0
- (i32.sub
- (get_local $0)
- (i32.const 1)
- )
- )
- (br_if $continue|0
- (get_local $0)
- )
- )
- )
- )
- (func $do/loopDoInDo (; 1 ;) (type $iv) (param $0 i32)
+ (start $start)
+ (func $start (; 0 ;) (type $v)
+ (local $0 i32)
(block $break|0
(loop $continue|0
(block
- (set_local $0
- (i32.sub
- (get_local $0)
- (i32.const 1)
- )
- )
- (block $break|1
- (loop $continue|1
+ (drop
+ (block (result i32)
(set_local $0
+ (get_global $do/n)
+ )
+ (set_global $do/n
(i32.sub
(get_local $0)
(i32.const 1)
)
)
- (br_if $continue|1
- (get_local $0)
+ (get_local $0)
+ )
+ )
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $do/m)
)
+ (set_global $do/m
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
)
)
)
(br_if $continue|0
- (get_local $0)
+ (get_global $do/n)
)
)
)
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/n)
+ (i32.const 0)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/m)
+ (i32.const 10)
+ )
+ )
+ (unreachable)
+ )
+ (set_global $do/n
+ (i32.const 10)
+ )
+ (block $break|1
+ (loop $continue|1
+ (nop)
+ (br_if $continue|1
+ (block (result i32)
+ (set_local $0
+ (get_global $do/n)
+ )
+ (set_global $do/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/n)
+ (i32.sub
+ (i32.const 0)
+ (i32.const 1)
+ )
+ )
+ )
+ (unreachable)
+ )
+ (set_global $do/n
+ (i32.const 10)
+ )
+ (set_global $do/m
+ (i32.const 0)
+ )
+ (block $break|2
+ (loop $continue|2
+ (block
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $do/n)
+ )
+ (set_global $do/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $do/m)
+ )
+ (set_global $do/m
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (block $break|3
+ (loop $continue|3
+ (block
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $do/n)
+ )
+ (set_global $do/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $do/o)
+ )
+ (set_global $do/o
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ )
+ (br_if $continue|3
+ (get_global $do/n)
+ )
+ )
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/n)
+ (i32.const 0)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/o)
+ (i32.const 9)
+ )
+ )
+ (unreachable)
+ )
+ )
+ (br_if $continue|2
+ (get_global $do/n)
+ )
+ )
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/n)
+ (i32.const 0)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/m)
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $do/o)
+ (i32.const 9)
+ )
+ )
+ (unreachable)
+ )
)
)
(;
@@ -97,9 +271,9 @@
FUNCTION_PROTOTYPE: isize
FUNCTION_PROTOTYPE: usize
GLOBAL: HEAP_BASE
- FUNCTION_PROTOTYPE: do/loopDo
- FUNCTION_PROTOTYPE: do/loopDoInDo
+ GLOBAL: do/n
+ GLOBAL: do/m
+ GLOBAL: do/o
[program.exports]
- FUNCTION_PROTOTYPE: do/loopDo
- FUNCTION_PROTOTYPE: do/loopDoInDo
+
;)
diff --git a/tests/compiler/export.optimized.wast b/tests/compiler/export.optimized.wast
index a30cebe0..285e3c9f 100644
--- a/tests/compiler/export.optimized.wast
+++ b/tests/compiler/export.optimized.wast
@@ -10,6 +10,7 @@
(export "renamed_b" (global $export/b))
(export "two" (func $export/ns.two))
(export "memory" (memory $0))
+ (start $export/ns.two)
(func $export/add (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(i32.add
(get_local $0)
diff --git a/tests/compiler/export.ts b/tests/compiler/export.ts
index 1094aff3..e7857e2f 100644
--- a/tests/compiler/export.ts
+++ b/tests/compiler/export.ts
@@ -11,6 +11,7 @@ export { sub as renamed_sub };
export const a: i32 = 1;
const b: i32 = 2;
+b;
export { b as renamed_b };
diff --git a/tests/compiler/export.wast b/tests/compiler/export.wast
index db50f644..5291ec16 100644
--- a/tests/compiler/export.wast
+++ b/tests/compiler/export.wast
@@ -11,6 +11,7 @@
(export "renamed_b" (global $export/b))
(export "two" (func $export/ns.two))
(export "memory" (memory $0))
+ (start $start)
(func $export/add (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(return
(i32.add
@@ -29,6 +30,11 @@
)
(func $export/ns.two (; 2 ;) (type $v)
)
+ (func $start (; 3 ;) (type $v)
+ (drop
+ (i32.const 2)
+ )
+ )
)
(;
[program.elements]
diff --git a/tests/compiler/for.ts b/tests/compiler/for.ts
index 0c392197..709b51b1 100644
--- a/tests/compiler/for.ts
+++ b/tests/compiler/for.ts
@@ -1,10 +1,10 @@
-let i: i32;
+var i: i32;
for (i = 0; i < 10; ++i) {
;
}
assert(i == 10);
-for (let j: i32 = 0; j < 10; ++j) {
+for (var j: i32 = 0; j < 10; ++j) {
;
}
diff --git a/tests/compiler/game-of-life.wast b/tests/compiler/game-of-life.wast
index 07bcbd50..8df0eac8 100644
--- a/tests/compiler/game-of-life.wast
+++ b/tests/compiler/game-of-life.wast
@@ -33,206 +33,204 @@
(local $6 i32)
(local $7 i32)
(local $8 i32)
- (local $9 i32)
- (local $10 i32)
- (nop)
- (nop)
(block
- (set_local $6
+ (set_local $0
(i32.sub
(get_global $../../examples/game-of-life/assembly/game-of-life/h)
(i32.const 1)
)
)
- (set_local $7
+ (set_local $1
(i32.sub
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
(i32.const 1)
)
)
)
- (block
- (set_local $10
- (i32.const 0)
- )
- )
(block $break|0
- (set_local $0
- (i32.const 0)
+ (block
+ (set_local $2
+ (i32.const 0)
+ )
)
(loop $continue|0
(if
(i32.lt_u
- (get_local $0)
+ (get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/h)
)
(block
(block
- (set_local $1
- (select
- (get_local $6)
- (i32.sub
+ (block
+ (set_local $3
+ (select
(get_local $0)
- (i32.const 1)
- )
- (i32.eq
- (get_local $0)
- (i32.const 0)
+ (i32.sub
+ (get_local $2)
+ (i32.const 1)
+ )
+ (i32.eq
+ (get_local $2)
+ (i32.const 0)
+ )
)
)
- )
- (set_local $2
- (select
- (i32.const 0)
- (i32.add
- (get_local $0)
- (i32.const 1)
- )
- (i32.eq
- (get_local $0)
- (get_local $6)
+ (set_local $4
+ (select
+ (i32.const 0)
+ (i32.add
+ (get_local $2)
+ (i32.const 1)
+ )
+ (i32.eq
+ (get_local $2)
+ (get_local $0)
+ )
)
)
)
(block $break|1
- (set_local $3
- (i32.const 0)
+ (block
+ (set_local $5
+ (i32.const 0)
+ )
)
(loop $continue|1
(if
(i32.lt_u
- (get_local $3)
+ (get_local $5)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
(block
(block
- (set_local $4
- (select
- (get_local $7)
- (i32.sub
- (get_local $3)
- (i32.const 1)
+ (block
+ (set_local $6
+ (select
+ (get_local $1)
+ (i32.sub
+ (get_local $5)
+ (i32.const 1)
+ )
+ (i32.eq
+ (get_local $5)
+ (i32.const 0)
+ )
)
- (i32.eq
- (get_local $3)
+ )
+ (set_local $7
+ (select
(i32.const 0)
+ (i32.add
+ (get_local $5)
+ (i32.const 1)
+ )
+ (i32.eq
+ (get_local $5)
+ (get_local $1)
+ )
)
)
)
- (set_local $5
- (select
- (i32.const 0)
- (i32.add
- (get_local $3)
- (i32.const 1)
- )
- (i32.eq
- (get_local $3)
- (get_local $7)
- )
- )
- )
- (set_local $8
- (i32.add
+ (block
+ (set_local $8
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
(i32.add
- (i32.load8_u
- (i32.add
- (i32.mul
- (get_local $1)
- (get_global $../../examples/game-of-life/assembly/game-of-life/w)
+ (i32.add
+ (i32.load8_u
+ (i32.add
+ (i32.mul
+ (get_local $3)
+ (get_global $../../examples/game-of-life/assembly/game-of-life/w)
+ )
+ (get_local $6)
+ )
+ )
+ (i32.load8_u
+ (i32.add
+ (i32.mul
+ (get_local $3)
+ (get_global $../../examples/game-of-life/assembly/game-of-life/w)
+ )
+ (get_local $5)
)
- (get_local $4)
)
)
(i32.load8_u
(i32.add
(i32.mul
- (get_local $1)
+ (get_local $3)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
- (get_local $3)
+ (get_local $7)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
- (get_local $1)
+ (get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
- (get_local $5)
+ (get_local $6)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
- (get_local $0)
+ (get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
- (get_local $4)
+ (get_local $7)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
- (get_local $0)
+ (get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
- (get_local $5)
+ (get_local $6)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
- (get_local $2)
+ (get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
- (get_local $4)
+ (get_local $5)
)
)
)
(i32.load8_u
(i32.add
(i32.mul
- (get_local $2)
+ (get_local $4)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
- (get_local $3)
+ (get_local $7)
)
)
)
- (i32.load8_u
- (i32.add
- (i32.mul
- (get_local $2)
- (get_global $../../examples/game-of-life/assembly/game-of-life/w)
- )
- (get_local $5)
- )
- )
- )
- )
- (set_local $9
- (i32.load8_u
- (i32.add
- (i32.mul
- (get_local $0)
- (get_global $../../examples/game-of-life/assembly/game-of-life/w)
- )
- (get_local $3)
- )
)
)
(if
- (get_local $9)
+ (i32.load8_u
+ (i32.add
+ (i32.mul
+ (get_local $2)
+ (get_global $../../examples/game-of-life/assembly/game-of-life/w)
+ )
+ (get_local $5)
+ )
+ )
(if
(if (result i32)
(i32.lt_u
@@ -253,11 +251,11 @@
(i32.add
(get_global $../../examples/game-of-life/assembly/game-of-life/s)
(i32.mul
- (get_local $0)
+ (get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
)
- (get_local $3)
+ (get_local $5)
)
(i32.const 0)
)
@@ -272,20 +270,20 @@
(i32.add
(get_global $../../examples/game-of-life/assembly/game-of-life/s)
(i32.mul
- (get_local $0)
+ (get_local $2)
(get_global $../../examples/game-of-life/assembly/game-of-life/w)
)
)
- (get_local $3)
+ (get_local $5)
)
(i32.const 1)
)
)
)
)
- (set_local $3
+ (set_local $5
(i32.add
- (get_local $3)
+ (get_local $5)
(i32.const 1)
)
)
@@ -295,9 +293,9 @@
)
)
)
- (set_local $0
+ (set_local $2
(i32.add
- (get_local $0)
+ (get_local $2)
(i32.const 1)
)
)
diff --git a/tests/compiler/import.wast b/tests/compiler/import.wast
index f7541ce6..c88c0dec 100644
--- a/tests/compiler/import.wast
+++ b/tests/compiler/import.wast
@@ -1,8 +1,8 @@
(module
(type $iii (func (param i32 i32) (result i32)))
(type $v (func))
- (global $export/a i32 (i32.const 1))
(global $export/b i32 (i32.const 2))
+ (global $export/a i32 (i32.const 1))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
(export "memory" (memory $0))
@@ -26,6 +26,9 @@
(func $export/ns.two (; 2 ;) (type $v)
)
(func $start (; 3 ;) (type $v)
+ (drop
+ (i32.const 2)
+ )
(drop
(i32.add
(call $export/add
diff --git a/tests/compiler/infer-type.ts b/tests/compiler/infer-type.ts
index 0333c576..04e7f0cc 100644
--- a/tests/compiler/infer-type.ts
+++ b/tests/compiler/infer-type.ts
@@ -8,39 +8,39 @@ const F = 1.5;
F;
function locals(): void {
- let li = 10;
- let lI = 0x100000000;
- let lF = 1.5;
- let ai = i;
- let aI = I;
- let aF = F;
+ var li = 10;
+ var lI = 0x100000000;
+ var lF = 1.5;
+ var ai = i;
+ var aI = I;
+ var aF = F;
}
locals();
function reti(): i32 {
return 0;
}
-let ri = reti();
+var ri = reti();
ri;
function retI(): i64 {
return 0;
}
-let rI = retI();
+var rI = retI();
rI;
function retf(): f32 {
return 0;
}
-let rf = retf();
+var rf = retf();
rf;
function refF(): f64 {
return 0;
}
-let rF = refF();
+var rF = refF();
rF;
-for (let a = 0, b = 10; a < b; ++a) {
+for (var a = 0, b = 10; a < b; ++a) {
;
}
diff --git a/tests/compiler/logical.ts b/tests/compiler/logical.ts
index 233a45e4..14218e9a 100644
--- a/tests/compiler/logical.ts
+++ b/tests/compiler/logical.ts
@@ -6,7 +6,7 @@
1 && 2 || unreachable();
1.0 && 2.0 || unreachable();
-let i: i32;
+var i: i32;
i = 1 && 2;
assert(i == 2);
@@ -14,7 +14,7 @@ assert(i == 2);
i = 0 || 1;
assert(i == 1);
-let I: i64;
+var I: i64;
I = 1 && 2;
assert(I == 2);
@@ -22,7 +22,7 @@ assert(I == 2);
I = 0 || 1;
assert(I == 1);
-let f: f32;
+var f: f32;
f = 1.0 && 2.0;
assert(f == 2.0);
@@ -30,7 +30,7 @@ assert(f == 2.0);
f = 0.0 || 1.0;
assert(f == 1.0);
-let F: f64;
+var F: f64;
F = 1.0 && 2.0;
assert(F == 2.0);
diff --git a/tests/compiler/memcpy.ts b/tests/compiler/memcpy.ts
index 985105e1..61abf32b 100644
--- a/tests/compiler/memcpy.ts
+++ b/tests/compiler/memcpy.ts
@@ -1,7 +1,7 @@
export function memcpy(dest: usize, src: usize, n: usize): usize {
// the following is based on musl's implementation of memcpy
- let d: usize = dest, s: usize = src;
- let w: u32, x: u32;
+ var d: usize = dest, s: usize = src;
+ var w: u32, x: u32;
// copy 1 byte each until src is aligned to 4 bytes
while (n && s % 4) {
@@ -147,7 +147,7 @@ store(base + 8 , 0x2222222222222222);
store(base + 16, 0x3333333333333333);
store(base + 24, 0x4444444444444444);
-let dest: usize;
+var dest: usize;
dest = memcpy(base + 1, base + 16, 4);
assert(dest == base + 1);
assert(load(base) == 0x1111113333333311);
diff --git a/tests/compiler/namespace.ts b/tests/compiler/namespace.ts
index b957f57f..91ccc25b 100644
--- a/tests/compiler/namespace.ts
+++ b/tests/compiler/namespace.ts
@@ -1,6 +1,6 @@
namespace Outer {
export namespace Inner {
- export let aVar: i32 = 0;
+ export var aVar: i32 = 0;
export function aFunc(): i32 { return aVar; }
export enum anEnum { ONE = 1, TWO = 2 }
}
diff --git a/tests/compiler/portable-conversions.ts b/tests/compiler/portable-conversions.ts
index a8b6afd3..0a697920 100644
--- a/tests/compiler/portable-conversions.ts
+++ b/tests/compiler/portable-conversions.ts
@@ -1,7 +1,7 @@
-let i: i32 = 0;
-let I: i64 = 0;
-let f: f32 = 0;
-let F: f64 = 0;
+var i: i32 = 0;
+var I: i64 = 0;
+var f: f32 = 0;
+var F: f64 = 0;
i8(i);
i8(I);
diff --git a/tests/compiler/reexport.optimized.wast b/tests/compiler/reexport.optimized.wast
index f3fc9b36..157cceed 100644
--- a/tests/compiler/reexport.optimized.wast
+++ b/tests/compiler/reexport.optimized.wast
@@ -1,8 +1,8 @@
(module
(type $iii (func (param i32 i32) (result i32)))
(type $v (func))
- (global $export/a i32 (i32.const 1))
(global $export/b i32 (i32.const 2))
+ (global $export/a i32 (i32.const 1))
(memory $0 1)
(export "add" (func $export/add))
(export "renamed_sub" (func $export/sub))
diff --git a/tests/compiler/reexport.wast b/tests/compiler/reexport.wast
index b9740ca9..aca3b6a8 100644
--- a/tests/compiler/reexport.wast
+++ b/tests/compiler/reexport.wast
@@ -1,8 +1,8 @@
(module
(type $iii (func (param i32 i32) (result i32)))
(type $v (func))
- (global $export/a i32 (i32.const 1))
(global $export/b i32 (i32.const 2))
+ (global $export/a i32 (i32.const 1))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
(export "add" (func $export/add))
@@ -32,6 +32,9 @@
(func $export/ns.two (; 2 ;) (type $v)
)
(func $start (; 3 ;) (type $v)
+ (drop
+ (i32.const 2)
+ )
(drop
(i32.add
(call $export/add
diff --git a/tests/compiler/ternary.ts b/tests/compiler/ternary.ts
index b6ab6041..eeb549f0 100644
--- a/tests/compiler/ternary.ts
+++ b/tests/compiler/ternary.ts
@@ -2,7 +2,7 @@
1 ? 1 : unreachable();
(0 ? unreachable() : 1) ? 1 : unreachable();
-let a: i32;
+var a: i32;
a = 0 ? unreachable() : 1;
a = 1 ? 1 : unreachable();
diff --git a/tests/compiler/tlsf.ts b/tests/compiler/tlsf.ts
index c959c3dd..ec768b6e 100644
--- a/tests/compiler/tlsf.ts
+++ b/tests/compiler/tlsf.ts
@@ -180,9 +180,9 @@ export function control$construct(ptr: usize): void {
block$set_next_free(ptr, ptr);
block$set_prev_free(ptr, ptr);
control$set_fl_bitmap(ptr, 0);
- for (let flIndex: usize = 0; flIndex < FL_INDEX_COUNT; ++flIndex) {
+ for (var flIndex: usize = 0; flIndex < FL_INDEX_COUNT; ++flIndex) {
control$set_sl_bitmap(ptr, flIndex, 0);
- for (let slIndex: usize = 0; slIndex < SL_INDEX_COUNT; ++slIndex)
+ for (var slIndex: usize = 0; slIndex < SL_INDEX_COUNT; ++slIndex)
control$set_block(ptr, flIndex, slIndex, ptr);
}
}
diff --git a/tests/compiler/unary.ts b/tests/compiler/unary.ts
index d8993e60..7f7ead55 100644
--- a/tests/compiler/unary.ts
+++ b/tests/compiler/unary.ts
@@ -6,7 +6,7 @@
-1.25;
!1.25;
-let i: i32 = 0;
+var i: i32 = 0;
+i;
-i;
@@ -30,7 +30,7 @@ i = --i;
i = i++;
i = i--;
-let I: i64 = 0;
+var I: i64 = 0;
+I;
-I;
@@ -54,7 +54,7 @@ I = --I;
I = I++;
I = I--;
-let f: f32 = 0;
+var f: f32 = 0;
+f;
-f;
@@ -75,7 +75,7 @@ f = --f;
f = f++;
f = f--;
-let F: f64 = 0;
+var F: f64 = 0;
+F;
-F;
diff --git a/tests/compiler/while.optimized.wast b/tests/compiler/while.optimized.wast
index d7dfbaf4..e14044fc 100644
--- a/tests/compiler/while.optimized.wast
+++ b/tests/compiler/while.optimized.wast
@@ -1,17 +1,26 @@
(module
- (type $iv (func (param i32)))
+ (type $v (func))
+ (global $while/n (mut i32) (i32.const 10))
+ (global $while/m (mut i32) (i32.const 0))
+ (global $while/o (mut i32) (i32.const 0))
(memory $0 1)
- (export "loopWhile" (func $while/loopWhile))
- (export "loopWhileInWhile" (func $while/loopWhileInWhile))
(export "memory" (memory $0))
- (func $while/loopWhile (; 0 ;) (type $iv) (param $0 i32)
+ (start $start)
+ (func $start (; 0 ;) (type $v)
+ (local $0 i32)
(loop $continue|0
(if
- (get_local $0)
+ (get_global $while/n)
(block
- (set_local $0
+ (set_global $while/n
(i32.sub
- (get_local $0)
+ (get_global $while/n)
+ (i32.const 1)
+ )
+ )
+ (set_global $while/m
+ (i32.add
+ (get_global $while/m)
(i32.const 1)
)
)
@@ -19,35 +28,140 @@
)
)
)
- )
- (func $while/loopWhileInWhile (; 1 ;) (type $iv) (param $0 i32)
- (loop $continue|0
+ (if
+ (get_global $while/n)
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $while/m)
+ (i32.const 10)
+ )
+ (unreachable)
+ )
+ (set_global $while/n
+ (i32.const 10)
+ )
+ (set_global $while/m
+ (i32.const 0)
+ )
+ (loop $continue|1
(if
- (get_local $0)
+ (get_global $while/n)
(block
- (set_local $0
+ (set_global $while/n
(i32.sub
- (get_local $0)
+ (get_global $while/n)
(i32.const 1)
)
)
- (loop $continue|1
+ (set_global $while/m
+ (i32.add
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ )
+ (loop $continue|2
(if
- (get_local $0)
+ (get_global $while/n)
(block
- (set_local $0
+ (set_global $while/n
(i32.sub
- (get_local $0)
+ (get_global $while/n)
(i32.const 1)
)
)
- (br $continue|1)
+ (set_global $while/o
+ (i32.add
+ (get_global $while/o)
+ (i32.const 1)
+ )
+ )
+ (br $continue|2)
)
)
)
- (br $continue|0)
+ (if
+ (get_global $while/n)
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $while/o)
+ (i32.const 9)
+ )
+ (unreachable)
+ )
+ (br $continue|1)
)
)
)
+ (if
+ (get_global $while/n)
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $while/o)
+ (i32.const 9)
+ )
+ (unreachable)
+ )
+ (set_global $while/n
+ (i32.const 1)
+ )
+ (set_global $while/m
+ (i32.const 0)
+ )
+ (loop $continue|3
+ (br_if $continue|3
+ (if (result i32)
+ (block (result i32)
+ (set_global $while/n
+ (i32.sub
+ (tee_local $0
+ (get_global $while/n)
+ )
+ (i32.const 1)
+ )
+ )
+ (tee_local $0
+ (get_local $0)
+ )
+ )
+ (block (result i32)
+ (set_global $while/m
+ (i32.add
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ )
+ (get_global $while/m)
+ )
+ (get_local $0)
+ )
+ )
+ )
+ (if
+ (i32.ne
+ (get_global $while/n)
+ (i32.const -1)
+ )
+ (unreachable)
+ )
+ (if
+ (i32.ne
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ (unreachable)
+ )
)
)
diff --git a/tests/compiler/while.ts b/tests/compiler/while.ts
index 95ad44f7..4f2d3f38 100644
--- a/tests/compiler/while.ts
+++ b/tests/compiler/while.ts
@@ -1,14 +1,32 @@
-export function loopWhile(n: i32): void {
- while (n) {
- n = n - 1;
- }
-}
+var n = 10;
+var m = 0;
-export function loopWhileInWhile(n: i32): void {
- while (n) {
- n = n - 1;
- while (n) {
- n = n - 1;
- }
- }
+while (n) {
+ n--;
+ m++;
}
+assert(n == 0);
+assert(m == 10);
+
+n = 10;
+m = 0;
+var o = 0;
+while (n) {
+ n--;
+ m++;
+ while (n) {
+ n--;
+ o++;
+ }
+ assert(n == 0);
+ assert(o == 9);
+}
+assert(n == 0);
+assert(m == 1);
+assert(o == 9);
+
+n = 1;
+m = 0;
+while (n-- && ++m);
+assert(n == -1);
+assert(m == 1);
diff --git a/tests/compiler/while.wast b/tests/compiler/while.wast
index 620299f0..0134242e 100644
--- a/tests/compiler/while.wast
+++ b/tests/compiler/while.wast
@@ -1,20 +1,47 @@
(module
- (type $iv (func (param i32)))
+ (type $v (func))
+ (global $while/n (mut i32) (i32.const 10))
+ (global $while/m (mut i32) (i32.const 0))
+ (global $while/o (mut i32) (i32.const 0))
(global $HEAP_BASE i32 (i32.const 4))
(memory $0 1)
- (export "loopWhile" (func $while/loopWhile))
- (export "loopWhileInWhile" (func $while/loopWhileInWhile))
(export "memory" (memory $0))
- (func $while/loopWhile (; 0 ;) (type $iv) (param $0 i32)
+ (start $start)
+ (func $start (; 0 ;) (type $v)
+ (local $0 i32)
(block $break|0
(loop $continue|0
(if
- (get_local $0)
+ (get_global $while/n)
(block
- (set_local $0
- (i32.sub
- (get_local $0)
- (i32.const 1)
+ (block
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $while/n)
+ )
+ (set_global $while/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $while/m)
+ )
+ (set_global $while/m
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
)
)
(br $continue|0)
@@ -22,42 +49,218 @@
)
)
)
- )
- (func $while/loopWhileInWhile (; 1 ;) (type $iv) (param $0 i32)
- (block $break|0
- (loop $continue|0
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/n)
+ (i32.const 0)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/m)
+ (i32.const 10)
+ )
+ )
+ (unreachable)
+ )
+ (set_global $while/n
+ (i32.const 10)
+ )
+ (set_global $while/m
+ (i32.const 0)
+ )
+ (block $break|1
+ (loop $continue|1
(if
- (get_local $0)
+ (get_global $while/n)
(block
(block
- (set_local $0
- (i32.sub
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $while/n)
+ )
+ (set_global $while/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
(get_local $0)
- (i32.const 1)
)
)
- (block $break|1
- (loop $continue|1
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $while/m)
+ )
+ (set_global $while/m
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (block $break|2
+ (loop $continue|2
(if
- (get_local $0)
+ (get_global $while/n)
(block
- (set_local $0
- (i32.sub
- (get_local $0)
- (i32.const 1)
+ (block
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $while/n)
+ )
+ (set_global $while/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (drop
+ (block (result i32)
+ (set_local $0
+ (get_global $while/o)
+ )
+ (set_global $while/o
+ (i32.add
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
)
)
- (br $continue|1)
+ (br $continue|2)
)
)
)
)
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/n)
+ (i32.const 0)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/o)
+ (i32.const 9)
+ )
+ )
+ (unreachable)
+ )
)
- (br $continue|0)
+ (br $continue|1)
)
)
)
)
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/n)
+ (i32.const 0)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/o)
+ (i32.const 9)
+ )
+ )
+ (unreachable)
+ )
+ (set_global $while/n
+ (i32.const 1)
+ )
+ (set_global $while/m
+ (i32.const 0)
+ )
+ (block $break|3
+ (loop $continue|3
+ (if
+ (if (result i32)
+ (tee_local $0
+ (block (result i32)
+ (set_local $0
+ (get_global $while/n)
+ )
+ (set_global $while/n
+ (i32.sub
+ (get_local $0)
+ (i32.const 1)
+ )
+ )
+ (get_local $0)
+ )
+ )
+ (block (result i32)
+ (set_global $while/m
+ (i32.add
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ )
+ (get_global $while/m)
+ )
+ (get_local $0)
+ )
+ (block
+ (nop)
+ (br $continue|3)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/n)
+ (i32.sub
+ (i32.const 0)
+ (i32.const 1)
+ )
+ )
+ )
+ (unreachable)
+ )
+ (if
+ (i32.eqz
+ (i32.eq
+ (get_global $while/m)
+ (i32.const 1)
+ )
+ )
+ (unreachable)
+ )
)
)
(;
@@ -106,9 +309,9 @@
FUNCTION_PROTOTYPE: isize
FUNCTION_PROTOTYPE: usize
GLOBAL: HEAP_BASE
- FUNCTION_PROTOTYPE: while/loopWhile
- FUNCTION_PROTOTYPE: while/loopWhileInWhile
+ GLOBAL: while/n
+ GLOBAL: while/m
+ GLOBAL: while/o
[program.exports]
- FUNCTION_PROTOTYPE: while/loopWhile
- FUNCTION_PROTOTYPE: while/loopWhileInWhile
+
;)