Add more inline-assembler-ish builtins; Update Binaryen

This commit is contained in:
dcodeIO 2018-04-27 19:12:25 +02:00
parent 06f99406be
commit 2aea14b518
15 changed files with 3452 additions and 2964 deletions

2
dist/asc.js vendored

File diff suppressed because one or more lines are too long

2
dist/asc.js.map vendored

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

2840
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -12,7 +12,7 @@
}, },
"dependencies": { "dependencies": {
"@protobufjs/utf8": "^1.1.0", "@protobufjs/utf8": "^1.1.0",
"binaryen": "45.0.0-nightly.20180412", "binaryen": "46.0.0-nightly.20180427",
"glob": "^7.1.2", "glob": "^7.1.2",
"long": "^4.0.0", "long": "^4.0.0",
"minimist": "^1.2.0", "minimist": "^1.2.0",

View File

@ -1676,29 +1676,6 @@ export function compileCall(
} }
} }
} }
case "i32.load8_s": return compileLoadInstruction(compiler, Type.i8, operands, Type.i32, reportNode);
case "i32.load8_u": return compileLoadInstruction(compiler, Type.u8, operands, Type.u32, reportNode);
case "i32.load16_s": return compileLoadInstruction(compiler, Type.i16, operands, Type.i32, reportNode);
case "i32.load16_u": return compileLoadInstruction(compiler, Type.u16, operands, Type.u32, reportNode);
case "i32.load": return compileLoadInstruction(compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.load8_s": return compileLoadInstruction(compiler, Type.i8, operands, Type.i64, reportNode);
case "i64.load8_u": return compileLoadInstruction(compiler, Type.u8, operands, Type.u64, reportNode);
case "i64.load16_s": return compileLoadInstruction(compiler, Type.i16, operands, Type.i64, reportNode);
case "i64.load16_u": return compileLoadInstruction(compiler, Type.u16, operands, Type.u64, reportNode);
case "i64.load32_s": return compileLoadInstruction(compiler, Type.i32, operands, Type.i64, reportNode);
case "i64.load32_u": return compileLoadInstruction(compiler, Type.u32, operands, Type.u64, reportNode);
case "i64.load": return compileLoadInstruction(compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.load": return compileLoadInstruction(compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.load": return compileLoadInstruction(compiler, Type.f64, operands, Type.f64, reportNode);
case "i32.store8": return compileStoreInstruction(compiler, Type.i8, operands, Type.i32, reportNode);
case "i32.store16": return compileStoreInstruction(compiler, Type.i16, operands, Type.i32, reportNode);
case "i32.store": return compileStoreInstruction(compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.store8": return compileStoreInstruction(compiler, Type.i8, operands, Type.i64, reportNode);
case "i64.store16": return compileStoreInstruction(compiler, Type.i16, operands, Type.i64, reportNode);
case "i64.store32": return compileStoreInstruction(compiler, Type.i32, operands, Type.i64, reportNode);
case "i64.store": return compileStoreInstruction(compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.store": return compileStoreInstruction(compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.store": return compileStoreInstruction(compiler, Type.f64, operands, Type.f64, reportNode);
// control flow // control flow
@ -2346,6 +2323,16 @@ export function compileCall(
return compiler.compileExpression(operands[0], Type.f64, ConversionKind.EXPLICIT); return compiler.compileExpression(operands[0], Type.f64, ConversionKind.EXPLICIT);
} }
} }
var expr = deferASMCall(compiler, prototype, operands, contextualType, reportNode);
if (expr) {
if (typeArguments && typeArguments.length) {
compiler.error(
DiagnosticCode.Type_0_is_not_generic,
reportNode.range, prototype.internalName
);
}
return expr;
}
compiler.error( compiler.error(
DiagnosticCode.Operation_not_supported, DiagnosticCode.Operation_not_supported,
reportNode.range reportNode.range
@ -2353,6 +2340,111 @@ export function compileCall(
return module.createUnreachable(); return module.createUnreachable();
} }
/** Defers an inline-assembler-like call to a built-in function. */
function deferASMCall(
compiler: Compiler,
prototype: FunctionPrototype,
operands: Expression[],
contextualType: Type,
reportNode: Node
): ExpressionRef {
switch (prototype.internalName) {
// TODO: Operators can't be just deferred (don't have a corresponding generic built-in)
// add, sub, mul, div_s, div_u, rem_s, rem_u
// and, or, xor, shl, shr_u, shr_s
// eq, eqz, ne, lt_s, lt_u, le_s, le_u, gt_s, gt_u, ge_s, ge_u
case "i32.clz": return deferASM("clz", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.clz": return deferASM("clz", compiler, Type.i64, operands, Type.i64, reportNode);
case "i32.ctz": return deferASM("ctz", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.ctz": return deferASM("ctz", compiler, Type.i64, operands, Type.i64, reportNode);
case "i32.popcnt": return deferASM("popcnt", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.popcnt": return deferASM("popcnt", compiler, Type.i64, operands, Type.i64, reportNode);
case "i32.rotl": return deferASM("rotl", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.rotl": return deferASM("rotl", compiler, Type.i64, operands, Type.i64, reportNode);
case "i32.rotr": return deferASM("rotr", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.rotr": return deferASM("rotr", compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.abs": return deferASM("abs", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.abs": return deferASM("abs", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.max": return deferASM("max", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.max": return deferASM("max", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.min": return deferASM("min", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.min": return deferASM("min", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.ceil": return deferASM("ceil", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.ceil": return deferASM("ceil", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.floor": return deferASM("floor", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.floor": return deferASM("floor", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.copysign": return deferASM("copysign", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.copysign": return deferASM("copysign", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.nearest": return deferASM("nearest", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.nearest": return deferASM("nearest", compiler, Type.f64, operands, Type.f64, reportNode);
case "i32.reinterpret_f32": return deferASM("reinterpret", compiler, Type.i32, operands, Type.f32, reportNode);
case "i64.reinterpret_f64": return deferASM("reinterpret", compiler, Type.i64, operands, Type.f64, reportNode);
case "f32.reinterpret_i32": return deferASM("reinterpret", compiler, Type.f32, operands, Type.i32, reportNode);
case "f64.reinterpret_i64": return deferASM("reinterpret", compiler, Type.f64, operands, Type.i64, reportNode);
case "f32.sqrt": return deferASM("sqrt", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.sqrt": return deferASM("sqrt", compiler, Type.f64, operands, Type.f64, reportNode);
case "f32.trunc": return deferASM("trunc", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.trunc": return deferASM("trunc", compiler, Type.f64, operands, Type.f64, reportNode);
case "i32.load8_s": return deferASM("load", compiler, Type.i8, operands, Type.i32, reportNode);
case "i32.load8_u": return deferASM("load", compiler, Type.u8, operands, Type.u32, reportNode);
case "i32.load16_s": return deferASM("load", compiler, Type.i16, operands, Type.i32, reportNode);
case "i32.load16_u": return deferASM("load", compiler, Type.u16, operands, Type.u32, reportNode);
case "i32.load": return deferASM("load", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.load8_s": return deferASM("load", compiler, Type.i8, operands, Type.i64, reportNode);
case "i64.load8_u": return deferASM("load", compiler, Type.u8, operands, Type.u64, reportNode);
case "i64.load16_s": return deferASM("load", compiler, Type.i16, operands, Type.i64, reportNode);
case "i64.load16_u": return deferASM("load", compiler, Type.u16, operands, Type.u64, reportNode);
case "i64.load32_s": return deferASM("load", compiler, Type.i32, operands, Type.i64, reportNode);
case "i64.load32_u": return deferASM("load", compiler, Type.u32, operands, Type.u64, reportNode);
case "i64.load": return deferASM("load", compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.load": return deferASM("load", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.load": return deferASM("load", compiler, Type.f64, operands, Type.f64, reportNode);
case "i32.store8": return deferASM("store", compiler, Type.i8, operands, Type.i32, reportNode);
case "i32.store16": return deferASM("store", compiler, Type.i16, operands, Type.i32, reportNode);
case "i32.store": return deferASM("store", compiler, Type.i32, operands, Type.i32, reportNode);
case "i64.store8": return deferASM("store", compiler, Type.i8, operands, Type.i64, reportNode);
case "i64.store16": return deferASM("store", compiler, Type.i16, operands, Type.i64, reportNode);
case "i64.store32": return deferASM("store", compiler, Type.i32, operands, Type.i64, reportNode);
case "i64.store": return deferASM("store", compiler, Type.i64, operands, Type.i64, reportNode);
case "f32.store": return deferASM("store", compiler, Type.f32, operands, Type.f32, reportNode);
case "f64.store": return deferASM("store", compiler, Type.f64, operands, Type.f64, reportNode);
}
return 0;
}
/** A helper for deferring inline-assembler-like calls to built-in functions. */
function deferASM(
name: string,
compiler: Compiler,
typeArgument: Type,
operands: Expression[],
valueType: Type,
reportNode: Node
): ExpressionRef {
var prototype = assert(compiler.program.elementsLookup.get(name));
assert(prototype.kind == ElementKind.FUNCTION_PROTOTYPE);
return compileCall(compiler, <FunctionPrototype>prototype, [ typeArgument ], operands, valueType, reportNode);
}
/** Evaluates the constant type of a type argument *or* expression. */
function evaluateConstantType( function evaluateConstantType(
compiler: Compiler, compiler: Compiler,
typeArguments: Type[] | null, typeArguments: Type[] | null,
@ -2401,6 +2493,7 @@ function evaluateConstantType(
return null; return null;
} }
/** Evaluates a `constantOffset` argument.*/
function evaluateConstantOffset(compiler: Compiler, expression: Expression): i32 { function evaluateConstantOffset(compiler: Compiler, expression: Expression): i32 {
var expr: ExpressionRef; var expr: ExpressionRef;
var value: i32; var value: i32;
@ -2518,29 +2611,3 @@ export function compileAbort(
module.createUnreachable() module.createUnreachable()
]); ]);
} }
/** Explicitly compiles a specific load instruction. */
export function compileLoadInstruction(
compiler: Compiler,
loadType: Type,
loadOperands: Expression[],
valueType: Type,
reportNode: Node
): ExpressionRef { // transform to a `<valueType>load<loadType>(offset)` call
var loadPrototype = assert(compiler.program.elementsLookup.get("load"));
assert(loadPrototype.kind == ElementKind.FUNCTION_PROTOTYPE);
return compileCall(compiler, <FunctionPrototype>loadPrototype, [ loadType ], loadOperands, valueType, reportNode);
}
/** Explicitly compiles a specific store instruction. */
export function compileStoreInstruction(
compiler: Compiler,
storeType: Type,
storeOperands: Expression[],
valueType: Type,
reportNode: Node
): ExpressionRef { // transform to a `store<storeType>(offset, <valueType>value)` call
var storePrototype = assert(compiler.program.elementsLookup.get("store"));
assert(storePrototype.kind == ElementKind.FUNCTION_PROTOTYPE);
return compileCall(compiler, <FunctionPrototype>storePrototype, [ storeType ], storeOperands, valueType, reportNode);
}

14
std/assembly.d.ts vendored
View File

@ -265,23 +265,23 @@ declare function alignof<T>(): usize;
declare function offsetof<T>(fieldName?: string): usize; declare function offsetof<T>(fieldName?: string): usize;
/** Changes the type of any value of `usize` kind to another one of `usize` kind. Useful for casting class instances to their pointer values and vice-versa. Beware that this is unsafe.*/ /** Changes the type of any value of `usize` kind to another one of `usize` kind. Useful for casting class instances to their pointer values and vice-versa. Beware that this is unsafe.*/
declare function changetype<T>(value: any): T; declare function changetype<T>(value: any): T;
/** Explicitly requests no bounds checks on the provided expression. */ /** Explicitly requests no bounds checks on the provided expression. Useful for array accesses. */
declare function unchecked<T>(value: T): T; declare function unchecked<T>(value: T): T;
/** Tests if a 32-bit or 64-bit float is `NaN`. */ /** Tests if a 32-bit or 64-bit float is `NaN`. */
declare function isNaN<T = f32 | f64>(value: T): bool; declare function isNaN<T = f32 | f64>(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 = f32 | f64>(value: T): bool; declare function isFinite<T = f32 | f64>(value: T): bool;
/** Tests if the specified expression is of an integer type and not a reference. Compiles to a constant. */ /** Tests if the specified type *or* expression is of an integer type and not a reference. Compiles to a constant. */
declare function isInteger<T>(value?: any): value is number; declare function isInteger<T>(value?: any): value is number;
/** Tests if the specified expression is of a float type. Compiles to a constant. */ /** Tests if the specified type *or* expression is of a float type. Compiles to a constant. */
declare function isFloat<T>(value?: any): value is number; declare function isFloat<T>(value?: any): value is number;
/** Tests if the specified expression can represent negative numbers. Compiles to a constant. */ /** Tests if the specified type *or* expression can represent negative numbers. Compiles to a constant. */
declare function isSigned<T>(value?: any): value is number; declare function isSigned<T>(value?: any): value is number;
/** Tests if the specified expression is of a reference type. Compiles to a constant. */ /** Tests if the specified type *or* expression is of a reference type. Compiles to a constant. */
declare function isReference<T>(value?: any): value is object | string; declare function isReference<T>(value?: any): value is object | string;
/** Tests if the specified expression can be used ass a string. Compiles to a constant. */ /** Tests if the specified type *or* expression can be used as a string. Compiles to a constant. */
declare function isString<T>(value?: any): value is string | String; declare function isString<T>(value?: any): value is string | String;
/** Tests if the specified expression can be used as an array. Compiles to a constant. */ /** Tests if the specified type *or* expression can be used as an array. Compiles to a constant. */
declare function isArray<T>(value?: any): value is Array<any>; declare function isArray<T>(value?: any): value is Array<any>;
/** Traps if the specified value is not true-ish, otherwise returns the (non-nullable) value. */ /** Traps if the specified value is not true-ish, otherwise returns the (non-nullable) value. */
declare function assert<T>(isTrueish: T, message?: string): T & object; // any better way to model `: T != null`? declare function assert<T>(isTrueish: T, message?: string): T & object; // any better way to model `: T != null`?

View File

@ -103,6 +103,12 @@ export declare function i32(value: void): i32;
export namespace i32 { export namespace i32 {
export const MIN_VALUE: i32 = -2147483648; export const MIN_VALUE: i32 = -2147483648;
export const MAX_VALUE: i32 = 2147483647; export const MAX_VALUE: i32 = 2147483647;
export declare function clz(value: i32): i32;
export declare function ctz(value: i32): i32;
export declare function popcnt(value: i32): i32;
export declare function rotl(value: i32, shift: i32): i32;
export declare function rotr(value: i32, shift: i32): i32;
export declare function reinterpret_f32(value: f32): i32;
export declare function load8_s(offset: usize, constantOffset?: usize): i32; export declare function load8_s(offset: usize, constantOffset?: usize): i32;
export declare function load8_u(offset: usize, constantOffset?: usize): i32; export declare function load8_u(offset: usize, constantOffset?: usize): i32;
export declare function load16_s(offset: usize, constantOffset?: usize): i32; export declare function load16_s(offset: usize, constantOffset?: usize): i32;
@ -117,6 +123,8 @@ export declare function i64(value: void): i64;
export namespace i64 { export namespace i64 {
export const MIN_VALUE: i64 = -9223372036854775808; export const MIN_VALUE: i64 = -9223372036854775808;
export const MAX_VALUE: i64 = 9223372036854775807; export const MAX_VALUE: i64 = 9223372036854775807;
export declare function clz(value: i64): i64;
export declare function ctz(value: i64): i64;
export declare function load8_s(offset: usize, constantOffset?: usize): i64; export declare function load8_s(offset: usize, constantOffset?: usize): i64;
export declare function load8_u(offset: usize, constantOffset?: usize): u64; export declare function load8_u(offset: usize, constantOffset?: usize): u64;
export declare function load16_s(offset: usize, constantOffset?: usize): i64; export declare function load16_s(offset: usize, constantOffset?: usize): i64;
@ -124,6 +132,10 @@ export namespace i64 {
export declare function load32_s(offset: usize, constantOffset?: usize): i64; export declare function load32_s(offset: usize, constantOffset?: usize): i64;
export declare function load32_u(offset: usize, constantOffset?: usize): u64; export declare function load32_u(offset: usize, constantOffset?: usize): u64;
export declare function load(offset: usize, constantOffset?: usize): i64; export declare function load(offset: usize, constantOffset?: usize): i64;
export declare function popcnt(value: i64): i64;
export declare function rotl(value: i64, shift: i64): i64;
export declare function rotr(value: i64, shift: i64): i64;
export declare function reinterpret_f64(value: f64): i64;
export declare function store8(offset: usize, value: i64, constantOffset?: usize): void; export declare function store8(offset: usize, value: i64, constantOffset?: usize): void;
export declare function store16(offset: usize, value: i64, constantOffset?: usize): void; export declare function store16(offset: usize, value: i64, constantOffset?: usize): void;
export declare function store32(offset: usize, value: i64, constantOffset?: usize): void; export declare function store32(offset: usize, value: i64, constantOffset?: usize): void;
@ -186,8 +198,18 @@ export namespace f32 {
export const MIN_SAFE_INTEGER: f32 = -16777215; export const MIN_SAFE_INTEGER: f32 = -16777215;
export const MAX_SAFE_INTEGER: f32 = 16777215; export const MAX_SAFE_INTEGER: f32 = 16777215;
export const EPSILON = reinterpret<f32>(0x34000000); // 0x1p-23f export const EPSILON = reinterpret<f32>(0x34000000); // 0x1p-23f
export declare function abs(value: f32): f32;
export declare function ceil(value: f32): f32;
export declare function copysign(x: f32, y: f32): f32;
export declare function floor(value: f32): f32;
export declare function load(offset: usize, constantOffset?: usize): f32; export declare function load(offset: usize, constantOffset?: usize): f32;
export declare function max(left: f32, right: f32): f32;
export declare function min(left: f32, right: f32): f32;
export declare function nearest(value: f32): f32;
export declare function reinterpret_i32(value: i32): f32;
export declare function sqrt(value: f32): f32;
export declare function store(offset: usize, value: f32, constantOffset?: usize): void; export declare function store(offset: usize, value: f32, constantOffset?: usize): void;
export declare function trunc(value: f32): f32;
} }
export declare function f64(value: void): f64; export declare function f64(value: void): f64;
@ -198,8 +220,18 @@ export namespace f64 {
export const MIN_SAFE_INTEGER: f64 = -9007199254740991; export const MIN_SAFE_INTEGER: f64 = -9007199254740991;
export const MAX_SAFE_INTEGER: f64 = 9007199254740991; export const MAX_SAFE_INTEGER: f64 = 9007199254740991;
export const EPSILON = reinterpret<f64>(0x3CB0000000000000); // 0x1p-52 export const EPSILON = reinterpret<f64>(0x3CB0000000000000); // 0x1p-52
export declare function abs(value: f64): f64;
export declare function ceil(value: f64): f64;
export declare function copysign(x: f64, y: f64): f64;
export declare function floor(value: f64): f64;
export declare function load(offset: usize, constantOffset?: usize): f64; export declare function load(offset: usize, constantOffset?: usize): f64;
export declare function max(left: f64, right: f64): f64;
export declare function min(left: f64, right: f64): f64;
export declare function nearest(value: f64): f64;
export declare function reinterpret_i64(value: i64): f64;
export declare function sqrt(value: f64): f64;
export declare function store(offset: usize, value: f64, constantOffset?: usize): void; export declare function store(offset: usize, value: f64, constantOffset?: usize): void;
export declare function trunc(value: f64): f64;
} }
export declare const HEAP_BASE: usize; export declare const HEAP_BASE: usize;

View File

@ -784,6 +784,172 @@
(i32.const 8) (i32.const 8)
(i64.const 1) (i64.const 1)
) )
(set_global $builtins/i
(i32.const 1067450368)
)
(set_global $builtins/f
(f32.const 3.5032461608120427e-44)
)
(set_global $builtins/I
(i64.const 4608308318706860032)
)
(set_global $builtins/F
(f64.const 1.24e-322)
)
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/i
(i32.const 10)
)
(set_global $builtins/I
(i64.const 200)
)
(set_global $builtins/f
(f32.const 1.25)
)
(set_global $builtins/F
(f64.const 25)
)
(if
(i32.eqz
(get_global $builtins/i)
)
(unreachable)
)
(if
(i32.eqz
(call $isNaN<f32>
(f32.const nan:0x400000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 261)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isNaN<f64>
(f64.const nan:0x8000000000000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 262)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const nan:0x400000)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 263)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 264)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const nan:0x8000000000000)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 265)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 266)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f32>
(f32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 267)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f64>
(f64.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 268)
(i32.const 0)
)
(unreachable)
)
)
(drop (drop
(i32.load8_s (i32.load8_s
(i32.const 8) (i32.const 8)
@ -815,7 +981,7 @@
) )
) )
(drop (drop
(i64.load8_s (i64.load8_u
(i32.const 8) (i32.const 8)
) )
) )
@ -890,172 +1056,6 @@
(i32.const 8) (i32.const 8)
(f64.const 1) (f64.const 1)
) )
(set_global $builtins/i
(i32.const 1067450368)
)
(set_global $builtins/f
(f32.const 3.5032461608120427e-44)
)
(set_global $builtins/I
(i64.const 4608308318706860032)
)
(set_global $builtins/F
(f64.const 1.24e-322)
)
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/i
(i32.const 10)
)
(set_global $builtins/I
(i64.const 200)
)
(set_global $builtins/f
(f32.const 1.25)
)
(set_global $builtins/F
(f64.const 25)
)
(if
(i32.eqz
(get_global $builtins/i)
)
(unreachable)
)
(if
(i32.eqz
(call $isNaN<f32>
(f32.const nan:0x400000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 288)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isNaN<f64>
(f64.const nan:0x8000000000000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 289)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const nan:0x400000)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 290)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 291)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const nan:0x8000000000000)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 292)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 293)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f32>
(f32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 294)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f64>
(f64.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 4)
(i32.const 295)
(i32.const 0)
)
(unreachable)
)
)
(drop (drop
(call $isNaN<f64> (call $isNaN<f64>
(f64.const 1) (f64.const 1)

View File

@ -196,33 +196,6 @@ store<i64>(8, <i64>1);
store<i64>(8, <i32>1); // must extend store<i64>(8, <i32>1); // must extend
// explicit load and store
i32.load8_s(8);
i32.load8_u(8);
i32.load16_s(8);
i32.load16_u(8);
i32.load(8);
i64.load8_s(8);
i64.load8_s(8);
i64.load16_s(8);
i64.load16_u(8);
i64.load32_s(8);
i64.load32_u(8);
i64.load(8);
f32.load(8);
f64.load(8);
i32.store8(8, 1);
i32.store16(8, 1);
i32.store(8, 1);
i64.store8(8, 1);
i64.store16(8, 1);
i64.store32(8, 1);
i64.store(8, 1);
f32.store(8, 1);
f64.store(8, 1);
// reinterpretation // reinterpretation
reinterpret<i32>(1.25); reinterpret<i32>(1.25);
@ -336,6 +309,80 @@ assert(f64.MIN_SAFE_INTEGER == -9007199254740991);
assert(f64.MAX_SAFE_INTEGER == 9007199254740991); assert(f64.MAX_SAFE_INTEGER == 9007199254740991);
assert(f64.EPSILON == 2.2204460492503131e-16); assert(f64.EPSILON == 2.2204460492503131e-16);
// inline-assembler
f32.abs(1.0);
f64.abs(1.0);
f32.ceil(1.0);
f64.ceil(1.0);
i32.clz(1);
i64.clz(1);
f32.copysign(1.0, 2.0);
f64.copysign(1.0, 2.0);
i32.ctz(1);
i64.ctz(1);
f32.floor(1.0);
f64.floor(1.0);
f32.nearest(1.0);
f64.nearest(1.0);
i32.popcnt(1);
i64.popcnt(1);
i32.load8_s(8);
i32.load8_u(8);
i32.load16_s(8);
i32.load16_u(8);
i32.load(8);
i64.load8_s(8);
i64.load8_u(8);
i64.load16_s(8);
i64.load16_u(8);
i64.load32_s(8);
i64.load32_u(8);
i64.load(8);
f32.load(8);
f64.load(8);
f32.max(1.0, 2.0);
f64.max(1.0, 2.0);
f32.min(1.0, 2.0);
f64.min(1.0, 2.0);
i32.reinterpret_f32(1.0);
i64.reinterpret_f64(1.0);
f32.reinterpret_i32(1);
f64.reinterpret_i64(1);
i32.rotl(1, 2);
i64.rotl(1, 2);
i32.rotr(1, 2);
i64.rotr(1, 2);
f32.sqrt(1.0);
f64.sqrt(1.0);
i32.store8(8, 1);
i32.store16(8, 1);
i32.store(8, 1);
i64.store8(8, 1);
i64.store16(8, 1);
i64.store32(8, 1);
i64.store(8, 1);
f32.store(8, 1.0);
f64.store(8, 1.0);
f32.trunc(1.0);
f64.trunc(1.0);
// should be importable // should be importable
import { isNaN as isItNaN } from "builtins"; import { isNaN as isItNaN } from "builtins";
isItNaN<f64>(1); isItNaN<f64>(1);

File diff suppressed because it is too large Load Diff

View File

@ -7031,6 +7031,172 @@
(i32.const 8) (i32.const 8)
(i64.const 1) (i64.const 1)
) )
(set_global $builtins/i
(i32.const 1067450368)
)
(set_global $builtins/f
(f32.const 3.5032461608120427e-44)
)
(set_global $builtins/I
(i64.const 4608308318706860032)
)
(set_global $builtins/F
(f64.const 1.24e-322)
)
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/i
(i32.const 10)
)
(set_global $builtins/I
(i64.const 200)
)
(set_global $builtins/f
(f32.const 1.25)
)
(set_global $builtins/F
(f64.const 25)
)
(if
(i32.eqz
(get_global $builtins/i)
)
(unreachable)
)
(if
(i32.eqz
(call $isNaN<f32>
(f32.const nan:0x400000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 261)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isNaN<f64>
(f64.const nan:0x8000000000000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 262)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const nan:0x400000)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 263)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 264)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const nan:0x8000000000000)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 265)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 266)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f32>
(f32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 267)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f64>
(f64.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 268)
(i32.const 0)
)
(unreachable)
)
)
(drop (drop
(i32.load8_s (i32.load8_s
(i32.const 8) (i32.const 8)
@ -7062,7 +7228,7 @@
) )
) )
(drop (drop
(i64.load8_s (i64.load8_u
(i32.const 8) (i32.const 8)
) )
) )
@ -7137,172 +7303,6 @@
(i32.const 8) (i32.const 8)
(f64.const 1) (f64.const 1)
) )
(set_global $builtins/i
(i32.const 1067450368)
)
(set_global $builtins/f
(f32.const 3.5032461608120427e-44)
)
(set_global $builtins/I
(i64.const 4608308318706860032)
)
(set_global $builtins/F
(f64.const 1.24e-322)
)
(drop
(current_memory)
)
(drop
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/s
(current_memory)
)
(set_global $builtins/s
(grow_memory
(i32.const 1)
)
)
(set_global $builtins/i
(i32.const 10)
)
(set_global $builtins/I
(i64.const 200)
)
(set_global $builtins/f
(f32.const 1.25)
)
(set_global $builtins/F
(f64.const 25)
)
(if
(i32.eqz
(get_global $builtins/i)
)
(unreachable)
)
(if
(i32.eqz
(call $isNaN<f32>
(f32.const nan:0x400000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 288)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isNaN<f64>
(f64.const nan:0x8000000000000)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 289)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const nan:0x400000)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 290)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f32>
(f32.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 291)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const nan:0x8000000000000)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 292)
(i32.const 0)
)
(unreachable)
)
)
(if
(call $isFinite<f64>
(f64.const inf)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 293)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f32>
(f32.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 294)
(i32.const 0)
)
(unreachable)
)
)
(if
(i32.eqz
(call $isFinite<f64>
(f64.const 0)
)
)
(block
(call $abort
(i32.const 0)
(i32.const 28)
(i32.const 295)
(i32.const 0)
)
(unreachable)
)
)
(drop (drop
(call $isNaN<f64> (call $isNaN<f64>
(f64.const 1) (f64.const 1)

File diff suppressed because it is too large Load Diff

View File

@ -589,12 +589,13 @@
) )
(f64.const -1) (f64.const -1)
) )
(if (result f64) (block (result f64)
(if
(i32.eq (i32.eq
(get_local $2) (get_local $2)
(i32.const 43) (i32.const 43)
) )
(block (result f64) (block
(if (if
(i32.eqz (i32.eqz
(tee_local $4 (tee_local $4
@ -618,7 +619,7 @@
) )
) )
) )
(f64.const 1) )
) )
(f64.const 1) (f64.const 1)
) )
@ -983,12 +984,13 @@
) )
(f64.const -1) (f64.const -1)
) )
(if (result f64) (block (result f64)
(if
(i32.eq (i32.eq
(get_local $2) (get_local $2)
(i32.const 43) (i32.const 43)
) )
(block (result f64) (block
(if (if
(i32.eqz (i32.eqz
(tee_local $3 (tee_local $3
@ -1012,7 +1014,7 @@
) )
) )
) )
(f64.const 1) )
) )
(f64.const 1) (f64.const 1)
) )