Fixes; Builtins; Testing in the interpreter

This commit is contained in:
dcodeIO 2017-12-03 23:04:33 +01:00
parent 032ae379cd
commit 017efc71b6
33 changed files with 791 additions and 68 deletions

View File

@ -3,7 +3,7 @@ AssemblyScript NEXT
[![Build Status](https://travis-ci.org/AssemblyScript/next.svg?branch=master)](https://travis-ci.org/AssemblyScript/next) [![Build Status](https://travis-ci.org/AssemblyScript/next.svg?branch=master)](https://travis-ci.org/AssemblyScript/next)
This repository contains compiler component prototypes for the next iteration of the AssemblyScript compiler written in AssemblyScript itself. This repository contains compiler components for the next iteration of the AssemblyScript compiler written in AssemblyScript itself.
Note that the code uses some features and standard library components that are not yet supported by any version of asc. To account for this, the code has been written in "portable AssemblyScript", a TypeScript-compatible subset of a subset of a superset of JavaScript, that also compiles to JavaScript using TSC. Note that the code uses some features and standard library components that are not yet supported by any version of asc. To account for this, the code has been written in "portable AssemblyScript", a TypeScript-compatible subset of a subset of a superset of JavaScript, that also compiles to JavaScript using TSC.

4
assembly.d.ts vendored
View File

@ -30,7 +30,7 @@ declare type f64 = number;
// builtins // builtins
/** Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero. */ /** Performs the sign-agnostic count leading zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered leading if the value is zero. */
declare function clz<T>(value: T): T; declare function clz<T extends number>(value: T): T;
/** Performs the sign-agnostic count tailing zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered trailing if the value is zero. */ /** Performs the sign-agnostic count tailing zero bits operation on a 32-bit or 64-bit integer. All zero bits are considered trailing if the value is zero. */
declare function ctz<T>(value: T): T; declare function ctz<T>(value: T): T;
/** Performs the sign-agnostic count number of one bits operation on a 32-bit or 64-bit integer. */ /** Performs the sign-agnostic count number of one bits operation on a 32-bit or 64-bit integer. */
@ -84,6 +84,8 @@ declare const Infinity: number;
declare function isNaN<T>(value: T): bool; declare function isNaN<T>(value: T): bool;
/** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */ /** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */
declare function isFinite<T>(value: T): bool; declare function isFinite<T>(value: T): bool;
/** Traps if the specified value is `false`. */
declare function assert(isTrue: bool): void;
// internal decorators // internal decorators

View File

@ -1,6 +1,6 @@
import { PATH_DELIMITER } from "./constants"; import { PATH_DELIMITER } from "./constants";
import { DiagnosticCode, DiagnosticMessage, DiagnosticEmitter } from "./diagnostics"; import { DiagnosticCode, DiagnosticMessage, DiagnosticEmitter } from "./diagnostics";
import { Module, MemorySegment, ExpressionRef, UnaryOp, BinaryOp, HostOp, NativeType, FunctionTypeRef } from "./module"; import { Module, MemorySegment, ExpressionRef, UnaryOp, BinaryOp, HostOp, NativeType, FunctionTypeRef, getExpressionId, ExpressionId } from "./module";
import { Program, ClassPrototype, Class, Element, ElementKind, Enum, FunctionPrototype, Function, Global, Local, Namespace, Parameter } from "./program"; import { Program, ClassPrototype, Class, Element, ElementKind, Enum, FunctionPrototype, Function, Global, Local, Namespace, Parameter } from "./program";
import { CharCode, I64, U64, normalizePath, sb } from "./util"; import { CharCode, I64, U64, normalizePath, sb } from "./util";
import { Token, Range } from "./tokenizer"; import { Token, Range } from "./tokenizer";
@ -286,11 +286,13 @@ export class Compiler extends DiagnosticEmitter {
// globals // globals
compileGlobalDeclaration(declaration: VariableDeclaration, isConst: bool): bool { compileGlobalDeclaration(declaration: VariableDeclaration, isConst: bool): Global | null {
const element: Element | null = <Element | null>this.program.elements.get(declaration.internalName); const element: Element | null = <Element | null>this.program.elements.get(declaration.internalName);
if (!element || element.kind != ElementKind.GLOBAL) if (!element || element.kind != ElementKind.GLOBAL)
throw new Error("unexpected missing global"); throw new Error("unexpected missing global");
return this.compileGlobal(<Global>element); return this.compileGlobal(<Global>element)
? <Global>element
: null;
} }
compileGlobal(element: Global): bool { compileGlobal(element: Global): bool {
@ -333,7 +335,7 @@ export class Compiler extends DiagnosticEmitter {
} else if (declaration) { } else if (declaration) {
if (declaration.initializer) { if (declaration.initializer) {
initializer = this.compileExpression(declaration.initializer, type); initializer = this.compileExpression(declaration.initializer, type);
initializeInStart = declaration.initializer.kind != NodeKind.LITERAL; // MVP doesn't support complex initializers initializeInStart = getExpressionId(initializer) != ExpressionId.Const; // MVP doesn't support complex initializers
} else { } else {
initializer = typeToNativeZero(this.module, type); initializer = typeToNativeZero(this.module, type);
initializeInStart = false; initializeInStart = false;
@ -342,12 +344,14 @@ export class Compiler extends DiagnosticEmitter {
throw new Error("unexpected missing declaration or constant value"); throw new Error("unexpected missing declaration or constant value");
const internalName: string = element.internalName; const internalName: string = element.internalName;
if (initializeInStart) { if (initializeInStart) {
this.module.addGlobal(internalName, nativeType, true, this.module.createI32(-1)); this.module.addGlobal(internalName, nativeType, true, typeToNativeZero(this.module, type));
this.startFunctionBody.push(this.module.createSetGlobal(internalName, initializer)); this.startFunctionBody.push(this.module.createSetGlobal(internalName, initializer));
} else } else {
this.module.addGlobal(internalName, nativeType, element.isMutable, initializer); this.module.addGlobal(internalName, nativeType, element.isMutable, initializer);
// if (element.globalExportName != null && element.hasConstantValue && !initializeInStart) if (!element.isMutable) {
// this.module.addGlobalExport(element.internalName, element.globalExportName); // TODO: check export, requires updated binaryen.js with Module#addGlobalExport
}
}
return element.isCompiled = true; return element.isCompiled = true;
} }
@ -373,7 +377,7 @@ export class Compiler extends DiagnosticEmitter {
let initializeInStart: bool = false; let initializeInStart: bool = false;
if (declaration.value) { if (declaration.value) {
initializer = this.compileExpression(<Expression>declaration.value, Type.i32); initializer = this.compileExpression(<Expression>declaration.value, Type.i32);
initializeInStart = declaration.value.kind != NodeKind.LITERAL; // MVP doesn't support complex initializers initializeInStart = getExpressionId(initializer) != ExpressionId.Const; // MVP doesn't support complex initializers
} else if (previousInternalName == null) { } else if (previousInternalName == null) {
initializer = this.module.createI32(0); initializer = this.module.createI32(0);
initializeInStart = false; initializeInStart = false;
@ -385,10 +389,12 @@ export class Compiler extends DiagnosticEmitter {
initializeInStart = true; initializeInStart = true;
} }
if (initializeInStart) { if (initializeInStart) {
this.module.addGlobal(val.internalName, NativeType.I32, true, this.module.createI32(-1)); this.module.addGlobal(val.internalName, NativeType.I32, true, this.module.createI32(0));
this.startFunctionBody.push(this.module.createSetGlobal(val.internalName, initializer)); this.startFunctionBody.push(this.module.createSetGlobal(val.internalName, initializer));
} else } else {
this.module.addGlobal(val.internalName, NativeType.I32, false, initializer); this.module.addGlobal(val.internalName, NativeType.I32, false, initializer);
// TODO: check export, requires updated binaryen.js with Module#addGlobalExport
}
} else } else
throw new Error("unexpected missing declaration or constant value"); throw new Error("unexpected missing declaration or constant value");
previousInternalName = val.internalName; previousInternalName = val.internalName;
@ -1183,6 +1189,20 @@ export class Compiler extends DiagnosticEmitter {
this.currentType = Type.bool; this.currentType = Type.bool;
break; break;
case Token.EXCLAMATION_EQUALS:
case Token.EXCLAMATION_EQUALS_EQUALS:
left = this.compileExpression(expression.left, contextualType, ConversionKind.NONE);
right = this.compileExpression(expression.right, this.currentType);
op = this.currentType == Type.f32
? BinaryOp.NeF32
: this.currentType == Type.f64
? BinaryOp.NeF64
: this.currentType.isLongInteger
? BinaryOp.NeI64
: BinaryOp.NeI32;
this.currentType = Type.bool;
break;
case Token.EQUALS: case Token.EQUALS:
return this.compileAssignment(expression.left, expression.right, contextualType); return this.compileAssignment(expression.left, expression.right, contextualType);
@ -1544,7 +1564,7 @@ export class Compiler extends DiagnosticEmitter {
return this.module.createHost(HostOp.CurrentMemory); return this.module.createHost(HostOp.CurrentMemory);
case "grow_memory": case "grow_memory":
this.warning(DiagnosticCode.Operation_is_unsafe, reportNode.range); // unsure // this.warning(DiagnosticCode.Operation_is_unsafe, reportNode.range); // unsure
return this.module.createHost(HostOp.GrowMemory, null, operands); return this.module.createHost(HostOp.GrowMemory, null, operands);
case "unreachable": case "unreachable":
@ -1566,7 +1586,7 @@ export class Compiler extends DiagnosticEmitter {
tempLocal = this.currentFunction.addLocal(Type.f32); tempLocal = this.currentFunction.addLocal(Type.f32);
return this.module.createBinary(BinaryOp.NeF32, return this.module.createBinary(BinaryOp.NeF32,
this.module.createTeeLocal(tempLocal.index, operands[0]), this.module.createTeeLocal(tempLocal.index, operands[0]),
this.module.createGetLocal(tempLocal.index, NativeType.F64) this.module.createGetLocal(tempLocal.index, NativeType.F32)
); );
} }
break; break;
@ -1604,6 +1624,12 @@ export class Compiler extends DiagnosticEmitter {
); );
} }
break; break;
case "assert":
return this.module.createIf(
this.module.createUnary(UnaryOp.EqzI32, operands[0]),
this.module.createUnreachable()
);
} }
this.error(DiagnosticCode.Operation_not_supported, reportNode.range); this.error(DiagnosticCode.Operation_not_supported, reportNode.range);
return this.module.createUnreachable(); return this.module.createUnreachable();

View File

@ -1,5 +1,5 @@
import { Range } from "./ast"; import { Range } from "./ast";
import { isLineBreak, sb } from "./util"; import { CharCode, isLineBreak, sb } from "./util";
import { DiagnosticCode, diagnosticCodeToString } from "./diagnosticMessages.generated"; import { DiagnosticCode, diagnosticCodeToString } from "./diagnosticMessages.generated";
export { DiagnosticCode, diagnosticCodeToString } from "./diagnosticMessages.generated"; export { DiagnosticCode, diagnosticCodeToString } from "./diagnosticMessages.generated";
@ -100,9 +100,9 @@ export function formatDiagnosticMessage(message: DiagnosticMessage, useColors: b
sb.push("\n"); sb.push("\n");
let pos: i32 = range.start; let pos: i32 = range.start;
let line: i32 = 1; let line: i32 = 1;
let column: i32 = 0; let column: i32 = 1;
while (pos-- > 0) while (pos-- > 0)
if (isLineBreak(text.charCodeAt(pos))) if (text.charCodeAt(pos) == CharCode.LINEFEED)
line++; line++;
else if (line == 1) else if (line == 1)
column++; column++;

View File

@ -613,6 +613,10 @@ export class Module {
return _BinaryenModuleValidate(this.ref) == 1; return _BinaryenModuleValidate(this.ref) == 1;
} }
interpret(): void {
return _BinaryenModuleInterpret(this.ref);
}
toBinary(): Uint8Array { toBinary(): Uint8Array {
throw new Error("not implemented"); throw new Error("not implemented");
} }
@ -726,6 +730,10 @@ export class Relooper {
} }
} }
// export function setAPITracing(on: bool): void {
// _BinaryenSetAPITracing(on ? 1 : 0);
// }
// helpers // helpers
// can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js // can't do stack allocation here: STACKTOP is a global in WASM but a hidden variable in asm.js

