From 017efc71b67966ec54a6474a45f4cac2ef9ec15b Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Sun, 3 Dec 2017 23:04:33 +0100 Subject: [PATCH] Fixes; Builtins; Testing in the interpreter --- README.md | 2 +- assembly.d.ts | 4 +- src/compiler.ts | 52 ++- src/diagnostics.ts | 6 +- src/module.ts | 8 + src/program.ts | 11 +- std/{ => impl}/array.ts | 2 +- std/{ => impl}/error.ts | 2 +- std/{ => impl}/map.ts | 2 +- std/impl/math.ts | 5 + std/{ => impl}/memory.ts | 2 +- std/impl/set.ts | 5 + std/{ => impl}/string.ts | 2 +- std/impl/tsconfig.json | 15 + std/math.ts | 5 - std/set.ts | 5 - std/tsconfig.json | 14 +- tests/binaryen/i64-binary-result.js | 18 + tests/compiler.ts | 17 +- tests/compiler/binary.wast | 9 +- tests/compiler/builtins.ts | 106 ++++++ tests/compiler/builtins.wast | 510 ++++++++++++++++++++++++++++ tests/compiler/do.wast | 4 + tests/compiler/export.wast | 4 + tests/compiler/if.wast | 4 + tests/compiler/import.wast | 4 + tests/compiler/literals.ts | 4 - tests/compiler/literals.wast | 16 +- tests/compiler/reexport.wast | 4 + tests/compiler/switch.wast | 4 + tests/compiler/unary.wast | 4 + tests/compiler/while.wast | 4 + tests/parser.ts | 5 +- 33 files changed, 791 insertions(+), 68 deletions(-) rename std/{ => impl}/array.ts (87%) rename std/{ => impl}/error.ts (84%) rename std/{ => impl}/map.ts (84%) create mode 100644 std/impl/math.ts rename std/{ => impl}/memory.ts (93%) create mode 100644 std/impl/set.ts rename std/{ => impl}/string.ts (97%) create mode 100644 std/impl/tsconfig.json delete mode 100644 std/math.ts delete mode 100644 std/set.ts create mode 100644 tests/binaryen/i64-binary-result.js create mode 100644 tests/compiler/builtins.ts create mode 100644 tests/compiler/builtins.wast diff --git a/README.md b/README.md index e5943814..30858b39 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ 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. diff --git a/assembly.d.ts b/assembly.d.ts index 57527144..d20654f6 100644 --- a/assembly.d.ts +++ b/assembly.d.ts @@ -30,7 +30,7 @@ declare type f64 = number; // 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. */ -declare function clz(value: T): T; +declare function clz(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. */ declare function ctz(value: T): T; /** 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(value: T): bool; /** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */ declare function isFinite(value: T): bool; +/** Traps if the specified value is `false`. */ +declare function assert(isTrue: bool): void; // internal decorators diff --git a/src/compiler.ts b/src/compiler.ts index 6c766329..49794986 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -1,6 +1,6 @@ import { PATH_DELIMITER } from "./constants"; 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 { CharCode, I64, U64, normalizePath, sb } from "./util"; import { Token, Range } from "./tokenizer"; @@ -286,11 +286,13 @@ export class Compiler extends DiagnosticEmitter { // globals - compileGlobalDeclaration(declaration: VariableDeclaration, isConst: bool): bool { + compileGlobalDeclaration(declaration: VariableDeclaration, isConst: bool): Global | null { const element: Element | null = this.program.elements.get(declaration.internalName); if (!element || element.kind != ElementKind.GLOBAL) throw new Error("unexpected missing global"); - return this.compileGlobal(element); + return this.compileGlobal(element) + ? element + : null; } compileGlobal(element: Global): bool { @@ -333,7 +335,7 @@ export class Compiler extends DiagnosticEmitter { } else if (declaration) { if (declaration.initializer) { 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 { initializer = typeToNativeZero(this.module, type); initializeInStart = false; @@ -342,12 +344,14 @@ export class Compiler extends DiagnosticEmitter { throw new Error("unexpected missing declaration or constant value"); const internalName: string = element.internalName; 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)); - } else + } else { this.module.addGlobal(internalName, nativeType, element.isMutable, initializer); - // if (element.globalExportName != null && element.hasConstantValue && !initializeInStart) - // this.module.addGlobalExport(element.internalName, element.globalExportName); + if (!element.isMutable) { + // TODO: check export, requires updated binaryen.js with Module#addGlobalExport + } + } return element.isCompiled = true; } @@ -373,7 +377,7 @@ export class Compiler extends DiagnosticEmitter { let initializeInStart: bool = false; if (declaration.value) { initializer = this.compileExpression(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) { initializer = this.module.createI32(0); initializeInStart = false; @@ -385,10 +389,12 @@ export class Compiler extends DiagnosticEmitter { initializeInStart = true; } 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)); - } else + } else { this.module.addGlobal(val.internalName, NativeType.I32, false, initializer); + // TODO: check export, requires updated binaryen.js with Module#addGlobalExport + } } else throw new Error("unexpected missing declaration or constant value"); previousInternalName = val.internalName; @@ -1183,6 +1189,20 @@ export class Compiler extends DiagnosticEmitter { this.currentType = Type.bool; 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: return this.compileAssignment(expression.left, expression.right, contextualType); @@ -1544,7 +1564,7 @@ export class Compiler extends DiagnosticEmitter { return this.module.createHost(HostOp.CurrentMemory); 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); case "unreachable": @@ -1566,7 +1586,7 @@ export class Compiler extends DiagnosticEmitter { tempLocal = this.currentFunction.addLocal(Type.f32); return this.module.createBinary(BinaryOp.NeF32, this.module.createTeeLocal(tempLocal.index, operands[0]), - this.module.createGetLocal(tempLocal.index, NativeType.F64) + this.module.createGetLocal(tempLocal.index, NativeType.F32) ); } break; @@ -1604,6 +1624,12 @@ export class Compiler extends DiagnosticEmitter { ); } 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); return this.module.createUnreachable(); diff --git a/src/diagnostics.ts b/src/diagnostics.ts index aa0f8630..009c7f8b 100644 --- a/src/diagnostics.ts +++ b/src/diagnostics.ts @@ -1,5 +1,5 @@ import { Range } from "./ast"; -import { isLineBreak, sb } from "./util"; +import { CharCode, isLineBreak, sb } from "./util"; import { 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"); let pos: i32 = range.start; let line: i32 = 1; - let column: i32 = 0; + let column: i32 = 1; while (pos-- > 0) - if (isLineBreak(text.charCodeAt(pos))) + if (text.charCodeAt(pos) == CharCode.LINEFEED) line++; else if (line == 1) column++; diff --git a/src/module.ts b/src/module.ts index 39acbdf2..19f360f9 100644 --- a/src/module.ts +++ b/src/module.ts @@ -613,6 +613,10 @@ export class Module { return _BinaryenModuleValidate(this.ref) == 1; } + interpret(): void { + return _BinaryenModuleInterpret(this.ref); + } + toBinary(): Uint8Array { throw new Error("not implemented"); } @@ -726,6 +730,10 @@ 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 diff --git a/src/program.ts b/src/program.ts index f733ae04..820a20da 100644 --- a/src/program.ts +++ b/src/program.ts @@ -1131,6 +1131,7 @@ function initializeBuiltins(program: Program): void { const genericInt: Type[] = [ Type.i32, Type.i64 ]; const genericFloat: Type[] = [ Type.f32, Type.f64 ]; + const usize: Type = program.target == Target.WASM64 ? Type.usize64 : Type.usize32; addGenericUnaryBuiltin(program, "clz", genericInt); addGenericUnaryBuiltin(program, "ctz", genericInt); @@ -1140,7 +1141,7 @@ function initializeBuiltins(program: Program): void { addGenericUnaryBuiltin(program, "abs", genericFloat); addGenericUnaryBuiltin(program, "ceil", genericFloat); - addGenericUnaryBuiltin(program, "copysign", genericFloat); + addGenericBinaryBuiltin(program, "copysign", genericFloat); addGenericUnaryBuiltin(program, "floor", genericFloat); addGenericBinaryBuiltin(program, "max", genericFloat); addGenericBinaryBuiltin(program, "min", genericFloat); @@ -1148,12 +1149,13 @@ function initializeBuiltins(program: Program): void { addGenericUnaryBuiltin(program, "sqrt", genericFloat); addGenericUnaryBuiltin(program, "trunc", genericFloat); - addBuiltin(program, "current_memory", [], Type.i32); - addBuiltin(program, "grow_memory", [ Type.i32 ], Type.i32); + addBuiltin(program, "current_memory", [], usize); + addBuiltin(program, "grow_memory", [ usize ], usize); addBuiltin(program, "unreachable", [], Type.void); addGenericUnaryTestBuiltin(program, "isNaN", genericFloat); addGenericUnaryTestBuiltin(program, "isFinite", genericFloat); + addBuiltin(program, "assert", [ Type.bool ], Type.void); // TODO: load, store, sizeof // 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); for (let i: i32 = 0; i < k; ++i) 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 { diff --git a/std/array.ts b/std/impl/array.ts similarity index 87% rename from std/array.ts rename to std/impl/array.ts index 327e8ee9..f8afbe23 100644 --- a/std/array.ts +++ b/std/impl/array.ts @@ -1,4 +1,4 @@ -/// +/// @global() class Array { diff --git a/std/error.ts b/std/impl/error.ts similarity index 84% rename from std/error.ts rename to std/impl/error.ts index 4c4c9266..ac40b47d 100644 --- a/std/error.ts +++ b/std/impl/error.ts @@ -1,4 +1,4 @@ -/// +/// @global() class Error { diff --git a/std/map.ts b/std/impl/map.ts similarity index 84% rename from std/map.ts rename to std/impl/map.ts index e96da1b9..41081f01 100644 --- a/std/map.ts +++ b/std/impl/map.ts @@ -1,4 +1,4 @@ -/// +/// @global() class Map { diff --git a/std/impl/math.ts b/std/impl/math.ts new file mode 100644 index 00000000..70631e72 --- /dev/null +++ b/std/impl/math.ts @@ -0,0 +1,5 @@ +/// + +@global() +class Math { +} diff --git a/std/memory.ts b/std/impl/memory.ts similarity index 93% rename from std/memory.ts rename to std/impl/memory.ts index 78edb95f..5309cf5a 100644 --- a/std/memory.ts +++ b/std/impl/memory.ts @@ -1,4 +1,4 @@ -/// +/// @global() class Memory { diff --git a/std/impl/set.ts b/std/impl/set.ts new file mode 100644 index 00000000..0da35c34 --- /dev/null +++ b/std/impl/set.ts @@ -0,0 +1,5 @@ +/// + +@global() +class Set { +} diff --git a/std/string.ts b/std/impl/string.ts similarity index 97% rename from std/string.ts rename to std/impl/string.ts index 6cdf71cd..10643885 100644 --- a/std/string.ts +++ b/std/impl/string.ts @@ -1,4 +1,4 @@ -/// +/// @global() @allocates() diff --git a/std/impl/tsconfig.json b/std/impl/tsconfig.json new file mode 100644 index 00000000..0809326f --- /dev/null +++ b/std/impl/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "noLib": true, + "experimentalDecorators": true + }, + "files": [ + "array.ts", + "error.ts", + "map.ts", + "math.ts", + "memory.ts", + "set.ts", + "string.ts" + ] +} \ No newline at end of file diff --git a/std/math.ts b/std/math.ts deleted file mode 100644 index 7c352a40..00000000 --- a/std/math.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// - -@global() -class Math { -} diff --git a/std/set.ts b/std/set.ts deleted file mode 100644 index 1e2f581b..00000000 --- a/std/set.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// - -@global() -class Set { -} diff --git a/std/tsconfig.json b/std/tsconfig.json index 0809326f..2516bc29 100644 --- a/std/tsconfig.json +++ b/std/tsconfig.json @@ -4,12 +4,12 @@ "experimentalDecorators": true }, "files": [ - "array.ts", - "error.ts", - "map.ts", - "math.ts", - "memory.ts", - "set.ts", - "string.ts" + "array.d.ts", + "error.d.ts", + "map.d.ts", + "math.d.ts", + "memory.d.ts", + "set.d.ts", + "string.d.ts" ] } \ No newline at end of file diff --git a/tests/binaryen/i64-binary-result.js b/tests/binaryen/i64-binary-result.js new file mode 100644 index 00000000..59ae8621 --- /dev/null +++ b/tests/binaryen/i64-binary-result.js @@ -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"); diff --git a/tests/compiler.ts b/tests/compiler.ts index a960aa88..d94c235b 100644 --- a/tests/compiler.ts +++ b/tests/compiler.ts @@ -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 fixture = path.basename(filename, ".ts") + ".wast"; - if (module.validate()) - console.log("Validates"); + if (module.validate()) { + 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) { fs.writeFileSync(__dirname + "/compiler/" + fixture, actual, { encoding: "utf8" }); @@ -61,11 +70,13 @@ glob.sync(filter, { cwd: __dirname + "/compiler" }).forEach(filename => { if (diffs !== null) { process.exitCode = 1; console.log(diffs); + console.log(chalk.default.red("diff ERROR")); } else { - console.log("No changes"); + console.log(chalk.default.green("diff OK")); } } + module.dispose(); console.log(); }); diff --git a/tests/compiler/binary.wast b/tests/compiler/binary.wast index e3854376..2f275ada 100644 --- a/tests/compiler/binary.wast +++ b/tests/compiler/binary.wast @@ -1,7 +1,7 @@ (module (type $v (func)) (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/f (mut f32) (f32.const 0)) (global $binary/F (mut f64) (f64.const 0)) @@ -112,9 +112,6 @@ (i32.const 1) ) ) - (set_global $binary/b - (i32.const 0) - ) (set_global $binary/b (i32.lt_s (get_global $binary/i) @@ -835,8 +832,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert binary/b binary/i binary/I diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts new file mode 100644 index 00000000..71816910 --- /dev/null +++ b/tests/compiler/builtins.ts @@ -0,0 +1,106 @@ +let b: bool; + +let i: i32; + +clz(1); +ctz(1); +popcnt(1); +rotl(1, 1); +rotr(1, 1); + +i = clz(1); +i = ctz(1); +i = popcnt(1); +i = rotl(1, 1); +i = rotr(1, 1); + +let I: i64; + +clz(1); +ctz(1); +popcnt(1); +rotl(1, 1); +rotr(1, 1); + +I = clz(1); +I = ctz(1); +I = popcnt(1); +I = rotl(1, 1); +I = rotr(1, 1); + +let f: f32; + +NaN; +Infinity; +abs(1.25); +ceil(1.25); +copysign(1.25, 2.5); +floor(1.25); +max(1.25, 2.5); +min(1.25, 2.5); +nearest(1.25); +// reinterpret +sqrt(1.25); +trunc(1.25); +isNaN(1.25); +isFinite(1.25); + +f = NaN; +f = Infinity; +f = abs(1.25); +f = ceil(1.25); +f = copysign(1.25, 2.5); +f = floor(1.25); +f = max(1.25, 2.5); +f = min(1.25, 2.5); +f = nearest(1.25); +// reinterpret +f = sqrt(1.25); +f = trunc(1.25); +b = isNaN(1.25); +b = isFinite(1.25); + +let F: f64; + +NaN; +Infinity; +NaN; +Infinity; +abs(1.25); +ceil(1.25); +copysign(1.25, 2.5); +floor(1.25); +max(1.25, 2.5); +min(1.25, 2.5); +nearest(1.25); +// reinterpret +sqrt(1.25); +trunc(1.25); +isNaN(1.25); +isFinite(1.25); + +F = NaN; +F = Infinity; +F = abs(1.25); +F = ceil(1.25); +F = copysign(1.25, 2.5); +F = floor(1.25); +F = max(1.25, 2.5); +F = min(1.25, 2.5); +F = nearest(1.25); +// reinterpret +F = sqrt(1.25); +F = trunc(1.25); +b = isNaN(1.25); +b = isFinite(1.25); + +let s: usize; + +current_memory(); +grow_memory(1); + +s = current_memory(); +s = grow_memory(1); +if (0) unreachable(); + +assert(true); diff --git a/tests/compiler/builtins.wast b/tests/compiler/builtins.wast new file mode 100644 index 00000000..68aa2d5a --- /dev/null +++ b/tests/compiler/builtins.wast @@ -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] + +;) diff --git a/tests/compiler/do.wast b/tests/compiler/do.wast index e407c35e..4dbdd366 100644 --- a/tests/compiler/do.wast +++ b/tests/compiler/do.wast @@ -71,8 +71,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert do/loopDo do/loopDoInDo [program.exports] diff --git a/tests/compiler/export.wast b/tests/compiler/export.wast index 75b5b63b..219bc5cf 100644 --- a/tests/compiler/export.wast +++ b/tests/compiler/export.wast @@ -40,8 +40,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert export/add export/sub export/a diff --git a/tests/compiler/if.wast b/tests/compiler/if.wast index c99452c6..00437e2a 100644 --- a/tests/compiler/if.wast +++ b/tests/compiler/if.wast @@ -62,8 +62,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert if/ifThenElse if/ifThen if/ifThenElseBlock diff --git a/tests/compiler/import.wast b/tests/compiler/import.wast index f4fc9104..168866b4 100644 --- a/tests/compiler/import.wast +++ b/tests/compiler/import.wast @@ -54,8 +54,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert export/add export/sub export/a diff --git a/tests/compiler/literals.ts b/tests/compiler/literals.ts index 585f14a7..0b3652c8 100644 --- a/tests/compiler/literals.ts +++ b/tests/compiler/literals.ts @@ -42,7 +42,3 @@ 0b1; true; false; -NaN; -Infinity; -NaN; -Infinity; diff --git a/tests/compiler/literals.wast b/tests/compiler/literals.wast index dff16834..845292be 100644 --- a/tests/compiler/literals.wast +++ b/tests/compiler/literals.wast @@ -137,18 +137,6 @@ (drop (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 sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert [program.exports] ;) diff --git a/tests/compiler/reexport.wast b/tests/compiler/reexport.wast index 30b1b4b8..79bd0241 100644 --- a/tests/compiler/reexport.wast +++ b/tests/compiler/reexport.wast @@ -56,8 +56,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert export/add export/sub export/a diff --git a/tests/compiler/switch.wast b/tests/compiler/switch.wast index 16c5898f..e292a04b 100644 --- a/tests/compiler/switch.wast +++ b/tests/compiler/switch.wast @@ -161,8 +161,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert switch/doSwitch switch/doSwitchDefaultFirst switch/doSwitchDefaultOmitted diff --git a/tests/compiler/unary.wast b/tests/compiler/unary.wast index 288d38e0..c2a61148 100644 --- a/tests/compiler/unary.wast +++ b/tests/compiler/unary.wast @@ -649,8 +649,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert unary/i unary/I unary/f diff --git a/tests/compiler/while.wast b/tests/compiler/while.wast index 36dedb08..a5af328e 100644 --- a/tests/compiler/while.wast +++ b/tests/compiler/while.wast @@ -80,8 +80,12 @@ nearest sqrt trunc + current_memory + grow_memory + unreachable isNaN isFinite + assert while/loopWhile while/loopWhileInWhile [program.exports] diff --git a/tests/parser.ts b/tests/parser.ts index f9384a2d..15751487 100644 --- a/tests/parser.ts +++ b/tests/parser.ts @@ -33,8 +33,11 @@ glob.sync(filter, { cwd: __dirname + "/parser" }).forEach(filename => { if (diffs !== null) { process.exitCode = 1; console.log(diffs); + console.log(chalk.default.red("diff ERROR")); } else { - console.log("No changes\n"); + console.log(chalk.default.green("diff OK")); } } + + console.log(); });