mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
PSON decoder example using namespaced imports
This commit is contained in:
parent
c67f87a988
commit
2888ba14ad
@ -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)**<br />
|
||||
Exposes WebAssembly's i64 operations to JavaScript using 32-bit integers (low and high bits).
|
||||
|
||||
* **[PSON decoder](./examples/pson)**<br />
|
||||
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
|
||||
|
2
examples/.gitignore
vendored
2
examples/.gitignore
vendored
@ -1,3 +1,5 @@
|
||||
*.wast
|
||||
*.wasm
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
package-lock.json
|
||||
|
@ -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<u32>(hm1, y - 1, y == 0);
|
||||
yp1 = select<u32>(0, y + 1, y == hm1);
|
||||
for (x = 0; x < w; ++x) {
|
||||
xm1 = select<u32>(wm1, x - 1, x == 0);
|
||||
xp1 = select<u32>(0, x + 1, x == wm1);
|
||||
n = load<u8>(ym1 * w + xm1) + load<u8>(ym1 * w + x) + load<u8>(ym1 * w + xp1)
|
||||
+ load<u8>(y * w + xm1) + load<u8>(y * w + xp1)
|
||||
+ load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1);
|
||||
v = load<u8>(y * w + x);
|
||||
if (v) {
|
||||
var hm1 = h - 1,
|
||||
wm1 = w - 1;
|
||||
for (var y: u32 = 0; y < h; ++y) {
|
||||
var ym1 = select<u32>(hm1, y - 1, y == 0),
|
||||
yp1 = select<u32>(0, y + 1, y == hm1);
|
||||
for (var x: u32 = 0; x < w; ++x) {
|
||||
var xm1 = select<u32>(wm1, x - 1, x == 0),
|
||||
xp1 = select<u32>(0, x + 1, x == wm1);
|
||||
var n = load<u8>(ym1 * w + xm1) + load<u8>(ym1 * w + x) + load<u8>(ym1 * w + xp1)
|
||||
+ load<u8>(y * w + xm1) + load<u8>(y * w + xp1)
|
||||
+ load<u8>(yp1 * w + xm1) + load<u8>(yp1 * w + x) + load<u8>(yp1 * w + xp1);
|
||||
if (load<u8>(y * w + x)) {
|
||||
if (n < 2 || n > 3)
|
||||
store<u8>(s + y * w + x, 0);
|
||||
} else if (n == 3)
|
||||
|
@ -1,5 +1,5 @@
|
||||
let lo: u32;
|
||||
let hi: u32;
|
||||
var lo: u32,
|
||||
hi: u32;
|
||||
|
||||
export function getLo(): u32 {
|
||||
return lo;
|
||||
|
19
examples/pson/README.md
Normal file
19
examples/pson/README.md
Normal file
@ -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
|
||||
```
|
156
examples/pson/assembly/pson.ts
Normal file
156
examples/pson/assembly/pson.ts
Normal file
@ -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<u8>(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(<i32>long, <i32>(long >>> 32));
|
||||
break;
|
||||
|
||||
case Token.FLOAT:
|
||||
pson.onFloat(load<f32>(offset));
|
||||
offset += 4;
|
||||
break;
|
||||
|
||||
case Token.DOUBLE:
|
||||
pson.onDouble(load<f64>(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<u8>(offset++);
|
||||
value |= <u32>(b & 0x7f) << (7 * shift++);
|
||||
} while (b & 0x80);
|
||||
return value;
|
||||
}
|
||||
|
||||
function readVarint64(): u64 {
|
||||
var value: u64 = 0;
|
||||
var shift: u64 = 0;
|
||||
do {
|
||||
var b = load<u8>(offset++);
|
||||
value |= <u64>(b & 0x7f) << (7 * shift++);
|
||||
} while (b & 0x80);
|
||||
return value;
|
||||
}
|
6
examples/pson/assembly/tsconfig.json
Normal file
6
examples/pson/assembly/tsconfig.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"extends": "../../../std/assembly.json",
|
||||
"include": [
|
||||
"./**/*.ts"
|
||||
]
|
||||
}
|
71
examples/pson/index.js
Normal file
71
examples/pson/index.js
Normal file
@ -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);
|
||||
}
|
14
examples/pson/package.json
Normal file
14
examples/pson/package.json
Normal file
@ -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"
|
||||
}
|
||||
}
|
24
examples/pson/tests/index.js
Normal file
24
examples/pson/tests/index.js
Normal file
@ -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);
|
@ -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<string>();
|
||||
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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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((<Uint8Array>u8s).length);
|
||||
var ptr = Heap.allocate(u8s.length);
|
||||
var idx = ptr;
|
||||
for (var i = 0, k = (<Uint8Array>u8s).length; i < k; ++i)
|
||||
store<u8>(idx++, (<Uint8Array>u8s)[i]);
|
||||
for (var i = 0, k = u8s.length; i < k; ++i)
|
||||
store<u8>(idx++, u8s[i]);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
function allocI32Array(i32s: i32[] | null): usize {
|
||||
if (!i32s) return 0;
|
||||
var ptr = Heap.allocate((<i32[]>i32s).length << 2);
|
||||
var ptr = Heap.allocate(i32s.length << 2);
|
||||
var idx = ptr;
|
||||
for (var i = 0, k = (<i32[]>i32s).length; i < k; ++i) {
|
||||
var val = (<i32[]>i32s)[i];
|
||||
for (var i = 0, k = i32s.length; i < k; ++i) {
|
||||
var val = i32s[i];
|
||||
// store<i32>(idx, val) is not portable
|
||||
store<u8>(idx , ( val & 0xff) as u8);
|
||||
store<u8>(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((<string>str)) + 1);
|
||||
var ptr = Heap.allocate(stringLengthUTF8(str) + 1);
|
||||
var idx = ptr;
|
||||
for (var i = 0, k = (<string>str).length; i < k; ++i) {
|
||||
var u = (<string>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) | ((<string>str).charCodeAt(++i) & 0x3FF);
|
||||
u = 0x10000 + ((u & 0x3FF) << 10) | (str.charCodeAt(++i) & 0x3FF);
|
||||
if (u <= 0x7F)
|
||||
store<u8>(idx++, u as u8);
|
||||
else if (u <= 0x7FF) {
|
||||
|
@ -1 +1,3 @@
|
||||
assert(true);
|
||||
assert(1 == 1);
|
||||
assert(0.5 > 0.4);
|
||||
|
@ -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)
|
||||
)
|
||||
)
|
||||
)
|
||||
(;
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -1,8 +1,8 @@
|
||||
let b: bool;
|
||||
var b: bool;
|
||||
|
||||
// integers
|
||||
|
||||
let i: i32;
|
||||
var i: i32;
|
||||
|
||||
clz<i32>(1);
|
||||
ctz<i32>(1);
|
||||
@ -22,7 +22,7 @@ i = abs<i32>(-42); assert(i == 42);
|
||||
i = max<i32>(1, 2); assert(i == 2);
|
||||
i = min<i32>(1, 2); assert(i == 1);
|
||||
|
||||
let I: i64;
|
||||
var I: i64;
|
||||
|
||||
clz<i64>(1);
|
||||
ctz<i64>(1);
|
||||
@ -42,7 +42,7 @@ I = min<i64>(1, 2); assert(i == 1);
|
||||
|
||||
// floats
|
||||
|
||||
let f: f32;
|
||||
var f: f32;
|
||||
|
||||
<f32>NaN;
|
||||
<f32>Infinity;
|
||||
@ -72,7 +72,7 @@ f = trunc<f32>(1.25);
|
||||
b = isNaN<f32>(1.25);
|
||||
b = isFinite<f32>(1.25);
|
||||
|
||||
let F: f64;
|
||||
var F: f64;
|
||||
|
||||
<f64>NaN;
|
||||
<f64>Infinity;
|
||||
@ -129,7 +129,7 @@ F = reinterpret<i64,f64>(25);
|
||||
|
||||
// host
|
||||
|
||||
let s: usize;
|
||||
var s: usize;
|
||||
|
||||
current_memory();
|
||||
grow_memory(1);
|
||||
@ -179,8 +179,9 @@ assert(isFinite<f64>(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");
|
||||
}
|
||||
|
@ -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
|
||||
;)
|
||||
|
@ -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)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
;)
|
||||
|
@ -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)
|
||||
|
@ -11,6 +11,7 @@ export { sub as renamed_sub };
|
||||
export const a: i32 = 1;
|
||||
|
||||
const b: i32 = 2;
|
||||
b;
|
||||
|
||||
export { b as renamed_b };
|
||||
|
||||
|
@ -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]
|
||||
|
@ -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) {
|
||||
;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
)
|
||||
)
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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<u64>(base + 8 , 0x2222222222222222);
|
||||
store<u64>(base + 16, 0x3333333333333333);
|
||||
store<u64>(base + 24, 0x4444444444444444);
|
||||
|
||||
let dest: usize;
|
||||
var dest: usize;
|
||||
dest = memcpy(base + 1, base + 16, 4);
|
||||
assert(dest == base + 1);
|
||||
assert(load<u64>(base) == 0x1111113333333311);
|
||||
|
@ -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 }
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
)
|
||||
)
|
||||
)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
;)
|
||||
|
Loading…
x
Reference in New Issue
Block a user