From 1221ff129da347bc44c9750b08ef77678e72e711 Mon Sep 17 00:00:00 2001 From: dcodeIO Date: Tue, 2 Jan 2018 21:41:25 +0100 Subject: [PATCH] More built-in constants; Get/set parsing fixes; I64.toF64 fixes --- examples/pson/assembly/pson.ts | 4 +- examples/pson/index.js | 3 - src/builtins.ts | 12 +- src/compiler.ts | 64 ++++--- src/parser.ts | 21 ++- src/program.ts | 4 +- src/tokenizer.ts | 6 +- src/util/i64.ts | 4 + std/assembly.d.ts | 12 ++ std/assembly/array.ts | 12 ++ std/portable.d.ts | 8 + std/portable.js | 6 +- tests/compiler/builtins.ts | 33 ++++ tests/compiler/builtins.wast | 306 +++++++++++++++++++++++++++++++++ 14 files changed, 448 insertions(+), 47 deletions(-) diff --git a/examples/pson/assembly/pson.ts b/examples/pson/assembly/pson.ts index fc6ca112..79f4da14 100644 --- a/examples/pson/assembly/pson.ts +++ b/examples/pson/assembly/pson.ts @@ -34,7 +34,6 @@ namespace pson { 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; @@ -43,8 +42,7 @@ export function decode(length: usize): void { offset = 0; while (offset < length) decodeValue(); - if (offset != length) - pson.onTruncated(); + assert(offset == length); } function decodeValue(): void { diff --git a/examples/pson/index.js b/examples/pson/index.js index e0a94256..3f955879 100644 --- a/examples/pson/index.js +++ b/examples/pson/index.js @@ -43,9 +43,6 @@ var pson = { }, onBinary: function(offset, length) { console.log("binary(length=" + length + "): " + mem.slice(offset, offset + length)); - }, - onTruncated: function() { - console.log("buffer is truncated :-("); } }; diff --git a/src/builtins.ts b/src/builtins.ts index cd0a3551..12db13a1 100644 --- a/src/builtins.ts +++ b/src/builtins.ts @@ -125,12 +125,18 @@ export function initialize(program: Program): void { [ "MAX_VALUE", new Global(program, "MAX_VALUE", "bool.MAX_VALUE", null, Type.bool).withConstantIntegerValue(1, 0) ] ]); addFunction(program, "f32").members = new Map([ + [ "MIN_VALUE", new Global(program, "MIN_VALUE", "f32.MIN_VALUE", null, Type.f32).withConstantFloatValue(-3.40282347e+38) ], + [ "MAX_VALUE", new Global(program, "MAX_VALUE", "f32.MAX_VALUE", null, Type.f32).withConstantFloatValue(3.40282347e+38) ], [ "MIN_SAFE_INTEGER", new Global(program, "MIN_SAFE_INTEGER", "f32.MIN_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(-16777215) ], - [ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f32.MAX_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(16777215) ] + [ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f32.MAX_SAFE_INTEGER", null, Type.f32).withConstantFloatValue(16777215) ], + [ "EPSILON", new Global(program, "EPSILON", "f32.EPSILON", null, Type.f32).withConstantFloatValue(1.19209290e-07) ] ]); addFunction(program, "f64").members = new Map([ + [ "MIN_VALUE", new Global(program, "MIN_VALUE", "f64.MIN_VALUE", null, Type.f64).withConstantFloatValue(-1.7976931348623157e+308) ], + [ "MAX_VALUE", new Global(program, "MAX_VALUE", "f64.MAX_VALUE", null, Type.f64).withConstantFloatValue(1.7976931348623157e+308) ], [ "MIN_SAFE_INTEGER", new Global(program, "MIN_SAFE_INTEGER", "f64.MIN_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(-9007199254740991) ], - [ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f64.MAX_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(9007199254740991) ] + [ "MAX_SAFE_INTEGER", new Global(program, "MAX_SAFE_INTEGER", "f64.MAX_SAFE_INTEGER", null, Type.f64).withConstantFloatValue(9007199254740991) ], + [ "EPSILON", new Global(program, "EPSILON", "f64.EPSILON", null, Type.f64).withConstantFloatValue(2.2204460492503131e-16) ] ]); if (program.target == Target.WASM64) { program.elements.set("isize", i64Func); @@ -694,7 +700,7 @@ export function compileCall(compiler: Compiler, prototype: FunctionPrototype, ty if (!validateCall(compiler, typeArguments, 1, operands, 1, reportNode)) return module.createUnreachable(); arg0 = compiler.compileExpression(operands[0], Type.void, ConversionKind.NONE); - if ((compiler.currentType == usizeType && (typeArguments)[0].classType) || (compiler.currentType.classType && (typeArguments)[0] == usizeType)) { + if (compiler.currentType != Type.void && compiler.currentType.kind == (typeArguments)[0].kind) { compiler.currentType = (typeArguments)[0]; return arg0; } diff --git a/src/compiler.ts b/src/compiler.ts index 7af38e72..bcd7b1b4 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -2362,6 +2362,8 @@ export class Compiler extends DiagnosticEmitter { target = this.program.resolvePropertyAccess(targetExpression, this.currentFunction); break; + // case NodeKind.ELEMENTACCESS: + default: this.error(DiagnosticCode.Operation_not_supported, expression.range); } @@ -2409,34 +2411,36 @@ export class Compiler extends DiagnosticEmitter { if (!element) return this.module.createUnreachable(); - // local - if (element.kind == ElementKind.LOCAL) { - assert((element).type != null); - this.currentType = (element).type; - if ((element).hasConstantValue) - return makeInlineConstant(element, this.module); - assert((element).index >= 0); - return this.module.createGetLocal((element).index, this.currentType.toNativeType()); - } + switch (element.kind) { - // global - if (element.kind == ElementKind.GLOBAL) { - if (element.isBuiltIn) - return compileBuiltinGetConstant(this, element); + case ElementKind.LOCAL: + assert((element).type != null); + this.currentType = (element).type; + if ((element).hasConstantValue) + return makeInlineConstant(element, this.module); + assert((element).index >= 0); + return this.module.createGetLocal((element).index, this.currentType.toNativeType()); - var global = element; - if (!this.compileGlobal(global)) // reports + case ElementKind.GLOBAL: + if (element.isBuiltIn) + return compileBuiltinGetConstant(this, element); + + var global = element; + if (!this.compileGlobal(global)) // reports + return this.module.createUnreachable(); + assert(global.type != null); // has been resolved when compileGlobal succeeds + this.currentType = global.type; + if (global.hasConstantValue) + return makeInlineConstant(global, this.module); + else + return this.module.createGetGlobal((element).internalName, this.currentType.toNativeType()); + + // case ElementKind.FIELD + + default: + this.error(DiagnosticCode.Operation_not_supported, expression.range); return this.module.createUnreachable(); - assert(global.type != null); - this.currentType = global.type; - if (global.hasConstantValue) - return makeInlineConstant(global, this.module); - else - return this.module.createGetGlobal((element).internalName, this.currentType.toNativeType()); } - - this.error(DiagnosticCode.Operation_not_supported, expression.range); - return this.module.createUnreachable(); } compileLiteralExpression(expression: LiteralExpression, contextualType: Type): ExpressionRef { @@ -2456,13 +2460,17 @@ export class Compiler extends DiagnosticEmitter { if (contextualType == Type.bool && (intValue.isZero || intValue.isOne)) return this.module.createI32(intValue.isZero ? 0 : 1); if (contextualType == Type.f64) - return this.module.createF64((intValue.lo) + (intValue.hi) * 0xffffffff); + return this.module.createF64(intValue.toF64()); if (contextualType == Type.f32) - return this.module.createF32((intValue.lo) + (intValue.hi) * 0xffffffff); + return this.module.createF32(intValue.toF64()); if (contextualType.isLongInteger) return this.module.createI64(intValue.lo, intValue.hi); - if (contextualType.isSmallInteger) - return this.module.createI32(intValue.toI32()); + if (contextualType.isSmallInteger) { + var smallIntValue: i32 = contextualType.isSignedInteger + ? intValue.lo << contextualType.smallIntegerShift >> contextualType.smallIntegerShift + : intValue.lo & contextualType.smallIntegerMask; + return this.module.createI32(smallIntValue); + } if (contextualType == Type.void && !intValue.fitsInI32) { this.currentType = Type.i64; return this.module.createI64(intValue.lo, intValue.hi); diff --git a/src/parser.ts b/src/parser.ts index a0b27e01..e602257e 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -717,12 +717,25 @@ export class Parser extends DiagnosticEmitter { if (tn.skip(Token.READONLY)) modifiers = addModifier(Node.createModifier(ModifierKind.READONLY, tn.range()), modifiers); + // check if accessor: ('get' | 'set') ^\n Identifier + tn.mark(); var isGetter = false; var isSetter = false; - if (isGetter = tn.skip(Token.GET)) - modifiers = addModifier(Node.createModifier(ModifierKind.GET, tn.range()), modifiers); - else if (isSetter = tn.skip(Token.SET)) // can't be both - modifiers = addModifier(Node.createModifier(ModifierKind.SET, tn.range()), modifiers); + if (isGetter = tn.skip(Token.GET)) { + if (tn.peek(true, true) == Token.IDENTIFIER && !tn.nextTokenOnNewLine) + modifiers = addModifier(Node.createModifier(ModifierKind.GET, tn.range()), modifiers); + else { + tn.reset(); + isGetter = false; + } + } else if (isSetter = tn.skip(Token.SET)) { // can't be both + if (tn.peek(true, true) == Token.IDENTIFIER && !tn.nextTokenOnNewLine) + modifiers = addModifier(Node.createModifier(ModifierKind.SET, tn.range()), modifiers); + else { + tn.reset(); + isSetter = false; + } + } if (tn.skip(Token.CONSTRUCTOR) || tn.skip(Token.IDENTIFIER)) { // order is important var identifier: IdentifierExpression = tn.token == Token.CONSTRUCTOR diff --git a/src/program.ts b/src/program.ts index 3029573b..9055b4b8 100644 --- a/src/program.ts +++ b/src/program.ts @@ -939,8 +939,10 @@ export class Program extends DiagnosticEmitter { target = this.resolvePropertyAccess(expression, contextualFunction); break; + // case NodeKind.ELEMENTACCESS: + default: - throw new Error("target must be an identifier or property access"); + throw new Error("property target expected"); } if (!target) return null; diff --git a/src/tokenizer.ts b/src/tokenizer.ts index d2d487c6..a7b786aa 100644 --- a/src/tokenizer.ts +++ b/src/tokenizer.ts @@ -730,13 +730,13 @@ export class Tokenizer extends DiagnosticEmitter { } } - peek(checkOnNewLine: bool = false): Token { + peek(checkOnNewLine: bool = false, preferIdentifier: bool = false, maxCompoundLength: i32 = i32.MAX_VALUE): Token { var text = this.source.text; if (this.nextToken < 0) { var posBefore = this.pos; var tokenBefore = this.token; var tokenPosBefore = this.tokenPos; - this.nextToken = this.unsafeNext(); + this.nextToken = this.unsafeNext(preferIdentifier, maxCompoundLength); if (checkOnNewLine) { this.nextTokenOnNewLine = false; while (--this.tokenPos > posBefore) { @@ -1096,7 +1096,7 @@ export class Tokenizer extends DiagnosticEmitter { if (this.pos < this.end) { var c = text.charCodeAt(this.pos); if (c == CharCode.E || c == CharCode.e) { - if (++this.pos < this.end && text.charCodeAt(this.pos) == CharCode.MINUS) + if (++this.pos < this.end && (text.charCodeAt(this.pos) == CharCode.MINUS || text.charCodeAt(this.pos) == CharCode.PLUS) && isDecimalDigit(text.charCodeAt(this.pos + 1))) ++this.pos; while (this.pos < this.end && isDecimalDigit(text.charCodeAt(this.pos))) ++this.pos; diff --git a/src/util/i64.ts b/src/util/i64.ts index 197967d1..ffff7cf1 100644 --- a/src/util/i64.ts +++ b/src/util/i64.ts @@ -60,6 +60,10 @@ export class I64 { return this.lo; } + toF64(): f64 { + return this.hi * 0x100000000 + (this.lo >>> 0); + } + eq(other: I64): bool { return this.eq32(other.lo, other.hi); } diff --git a/std/assembly.d.ts b/std/assembly.d.ts index af7d3c1b..85819f6f 100644 --- a/std/assembly.d.ts +++ b/std/assembly.d.ts @@ -98,14 +98,26 @@ declare namespace bool { /** Converts any other numeric value to a 32-bit float. */ declare function f32(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f32; declare namespace f32 { + export const MIN_VALUE: f32; + export const MAX_VALUE: f32; + /** Smallest safely representable integer value. */ export const MIN_SAFE_INTEGER: f32; + /** Largest safely representable integer value. */ export const MAX_SAFE_INTEGER: f32; + /** Difference between 1 and the smallest representable value greater than 1. */ + export const EPSILON: f32; } /** Converts any other numeric value to a 64-bit float. */ declare function f64(value: i8 | i16 | i32 | i64 | isize | u8 | u16 | u32 | u64 | usize | bool | f32 | f64): f64; declare namespace f64 { + export const MIN_VALUE: f64; + export const MAX_VALUE: f64; + /** Smallest safely representable integer value. */ export const MIN_SAFE_INTEGER: f64; + /** Largest safely representable integer value. */ export const MAX_SAFE_INTEGER: f64; + /** Difference between 1 and the smallest representable value greater than 1. */ + export const EPSILON: f64; } // Built-ins diff --git a/std/assembly/array.ts b/std/assembly/array.ts index e91e07ee..6cb321c7 100644 --- a/std/assembly/array.ts +++ b/std/assembly/array.ts @@ -17,6 +17,18 @@ export class Array { } } + @operator("[]") + get(index: i32): T { + assert(index > 0 && index < this.capacity); + throw new Error("not implemented"); + } + + @operator("[]=") + set(index: i32, value: T): void { + assert(index > 0 && index < this.capacity); + throw new Error("not implemented"); + } + dispose(): void { store(changetype(this), 0); Heap.dispose(this.ptr); diff --git a/std/portable.d.ts b/std/portable.d.ts index ea276b23..77656aaa 100644 --- a/std/portable.d.ts +++ b/std/portable.d.ts @@ -78,14 +78,22 @@ declare namespace bool { /** Converts any other numeric value to a 32-bit float. */ declare function f32(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): f32; declare namespace f32 { + /** Smallest safely representable integer value. */ export const MIN_SAFE_INTEGER: f32; + /** Largest safely representable integer value. */ export const MAX_SAFE_INTEGER: f32; + /** Difference between 1 and the smallest representable value greater than 1. */ + export const EPSILON: f32; } /** Converts any other numeric value to a 64-bit float. */ declare function f64(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): f64; declare namespace f64 { + /** Smallest safely representable integer value. */ export const MIN_SAFE_INTEGER: f64; + /** Largest safely representable integer value. */ export const MAX_SAFE_INTEGER: f64; + /** Difference between 1 and the smallest representable value greater than 1. */ + export const EPSILON: f64; } // Portable built-ins diff --git a/std/portable.js b/std/portable.js index 65969003..db7b8deb 100644 --- a/std/portable.js +++ b/std/portable.js @@ -46,13 +46,15 @@ Object.defineProperties( globalScope["f32"] = function f32(value) { return Math.fround(value); } , { "MIN_SAFE_INTEGER": { value: -16777215, writable: false }, - "MAX_SAFE_INTEGER": { value: 16777215, writable: false } + "MAX_SAFE_INTEGER": { value: 16777215, writable: false }, + "EPSILON": { value: Math.fround(1.19209290e-07), writable: false } }); Object.defineProperties( globalScope["f64"] = function f64(value) { return +value; } , { "MIN_SAFE_INTEGER": { value: -9007199254740991, writable: false }, - "MAX_SAFE_INTEGER": { value: 9007199254740991, writable: false } + "MAX_SAFE_INTEGER": { value: 9007199254740991, writable: false }, + "EPSILON": { value: 2.2204460492503131e-16, writable: false } }); globalScope["clz"] = Math.clz32; diff --git a/tests/compiler/builtins.ts b/tests/compiler/builtins.ts index d7b00df0..059ff5cc 100644 --- a/tests/compiler/builtins.ts +++ b/tests/compiler/builtins.ts @@ -185,3 +185,36 @@ export function test(): void { // parseInt("1", 10); // parseFloat("1.0"); } + +// limits + +assert(i8.MIN_VALUE == 0x80); +assert(i8.MAX_VALUE == 0x7f); +assert(i16.MIN_VALUE == 0x8000); +assert(i16.MAX_VALUE == 0x7fff); +assert(i32.MIN_VALUE == 0x80000000); +assert(i32.MAX_VALUE == 0x7fffffff); +assert(i64.MIN_VALUE == 0x8000000000000000); +assert(i64.MAX_VALUE == 0x7fffffffffffffff); + +assert(u8.MIN_VALUE == 0); +assert(u8.MAX_VALUE == 0xff); +assert(u16.MIN_VALUE == 0); +assert(u16.MAX_VALUE == 0xffff); +assert(u32.MIN_VALUE == 0); +assert(u32.MAX_VALUE == 0xffffffff); +assert(u64.MIN_VALUE == 0); +assert(u64.MAX_VALUE == 0xffffffffffffffff); +assert(bool.MIN_VALUE == 0); assert(bool.MIN_VALUE == false); +assert(bool.MAX_VALUE == 1); assert(bool.MAX_VALUE == true); + +assert(f32.MIN_VALUE == -3.40282347e+38); +assert(f32.MAX_VALUE == 3.40282347e+38); +assert(f32.MIN_SAFE_INTEGER == -16777215); +assert(f32.MAX_SAFE_INTEGER == 16777215); +assert(f32.EPSILON == 1.19209290e-07); +assert(f64.MIN_VALUE == -1.7976931348623157e+308); +assert(f64.MAX_VALUE == 1.7976931348623157e+308); +assert(f64.MIN_SAFE_INTEGER == -9007199254740991); +assert(f64.MAX_SAFE_INTEGER == 9007199254740991); +assert(f64.EPSILON == 2.2204460492503131e-16); diff --git a/tests/compiler/builtins.wast b/tests/compiler/builtins.wast index 2c0c363f..275496d8 100644 --- a/tests/compiler/builtins.wast +++ b/tests/compiler/builtins.wast @@ -6,6 +6,34 @@ (global $builtins/b (mut i32) (i32.const 0)) (global $builtins/F (mut f64) (f64.const 0)) (global $builtins/s (mut i32) (i32.const 0)) + (global $i8.MIN_VALUE i32 (i32.const -128)) + (global $i8.MAX_VALUE i32 (i32.const 127)) + (global $i16.MIN_VALUE i32 (i32.const -32768)) + (global $i16.MAX_VALUE i32 (i32.const 32767)) + (global $i32.MIN_VALUE i32 (i32.const -2147483648)) + (global $i32.MAX_VALUE i32 (i32.const 2147483647)) + (global $i64.MIN_VALUE i64 (i64.const -9223372036854775808)) + (global $i64.MAX_VALUE i64 (i64.const 9223372036854775807)) + (global $u8.MIN_VALUE i32 (i32.const 0)) + (global $u8.MAX_VALUE i32 (i32.const 255)) + (global $u16.MIN_VALUE i32 (i32.const 0)) + (global $u16.MAX_VALUE i32 (i32.const 65535)) + (global $u32.MIN_VALUE i32 (i32.const 0)) + (global $u32.MAX_VALUE i32 (i32.const -1)) + (global $u64.MIN_VALUE i64 (i64.const 0)) + (global $u64.MAX_VALUE i64 (i64.const -1)) + (global $bool.MIN_VALUE i32 (i32.const 0)) + (global $bool.MAX_VALUE i32 (i32.const 1)) + (global $f32.MIN_VALUE f32 (f32.const -3402823466385288598117041e14)) + (global $f32.MAX_VALUE f32 (f32.const 3402823466385288598117041e14)) + (global $f32.MIN_SAFE_INTEGER f32 (f32.const -16777215)) + (global $f32.MAX_SAFE_INTEGER f32 (f32.const 16777215)) + (global $f32.EPSILON f32 (f32.const 1.1920928955078125e-07)) + (global $f64.MIN_VALUE f64 (f64.const -1797693134862315708145274e284)) + (global $f64.MAX_VALUE f64 (f64.const 1797693134862315708145274e284)) + (global $f64.MIN_SAFE_INTEGER f64 (f64.const -9007199254740991)) + (global $f64.MAX_SAFE_INTEGER f64 (f64.const 9007199254740991)) + (global $f64.EPSILON f64 (f64.const 2.220446049250313e-16)) (global $HEAP_BASE i32 (i32.const 4)) (memory $0 1) (export "test" (func $builtins/test)) @@ -1034,6 +1062,284 @@ ) (unreachable) ) + (if + (i32.eqz + (i32.eq + (i32.const -128) + (i32.const -128) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 127) + (i32.const 127) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const -32768) + (i32.const -32768) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 32767) + (i32.const 32767) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const -2147483648) + (i32.const -2147483648) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 2147483647) + (i32.const 2147483647) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i64.eq + (i64.const -9223372036854775808) + (i64.const -9223372036854775808) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i64.eq + (i64.const 9223372036854775807) + (i64.const 9223372036854775807) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 0) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 255) + (i32.const 255) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 0) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 65535) + (i32.const 65535) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 0) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const -1) + (i32.const -1) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i64.eq + (i64.const 0) + (i64.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i64.eq + (i64.const -1) + (i64.const -1) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 0) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 0) + (i32.const 0) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 1) + (i32.const 1) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (i32.eq + (i32.const 1) + (i32.const 1) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f32.eq + (f32.const -3402823466385288598117041e14) + (f32.neg + (f32.const 3402823466385288598117041e14) + ) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f32.eq + (f32.const 3402823466385288598117041e14) + (f32.const 3402823466385288598117041e14) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f32.eq + (f32.const -16777215) + (f32.neg + (f32.const 16777215) + ) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f32.eq + (f32.const 16777215) + (f32.const 16777215) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f32.eq + (f32.const 1.1920928955078125e-07) + (f32.const 1.1920928955078125e-07) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f64.eq + (f64.const -1797693134862315708145274e284) + (f64.neg + (f64.const 1797693134862315708145274e284) + ) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f64.eq + (f64.const 1797693134862315708145274e284) + (f64.const 1797693134862315708145274e284) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f64.eq + (f64.const -9007199254740991) + (f64.neg + (f64.const 9007199254740991) + ) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f64.eq + (f64.const 9007199254740991) + (f64.const 9007199254740991) + ) + ) + (unreachable) + ) + (if + (i32.eqz + (f64.eq + (f64.const 2.220446049250313e-16) + (f64.const 2.220446049250313e-16) + ) + ) + (unreachable) + ) ) ) (;