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

4
assembly.d.ts vendored
View File

@ -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<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. */
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. */
@ -84,6 +84,8 @@ declare const Infinity: number;
declare function isNaN<T>(value: T): bool;
/** Tests if a 32-bit or 64-bit float is finite, that is not NaN or +/-Infinity. */
declare function isFinite<T>(value: T): bool;
/** Traps if the specified value is `false`. */
declare function assert(isTrue: bool): void;
// internal decorators

View File

@ -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 = <Element | null>this.program.elements.get(declaration.internalName);
if (!element || element.kind != ElementKind.GLOBAL)
throw new Error("unexpected missing global");
return this.compileGlobal(<Global>element);
return this.compileGlobal(<Global>element)
? <Global>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(<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) {
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();

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
/// <reference path="../assembly.d.ts" />
/// <reference path="../../assembly.d.ts" />
@global()
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()
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()
@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
},
"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"
]
}

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

View File

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

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
sqrt
trunc
current_memory
grow_memory
unreachable
isNaN
isFinite
assert
do/loopDo
do/loopDoInDo
[program.exports]

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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