mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 15:12:12 +00:00
Implement ternary using if, see AssemblyScript/assemblyscript#123
This commit is contained in:
parent
558a4d5c63
commit
c6af2d1454
2
assembly.d.ts
vendored
2
assembly.d.ts
vendored
@ -66,7 +66,7 @@ declare function current_memory(): i32;
|
|||||||
/** Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous memory size in units of pages or `-1` on failure. */
|
/** Grows linear memory by a given unsigned delta of pages. One page is 64kb. Returns the previous memory size in units of pages or `-1` on failure. */
|
||||||
declare function grow_memory(value: i32): i32;
|
declare function grow_memory(value: i32): i32;
|
||||||
/** Emits an unreachable operation that results in a runtime error when executed. */
|
/** Emits an unreachable operation that results in a runtime error when executed. */
|
||||||
declare function unreachable(): void;
|
declare function unreachable(): any; // sic
|
||||||
|
|
||||||
/** Loads a value of the specified type from memory. */
|
/** Loads a value of the specified type from memory. */
|
||||||
declare function load<T>(offset: usize): T;
|
declare function load<T>(offset: usize): T;
|
||||||
|
@ -8,5 +8,14 @@
|
|||||||
"desc": "Print this message.",
|
"desc": "Print this message.",
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"aliases": [ "h" ]
|
"aliases": [ "h" ]
|
||||||
|
},
|
||||||
|
"optimize": {
|
||||||
|
"desc": "Optimize the module.",
|
||||||
|
"type": "boolean",
|
||||||
|
"aliases": [ "O" ]
|
||||||
|
},
|
||||||
|
"validate": {
|
||||||
|
"desc": "Validate the module.",
|
||||||
|
"type": "boolean"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
25
bin/asc.ts
25
bin/asc.ts
@ -8,6 +8,7 @@ import * as as from "../src";
|
|||||||
|
|
||||||
var conf: { [key: string]: { desc: string, type: string, aliases: string[], default: any } } = require("./asc.json");
|
var conf: { [key: string]: { desc: string, type: string, aliases: string[], default: any } } = require("./asc.json");
|
||||||
var opts: minimist.Opts = {};
|
var opts: minimist.Opts = {};
|
||||||
|
|
||||||
Object.keys(conf).forEach(key => {
|
Object.keys(conf).forEach(key => {
|
||||||
var opt = conf[key];
|
var opt = conf[key];
|
||||||
if (opt.aliases)
|
if (opt.aliases)
|
||||||
@ -80,7 +81,7 @@ let diagnostic: as.DiagnosticMessage | null;
|
|||||||
let hasErrors: boolean = false;
|
let hasErrors: boolean = false;
|
||||||
|
|
||||||
while ((diagnostic = as.nextDiagnostic(parser)) != null) {
|
while ((diagnostic = as.nextDiagnostic(parser)) != null) {
|
||||||
console.error(as.formatDiagnostic(diagnostic, process.stdout.isTTY, true));
|
console.error(as.formatDiagnostic(diagnostic, process.stderr.isTTY, true));
|
||||||
if (as.isError(diagnostic))
|
if (as.isError(diagnostic))
|
||||||
hasErrors = true;
|
hasErrors = true;
|
||||||
}
|
}
|
||||||
@ -89,5 +90,27 @@ if (hasErrors)
|
|||||||
process.exit(1);
|
process.exit(1);
|
||||||
|
|
||||||
const module = as.compile(parser);
|
const module = as.compile(parser);
|
||||||
|
|
||||||
|
hasErrors = false;
|
||||||
|
while ((diagnostic = as.nextDiagnostic(parser)) != null) {
|
||||||
|
console.error(as.formatDiagnostic(diagnostic, process.stderr.isTTY, true));
|
||||||
|
if (as.isError(diagnostic))
|
||||||
|
hasErrors = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasErrors) {
|
||||||
|
module.dispose();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args["validate"])
|
||||||
|
if (!module.validate()) {
|
||||||
|
module.dispose();
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args["optimize"])
|
||||||
|
module.optimize();
|
||||||
|
|
||||||
_BinaryenModulePrint(module.ref);
|
_BinaryenModulePrint(module.ref);
|
||||||
module.dispose();
|
module.dispose();
|
||||||
|
12
src/ast.ts
12
src/ast.ts
@ -19,7 +19,7 @@
|
|||||||
│ ├ ParenthesizedExpression
|
│ ├ ParenthesizedExpression
|
||||||
│ ├ NewExpression
|
│ ├ NewExpression
|
||||||
│ ├ PropertyAccessExpression
|
│ ├ PropertyAccessExpression
|
||||||
│ ├ SelectExpression
|
│ ├ TernaryExpression
|
||||||
│ └ UnaryExpression
|
│ └ UnaryExpression
|
||||||
│ ├ UnaryPostfixExpression
|
│ ├ UnaryPostfixExpression
|
||||||
│ └ UnaryPrefixExpression
|
│ └ UnaryPrefixExpression
|
||||||
@ -101,7 +101,7 @@ export enum NodeKind {
|
|||||||
NULL,
|
NULL,
|
||||||
PARENTHESIZED,
|
PARENTHESIZED,
|
||||||
PROPERTYACCESS,
|
PROPERTYACCESS,
|
||||||
SELECT,
|
TERNARY,
|
||||||
SUPER,
|
SUPER,
|
||||||
THIS,
|
THIS,
|
||||||
TRUE,
|
TRUE,
|
||||||
@ -302,8 +302,8 @@ export abstract class Expression extends Node {
|
|||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static createSelect(condition: Expression, ifThen: Expression, ifElse: Expression, range: Range): SelectExpression {
|
static createTernary(condition: Expression, ifThen: Expression, ifElse: Expression, range: Range): TernaryExpression {
|
||||||
const expr: SelectExpression = new SelectExpression();
|
const expr: TernaryExpression = new TernaryExpression();
|
||||||
expr.range = range;
|
expr.range = range;
|
||||||
(expr.condition = condition).parent = expr;
|
(expr.condition = condition).parent = expr;
|
||||||
(expr.ifThen = ifThen).parent = expr;
|
(expr.ifThen = ifThen).parent = expr;
|
||||||
@ -549,9 +549,9 @@ export class RegexpLiteralExpression extends LiteralExpression {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class SelectExpression extends Expression {
|
export class TernaryExpression extends Expression {
|
||||||
|
|
||||||
kind = NodeKind.SELECT;
|
kind = NodeKind.TERNARY;
|
||||||
condition: Expression;
|
condition: Expression;
|
||||||
ifThen: Expression;
|
ifThen: Expression;
|
||||||
ifElse: Expression;
|
ifElse: Expression;
|
||||||
|
@ -59,7 +59,7 @@ import {
|
|||||||
NewExpression,
|
NewExpression,
|
||||||
ParenthesizedExpression,
|
ParenthesizedExpression,
|
||||||
PropertyAccessExpression,
|
PropertyAccessExpression,
|
||||||
SelectExpression,
|
TernaryExpression,
|
||||||
StringLiteralExpression,
|
StringLiteralExpression,
|
||||||
UnaryPostfixExpression,
|
UnaryPostfixExpression,
|
||||||
UnaryPrefixExpression,
|
UnaryPrefixExpression,
|
||||||
@ -927,8 +927,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
expr = this.compilePropertyAccessExpression(<PropertyAccessExpression>expression, contextualType);
|
expr = this.compilePropertyAccessExpression(<PropertyAccessExpression>expression, contextualType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NodeKind.SELECT:
|
case NodeKind.TERNARY:
|
||||||
expr = this.compileSelectExpression(<SelectExpression>expression, contextualType);
|
expr = this.compileTernaryExpression(<TernaryExpression>expression, contextualType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case NodeKind.UNARYPOSTFIX:
|
case NodeKind.UNARYPOSTFIX:
|
||||||
@ -1482,6 +1482,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
/** Compiles a call to a function. If an instance method, `this` is the first element in `argumentExpressions`. */
|
/** Compiles a call to a function. If an instance method, `this` is the first element in `argumentExpressions`. */
|
||||||
compileCall(functionInstance: Function, argumentExpressions: Expression[], reportNode: Node): ExpressionRef {
|
compileCall(functionInstance: Function, argumentExpressions: Expression[], reportNode: Node): ExpressionRef {
|
||||||
|
const previousType: Type = this.currentType;
|
||||||
|
|
||||||
// validate and compile arguments
|
// validate and compile arguments
|
||||||
const parameters: Parameter[] = functionInstance.parameters;
|
const parameters: Parameter[] = functionInstance.parameters;
|
||||||
@ -1627,6 +1628,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.module.createHost(HostOp.GrowMemory, null, operands);
|
return this.module.createHost(HostOp.GrowMemory, null, operands);
|
||||||
|
|
||||||
case "unreachable":
|
case "unreachable":
|
||||||
|
this.currentType = previousType;
|
||||||
return this.module.createUnreachable();
|
return this.module.createUnreachable();
|
||||||
|
|
||||||
case "isNaN": // value != value
|
case "isNaN": // value != value
|
||||||
@ -1645,35 +1647,35 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "isFinite": // value != value ? false : abs(value) != Infinity
|
case "isFinite": // v=[abs(value) != Infinity, false]; return value == value ? v[0] : v[1]
|
||||||
if (functionInstance.typeArguments[0] == Type.f64) {
|
if (functionInstance.typeArguments[0] == Type.f64) {
|
||||||
tempLocal = this.currentFunction.addLocal(Type.f64);
|
tempLocal = this.currentFunction.addLocal(Type.f64);
|
||||||
return this.module.createSelect(
|
return this.module.createSelect(
|
||||||
this.module.createBinary(BinaryOp.NeF64,
|
|
||||||
this.module.createTeeLocal(tempLocal.index, operands[0]),
|
|
||||||
this.module.createGetLocal(tempLocal.index, NativeType.F64)
|
|
||||||
),
|
|
||||||
this.module.createI32(0),
|
|
||||||
this.module.createBinary(BinaryOp.NeF64,
|
this.module.createBinary(BinaryOp.NeF64,
|
||||||
this.module.createUnary(UnaryOp.AbsF64,
|
this.module.createUnary(UnaryOp.AbsF64,
|
||||||
this.module.createGetLocal(tempLocal.index, NativeType.F64)
|
this.module.createTeeLocal(tempLocal.index, operands[0])
|
||||||
),
|
),
|
||||||
this.module.createF64(Infinity)
|
this.module.createF64(Infinity)
|
||||||
|
),
|
||||||
|
this.module.createI32(0),
|
||||||
|
this.module.createBinary(BinaryOp.EqF64,
|
||||||
|
this.module.createGetLocal(tempLocal.index, NativeType.F64),
|
||||||
|
this.module.createGetLocal(tempLocal.index, NativeType.F64)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
} else if (functionInstance.typeArguments[0] == Type.f32) {
|
} else if (functionInstance.typeArguments[0] == Type.f32) {
|
||||||
tempLocal = this.currentFunction.addLocal(Type.f32);
|
tempLocal = this.currentFunction.addLocal(Type.f32);
|
||||||
return this.module.createSelect(
|
return this.module.createSelect(
|
||||||
this.module.createBinary(BinaryOp.NeF32,
|
|
||||||
this.module.createTeeLocal(tempLocal.index, operands[0]),
|
|
||||||
this.module.createGetLocal(tempLocal.index, NativeType.F32)
|
|
||||||
),
|
|
||||||
this.module.createI32(0),
|
|
||||||
this.module.createBinary(BinaryOp.NeF32,
|
this.module.createBinary(BinaryOp.NeF32,
|
||||||
this.module.createUnary(UnaryOp.AbsF32,
|
this.module.createUnary(UnaryOp.AbsF32,
|
||||||
this.module.createGetLocal(tempLocal.index, NativeType.F32)
|
this.module.createTeeLocal(tempLocal.index, operands[0])
|
||||||
),
|
),
|
||||||
this.module.createF32(Infinity)
|
this.module.createF32(Infinity)
|
||||||
|
),
|
||||||
|
this.module.createI32(0),
|
||||||
|
this.module.createBinary(BinaryOp.EqF32,
|
||||||
|
this.module.createGetLocal(tempLocal.index, NativeType.F32),
|
||||||
|
this.module.createGetLocal(tempLocal.index, NativeType.F32)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1845,11 +1847,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
throw new Error("not implemented");
|
throw new Error("not implemented");
|
||||||
}
|
}
|
||||||
|
|
||||||
compileSelectExpression(expression: SelectExpression, contextualType: Type): ExpressionRef {
|
compileTernaryExpression(expression: TernaryExpression, contextualType: Type): ExpressionRef {
|
||||||
const condition: ExpressionRef = this.compileExpression(expression.condition, Type.i32);
|
const condition: ExpressionRef = this.compileExpression(expression.condition, Type.i32);
|
||||||
const ifThen: ExpressionRef = this.compileExpression(expression.ifThen, contextualType);
|
const ifThen: ExpressionRef = this.compileExpression(expression.ifThen, contextualType);
|
||||||
const ifElse: ExpressionRef = this.compileExpression(expression.ifElse, contextualType);
|
const ifElse: ExpressionRef = this.compileExpression(expression.ifElse, contextualType);
|
||||||
return this.module.createSelect(condition, ifThen, ifElse);
|
return this.module.createIf(condition, ifThen, ifElse);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileUnaryPostfixExpression(expression: UnaryPostfixExpression, contextualType: Type): ExpressionRef {
|
compileUnaryPostfixExpression(expression: UnaryPostfixExpression, contextualType: Type): ExpressionRef {
|
||||||
|
@ -448,7 +448,7 @@ export class Module {
|
|||||||
return _BinaryenReturn(this.ref, expression);
|
return _BinaryenReturn(this.ref, expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
createSelect(condition: ExpressionRef, ifTrue: ExpressionRef, ifFalse: ExpressionRef): ExpressionRef {
|
createSelect(ifTrue: ExpressionRef, ifFalse: ExpressionRef, condition: ExpressionRef): ExpressionRef {
|
||||||
if (this.noEmit) return 0;
|
if (this.noEmit) return 0;
|
||||||
return _BinaryenSelect(this.ref, condition, ifTrue, ifFalse);
|
return _BinaryenSelect(this.ref, condition, ifTrue, ifFalse);
|
||||||
}
|
}
|
||||||
|
@ -1456,7 +1456,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
this.error(DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, expr.range);
|
this.error(DiagnosticCode.The_operand_of_an_increment_or_decrement_operator_must_be_a_variable_or_a_property_access, expr.range);
|
||||||
expr = Expression.createUnaryPostfix(token, expr, tn.range(startPos, tn.pos));
|
expr = Expression.createUnaryPostfix(token, expr, tn.range(startPos, tn.pos));
|
||||||
|
|
||||||
// SelectExpression
|
// TernaryExpression
|
||||||
} else if (token == Token.QUESTION) {
|
} else if (token == Token.QUESTION) {
|
||||||
const ifThen: Expression | null = this.parseExpression(tn);
|
const ifThen: Expression | null = this.parseExpression(tn);
|
||||||
if (!ifThen)
|
if (!ifThen)
|
||||||
@ -1465,7 +1465,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
const ifElse: Expression | null = this.parseExpression(tn);
|
const ifElse: Expression | null = this.parseExpression(tn);
|
||||||
if (!ifElse)
|
if (!ifElse)
|
||||||
return null;
|
return null;
|
||||||
expr = Expression.createSelect(<Expression>expr, <Expression>ifThen, <Expression>ifElse, tn.range(startPos, tn.pos));
|
expr = Expression.createTernary(<Expression>expr, <Expression>ifThen, <Expression>ifElse, tn.range(startPos, tn.pos));
|
||||||
} else {
|
} else {
|
||||||
this.error(DiagnosticCode._0_expected, tn.range(), ":");
|
this.error(DiagnosticCode._0_expected, tn.range(), ":");
|
||||||
return null;
|
return null;
|
||||||
|
@ -121,3 +121,14 @@ sizeof<f64>();
|
|||||||
|
|
||||||
i = load<i32>(4);
|
i = load<i32>(4);
|
||||||
store<i32>(4, i);
|
store<i32>(4, i);
|
||||||
|
|
||||||
|
if (NaN == NaN)
|
||||||
|
unreachable();
|
||||||
|
if (!isNaN<f32>(NaN))
|
||||||
|
unreachable();
|
||||||
|
if (isFinite<f32>(NaN))
|
||||||
|
unreachable();
|
||||||
|
if (isFinite<f32>(Infinity))
|
||||||
|
unreachable();
|
||||||
|
if (!isFinite<f64>(0))
|
||||||
|
unreachable();
|
||||||
|
@ -19,6 +19,10 @@
|
|||||||
(local $5 f64)
|
(local $5 f64)
|
||||||
(local $6 f64)
|
(local $6 f64)
|
||||||
(local $7 f64)
|
(local $7 f64)
|
||||||
|
(local $8 f32)
|
||||||
|
(local $9 f32)
|
||||||
|
(local $10 f32)
|
||||||
|
(local $11 f64)
|
||||||
(drop
|
(drop
|
||||||
(i32.clz
|
(i32.clz
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
@ -191,17 +195,17 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(select
|
(select
|
||||||
(i32.const 0)
|
|
||||||
(f32.ne
|
(f32.ne
|
||||||
(f32.abs
|
(f32.abs
|
||||||
(get_local $1)
|
(tee_local $1
|
||||||
|
(f32.const 1.25)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
(f32.const inf)
|
(f32.const inf)
|
||||||
)
|
)
|
||||||
(f32.ne
|
(i32.const 0)
|
||||||
(tee_local $1
|
(f32.eq
|
||||||
(f32.const 1.25)
|
(get_local $1)
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -270,17 +274,17 @@
|
|||||||
)
|
)
|
||||||
(set_global $builtins/b
|
(set_global $builtins/b
|
||||||
(select
|
(select
|
||||||
(i32.const 0)
|
|
||||||
(f32.ne
|
(f32.ne
|
||||||
(f32.abs
|
(f32.abs
|
||||||
(get_local $3)
|
(tee_local $3
|
||||||
|
(f32.const 1.25)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
(f32.const inf)
|
(f32.const inf)
|
||||||
)
|
)
|
||||||
(f32.ne
|
(i32.const 0)
|
||||||
(tee_local $3
|
(f32.eq
|
||||||
(f32.const 1.25)
|
(get_local $3)
|
||||||
)
|
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -355,17 +359,17 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(select
|
(select
|
||||||
(i32.const 0)
|
|
||||||
(f64.ne
|
(f64.ne
|
||||||
(f64.abs
|
(f64.abs
|
||||||
(get_local $5)
|
(tee_local $5
|
||||||
|
(f64.const 1.25)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
(f64.const inf)
|
(f64.const inf)
|
||||||
)
|
)
|
||||||
(f64.ne
|
(i32.const 0)
|
||||||
(tee_local $5
|
(f64.eq
|
||||||
(f64.const 1.25)
|
(get_local $5)
|
||||||
)
|
|
||||||
(get_local $5)
|
(get_local $5)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -434,17 +438,17 @@
|
|||||||
)
|
)
|
||||||
(set_global $builtins/b
|
(set_global $builtins/b
|
||||||
(select
|
(select
|
||||||
(i32.const 0)
|
|
||||||
(f64.ne
|
(f64.ne
|
||||||
(f64.abs
|
(f64.abs
|
||||||
(get_local $7)
|
(tee_local $7
|
||||||
|
(f64.const 1.25)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
(f64.const inf)
|
(f64.const inf)
|
||||||
)
|
)
|
||||||
(f64.ne
|
(i32.const 0)
|
||||||
(tee_local $7
|
(f64.eq
|
||||||
(f64.const 1.25)
|
(get_local $7)
|
||||||
)
|
|
||||||
(get_local $7)
|
(get_local $7)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -523,6 +527,80 @@
|
|||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(get_global $builtins/i)
|
(get_global $builtins/i)
|
||||||
)
|
)
|
||||||
|
(if
|
||||||
|
(f64.eq
|
||||||
|
(f64.const nan:0x8000000000000)
|
||||||
|
(f64.const nan:0x8000000000000)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(f32.ne
|
||||||
|
(tee_local $8
|
||||||
|
(f32.const nan:0x400000)
|
||||||
|
)
|
||||||
|
(get_local $8)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(select
|
||||||
|
(f32.ne
|
||||||
|
(f32.abs
|
||||||
|
(tee_local $9
|
||||||
|
(f32.const nan:0x400000)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(f32.const inf)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
(f32.eq
|
||||||
|
(get_local $9)
|
||||||
|
(get_local $9)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(select
|
||||||
|
(f32.ne
|
||||||
|
(f32.abs
|
||||||
|
(tee_local $10
|
||||||
|
(f32.const inf)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(f32.const inf)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
(f32.eq
|
||||||
|
(get_local $10)
|
||||||
|
(get_local $10)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(select
|
||||||
|
(f64.ne
|
||||||
|
(f64.abs
|
||||||
|
(tee_local $11
|
||||||
|
(f64.const 0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(f64.const inf)
|
||||||
|
)
|
||||||
|
(i32.const 0)
|
||||||
|
(f64.eq
|
||||||
|
(get_local $11)
|
||||||
|
(get_local $11)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(;
|
(;
|
||||||
|
5
tests/compiler/ternary.ts
Normal file
5
tests/compiler/ternary.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
let a: i32;
|
||||||
|
|
||||||
|
a = 0 ? unreachable() : 1;
|
||||||
|
a = 1 ? 1 : unreachable();
|
||||||
|
a = (0 ? unreachable() : 1) ? 1 : unreachable();
|
64
tests/compiler/ternary.wast
Normal file
64
tests/compiler/ternary.wast
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
(module
|
||||||
|
(type $v (func))
|
||||||
|
(global $ternary/a (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)
|
||||||
|
(set_global $ternary/a
|
||||||
|
(if (result i32)
|
||||||
|
(i32.const 0)
|
||||||
|
(unreachable)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $ternary/a
|
||||||
|
(if (result i32)
|
||||||
|
(i32.const 1)
|
||||||
|
(i32.const 1)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(set_global $ternary/a
|
||||||
|
(if (result i32)
|
||||||
|
(if (result i32)
|
||||||
|
(i32.const 0)
|
||||||
|
(unreachable)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(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
|
||||||
|
sizeof
|
||||||
|
load
|
||||||
|
store
|
||||||
|
ternary/a
|
||||||
|
[program.exports]
|
||||||
|
|
||||||
|
;)
|
Loading…
x
Reference in New Issue
Block a user