View File

@ -1131,6 +1131,7 @@ function initializeBuiltins(program: Program): void {
const genericInt: Type[] = [ Type.i32, Type.i64 ]; const genericInt: Type[] = [ Type.i32, Type.i64 ];
const genericFloat: Type[] = [ Type.f32, Type.f64 ]; const genericFloat: Type[] = [ Type.f32, Type.f64 ];
const usize: Type = program.target == Target.WASM64 ? Type.usize64 : Type.usize32;
addGenericUnaryBuiltin(program, "clz", genericInt); addGenericUnaryBuiltin(program, "clz", genericInt);
addGenericUnaryBuiltin(program, "ctz", genericInt); addGenericUnaryBuiltin(program, "ctz", genericInt);
@ -1140,7 +1141,7 @@ function initializeBuiltins(program: Program): void {
addGenericUnaryBuiltin(program, "abs", genericFloat); addGenericUnaryBuiltin(program, "abs", genericFloat);
addGenericUnaryBuiltin(program, "ceil", genericFloat); addGenericUnaryBuiltin(program, "ceil", genericFloat);
addGenericUnaryBuiltin(program, "copysign", genericFloat); addGenericBinaryBuiltin(program, "copysign", genericFloat);
addGenericUnaryBuiltin(program, "floor", genericFloat); addGenericUnaryBuiltin(program, "floor", genericFloat);
addGenericBinaryBuiltin(program, "max", genericFloat); addGenericBinaryBuiltin(program, "max", genericFloat);
addGenericBinaryBuiltin(program, "min", genericFloat); addGenericBinaryBuiltin(program, "min", genericFloat);
@ -1148,12 +1149,13 @@ function initializeBuiltins(program: Program): void {
addGenericUnaryBuiltin(program, "sqrt", genericFloat); addGenericUnaryBuiltin(program, "sqrt", genericFloat);
addGenericUnaryBuiltin(program, "trunc", genericFloat); addGenericUnaryBuiltin(program, "trunc", genericFloat);
addBuiltin(program, "current_memory", [], Type.i32); addBuiltin(program, "current_memory", [], usize);
addBuiltin(program, "grow_memory", [ Type.i32 ], Type.i32); addBuiltin(program, "grow_memory", [ usize ], usize);
addBuiltin(program, "unreachable", [], Type.void); addBuiltin(program, "unreachable", [], Type.void);
addGenericUnaryTestBuiltin(program, "isNaN", genericFloat); addGenericUnaryTestBuiltin(program, "isNaN", genericFloat);
addGenericUnaryTestBuiltin(program, "isFinite", genericFloat); addGenericUnaryTestBuiltin(program, "isFinite", genericFloat);
addBuiltin(program, "assert", [ Type.bool ], Type.void);
// TODO: load, store, sizeof // TODO: load, store, sizeof
// sizeof, for example, has varying Ts but really shouldn't provide an instance for each class // sizeof, for example, has varying Ts but really shouldn't provide an instance for each class
@ -1167,7 +1169,8 @@ function addBuiltin(program: Program, name: string, parameterTypes: Type[], retu
const parameters: Parameter[] = new Array(k); const parameters: Parameter[] = new Array(k);
for (let i: i32 = 0; i < k; ++i) for (let i: i32 = 0; i < k; ++i)
parameters[i] = new Parameter("arg" + i, parameterTypes[i], null); parameters[i] = new Parameter("arg" + i, parameterTypes[i], null);
prototype.instances.set("", new Function(prototype, name, [], parameters, Type.bool, null)); prototype.instances.set("", new Function(prototype, name, [], parameters, returnType, null));
program.elements.set(name, prototype);
} }
function addGenericUnaryBuiltin(program: Program, name: string, types: Type[]): void { function addGenericUnaryBuiltin(program: Program, name: string, types: Type[]): void {

View File

@ -1,4 +1,4 @@
/// <reference path="../assembly.d.ts" /> /// <reference path="../../assembly.d.ts" />
@global() @global()
class Array<T> { class Array<T> {

View File

@ -1,4 +1,4 @@
/// <reference path="../assembly.d.ts" /> /// <reference path="../../assembly.d.ts" />
@global() @global()
class Error { class Error {

View File

@ -1,4 +1,4 @@
/// <reference path="../assembly.d.ts" /> /// <reference path="../../assembly.d.ts" />
@global() @global()
class Map<K,V> { class Map<K,V> {

5
std/impl/math.ts Normal file
View File

@ -0,0 +1,5 @@
/// <reference path="../../assembly.d.ts" />
@global()
class Math {
}

View File

@ -1,4 +1,4 @@
/// <reference path="../assembly.d.ts" /> /// <reference path="../../assembly.d.ts" />
@global() @global()
class Memory { class Memory {

5
std/impl/set.ts Normal file
View File

@ -0,0 +1,5 @@
/// <reference path="../../assembly.d.ts" />
@global()
class Set<T> {
}

View File

@ -1,4 +1,4 @@
/// <reference path="../assembly.d.ts" /> /// <reference path="../../assembly.d.ts" />
@global() @global()
@allocates() @allocates()

15
std/impl/tsconfig.json Normal file
View File

@ -0,0 +1,15 @@
{
"compilerOptions": {
"noLib": true,
"experimentalDecorators": true
},
"files": [
"array.ts",
"error.ts",
"map.ts",
"math.ts",
"memory.ts",
"set.ts",
"string.ts"
]
}

View File

@ -1,5 +0,0 @@
/// <reference path="../assembly.d.ts" />
@global()
class Math {
}

View File

@ -1,5 +0,0 @@
/// <reference path="../assembly.d.ts" />
@global()
class Set<T> {
}

View File

@ -4,12 +4,12 @@
"experimentalDecorators": true "experimentalDecorators": true
}, },
"files": [ "files": [
"array.ts", "array.d.ts",
"error.ts", "error.d.ts",
"map.ts", "map.d.ts",
"math.ts", "math.d.ts",
"memory.ts", "memory.d.ts",
"set.ts", "set.d.ts",
"string.ts" "string.d.ts"
] ]
} }

View File

@ -0,0 +1,18 @@
var binaryen = require("binaryen");
// "non-final block elements returning a value must be drop()ed"
// "0 == 0: block with value must not have last element that is none, on"
var mod = new binaryen.Module();
var funcType = mod.addFunctionType("I", binaryen.void, [ binaryen.i64 ]);
var func = mod.addFunction("test", funcType, [ binaryen.i32 ],
mod.block("", [
mod.setLocal(1, mod.i64.eq(mod.i64.const(0, 0), mod.getLocal(0, binaryen.i64)))
])
);
mod.addExport("test", func);
console.log(mod.emitText());
if (mod.validate())
console.log("-> ok: i64.eq returns i32");

View File

@ -49,8 +49,17 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
const actual = module.toText() + "(;\n[program.elements]\n " + iterate(program.elements.keys()).join("\n ") + "\n[program.exports]\n " + iterate(program.exports.keys()).join("\n ") + "\n;)\n"; const actual = module.toText() + "(;\n[program.elements]\n " + iterate(program.elements.keys()).join("\n ") + "\n[program.exports]\n " + iterate(program.exports.keys()).join("\n ") + "\n;)\n";
const fixture = path.basename(filename, ".ts") + ".wast"; const fixture = path.basename(filename, ".ts") + ".wast";
if (module.validate()) if (module.validate()) {
console.log("Validates"); console.log(chalk.default.green("validate OK"));
try {
module.interpret();
console.log(chalk.default.green("interpret OK"));
} catch (e) {
process.exitCode = 1;
console.log(chalk.default.red("interpret ERROR"));
}
} else
console.log(chalk.default.red("validate ERROR"));
if (isCreate) { if (isCreate) {
fs.writeFileSync(__dirname + "/compiler/" + fixture, actual, { encoding: "utf8" }); fs.writeFileSync(__dirname + "/compiler/" + fixture, actual, { encoding: "utf8" });
@ -61,11 +70,13 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => {
if (diffs !== null) { if (diffs !== null) {
process.exitCode = 1; process.exitCode = 1;
console.log(diffs); console.log(diffs);
console.log(chalk.default.red("diff ERROR"));
} else { } else {
console.log("No changes"); console.log(chalk.default.green("diff OK"));
} }
} }
module.dispose();
console.log(); console.log();
}); });

View File

@ -1,7 +1,7 @@
(module (module
(type $v (func)) (type $v (func))
(global $binary/i (mut i32) (i32.const 0)) (global $binary/i (mut i32) (i32.const 0))
(global $binary/b (mut i32) (i32.const -1)) (global $binary/b (mut i32) (i32.const 0))
(global $binary/I (mut i64) (i64.const 0)) (global $binary/I (mut i64) (i64.const 0))
(global $binary/f (mut f32) (f32.const 0)) (global $binary/f (mut f32) (f32.const 0))
(global $binary/F (mut f64) (f64.const 0)) (global $binary/F (mut f64) (f64.const 0))
@ -112,9 +112,6 @@
(i32.const 1) (i32.const 1)
) )
) )
(set_global $binary/b
(i32.const 0)
)
(set_global $binary/b (set_global $binary/b
(i32.lt_s (i32.lt_s
(get_global $binary/i) (get_global $binary/i)
@ -835,8 +832,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
binary/b binary/b
binary/i binary/i
binary/I binary/I

106
tests/compiler/builtins.ts Normal file
View File

@ -0,0 +1,106 @@
let b: bool;
let i: i32;
clz<i32>(1);
ctz<i32>(1);
popcnt<i32>(1);
rotl<i32>(1, 1);
rotr<i32>(1, 1);
i = clz<i32>(1);
i = ctz<i32>(1);
i = popcnt<i32>(1);
i = rotl<i32>(1, 1);
i = rotr<i32>(1, 1);
let I: i64;
clz<i64>(1);
ctz<i64>(1);
popcnt<i64>(1);
rotl<i64>(1, 1);
rotr<i64>(1, 1);
I = clz<i64>(1);
I = ctz<i64>(1);
I = popcnt<i64>(1);
I = rotl<i64>(1, 1);
I = rotr<i64>(1, 1);
let f: f32;
<f32>NaN;
<f32>Infinity;
abs<f32>(1.25);
ceil<f32>(1.25);
copysign<f32>(1.25, 2.5);
floor<f32>(1.25);
max<f32>(1.25, 2.5);
min<f32>(1.25, 2.5);
nearest<f32>(1.25);
// reinterpret
sqrt<f32>(1.25);
trunc<f32>(1.25);
isNaN<f32>(1.25);
isFinite<f32>(1.25);
f = NaN;
f = Infinity;
f = abs<f32>(1.25);
f = ceil<f32>(1.25);
f = copysign<f32>(1.25, 2.5);
f = floor<f32>(1.25);
f = max<f32>(1.25, 2.5);
f = min<f32>(1.25, 2.5);
f = nearest<f32>(1.25);
// reinterpret
f = sqrt<f32>(1.25);
f = trunc<f32>(1.25);
b = isNaN<f32>(1.25);
b = isFinite<f32>(1.25);
let F: f64;
<f64>NaN;
<f64>Infinity;
NaN;
Infinity;
abs<f64>(1.25);
ceil<f64>(1.25);
copysign<f64>(1.25, 2.5);
floor<f64>(1.25);
max<f64>(1.25, 2.5);
min<f64>(1.25, 2.5);
nearest<f64>(1.25);
// reinterpret
sqrt<f64>(1.25);
trunc<f64>(1.25);
isNaN<f64>(1.25);
isFinite<f64>(1.25);
F = NaN;
F = Infinity;
F = abs<f64>(1.25);
F = ceil<f64>(1.25);
F = copysign<f64>(1.25, 2.5);
F = floor<f64>(1.25);
F = max<f64>(1.25, 2.5);
F = min<f64>(1.25, 2.5);
F = nearest<f64>(1.25);
// reinterpret
F = sqrt<f64>(1.25);
F = trunc<f64>(1.25);
b = isNaN<f64>(1.25);
b = isFinite<f64>(1.25);
let s: usize;
current_memory();
grow_memory(1);
s = current_memory();
s = grow_memory(1);
if (0) unreachable();
assert(true);

View File

@ -0,0 +1,510 @@
(module
(type $v (func))
(global $builtins/i (mut i32) (i32.const 0))
(global $builtins/I (mut i64) (i64.const 0))
(global $builtins/f (mut f32) (f32.const 0))
(global $builtins/b (mut i32) (i32.const 0))
(global $builtins/F (mut f64) (f64.const 0))
(global $builtins/s (mut i32) (i32.const 0))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "memory" (memory $0))
(start $start)
(func $start (; 0 ;) (type $v)
(local $0 f32)
(local $1 f32)
(local $2 f32)
(local $3 f32)
(local $4 f64)
(local $5 f64)
(local $6 f64)
(local $7 f64)
(drop
(i32.clz
(i32.const 1)
)
)
(drop
(i32.ctz
(i32.const 1)
)
)
(drop
(i32.popcnt
(i32.const 1)
)
)
(drop
(i32.rotl
(i32.const 1)
(i32.const 1)
)
)
(drop
(i32.rotr
(i32.const 1)
(i32.const 1)
)
)
(set_global $builtins/i
(i32.clz
(i32.const 1)
)
)
(set_global $builtins/i
(i32.ctz
(i32.const 1)
)
)
(set_global $builtins/i
(i32.popcnt
(i32.const 1)
)
)
(set_global $builtins/i
(i32.rotl
(i32.const 1)
(i32.const 1)
)
)
(set_global $builtins/i
(i32.rotr
(i32.const 1)
(i32.const 1)
)
)
(drop
(i64.clz
(i64.const 1)
)
)
(drop
(i64.ctz
(i64.const 1)
)
)
(drop
(i64.popcnt
(i64.const 1)
)
)
(drop
(i64.rotl
(i64.const 1)
(i64.const 1)
)
)
(drop
(i64.rotr
(i64.const 1)
(i64.const 1)
)
)
(set_global $builtins/I
(i64.clz
(i64.const 1)
)
)
(set_global $builtins/I
(i64.ctz
(i64.const 1)
)
)
(set_global $builtins/I
(i64.popcnt
(i64.const 1)
)
)
(set_global $builtins/I
(i64.rotl
(i64.const 1)
(i64.const 1)
)
)
(set_global $builtins/I
(i64.rotr
(i64.const 1)
(i64.const 1)
)
)
(drop
(f32.const nan:0x400000)
)
(drop
(f32.const inf)
)
(drop
(f32.abs
(f32.const 1.25)
)
)
(drop
(f32.ceil
(f32.const 1.25)
)
)
(drop
(f32.copysign
(f32.const 1.25)
(f32.const 2.5)
)
)
(drop
(f32.floor
(f32.const 1.25)
)
)
(drop
(f32.max
(f32.const 1.25)
(f32.const 2.5)
)
)
(drop
(f32.min
(f32.const 1.25)
(f32.const 2.5)
)
)
(drop
(f32.nearest
(f32.const 1.25)
)
)
(drop
(f32.sqrt
(f32.const 1.25)
)
)
(drop
(f32.trunc
(f32.const 1.25)
)
)
(drop
(f32.ne
(tee_local $0
(f32.const 1.25)
)
(get_local $0)
)
)
(drop
(select
(i32.const 0)
(f32.ne
(f32.abs
(get_local $1)
)
(f32.const inf)
)
(f32.ne
(tee_local $1
(f32.const 1.25)
)
(get_local $1)
)
)
)
(set_global $builtins/f
(f32.const nan:0x400000)
)
(set_global $builtins/f
(f32.const inf)
)
(set_global $builtins/f
(f32.abs
(f32.const 1.25)
)
)
(set_global $builtins/f
(f32.ceil
(f32.const 1.25)
)
)
(set_global $builtins/f
(f32.copysign
(f32.const 1.25)
(f32.const 2.5)
)
)
(set_global $builtins/f
(f32.floor
(f32.const 1.25)
)
)
(set_global $builtins/f
(f32.max
(f32.const 1.25)
(f32.const 2.5)
)
)
(set_global $builtins/f
(f32.min
(f32.const 1.25)
(f32.const 2.5)
)
)
(set_global $builtins/f
(f32.nearest
(f32.const 1.25)
)
)
(set_global $builtins/f
(f32.sqrt
(f32.const 1.25)
)
)
(set_global $builtins/f
(f32.trunc
(f32.const 1.25)
)
)
(set_global $builtins/b
(f32.ne
(tee_local $2
(f32.const 1.25)
)
(get_local $2)
)
)
(set_global $builtins/b
(select
(i32.const 0)
(f32.ne
(f32.abs
(get_local $3)
)
(f32.const inf)
)
(f32.ne
(tee_local $3
(f32.const 1.25)
)
(get_local $3)
)
)
)
(drop
(f64.const nan:0x8000000000000)
)
(drop
(f64.const inf)
)
(drop
(f64.const nan:0x8000000000000)
)
(drop
(f64.const inf)
)
(drop
(f64.abs
(f64.const 1.25)
)
)
(drop
(f64.ceil
(f64.const 1.25)
)
)
(drop
(f64.copysign
(f64.const 1.25)
(f64.const 2.5)
)
)
(drop
(f64.floor
(f64.const 1.25)
)
)
(drop
(f64.max
(f64.const 1.25)
(f64.const 2.5)
)
)
(drop
(f64.min
(f64.const 1.25)
(f64.const 2.5)
)
)
(drop
(f64.nearest
(f64.const 1.25)
)
)
(drop
(f64.sqrt
(f64.const 1.25)
)
)
(drop
(f64.trunc
(f64.const 1.25)
)
)
(drop
(f64.ne
(tee_local $4
(f64.const 1.25)
)
(get_local $4)
)
)
(drop
(select
(i32.const 0)
(f64.ne
(f64.abs
(get_local $5)
)
(f64.const inf)
)
(f64.ne
(tee_local $5
(f64.const 1.25)
)
(get_local $5)
)
)
)
(set_global $builtins/F
(f64.const nan:0x8000000000000)
)
(set_global $builtins/F
(f64.const inf)
)
(set_global $builtins/F
(f64.abs
(f64.const 1.25)
)
)
(set_global $builtins/F
(f64.ceil
(f64.const 1.25)
)
)
(set_global $builtins/F
(f64.copysign
(f64.const 1.25)
(f64.const 2.5)
)
)
(set_global $builtins/F
(f64.floor
(f64.const 1.25)
)
)
(set_global $builtins/F
(f64.max
(f64.const 1.25)
(f64.const 2.5)
)
)
(set_global $builtins/F
(f64.min
(f64.const 1.25)
(f64.const 2.5)
)
)
(set_global $builtins/F
(f64.nearest
(f64.const 1.25)
)
)
(set_global $builtins/F
(f64.sqrt
(f64.const 1.25)
)
)
(set_global $builtins/F
(f64.trunc
(f64.const 1.25)
)
)
(set_global $builtins/b
(f64.ne
(tee_local $6
(f64.const 1.25)
)
(get_local $6)
)
)
(set_global $builtins/b
(select
(i32.const 0)
(f64.ne
(f64.abs
(get_local $7)
)
(f64.const inf)
)
(f64.ne
(tee_local $7
(f64.const 1.25)
)
(get_local $7)
)
)
)
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(if
(i32.const 0)
(unreachable)
)
(if
(i32.eqz
(i32.const 1)
)
(unreachable)
)
)
)
(;
[program.elements]
clz
ctz
popcnt
rotl
rotr
abs
ceil
copysign
floor
max
min
nearest
sqrt
trunc
current_memory
grow_memory
unreachable
isNaN
isFinite
assert
builtins/b
builtins/i
builtins/I
builtins/f
builtins/F
builtins/s
[program.exports]
;)

View File

@ -71,8 +71,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
do/loopDo do/loopDo
do/loopDoInDo do/loopDoInDo
[program.exports] [program.exports]

View File

@ -40,8 +40,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
export/add export/add
export/sub export/sub
export/a export/a

View File

@ -62,8 +62,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
if/ifThenElse if/ifThenElse
if/ifThen if/ifThen
if/ifThenElseBlock if/ifThenElseBlock

View File

@ -54,8 +54,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
export/add export/add
export/sub export/sub
export/a export/a

View File

@ -42,7 +42,3 @@
0b1; 0b1;
true; true;
false; false;
NaN;
Infinity;
<f32>NaN;
<f32>Infinity;

View File

@ -137,18 +137,6 @@
(drop (drop
(i32.const 0) (i32.const 0)
) )
(drop
(f64.const nan:0x8000000000000)
)
(drop
(f64.const inf)
)
(drop
(f32.const nan:0x400000)
)
(drop
(f32.const inf)
)
) )
) )
(; (;
@ -167,8 +155,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
[program.exports] [program.exports]
;) ;)

View File

@ -56,8 +56,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
export/add export/add
export/sub export/sub
export/a export/a

View File

@ -161,8 +161,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
switch/doSwitch switch/doSwitch
switch/doSwitchDefaultFirst switch/doSwitchDefaultFirst
switch/doSwitchDefaultOmitted switch/doSwitchDefaultOmitted

View File

@ -649,8 +649,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
unary/i unary/i
unary/I unary/I
unary/f unary/f

View File

@ -80,8 +80,12 @@
nearest nearest
sqrt sqrt
trunc trunc
current_memory
grow_memory
unreachable
isNaN isNaN
isFinite isFinite
assert
while/loopWhile while/loopWhile
while/loopWhileInWhile while/loopWhileInWhile
[program.exports] [program.exports]

View File

@ -33,8 +33,11 @@ glob.sync(filter, { cwd: __dirname + "/parser" }).forEach(filename => {
if (diffs !== null) { if (diffs !== null) {
process.exitCode = 1; process.exitCode = 1;
console.log(diffs); console.log(diffs);
console.log(chalk.default.red("diff ERROR"));
} else { } else {
console.log("No changes\n"); console.log(chalk.default.green("diff OK"));
} }
} }
console.log();
}); });