mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Statically eliminate unnecessary branches in generic contexts
In order to use the new compile time type checks in generics, untaken branches must be skipped because these might be invalid.
This commit is contained in:
parent
2ed9fac171
commit
83e96892f2
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
1
dist/asc.js.map
vendored
1
dist/asc.js.map
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js
vendored
2
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
1
dist/assemblyscript.js.map
vendored
1
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -1331,19 +1331,21 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
flow.continueLabel = previousContinueLabel;
|
flow.continueLabel = previousContinueLabel;
|
||||||
|
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
var condition = makeIsTrueish(
|
var condExpr = makeIsTrueish(
|
||||||
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
||||||
this.currentType,
|
this.currentType,
|
||||||
module
|
module
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// No need to eliminate the condition in generic contexts as the statement is executed anyway.
|
||||||
|
|
||||||
this.currentFunction.leaveBreakContext();
|
this.currentFunction.leaveBreakContext();
|
||||||
|
|
||||||
return module.createBlock(breakLabel, [
|
return module.createBlock(breakLabel, [
|
||||||
module.createLoop(continueLabel,
|
module.createLoop(continueLabel,
|
||||||
module.createBlock(null, [
|
module.createBlock(null, [
|
||||||
body,
|
body,
|
||||||
module.createBreak(continueLabel, condition)
|
module.createBreak(continueLabel, condExpr)
|
||||||
], NativeType.None))
|
], NativeType.None))
|
||||||
], NativeType.None);
|
], NativeType.None);
|
||||||
}
|
}
|
||||||
@ -1418,26 +1420,44 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
compileIfStatement(statement: IfStatement): ExpressionRef {
|
compileIfStatement(statement: IfStatement): ExpressionRef {
|
||||||
var module = this.module;
|
var module = this.module;
|
||||||
|
var currentFunction = this.currentFunction;
|
||||||
|
var ifTrue = statement.ifTrue;
|
||||||
|
var ifFalse = statement.ifFalse;
|
||||||
|
|
||||||
// The condition doesn't initiate a branch yet
|
// The condition doesn't initiate a branch yet
|
||||||
var condition = makeIsTrueish(
|
var condExpr = makeIsTrueish(
|
||||||
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
||||||
this.currentType,
|
this.currentType,
|
||||||
module
|
module
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Eliminate unnecesssary branches in generic contexts if the condition is constant
|
||||||
|
if (
|
||||||
|
this.currentFunction.isAny(CommonFlags.GENERIC | CommonFlags.GENERIC_CONTEXT) &&
|
||||||
|
_BinaryenExpressionGetId(condExpr = this.precomputeExpressionRef(condExpr)) == ExpressionId.Const &&
|
||||||
|
_BinaryenExpressionGetType(condExpr) == NativeType.I32
|
||||||
|
) {
|
||||||
|
let ret: ExpressionRef;
|
||||||
|
if (_BinaryenConstGetValueI32(condExpr)) {
|
||||||
|
ret = this.compileStatement(ifTrue);
|
||||||
|
} else if (ifFalse) {
|
||||||
|
ret = this.compileStatement(ifFalse);
|
||||||
|
} else {
|
||||||
|
ret = module.createNop();
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
// Each arm initiates a branch
|
// Each arm initiates a branch
|
||||||
var currentFunction = this.currentFunction;
|
|
||||||
var flow = currentFunction.flow.enterBranchOrScope();
|
var flow = currentFunction.flow.enterBranchOrScope();
|
||||||
currentFunction.flow = flow;
|
currentFunction.flow = flow;
|
||||||
var ifTrueExpr = this.compileStatement(statement.ifTrue);
|
var ifTrueExpr = this.compileStatement(ifTrue);
|
||||||
var ifTrueReturns = flow.is(FlowFlags.RETURNS);
|
var ifTrueReturns = flow.is(FlowFlags.RETURNS);
|
||||||
flow = flow.leaveBranchOrScope();
|
flow = flow.leaveBranchOrScope();
|
||||||
currentFunction.flow = flow;
|
currentFunction.flow = flow;
|
||||||
|
|
||||||
var ifFalseExpr: ExpressionRef = 0;
|
var ifFalseExpr: ExpressionRef = 0;
|
||||||
var ifFalseReturns = false;
|
var ifFalseReturns = false;
|
||||||
var ifFalse = statement.ifFalse;
|
|
||||||
if (ifFalse) {
|
if (ifFalse) {
|
||||||
flow = flow.enterBranchOrScope();
|
flow = flow.enterBranchOrScope();
|
||||||
currentFunction.flow = flow;
|
currentFunction.flow = flow;
|
||||||
@ -1449,7 +1469,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
if (ifTrueReturns && ifFalseReturns) { // not necessary to append a hint
|
if (ifTrueReturns && ifFalseReturns) { // not necessary to append a hint
|
||||||
flow.set(FlowFlags.RETURNS);
|
flow.set(FlowFlags.RETURNS);
|
||||||
}
|
}
|
||||||
return module.createIf(condition, ifTrueExpr, ifFalseExpr);
|
return module.createIf(condExpr, ifTrueExpr, ifFalseExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileReturnStatement(statement: ReturnStatement): ExpressionRef {
|
compileReturnStatement(statement: ReturnStatement): ExpressionRef {
|
||||||
@ -1724,12 +1744,23 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
var module = this.module;
|
var module = this.module;
|
||||||
|
|
||||||
// The condition does not yet initialize a branch
|
// The condition does not yet initialize a branch
|
||||||
var condition = makeIsTrueish(
|
var condExpr = makeIsTrueish(
|
||||||
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
||||||
this.currentType,
|
this.currentType,
|
||||||
module
|
module
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Eliminate unnecesssary loops in generic contexts if the condition is constant
|
||||||
|
if (
|
||||||
|
this.currentFunction.isAny(CommonFlags.GENERIC | CommonFlags.GENERIC_CONTEXT) &&
|
||||||
|
_BinaryenExpressionGetId(condExpr = this.precomputeExpressionRef(condExpr)) == ExpressionId.Const &&
|
||||||
|
_BinaryenExpressionGetType(condExpr) == NativeType.I32
|
||||||
|
) {
|
||||||
|
if (!_BinaryenConstGetValueI32(condExpr)) {
|
||||||
|
return module.createNop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Statements initiate a new branch with its own break context
|
// Statements initiate a new branch with its own break context
|
||||||
var currentFunction = this.currentFunction;
|
var currentFunction = this.currentFunction;
|
||||||
var label = currentFunction.enterBreakContext();
|
var label = currentFunction.enterBreakContext();
|
||||||
@ -1750,7 +1781,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
|
|
||||||
var expr = module.createBlock(breakLabel, [
|
var expr = module.createBlock(breakLabel, [
|
||||||
module.createLoop(continueLabel,
|
module.createLoop(continueLabel,
|
||||||
module.createIf(condition, module.createBlock(null, [
|
module.createIf(condExpr, module.createBlock(null, [
|
||||||
body,
|
body,
|
||||||
module.createBreak(continueLabel)
|
module.createBreak(continueLabel)
|
||||||
], NativeType.None))
|
], NativeType.None))
|
||||||
@ -4952,14 +4983,29 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileTernaryExpression(expression: TernaryExpression, contextualType: Type): ExpressionRef {
|
compileTernaryExpression(expression: TernaryExpression, contextualType: Type): ExpressionRef {
|
||||||
var condition = makeIsTrueish(
|
var ifThen = expression.ifThen;
|
||||||
|
var ifElse = expression.ifElse;
|
||||||
|
|
||||||
|
var condExpr = makeIsTrueish(
|
||||||
this.compileExpression(expression.condition, Type.u32, ConversionKind.NONE),
|
this.compileExpression(expression.condition, Type.u32, ConversionKind.NONE),
|
||||||
this.currentType,
|
this.currentType,
|
||||||
this.module
|
this.module
|
||||||
);
|
);
|
||||||
var ifThen = this.compileExpression(expression.ifThen, contextualType);
|
|
||||||
var ifElse = this.compileExpression(expression.ifElse, contextualType);
|
// Eliminate unnecesssary branches in generic contexts if the condition is constant
|
||||||
return this.module.createIf(condition, ifThen, ifElse);
|
if (
|
||||||
|
this.currentFunction.isAny(CommonFlags.GENERIC | CommonFlags.GENERIC_CONTEXT) &&
|
||||||
|
_BinaryenExpressionGetId(condExpr = this.precomputeExpressionRef(condExpr)) == ExpressionId.Const &&
|
||||||
|
_BinaryenExpressionGetType(condExpr) == NativeType.I32
|
||||||
|
) {
|
||||||
|
return _BinaryenConstGetValueI32(condExpr)
|
||||||
|
? this.compileExpression(ifThen, contextualType)
|
||||||
|
: this.compileExpression(ifElse, contextualType);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ifThenExpr = this.compileExpression(ifThen, contextualType);
|
||||||
|
var ifElseExpr = this.compileExpression(ifElse, contextualType);
|
||||||
|
return this.module.createIf(condExpr, ifThenExpr, ifElseExpr);
|
||||||
}
|
}
|
||||||
|
|
||||||
compileUnaryPostfixExpression(expression: UnaryPostfixExpression, contextualType: Type): ExpressionRef {
|
compileUnaryPostfixExpression(expression: UnaryPostfixExpression, contextualType: Type): ExpressionRef {
|
||||||
|
@ -202,7 +202,6 @@ export function formatDiagnosticContext(range: Range, useColors: bool = false):
|
|||||||
export abstract class DiagnosticEmitter {
|
export abstract class DiagnosticEmitter {
|
||||||
|
|
||||||
diagnostics: DiagnosticMessage[];
|
diagnostics: DiagnosticMessage[];
|
||||||
// silentDiagnostics: bool = false;
|
|
||||||
|
|
||||||
constructor(diagnostics: DiagnosticMessage[] | null = null) {
|
constructor(diagnostics: DiagnosticMessage[] | null = null) {
|
||||||
this.diagnostics = diagnostics ? <DiagnosticMessage[]>diagnostics : new Array();
|
this.diagnostics = diagnostics ? <DiagnosticMessage[]>diagnostics : new Array();
|
||||||
|
@ -1459,12 +1459,17 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
flags |= CommonFlags.STATIC;
|
flags |= CommonFlags.STATIC;
|
||||||
staticStart = tn.tokenPos;
|
staticStart = tn.tokenPos;
|
||||||
staticEnd = tn.pos;
|
staticEnd = tn.pos;
|
||||||
} else if (tn.skip(Token.ABSTRACT)) {
|
|
||||||
flags |= (CommonFlags.ABSTRACT | CommonFlags.INSTANCE);
|
|
||||||
abstractStart = tn.tokenPos;
|
|
||||||
abstractEnd = tn.pos;
|
|
||||||
} else {
|
} else {
|
||||||
flags |= CommonFlags.INSTANCE;
|
if (tn.skip(Token.ABSTRACT)) {
|
||||||
|
flags |= (CommonFlags.ABSTRACT | CommonFlags.INSTANCE);
|
||||||
|
abstractStart = tn.tokenPos;
|
||||||
|
abstractEnd = tn.pos;
|
||||||
|
} else {
|
||||||
|
flags |= CommonFlags.INSTANCE;
|
||||||
|
}
|
||||||
|
if (parentFlags & CommonFlags.GENERIC) {
|
||||||
|
flags |= CommonFlags.GENERIC_CONTEXT;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var readonlyStart: i32 = 0;
|
var readonlyStart: i32 = 0;
|
||||||
@ -2737,12 +2742,12 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
// fall-through
|
// fall-through
|
||||||
}
|
}
|
||||||
// function expression
|
// function expression
|
||||||
case Token.QUESTION: // optional parameter
|
|
||||||
case Token.COLON: { // type annotation
|
case Token.COLON: { // type annotation
|
||||||
tn.reset(state);
|
tn.reset(state);
|
||||||
return this.parseFunctionExpression(tn);
|
return this.parseFunctionExpression(tn);
|
||||||
}
|
}
|
||||||
// can be both
|
// can be both
|
||||||
|
case Token.QUESTION: // optional parameter or ternary
|
||||||
case Token.COMMA: {
|
case Token.COMMA: {
|
||||||
break; // continue
|
break; // continue
|
||||||
}
|
}
|
||||||
|
@ -2036,25 +2036,27 @@ export enum CommonFlags {
|
|||||||
AMBIENT = 1 << 16,
|
AMBIENT = 1 << 16,
|
||||||
/** Is generic. */
|
/** Is generic. */
|
||||||
GENERIC = 1 << 17,
|
GENERIC = 1 << 17,
|
||||||
|
/** Is part of a generic context. */
|
||||||
|
GENERIC_CONTEXT = 1 << 18,
|
||||||
/** Is an instance member. */
|
/** Is an instance member. */
|
||||||
INSTANCE = 1 << 18,
|
INSTANCE = 1 << 19,
|
||||||
/** Is a constructor. */
|
/** Is a constructor. */
|
||||||
CONSTRUCTOR = 1 << 19,
|
CONSTRUCTOR = 1 << 20,
|
||||||
/** Is an arrow function. */
|
/** Is an arrow function. */
|
||||||
ARROW = 1 << 20,
|
ARROW = 1 << 21,
|
||||||
/** Is a module export. */
|
/** Is a module export. */
|
||||||
MODULE_EXPORT = 1 << 21,
|
MODULE_EXPORT = 1 << 22,
|
||||||
/** Is a module import. */
|
/** Is a module import. */
|
||||||
MODULE_IMPORT = 1 << 22,
|
MODULE_IMPORT = 1 << 23,
|
||||||
|
|
||||||
// Compilation states
|
// Compilation states
|
||||||
|
|
||||||
/** Is compiled. */
|
/** Is compiled. */
|
||||||
COMPILED = 1 << 23,
|
COMPILED = 1 << 24,
|
||||||
/** Has a constant value and is therefore inlined. */
|
/** Has a constant value and is therefore inlined. */
|
||||||
INLINED = 1 << 24,
|
INLINED = 1 << 25,
|
||||||
/** Is scoped. */
|
/** Is scoped. */
|
||||||
SCOPED = 1 << 25
|
SCOPED = 1 << 26
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Base class of all program elements. */
|
/** Base class of all program elements. */
|
||||||
@ -2084,7 +2086,8 @@ export abstract class Element {
|
|||||||
|
|
||||||
/** Tests if this element has a specific flag or flags. */
|
/** Tests if this element has a specific flag or flags. */
|
||||||
is(flag: CommonFlags): bool { return (this.flags & flag) == flag; }
|
is(flag: CommonFlags): bool { return (this.flags & flag) == flag; }
|
||||||
|
/** Tests if this element has any of the specified flags. */
|
||||||
|
isAny(flags: CommonFlags): bool { return (this.flags & flags) != 0; }
|
||||||
/** Sets a specific flag or flags. */
|
/** Sets a specific flag or flags. */
|
||||||
set(flag: CommonFlags): void { this.flags |= flag; }
|
set(flag: CommonFlags): void { this.flags |= flag; }
|
||||||
}
|
}
|
||||||
|
10
std/assembly.d.ts
vendored
10
std/assembly.d.ts
vendored
@ -195,15 +195,15 @@ 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 expression is of an integer type and not a reference. Compiles to a constant. */
|
||||||
declare function isInteger(value: any): bool;
|
declare function isInteger(value: any): value is number;
|
||||||
/** Tests if the specified expression is of a float type. Compiles to a constant. */
|
/** Tests if the specified expression is of a float type. Compiles to a constant. */
|
||||||
declare function isFloat(value: any): bool;
|
declare function isFloat(value: any): value is number;
|
||||||
/** Tests if the specified expression is of a reference type. Compiles to a constant. */
|
/** Tests if the specified expression is of a reference type. Compiles to a constant. */
|
||||||
declare function isReference(value: any): bool;
|
declare function isReference(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 expression can be used ass a string. Compiles to a constant. */
|
||||||
declare function isString(value: any): bool;
|
declare function isString(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 expression can be used as an array. Compiles to a constant. */
|
||||||
declare function isArray(value: any): bool;
|
declare function isArray(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`?
|
||||||
/** Parses an integer string to a 64-bit float. */
|
/** Parses an integer string to a 64-bit float. */
|
||||||
|
10
std/portable.d.ts
vendored
10
std/portable.d.ts
vendored
@ -141,15 +141,15 @@ 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 value is a valid integer. Can't distinguish an integer from an integral float. */
|
/** Tests if the specified value is a valid integer. Can't distinguish an integer from an integral float. */
|
||||||
declare function isInteger(value: any): bool;
|
declare function isInteger(value: any): value is number;
|
||||||
/** Tests if the specified value is a valid float. Can't distinguish a float from an integer. */
|
/** Tests if the specified value is a valid float. Can't distinguish a float from an integer. */
|
||||||
declare function isFloat(value: any): bool;
|
declare function isFloat(value: any): value is number;
|
||||||
/** Tests if the specified value is of a reference type. */
|
/** Tests if the specified value is of a reference type. */
|
||||||
declare function isReference(value: any): bool;
|
declare function isReference(value: any): value is object | string;
|
||||||
/** Tests if the specified value can be used as a string. */
|
/** Tests if the specified value can be used as a string. */
|
||||||
declare function isString(value: any): bool;
|
declare function isString(value: any): value is string | String;
|
||||||
/** Tests if the specified value can be used as an array. */
|
/** Tests if the specified value can be used as an array. */
|
||||||
declare function isArray(value: any): bool;
|
declare function isArray(value: any): value is Array<any>;
|
||||||
/** Traps if the specified value is not true-ish, otherwise returns the value. */
|
/** Traps if the specified value is not true-ish, otherwise returns the value. */
|
||||||
declare function assert<T>(isTrueish: T | null, message?: string): T;
|
declare function assert<T>(isTrueish: T | null, message?: string): T;
|
||||||
/** Parses an integer string to a 64-bit float. */
|
/** Parses an integer string to a 64-bit float. */
|
||||||
|
@ -640,6 +640,12 @@
|
|||||||
(set_global $builtins/F
|
(set_global $builtins/F
|
||||||
(f64.const 25)
|
(f64.const 25)
|
||||||
)
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(get_global $builtins/i)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
(if
|
(if
|
||||||
(f32.eq
|
(f32.eq
|
||||||
(tee_local $0
|
(tee_local $0
|
||||||
|
@ -213,7 +213,7 @@ I = select<i64>(100, 200, false);
|
|||||||
f = select<f32>(1.25, 2.5, true);
|
f = select<f32>(1.25, 2.5, true);
|
||||||
F = select<f64>(12.5, 25.0, false);
|
F = select<f64>(12.5, 25.0, false);
|
||||||
|
|
||||||
if (0) unreachable();
|
if (!i) unreachable();
|
||||||
|
|
||||||
// AS specific
|
// AS specific
|
||||||
|
|
||||||
|
@ -1221,7 +1221,9 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i32.const 0)
|
(i32.eqz
|
||||||
|
(get_global $builtins/i)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
|
@ -4066,6 +4066,12 @@
|
|||||||
(set_global $builtins/F
|
(set_global $builtins/F
|
||||||
(f64.const 25)
|
(f64.const 25)
|
||||||
)
|
)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(get_global $builtins/i)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
(if
|
(if
|
||||||
(f32.eq
|
(f32.eq
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
|
@ -5614,7 +5614,9 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
(if
|
(if
|
||||||
(i32.const 0)
|
(i32.eqz
|
||||||
|
(get_global $builtins/i)
|
||||||
|
)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
(module
|
(module
|
||||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
(type $iiiiv (func (param i32 i32 i32 i32)))
|
||||||
(type $iii (func (param i32 i32) (result i32)))
|
(type $iii (func (param i32 i32) (result i32)))
|
||||||
|
(type $i (func (result i32)))
|
||||||
(type $iiiv (func (param i32 i32 i32)))
|
(type $iiiv (func (param i32 i32 i32)))
|
||||||
(type $v (func))
|
(type $v (func))
|
||||||
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
|
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
|
||||||
|
@ -217,73 +217,7 @@
|
|||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(func "$(lib)/polyfills/bswap16<u32>" (; 5 ;) (type $ii) (param $0 i32) (result i32)
|
(func "$(lib)/polyfills/bswap<u32>" (; 5 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
(local $1 i32)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.and
|
|
||||||
(if (result i32)
|
|
||||||
(tee_local $1
|
|
||||||
(i32.and
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 25)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.and
|
|
||||||
(if (result i32)
|
|
||||||
(tee_local $1
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(return
|
|
||||||
(i32.or
|
|
||||||
(i32.or
|
|
||||||
(i32.and
|
|
||||||
(i32.shl
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
(i32.const 65280)
|
|
||||||
)
|
|
||||||
(i32.and
|
|
||||||
(i32.shr_u
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
(i32.const 255)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.and
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const -65536)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(func "$(lib)/polyfills/bswap<u32>" (; 6 ;) (type $ii) (param $0 i32) (result i32)
|
|
||||||
(local $1 i32)
|
(local $1 i32)
|
||||||
(if
|
(if
|
||||||
(i32.eqz
|
(i32.eqz
|
||||||
@ -337,73 +271,7 @@
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(func "$(lib)/polyfills/bswap16<i32>" (; 7 ;) (type $ii) (param $0 i32) (result i32)
|
(func "$(lib)/polyfills/bswap<u64>" (; 6 ;) (type $II) (param $0 i64) (result i64)
|
||||||
(local $1 i32)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.and
|
|
||||||
(if (result i32)
|
|
||||||
(tee_local $1
|
|
||||||
(i32.and
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 25)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.and
|
|
||||||
(if (result i32)
|
|
||||||
(tee_local $1
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(return
|
|
||||||
(i32.or
|
|
||||||
(i32.or
|
|
||||||
(i32.and
|
|
||||||
(i32.shl
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
(i32.const 65280)
|
|
||||||
)
|
|
||||||
(i32.and
|
|
||||||
(i32.shr_s
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
(i32.const 255)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.and
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const -65536)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(func "$(lib)/polyfills/bswap<u64>" (; 8 ;) (type $II) (param $0 i64) (result i64)
|
|
||||||
(local $1 i32)
|
(local $1 i32)
|
||||||
(if
|
(if
|
||||||
(i32.eqz
|
(i32.eqz
|
||||||
@ -477,6 +345,138 @@
|
|||||||
(i64.const 32)
|
(i64.const 32)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
(func "$(lib)/polyfills/bswap16<u32>" (; 7 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(local $1 i32)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(i32.and
|
||||||
|
(if (result i32)
|
||||||
|
(tee_local $1
|
||||||
|
(i32.and
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 4)
|
||||||
|
(i32.const 25)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.and
|
||||||
|
(if (result i32)
|
||||||
|
(tee_local $1
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.or
|
||||||
|
(i32.or
|
||||||
|
(i32.and
|
||||||
|
(i32.shl
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(i32.const 65280)
|
||||||
|
)
|
||||||
|
(i32.and
|
||||||
|
(i32.shr_u
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(i32.const 255)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.and
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const -65536)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(func "$(lib)/polyfills/bswap16<i32>" (; 8 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(local $1 i32)
|
||||||
|
(if
|
||||||
|
(i32.eqz
|
||||||
|
(i32.and
|
||||||
|
(if (result i32)
|
||||||
|
(tee_local $1
|
||||||
|
(i32.and
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(block
|
||||||
|
(call $abort
|
||||||
|
(i32.const 0)
|
||||||
|
(i32.const 4)
|
||||||
|
(i32.const 25)
|
||||||
|
(i32.const 2)
|
||||||
|
)
|
||||||
|
(unreachable)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(if
|
||||||
|
(i32.and
|
||||||
|
(if (result i32)
|
||||||
|
(tee_local $1
|
||||||
|
(i32.const 0)
|
||||||
|
)
|
||||||
|
(get_local $1)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(i32.const 1)
|
||||||
|
)
|
||||||
|
(return
|
||||||
|
(i32.or
|
||||||
|
(i32.or
|
||||||
|
(i32.and
|
||||||
|
(i32.shl
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(i32.const 65280)
|
||||||
|
)
|
||||||
|
(i32.and
|
||||||
|
(i32.shr_s
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const 8)
|
||||||
|
)
|
||||||
|
(i32.const 255)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(i32.and
|
||||||
|
(get_local $0)
|
||||||
|
(i32.const -65536)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
(func $start (; 9 ;) (type $v)
|
(func $start (; 9 ;) (type $v)
|
||||||
(if
|
(if
|
||||||
(i32.ne
|
(i32.ne
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user