mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-07-03 00:21:52 +00:00
Revised implicit type conversions; Initial function expression compilation
This commit is contained in:
dist
src
ast.tsbuiltins.tscompiler.tsdiagnosticMessages.generated.tsdiagnosticMessages.json
extra
parser.tsprogram.tstypes.tsstd/assembly
tests/compiler
fmod.untouched.watfunction-expression.optimized.watfunction-expression.tsfunction-expression.untouched.watgame-of-life.untouched.watlogical.untouched.watmemcpy.untouched.watretain-i32.tsshowcase.untouched.wat
std
allocator_arena.untouched.watarray.untouched.watnew.untouched.watpolyfills.untouched.watset.optimized.watset.untouched.watstring.untouched.wat
tlsf.optimized.wattlsf.tstlsf.untouched.watwhile.untouched.wat
2
dist/asc.js
vendored
2
dist/asc.js
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
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
14
src/ast.ts
14
src/ast.ts
@ -721,7 +721,7 @@ export abstract class Node {
|
|||||||
|
|
||||||
static createFunctionDeclaration(
|
static createFunctionDeclaration(
|
||||||
name: IdentifierExpression,
|
name: IdentifierExpression,
|
||||||
typeParameters: TypeParameter[],
|
typeParameters: TypeParameter[] | null,
|
||||||
parameters: Parameter[],
|
parameters: Parameter[],
|
||||||
returnType: TypeNode | null,
|
returnType: TypeNode | null,
|
||||||
body: Statement | null,
|
body: Statement | null,
|
||||||
@ -732,7 +732,7 @@ export abstract class Node {
|
|||||||
var stmt = new FunctionDeclaration();
|
var stmt = new FunctionDeclaration();
|
||||||
stmt.range = range;
|
stmt.range = range;
|
||||||
stmt.name = name; name.parent = stmt;
|
stmt.name = name; name.parent = stmt;
|
||||||
stmt.typeParameters = typeParameters; setParent(typeParameters, stmt);
|
stmt.typeParameters = typeParameters; if (typeParameters) setParent(typeParameters, stmt);
|
||||||
stmt.parameters = parameters; setParent(parameters, stmt);
|
stmt.parameters = parameters; setParent(parameters, stmt);
|
||||||
stmt.returnType = returnType; if (returnType) returnType.parent = stmt;
|
stmt.returnType = returnType; if (returnType) returnType.parent = stmt;
|
||||||
stmt.body = body; if (body) body.parent = stmt;
|
stmt.body = body; if (body) body.parent = stmt;
|
||||||
@ -743,7 +743,7 @@ export abstract class Node {
|
|||||||
|
|
||||||
static createMethodDeclaration(
|
static createMethodDeclaration(
|
||||||
name: IdentifierExpression,
|
name: IdentifierExpression,
|
||||||
typeParameters: TypeParameter[],
|
typeParameters: TypeParameter[] | null,
|
||||||
parameters: Parameter[],
|
parameters: Parameter[],
|
||||||
returnType: TypeNode | null,
|
returnType: TypeNode | null,
|
||||||
body: Statement | null,
|
body: Statement | null,
|
||||||
@ -754,7 +754,7 @@ export abstract class Node {
|
|||||||
var stmt = new MethodDeclaration();
|
var stmt = new MethodDeclaration();
|
||||||
stmt.range = range;
|
stmt.range = range;
|
||||||
stmt.name = name; name.parent = stmt;
|
stmt.name = name; name.parent = stmt;
|
||||||
stmt.typeParameters = typeParameters; setParent(typeParameters, stmt);
|
stmt.typeParameters = typeParameters; if (typeParameters) setParent(typeParameters, stmt);
|
||||||
stmt.parameters = parameters; setParent(parameters, stmt);
|
stmt.parameters = parameters; setParent(parameters, stmt);
|
||||||
stmt.returnType = returnType; if (returnType) returnType.parent = stmt;
|
stmt.returnType = returnType; if (returnType) returnType.parent = stmt;
|
||||||
stmt.body = body; if (body) body.parent = stmt;
|
stmt.body = body; if (body) body.parent = stmt;
|
||||||
@ -1490,13 +1490,17 @@ export class FunctionDeclaration extends DeclarationStatement {
|
|||||||
kind = NodeKind.FUNCTIONDECLARATION;
|
kind = NodeKind.FUNCTIONDECLARATION;
|
||||||
|
|
||||||
/** Accepted type parameters. */
|
/** Accepted type parameters. */
|
||||||
typeParameters: TypeParameter[];
|
typeParameters: TypeParameter[] | null;
|
||||||
/** Accepted parameters. */
|
/** Accepted parameters. */
|
||||||
parameters: Parameter[];
|
parameters: Parameter[];
|
||||||
/** Return type. */
|
/** Return type. */
|
||||||
returnType: TypeNode | null;
|
returnType: TypeNode | null;
|
||||||
/** Body statement. Usually a block. */
|
/** Body statement. Usually a block. */
|
||||||
body: Statement | null;
|
body: Statement | null;
|
||||||
|
|
||||||
|
get isGeneric(): bool {
|
||||||
|
return this.typeParameters != null && this.typeParameters.length > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents an `if` statement. */
|
/** Represents an `if` statement. */
|
||||||
|
@ -2303,7 +2303,7 @@ function evaluateConstantOffset(compiler: Compiler, expression: Expression): i32
|
|||||||
var expr: ExpressionRef;
|
var expr: ExpressionRef;
|
||||||
var value: i32;
|
var value: i32;
|
||||||
if (compiler.options.isWasm64) {
|
if (compiler.options.isWasm64) {
|
||||||
expr = compiler.precomputeExpression(expression, Type.i64);
|
expr = compiler.precomputeExpression(expression, Type.usize64);
|
||||||
if (
|
if (
|
||||||
_BinaryenExpressionGetId(expr) != ExpressionId.Const ||
|
_BinaryenExpressionGetId(expr) != ExpressionId.Const ||
|
||||||
_BinaryenExpressionGetType(expr) != NativeType.I64 ||
|
_BinaryenExpressionGetType(expr) != NativeType.I64 ||
|
||||||
@ -2317,7 +2317,7 @@ function evaluateConstantOffset(compiler: Compiler, expression: Expression): i32
|
|||||||
value = -1;
|
value = -1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
expr = compiler.precomputeExpression(expression, Type.i32);
|
expr = compiler.precomputeExpression(expression, Type.usize32);
|
||||||
if (
|
if (
|
||||||
_BinaryenExpressionGetId(expr) != ExpressionId.Const ||
|
_BinaryenExpressionGetId(expr) != ExpressionId.Const ||
|
||||||
_BinaryenExpressionGetType(expr) != NativeType.I32 ||
|
_BinaryenExpressionGetType(expr) != NativeType.I32 ||
|
||||||
|
168
src/compiler.ts
168
src/compiler.ts
@ -88,6 +88,7 @@ import {
|
|||||||
CommaExpression,
|
CommaExpression,
|
||||||
ElementAccessExpression,
|
ElementAccessExpression,
|
||||||
FloatLiteralExpression,
|
FloatLiteralExpression,
|
||||||
|
FunctionExpression,
|
||||||
IdentifierExpression,
|
IdentifierExpression,
|
||||||
IntegerLiteralExpression,
|
IntegerLiteralExpression,
|
||||||
LiteralExpression,
|
LiteralExpression,
|
||||||
@ -200,6 +201,9 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
/** Map of already compiled static string segments. */
|
/** Map of already compiled static string segments. */
|
||||||
stringSegments: Map<string,MemorySegment> = new Map();
|
stringSegments: Map<string,MemorySegment> = new Map();
|
||||||
|
|
||||||
|
/** Function table being compiled. */
|
||||||
|
functionTable: Function[] = new Array();
|
||||||
|
|
||||||
/** Already processed file names. */
|
/** Already processed file names. */
|
||||||
files: Set<string> = new Set();
|
files: Set<string> = new Set();
|
||||||
|
|
||||||
@ -294,6 +298,16 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
"memory"
|
"memory"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set up function table
|
||||||
|
if (k = this.functionTable.length) {
|
||||||
|
var entries = new Array<FunctionRef>(k);
|
||||||
|
for (i = 0; i < k; ++i) {
|
||||||
|
entries[i] = this.functionTable[i].ref;
|
||||||
|
}
|
||||||
|
this.module.setFunctionTable(entries);
|
||||||
|
}
|
||||||
|
|
||||||
return this.module;
|
return this.module;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -376,7 +390,7 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
noTreeShaking ||
|
noTreeShaking ||
|
||||||
(isEntry && hasModifier(ModifierKind.EXPORT, (<FunctionDeclaration>statement).modifiers))
|
(isEntry && hasModifier(ModifierKind.EXPORT, (<FunctionDeclaration>statement).modifiers))
|
||||||
) &&
|
) &&
|
||||||
!(<FunctionDeclaration>statement).typeParameters.length
|
!(<FunctionDeclaration>statement).isGeneric
|
||||||
) {
|
) {
|
||||||
this.compileFunctionDeclaration(<FunctionDeclaration>statement, []);
|
this.compileFunctionDeclaration(<FunctionDeclaration>statement, []);
|
||||||
}
|
}
|
||||||
@ -868,7 +882,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
(
|
(
|
||||||
noTreeShaking ||
|
noTreeShaking ||
|
||||||
hasModifier(ModifierKind.EXPORT, (<FunctionDeclaration>member).modifiers)
|
hasModifier(ModifierKind.EXPORT, (<FunctionDeclaration>member).modifiers)
|
||||||
) && !(<FunctionDeclaration>member).typeParameters.length
|
) &&
|
||||||
|
!(<FunctionDeclaration>member).isGeneric
|
||||||
) {
|
) {
|
||||||
this.compileFunctionDeclaration(<FunctionDeclaration>member, []);
|
this.compileFunctionDeclaration(<FunctionDeclaration>member, []);
|
||||||
}
|
}
|
||||||
@ -1077,6 +1092,20 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return segment;
|
return segment;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// function table
|
||||||
|
|
||||||
|
/** Adds a function table entry and returns the assigned index. */
|
||||||
|
addFunctionTableEntry(func: Function): i32 {
|
||||||
|
assert(func.is(ElementFlags.COMPILED));
|
||||||
|
if (func.functionTableIndex >= 0) {
|
||||||
|
return func.functionTableIndex;
|
||||||
|
}
|
||||||
|
var index = this.functionTable.length;
|
||||||
|
this.functionTable.push(func);
|
||||||
|
func.functionTableIndex = index;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
// statements
|
// statements
|
||||||
|
|
||||||
compileStatement(statement: Statement): ExpressionRef {
|
compileStatement(statement: Statement): ExpressionRef {
|
||||||
@ -1241,7 +1270,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
this.currentFunction.flow.breakLabel = previousBreakLabel;
|
this.currentFunction.flow.breakLabel = previousBreakLabel;
|
||||||
this.currentFunction.flow.continueLabel = previousContinueLabel;
|
this.currentFunction.flow.continueLabel = previousContinueLabel;
|
||||||
|
|
||||||
var condition = this.compileExpression(statement.condition, Type.i32);
|
var condition = makeIsTrueish(
|
||||||
|
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
||||||
|
this.currentType,
|
||||||
|
this.module
|
||||||
|
);
|
||||||
|
|
||||||
this.currentFunction.leaveBreakContext();
|
this.currentFunction.leaveBreakContext();
|
||||||
|
|
||||||
@ -1319,7 +1352,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
compileIfStatement(statement: IfStatement): ExpressionRef {
|
compileIfStatement(statement: IfStatement): ExpressionRef {
|
||||||
|
|
||||||
// The condition doesn't initiate a branch yet
|
// The condition doesn't initiate a branch yet
|
||||||
var condition = this.compileExpression(statement.condition, Type.i32);
|
var condition = makeIsTrueish(
|
||||||
|
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
||||||
|
this.currentType,
|
||||||
|
this.module
|
||||||
|
);
|
||||||
|
|
||||||
// Each arm initiates a branch
|
// Each arm initiates a branch
|
||||||
this.currentFunction.flow = this.currentFunction.flow.enterBranchOrScope();
|
this.currentFunction.flow = this.currentFunction.flow.enterBranchOrScope();
|
||||||
@ -1359,14 +1396,14 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
var context = this.currentFunction.enterBreakContext();
|
var context = this.currentFunction.enterBreakContext();
|
||||||
|
|
||||||
// introduce a local for evaluating the condition (exactly once)
|
// introduce a local for evaluating the condition (exactly once)
|
||||||
var tempLocal = this.currentFunction.getTempLocal(Type.i32);
|
var tempLocal = this.currentFunction.getTempLocal(Type.u32);
|
||||||
var k = statement.cases.length;
|
var k = statement.cases.length;
|
||||||
|
|
||||||
// Prepend initializer to inner block. Does not initiate a new branch, yet.
|
// Prepend initializer to inner block. Does not initiate a new branch, yet.
|
||||||
var breaks = new Array<ExpressionRef>(1 + k);
|
var breaks = new Array<ExpressionRef>(1 + k);
|
||||||
breaks[0] = this.module.createSetLocal( // initializer
|
breaks[0] = this.module.createSetLocal( // initializer
|
||||||
tempLocal.index,
|
tempLocal.index,
|
||||||
this.compileExpression(statement.condition, Type.i32)
|
this.compileExpression(statement.condition, Type.u32)
|
||||||
);
|
);
|
||||||
|
|
||||||
// make one br_if per (possibly dynamic) labeled case (binaryen optimizes to br_table where possible)
|
// make one br_if per (possibly dynamic) labeled case (binaryen optimizes to br_table where possible)
|
||||||
@ -1577,7 +1614,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
compileWhileStatement(statement: WhileStatement): ExpressionRef {
|
compileWhileStatement(statement: WhileStatement): ExpressionRef {
|
||||||
|
|
||||||
// The condition does not yet initialize a branch
|
// The condition does not yet initialize a branch
|
||||||
var condition = this.compileExpression(statement.condition, Type.i32);
|
var condition = makeIsTrueish(
|
||||||
|
this.compileExpression(statement.condition, Type.i32, ConversionKind.NONE),
|
||||||
|
this.currentType,
|
||||||
|
this.module
|
||||||
|
);
|
||||||
|
|
||||||
// Statements initiate a new branch with its own break context
|
// Statements initiate a new branch with its own break context
|
||||||
var label = this.currentFunction.enterBreakContext();
|
var label = this.currentFunction.enterBreakContext();
|
||||||
@ -1715,6 +1756,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
expr = this.compileElementAccessExpression(<ElementAccessExpression>expression, contextualType);
|
expr = this.compileElementAccessExpression(<ElementAccessExpression>expression, contextualType);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case NodeKind.FUNCTION:
|
||||||
|
case NodeKind.FUNCTIONARROW:
|
||||||
|
expr = this.compileFunctionExpression(<FunctionExpression>expression, contextualType);
|
||||||
|
break;
|
||||||
|
|
||||||
case NodeKind.IDENTIFIER:
|
case NodeKind.IDENTIFIER:
|
||||||
case NodeKind.FALSE:
|
case NodeKind.FALSE:
|
||||||
case NodeKind.NULL:
|
case NodeKind.NULL:
|
||||||
@ -1817,6 +1863,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
return this.module.createDrop(expr);
|
return this.module.createDrop(expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (conversionKind == ConversionKind.IMPLICIT && !fromType.isAssignableTo(toType)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Conversion_from_type_0_to_1_requires_an_explicit_cast,
|
||||||
|
reportNode.range, fromType.toString(), toType.toString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var mod = this.module;
|
var mod = this.module;
|
||||||
var losesInformation = false;
|
var losesInformation = false;
|
||||||
|
|
||||||
@ -1974,13 +2027,6 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
// otherwise (smaller) i32/u32 to (same size) i32/u32
|
// otherwise (smaller) i32/u32 to (same size) i32/u32
|
||||||
}
|
}
|
||||||
|
|
||||||
if (losesInformation && conversionKind == ConversionKind.IMPLICIT) {
|
|
||||||
this.error(
|
|
||||||
DiagnosticCode.Conversion_from_type_0_to_1_possibly_loses_information_and_thus_requires_an_explicit_cast,
|
|
||||||
reportNode.range, fromType.toString(), toType.toString()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return expr;
|
return expr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3768,6 +3814,25 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
], expression);
|
], expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compileFunctionExpression(expression: FunctionExpression, contextualType: Type): ExpressionRef {
|
||||||
|
var declaration = expression.declaration;
|
||||||
|
var simpleName = (declaration.name.text.length
|
||||||
|
? declaration.name.text
|
||||||
|
: "anonymous") + "|" + this.functionTable.length.toString(10);
|
||||||
|
var prototype = new FunctionPrototype(
|
||||||
|
this.program,
|
||||||
|
simpleName,
|
||||||
|
this.currentFunction.internalName + "~" + simpleName,
|
||||||
|
declaration
|
||||||
|
);
|
||||||
|
var instance = this.compileFunctionUsingTypeArguments(prototype, [], null, declaration);
|
||||||
|
if (!instance) return this.module.createUnreachable();
|
||||||
|
this.currentType = Type.u32.asFunction(instance);
|
||||||
|
var index = this.addFunctionTableEntry(instance);
|
||||||
|
if (index < 0) return this.module.createUnreachable();
|
||||||
|
return this.module.createI32(index);
|
||||||
|
}
|
||||||
|
|
||||||
compileIdentifierExpression(expression: IdentifierExpression, contextualType: Type): ExpressionRef {
|
compileIdentifierExpression(expression: IdentifierExpression, contextualType: Type): ExpressionRef {
|
||||||
// check special keywords first
|
// check special keywords first
|
||||||
switch (expression.kind) {
|
switch (expression.kind) {
|
||||||
@ -4045,7 +4110,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
this.stringSegments.set(stringValue, stringSegment);
|
this.stringSegments.set(stringValue, stringSegment);
|
||||||
}
|
}
|
||||||
var stringOffset = stringSegment.offset;
|
var stringOffset = stringSegment.offset;
|
||||||
this.currentType = this.options.usizeType;
|
var stringType = this.program.types.get("string");
|
||||||
|
this.currentType = stringType ? stringType : this.options.usizeType;
|
||||||
if (this.options.isWasm64) {
|
if (this.options.isWasm64) {
|
||||||
return this.module.createI64(i64_low(stringOffset), i64_high(stringOffset));
|
return this.module.createI64(i64_low(stringOffset), i64_high(stringOffset));
|
||||||
}
|
}
|
||||||
@ -4244,7 +4310,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
assert((<Field>element).memoryOffset >= 0);
|
assert((<Field>element).memoryOffset >= 0);
|
||||||
targetExpr = this.compileExpression(
|
targetExpr = this.compileExpression(
|
||||||
<Expression>resolved.targetExpression,
|
<Expression>resolved.targetExpression,
|
||||||
this.options.usizeType
|
this.options.usizeType,
|
||||||
|
ConversionKind.NONE
|
||||||
);
|
);
|
||||||
this.currentType = (<Field>element).type;
|
this.currentType = (<Field>element).type;
|
||||||
return this.module.createLoad(
|
return this.module.createLoad(
|
||||||
@ -4265,9 +4332,8 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
if (getterInstance.is(ElementFlags.INSTANCE)) {
|
if (getterInstance.is(ElementFlags.INSTANCE)) {
|
||||||
targetExpr = this.compileExpression(
|
targetExpr = this.compileExpression(
|
||||||
<Expression>resolved.targetExpression,
|
<Expression>resolved.targetExpression,
|
||||||
this.options.isWasm64
|
this.options.usizeType,
|
||||||
? Type.usize64
|
ConversionKind.NONE
|
||||||
: Type.usize32
|
|
||||||
);
|
);
|
||||||
this.currentType = getterInstance.returnType;
|
this.currentType = getterInstance.returnType;
|
||||||
return this.makeCall(getterInstance, [ targetExpr ]);
|
return this.makeCall(getterInstance, [ targetExpr ]);
|
||||||
@ -4283,7 +4349,11 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
compileTernaryExpression(expression: TernaryExpression, contextualType: Type): ExpressionRef {
|
compileTernaryExpression(expression: TernaryExpression, contextualType: Type): ExpressionRef {
|
||||||
var condition = this.compileExpression(expression.condition, Type.i32);
|
var condition = makeIsTrueish(
|
||||||
|
this.compileExpression(expression.condition, Type.u32, ConversionKind.NONE),
|
||||||
|
this.currentType,
|
||||||
|
this.module
|
||||||
|
);
|
||||||
var ifThen = this.compileExpression(expression.ifThen, contextualType);
|
var ifThen = this.compileExpression(expression.ifThen, contextualType);
|
||||||
var ifElse = this.compileExpression(expression.ifElse, contextualType);
|
var ifElse = this.compileExpression(expression.ifElse, contextualType);
|
||||||
return this.module.createIf(condition, ifThen, ifElse);
|
return this.module.createIf(condition, ifThen, ifElse);
|
||||||
@ -4308,6 +4378,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
switch (expression.operator) {
|
switch (expression.operator) {
|
||||||
|
|
||||||
case Token.PLUS_PLUS:
|
case Token.PLUS_PLUS:
|
||||||
|
if (this.currentType.isReference) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
expression.range
|
||||||
|
);
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
}
|
||||||
switch (this.currentType.kind) {
|
switch (this.currentType.kind) {
|
||||||
|
|
||||||
case TypeKind.I8:
|
case TypeKind.I8:
|
||||||
@ -4363,6 +4440,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.MINUS_MINUS:
|
case Token.MINUS_MINUS:
|
||||||
|
if (this.currentType.isReference) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
expression.range
|
||||||
|
);
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
}
|
||||||
switch (this.currentType.kind) {
|
switch (this.currentType.kind) {
|
||||||
|
|
||||||
case TypeKind.I8:
|
case TypeKind.I8:
|
||||||
@ -4496,6 +4580,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.MINUS:
|
case Token.MINUS:
|
||||||
|
if (this.currentType.isReference) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
expression.range
|
||||||
|
);
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
}
|
||||||
if (expression.operand.kind == NodeKind.LITERAL && (
|
if (expression.operand.kind == NodeKind.LITERAL && (
|
||||||
(<LiteralExpression>expression.operand).literalKind == LiteralKind.INTEGER ||
|
(<LiteralExpression>expression.operand).literalKind == LiteralKind.INTEGER ||
|
||||||
(<LiteralExpression>expression.operand).literalKind == LiteralKind.FLOAT
|
(<LiteralExpression>expression.operand).literalKind == LiteralKind.FLOAT
|
||||||
@ -4559,6 +4650,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.PLUS_PLUS:
|
case Token.PLUS_PLUS:
|
||||||
|
if (this.currentType.isReference) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
expression.range
|
||||||
|
);
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
}
|
||||||
compound = true;
|
compound = true;
|
||||||
expr = this.compileExpression(
|
expr = this.compileExpression(
|
||||||
expression.operand,
|
expression.operand,
|
||||||
@ -4616,6 +4714,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.MINUS_MINUS:
|
case Token.MINUS_MINUS:
|
||||||
|
if (this.currentType.isReference) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
expression.range
|
||||||
|
);
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
}
|
||||||
compound = true;
|
compound = true;
|
||||||
expr = this.compileExpression(
|
expr = this.compileExpression(
|
||||||
expression.operand,
|
expression.operand,
|
||||||
@ -4687,6 +4792,13 @@ export class Compiler extends DiagnosticEmitter {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Token.TILDE:
|
case Token.TILDE:
|
||||||
|
if (this.currentType.isReference) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Operation_not_supported,
|
||||||
|
expression.range
|
||||||
|
);
|
||||||
|
return this.module.createUnreachable();
|
||||||
|
}
|
||||||
expr = this.compileExpression(
|
expr = this.compileExpression(
|
||||||
expression.operand,
|
expression.operand,
|
||||||
contextualType == Type.void
|
contextualType == Type.void
|
||||||
@ -4866,13 +4978,13 @@ export function makeIsFalseish(expr: ExpressionRef, type: Type, module: Module):
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Creates a comparison whether an expression is 'true' in a broader sense. */
|
/** Creates a comparison whether an expression is 'true' in a broader sense. */
|
||||||
export function makeIsTrueish(expr: ExpressionRef, type: Type, module: Module): ExpressionRef {
|
export function makeIsTrueish(
|
||||||
|
expr: ExpressionRef,
|
||||||
|
type: Type,
|
||||||
|
module: Module
|
||||||
|
): ExpressionRef {
|
||||||
switch (type.kind) {
|
switch (type.kind) {
|
||||||
|
|
||||||
default: // any integer up to 32 bits
|
|
||||||
expr = module.createBinary(BinaryOp.NeI32, expr, module.createI32(0));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case TypeKind.I64:
|
case TypeKind.I64:
|
||||||
case TypeKind.U64:
|
case TypeKind.U64:
|
||||||
expr = module.createBinary(BinaryOp.NeI64, expr, module.createI64(0));
|
expr = module.createBinary(BinaryOp.NeI64, expr, module.createI64(0));
|
||||||
@ -4881,9 +4993,9 @@ export function makeIsTrueish(expr: ExpressionRef, type: Type, module: Module):
|
|||||||
case TypeKind.USIZE:
|
case TypeKind.USIZE:
|
||||||
// TODO: strings
|
// TODO: strings
|
||||||
case TypeKind.ISIZE:
|
case TypeKind.ISIZE:
|
||||||
expr = type.size == 64
|
if (type.size == 64) {
|
||||||
? module.createBinary(BinaryOp.NeI64, expr, module.createI64(0))
|
expr = module.createBinary(BinaryOp.NeI64, expr, module.createI64(0));
|
||||||
: module.createBinary(BinaryOp.NeI32, expr, module.createI32(0));
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TypeKind.F32:
|
case TypeKind.F32:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
export enum DiagnosticCode {
|
export enum DiagnosticCode {
|
||||||
Operation_not_supported = 100,
|
Operation_not_supported = 100,
|
||||||
Operation_is_unsafe = 101,
|
Operation_is_unsafe = 101,
|
||||||
Conversion_from_type_0_to_1_possibly_loses_information_and_thus_requires_an_explicit_cast = 200,
|
Conversion_from_type_0_to_1_requires_an_explicit_cast = 200,
|
||||||
Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit = 201,
|
Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit = 201,
|
||||||
Type_0_cannot_be_changed_to_type_1 = 202,
|
Type_0_cannot_be_changed_to_type_1 = 202,
|
||||||
Type_0_cannot_be_reinterpreted_as_type_1 = 203,
|
Type_0_cannot_be_reinterpreted_as_type_1 = 203,
|
||||||
@ -101,7 +101,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
switch (code) {
|
switch (code) {
|
||||||
case 100: return "Operation not supported.";
|
case 100: return "Operation not supported.";
|
||||||
case 101: return "Operation is unsafe.";
|
case 101: return "Operation is unsafe.";
|
||||||
case 200: return "Conversion from type '{0}' to '{1}' possibly loses information and thus requires an explicit cast.";
|
case 200: return "Conversion from type '{0}' to '{1}' requires an explicit cast.";
|
||||||
case 201: return "Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.";
|
case 201: return "Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.";
|
||||||
case 202: return "Type '{0}' cannot be changed to type '{1}'.";
|
case 202: return "Type '{0}' cannot be changed to type '{1}'.";
|
||||||
case 203: return "Type '{0}' cannot be reinterpreted as type '{1}'.";
|
case 203: return "Type '{0}' cannot be reinterpreted as type '{1}'.";
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"Operation not supported.": 100,
|
"Operation not supported.": 100,
|
||||||
"Operation is unsafe.": 101,
|
"Operation is unsafe.": 101,
|
||||||
"Conversion from type '{0}' to '{1}' possibly loses information and thus requires an explicit cast.": 200,
|
"Conversion from type '{0}' to '{1}' requires an explicit cast.": 200,
|
||||||
"Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.": 201,
|
"Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.": 201,
|
||||||
"Type '{0}' cannot be changed to type '{1}'.": 202,
|
"Type '{0}' cannot be changed to type '{1}'.": 202,
|
||||||
"Type '{0}' cannot be reinterpreted as type '{1}'.": 203,
|
"Type '{0}' cannot be reinterpreted as type '{1}'.": 203,
|
||||||
|
@ -876,6 +876,7 @@ export function serializeFunctionDeclaration(node: FunctionDeclaration, sb: stri
|
|||||||
function serializeFunctionCommon(node: FunctionDeclaration, sb: string[], isArrow: bool = false): void {
|
function serializeFunctionCommon(node: FunctionDeclaration, sb: string[], isArrow: bool = false): void {
|
||||||
var i: i32, k: i32;
|
var i: i32, k: i32;
|
||||||
serializeIdentifierExpression(node.name, sb);
|
serializeIdentifierExpression(node.name, sb);
|
||||||
|
if (node.typeParameters) {
|
||||||
if (k = node.typeParameters.length) {
|
if (k = node.typeParameters.length) {
|
||||||
sb.push("<");
|
sb.push("<");
|
||||||
serializeTypeParameter(node.typeParameters[0], sb);
|
serializeTypeParameter(node.typeParameters[0], sb);
|
||||||
@ -885,6 +886,7 @@ function serializeFunctionCommon(node: FunctionDeclaration, sb: string[], isArro
|
|||||||
}
|
}
|
||||||
sb.push(">");
|
sb.push(">");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
sb.push("(");
|
sb.push("(");
|
||||||
if (k = node.parameters.length) {
|
if (k = node.parameters.length) {
|
||||||
serializeParameter(node.parameters[0], sb);
|
serializeParameter(node.parameters[0], sb);
|
||||||
|
@ -56,6 +56,7 @@ import {
|
|||||||
ExportStatement,
|
ExportStatement,
|
||||||
ExpressionStatement,
|
ExpressionStatement,
|
||||||
ForStatement,
|
ForStatement,
|
||||||
|
FunctionExpression,
|
||||||
FunctionDeclaration,
|
FunctionDeclaration,
|
||||||
IfStatement,
|
IfStatement,
|
||||||
ImportDeclaration,
|
ImportDeclaration,
|
||||||
@ -79,8 +80,7 @@ import {
|
|||||||
addModifier,
|
addModifier,
|
||||||
getModifier,
|
getModifier,
|
||||||
hasModifier,
|
hasModifier,
|
||||||
setReusableModifiers,
|
setReusableModifiers
|
||||||
FunctionExpression
|
|
||||||
|
|
||||||
} from "./ast";
|
} from "./ast";
|
||||||
|
|
||||||
@ -874,8 +874,6 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
if (tn.skip(Token.LESSTHAN)) {
|
if (tn.skip(Token.LESSTHAN)) {
|
||||||
typeParameters = this.parseTypeParameters(tn);
|
typeParameters = this.parseTypeParameters(tn);
|
||||||
if (!typeParameters) return null;
|
if (!typeParameters) return null;
|
||||||
} else {
|
|
||||||
typeParameters = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tn.skip(Token.OPENPAREN)) {
|
if (!tn.skip(Token.OPENPAREN)) {
|
||||||
@ -1046,7 +1044,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
|
|
||||||
var declaration = Node.createFunctionDeclaration(
|
var declaration = Node.createFunctionDeclaration(
|
||||||
identifier,
|
identifier,
|
||||||
[],
|
null,
|
||||||
parameters,
|
parameters,
|
||||||
returnType,
|
returnType,
|
||||||
body,
|
body,
|
||||||
@ -1213,7 +1211,7 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
? Node.createConstructorExpression(tn.range())
|
? Node.createConstructorExpression(tn.range())
|
||||||
: Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
: Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
||||||
|
|
||||||
var typeParameters: TypeParameter[] | null;
|
var typeParameters: TypeParameter[] | null = null;
|
||||||
if (tn.skip(Token.LESSTHAN)) {
|
if (tn.skip(Token.LESSTHAN)) {
|
||||||
if (isConstructor) {
|
if (isConstructor) {
|
||||||
this.error(
|
this.error(
|
||||||
@ -1223,8 +1221,6 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
typeParameters = this.parseTypeParameters(tn);
|
typeParameters = this.parseTypeParameters(tn);
|
||||||
if (!typeParameters) return null;
|
if (!typeParameters) return null;
|
||||||
} else {
|
|
||||||
typeParameters = [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// method: '(' Parameters (':' Type)? '{' Statement* '}' ';'?
|
// method: '(' Parameters (':' Type)? '{' Statement* '}' ';'?
|
||||||
|
@ -474,13 +474,19 @@ export class Program extends DiagnosticEmitter {
|
|||||||
// check and possibly register string type
|
// check and possibly register string type
|
||||||
if (
|
if (
|
||||||
prototype.is(ElementFlags.GLOBAL) &&
|
prototype.is(ElementFlags.GLOBAL) &&
|
||||||
declaration.name.text === "String" &&
|
declaration.name.text == "String"
|
||||||
!this.types.has("string")
|
|
||||||
) {
|
) {
|
||||||
|
if (!this.types.has("string")) {
|
||||||
var instance = prototype.resolve(null);
|
var instance = prototype.resolve(null);
|
||||||
if (instance) {
|
if (instance) {
|
||||||
this.types.set("string", instance.type);
|
this.types.set("string", instance.type);
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Duplicate_identifier_0,
|
||||||
|
declaration.name.range, declaration.programLevelInternalName
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2116,7 +2122,7 @@ export class FunctionPrototype extends Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.declaration.typeParameters.length) {
|
if (this.declaration.isGeneric) {
|
||||||
this.set(ElementFlags.GENERIC);
|
this.set(ElementFlags.GENERIC);
|
||||||
}
|
}
|
||||||
if (this.classPrototype = classPrototype) {
|
if (this.classPrototype = classPrototype) {
|
||||||
@ -2163,7 +2169,7 @@ export class FunctionPrototype extends Element {
|
|||||||
// override call specific contextual type arguments
|
// override call specific contextual type arguments
|
||||||
var functionTypeParameters = declaration.typeParameters;
|
var functionTypeParameters = declaration.typeParameters;
|
||||||
if (functionTypeArguments && (k = functionTypeArguments.length)) {
|
if (functionTypeArguments && (k = functionTypeArguments.length)) {
|
||||||
if (k != functionTypeParameters.length) {
|
if (!functionTypeParameters || k != functionTypeParameters.length) {
|
||||||
throw new Error("type argument count mismatch");
|
throw new Error("type argument count mismatch");
|
||||||
}
|
}
|
||||||
for (i = 0; i < k; ++i) {
|
for (i = 0; i < k; ++i) {
|
||||||
@ -2229,7 +2235,7 @@ export class FunctionPrototype extends Element {
|
|||||||
if (this.is(ElementFlags.GENERIC)) {
|
if (this.is(ElementFlags.GENERIC)) {
|
||||||
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0);
|
assert(typeArgumentNodes != null && typeArgumentNodes.length != 0);
|
||||||
resolvedTypeArguments = this.program.resolveTypeArguments(
|
resolvedTypeArguments = this.program.resolveTypeArguments(
|
||||||
this.declaration.typeParameters,
|
assert(this.declaration.typeParameters),
|
||||||
typeArgumentNodes,
|
typeArgumentNodes,
|
||||||
contextualTypeArguments,
|
contextualTypeArguments,
|
||||||
reportNode
|
reportNode
|
||||||
@ -2288,6 +2294,10 @@ export class Function extends Element {
|
|||||||
flow: Flow;
|
flow: Flow;
|
||||||
/** Remembered debug locations. */
|
/** Remembered debug locations. */
|
||||||
debugLocations: Range[] | null = null;
|
debugLocations: Range[] | null = null;
|
||||||
|
/** Function reference, if compiled. */
|
||||||
|
ref: FunctionRef = 0;
|
||||||
|
/** Function table index, if any. */
|
||||||
|
functionTableIndex: i32 = -1;
|
||||||
|
|
||||||
private nextBreakId: i32 = 0;
|
private nextBreakId: i32 = 0;
|
||||||
private breakStack: i32[] | null = null;
|
private breakStack: i32[] | null = null;
|
||||||
@ -2444,6 +2454,7 @@ export class Function extends Element {
|
|||||||
|
|
||||||
/** Finalizes the function once compiled, releasing no longer needed resources. */
|
/** Finalizes the function once compiled, releasing no longer needed resources. */
|
||||||
finalize(module: Module, ref: FunctionRef): void {
|
finalize(module: Module, ref: FunctionRef): void {
|
||||||
|
this.ref = ref;
|
||||||
assert(!this.breakStack || !this.breakStack.length); // internal error
|
assert(!this.breakStack || !this.breakStack.length); // internal error
|
||||||
this.breakStack = null;
|
this.breakStack = null;
|
||||||
this.breakContext = null;
|
this.breakContext = null;
|
||||||
@ -2466,6 +2477,11 @@ export class Function extends Element {
|
|||||||
this.debugLocations = null;
|
this.debugLocations = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Tests if a value of this function type is assignable to a target of the specified function type. */
|
||||||
|
isAssignableTo(target: Function): bool {
|
||||||
|
return this == target; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
/** Returns the TypeScript representation of this function. */
|
/** Returns the TypeScript representation of this function. */
|
||||||
toString(): string { return this.prototype.simpleName; }
|
toString(): string { return this.prototype.simpleName; }
|
||||||
|
|
||||||
@ -2865,6 +2881,17 @@ export class Class extends Element {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Tests if a value of this class type is assignable to a target of the specified class type. */
|
||||||
|
isAssignableTo(target: Class): bool {
|
||||||
|
var current: Class | null = this;
|
||||||
|
do {
|
||||||
|
if (current == target) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
} while (current = current.base);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
toString(): string {
|
toString(): string {
|
||||||
return this.prototype.simpleName;
|
return this.prototype.simpleName;
|
||||||
}
|
}
|
||||||
|
192
src/types.ts
192
src/types.ts
@ -122,7 +122,7 @@ export class Type {
|
|||||||
|
|
||||||
/** Composes a function type from this type and a function. */
|
/** Composes a function type from this type and a function. */
|
||||||
asFunction(functionType: Function): Type {
|
asFunction(functionType: Function): Type {
|
||||||
assert(this.kind == TypeKind.USIZE && !this.isReference);
|
assert(this.kind == TypeKind.U32 && !this.isReference);
|
||||||
var ret = new Type(this.kind, this.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, this.size);
|
var ret = new Type(this.kind, this.flags & ~TypeFlags.VALUE | TypeFlags.REFERENCE, this.size);
|
||||||
ret.functionType = functionType;
|
ret.functionType = functionType;
|
||||||
return ret;
|
return ret;
|
||||||
@ -140,6 +140,196 @@ export class Type {
|
|||||||
return this.nullableType;
|
return this.nullableType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Tests if a value of this type is assignable to a target of the specified type. */
|
||||||
|
isAssignableTo(target: Type): bool {
|
||||||
|
var currentClass: Class | null;
|
||||||
|
var targetClass: Class | null;
|
||||||
|
var currentFunction: Function | null;
|
||||||
|
var targetFunction: Function | null;
|
||||||
|
if (this.isReference) {
|
||||||
|
if (target.isReference) {
|
||||||
|
if (currentClass = this.classType) {
|
||||||
|
if (targetClass = target.classType) {
|
||||||
|
return currentClass.isAssignableTo(targetClass);
|
||||||
|
}
|
||||||
|
} else if (currentFunction = this.functionType) {
|
||||||
|
if (targetFunction = target.functionType) {
|
||||||
|
return currentFunction.isAssignableTo(targetFunction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (!target.isReference) {
|
||||||
|
switch (this.kind) {
|
||||||
|
|
||||||
|
case TypeKind.I8:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I8: // same
|
||||||
|
case TypeKind.I16: // larger
|
||||||
|
case TypeKind.I32: // larger
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.ISIZE: // larger
|
||||||
|
case TypeKind.U8: // signed to unsigned
|
||||||
|
case TypeKind.U16: // larger
|
||||||
|
case TypeKind.U32: // larger
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // larger
|
||||||
|
case TypeKind.F32: // safe
|
||||||
|
case TypeKind.F64: // safe
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.I16:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I16: // same
|
||||||
|
case TypeKind.I32: // larger
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.ISIZE: // larger
|
||||||
|
case TypeKind.U16: // signed to unsigned
|
||||||
|
case TypeKind.U32: // larger
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // larger
|
||||||
|
case TypeKind.F32: // safe
|
||||||
|
case TypeKind.F64: // safe
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.I32:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I32: // same
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.ISIZE: // same or larger
|
||||||
|
case TypeKind.U32: // signed to unsigned
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // signed to unsigned or larger
|
||||||
|
case TypeKind.F64: // safe
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.I64:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I64: // same
|
||||||
|
case TypeKind.U64: // signed to unsigned
|
||||||
|
return true;
|
||||||
|
case TypeKind.ISIZE: // possibly same
|
||||||
|
case TypeKind.USIZE: // possibly signed to unsigned
|
||||||
|
return target.size == 64;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.ISIZE:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I32: // possibly same
|
||||||
|
case TypeKind.U32: // possibly signed to unsigned
|
||||||
|
return this.size == 32;
|
||||||
|
case TypeKind.I64: // same or larger
|
||||||
|
case TypeKind.ISIZE: // same
|
||||||
|
case TypeKind.U64: // signed to unsigned or larger
|
||||||
|
case TypeKind.USIZE: // signed to unsigned
|
||||||
|
return true;
|
||||||
|
case TypeKind.F64: // possibly safe
|
||||||
|
return target.size == 32;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.U8:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I16: // larger
|
||||||
|
case TypeKind.I32: // larger
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.ISIZE: // larger
|
||||||
|
case TypeKind.U8: // same
|
||||||
|
case TypeKind.U16: // larger
|
||||||
|
case TypeKind.U32: // larger
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // larger
|
||||||
|
case TypeKind.F32: // safe
|
||||||
|
case TypeKind.F64: // safe
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.U16:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I32: // larger
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.ISIZE: // larger
|
||||||
|
case TypeKind.U16: // same
|
||||||
|
case TypeKind.U32: // larger
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // larger
|
||||||
|
case TypeKind.F32: // safe
|
||||||
|
case TypeKind.F64: // safe
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.U32:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.U32: // same
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // same or larger
|
||||||
|
case TypeKind.F64: // safe
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.U64:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.U64: // same
|
||||||
|
return true;
|
||||||
|
case TypeKind.USIZE: // possibly same
|
||||||
|
return target.size == 64;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.USIZE:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.U32: // possibly same
|
||||||
|
return this.size == 32;
|
||||||
|
case TypeKind.U64: // same or larger
|
||||||
|
case TypeKind.USIZE: // same
|
||||||
|
return true;
|
||||||
|
case TypeKind.F64: // possibly safe
|
||||||
|
return target.size == 32;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.BOOL:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.I8: // larger
|
||||||
|
case TypeKind.I16: // larger
|
||||||
|
case TypeKind.I32: // larger
|
||||||
|
case TypeKind.I64: // larger
|
||||||
|
case TypeKind.ISIZE: // larger
|
||||||
|
case TypeKind.U8: // larger
|
||||||
|
case TypeKind.U16: // larger
|
||||||
|
case TypeKind.U32: // larger
|
||||||
|
case TypeKind.U64: // larger
|
||||||
|
case TypeKind.USIZE: // larger
|
||||||
|
case TypeKind.BOOL: // same
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.F32:
|
||||||
|
switch (target.kind) {
|
||||||
|
case TypeKind.F32: // same
|
||||||
|
case TypeKind.F64: // larger
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TypeKind.F64:
|
||||||
|
return target.kind == TypeKind.F64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/** Converts this type to its TypeScript representation. */
|
/** Converts this type to its TypeScript representation. */
|
||||||
toString(kindOnly: bool = false): string {
|
toString(kindOnly: bool = false): string {
|
||||||
switch (this.kind) {
|
switch (this.kind) {
|
||||||
|
@ -17,7 +17,7 @@ export function allocate_memory(size: usize): usize {
|
|||||||
var off = (ptr + size + ALIGN_MASK) & ~ALIGN_MASK;
|
var off = (ptr + size + ALIGN_MASK) & ~ALIGN_MASK;
|
||||||
var avail = <usize>current_memory() << 16;
|
var avail = <usize>current_memory() << 16;
|
||||||
if (off > avail && grow_memory(
|
if (off > avail && grow_memory(
|
||||||
max(
|
<i32>max(
|
||||||
(((off + 0xffff) & ~0xffff) - avail) >> 16, // minimum required pages
|
(((off + 0xffff) & ~0xffff) - avail) >> 16, // minimum required pages
|
||||||
avail >> 16 // at least double memory
|
avail >> 16 // at least double memory
|
||||||
)
|
)
|
||||||
|
@ -8,7 +8,7 @@ export class Array<T> {
|
|||||||
assert(newCapacity > this.__capacity);
|
assert(newCapacity > this.__capacity);
|
||||||
var newMemory = allocate_memory(<usize>newCapacity * sizeof<T>());
|
var newMemory = allocate_memory(<usize>newCapacity * sizeof<T>());
|
||||||
if (this.__memory) {
|
if (this.__memory) {
|
||||||
move_memory(newMemory, this.__memory, this.__capacity * sizeof<T>());
|
move_memory(newMemory, this.__memory, <usize>this.__capacity * sizeof<T>());
|
||||||
free_memory(this.__memory);
|
free_memory(this.__memory);
|
||||||
}
|
}
|
||||||
this.__memory = newMemory;
|
this.__memory = newMemory;
|
||||||
@ -63,7 +63,7 @@ export class Array<T> {
|
|||||||
fromIndex = this.__length + fromIndex;
|
fromIndex = this.__length + fromIndex;
|
||||||
}
|
}
|
||||||
while (<u32>fromIndex < this.__length) {
|
while (<u32>fromIndex < this.__length) {
|
||||||
if (load<T>(this.__memory + fromIndex * sizeof<T>()) == searchElement) {
|
if (load<T>(this.__memory + <usize>fromIndex * sizeof<T>()) == searchElement) {
|
||||||
return fromIndex;
|
return fromIndex;
|
||||||
}
|
}
|
||||||
++fromIndex;
|
++fromIndex;
|
||||||
@ -78,7 +78,7 @@ export class Array<T> {
|
|||||||
fromIndex = this.__length - 1;
|
fromIndex = this.__length - 1;
|
||||||
}
|
}
|
||||||
while (fromIndex >= 0) {
|
while (fromIndex >= 0) {
|
||||||
if (load<T>(this.__memory + fromIndex * sizeof<T>()) == searchElement) {
|
if (load<T>(this.__memory + <usize>fromIndex * sizeof<T>()) == searchElement) {
|
||||||
return fromIndex;
|
return fromIndex;
|
||||||
}
|
}
|
||||||
--fromIndex;
|
--fromIndex;
|
||||||
@ -90,7 +90,7 @@ export class Array<T> {
|
|||||||
if (this.__length == this.__capacity) {
|
if (this.__length == this.__capacity) {
|
||||||
this.__grow(this.__capacity ? this.__capacity << 1 : 1);
|
this.__grow(this.__capacity ? this.__capacity << 1 : 1);
|
||||||
}
|
}
|
||||||
store<T>(this.__memory + this.__length * sizeof<T>(), element);
|
store<T>(this.__memory + <usize>this.__length * sizeof<T>(), element);
|
||||||
return ++this.__length;
|
return ++this.__length;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -98,7 +98,7 @@ export class Array<T> {
|
|||||||
if (this.__length < 1) {
|
if (this.__length < 1) {
|
||||||
throw new RangeError("Array is empty"); // return changetype<T>(0) ?
|
throw new RangeError("Array is empty"); // return changetype<T>(0) ?
|
||||||
}
|
}
|
||||||
return load<T>(this.__memory + --this.__length * sizeof<T>());
|
return load<T>(this.__memory + <usize>--this.__length * sizeof<T>());
|
||||||
}
|
}
|
||||||
|
|
||||||
shift(): T {
|
shift(): T {
|
||||||
@ -109,10 +109,10 @@ export class Array<T> {
|
|||||||
move_memory(
|
move_memory(
|
||||||
this.__memory,
|
this.__memory,
|
||||||
this.__memory + sizeof<T>(),
|
this.__memory + sizeof<T>(),
|
||||||
(this.__capacity - 1) * sizeof<T>()
|
<usize>(this.__capacity - 1) * sizeof<T>()
|
||||||
);
|
);
|
||||||
set_memory(
|
set_memory(
|
||||||
this.__memory + (this.__capacity - 1) * sizeof<T>(),
|
this.__memory + <usize>(this.__capacity - 1) * sizeof<T>(),
|
||||||
0,
|
0,
|
||||||
sizeof<T>()
|
sizeof<T>()
|
||||||
);
|
);
|
||||||
@ -131,7 +131,7 @@ export class Array<T> {
|
|||||||
move_memory(
|
move_memory(
|
||||||
newMemory + sizeof<T>(),
|
newMemory + sizeof<T>(),
|
||||||
this.__memory,
|
this.__memory,
|
||||||
oldCapacity * sizeof<T>()
|
<usize>oldCapacity * sizeof<T>()
|
||||||
);
|
);
|
||||||
free_memory(this.__memory);
|
free_memory(this.__memory);
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ export class Array<T> {
|
|||||||
move_memory(
|
move_memory(
|
||||||
this.__memory + sizeof<T>(),
|
this.__memory + sizeof<T>(),
|
||||||
this.__memory,
|
this.__memory,
|
||||||
oldCapacity * sizeof<T>()
|
<usize>oldCapacity * sizeof<T>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
store<T>(this.__memory, element);
|
store<T>(this.__memory, element);
|
||||||
@ -196,7 +196,7 @@ export class Array<T> {
|
|||||||
move_memory(
|
move_memory(
|
||||||
this.__memory + <usize>start * sizeof<T>(),
|
this.__memory + <usize>start * sizeof<T>(),
|
||||||
this.__memory + <usize>(start + deleteCount) * sizeof<T>(),
|
this.__memory + <usize>(start + deleteCount) * sizeof<T>(),
|
||||||
deleteCount * sizeof<T>()
|
<usize>deleteCount * sizeof<T>()
|
||||||
);
|
);
|
||||||
this.__length -= deleteCount;
|
this.__length -= deleteCount;
|
||||||
}
|
}
|
||||||
|
@ -133,10 +133,10 @@ declare function isize(value: void): isize;
|
|||||||
namespace isize {
|
namespace isize {
|
||||||
export const MIN_VALUE: isize = sizeof<i32>() == sizeof<isize>()
|
export const MIN_VALUE: isize = sizeof<i32>() == sizeof<isize>()
|
||||||
? -2147483648
|
? -2147483648
|
||||||
: <usize>-9223372036854775808;
|
: <isize>-9223372036854775808;
|
||||||
export const MAX_VALUE: isize = sizeof<i32>() == sizeof<isize>()
|
export const MAX_VALUE: isize = sizeof<i32>() == sizeof<isize>()
|
||||||
? 2147483647
|
? 2147483647
|
||||||
: <usize>9223372036854775807;
|
: <isize>9223372036854775807;
|
||||||
}
|
}
|
||||||
export { isize };
|
export { isize };
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ export class Set<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get size(): i32 {
|
get size(): i32 {
|
||||||
return this.__size;
|
return <i32>this.__size;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: not a proper set implementation, just a filler
|
// FIXME: not a proper set implementation, just a filler
|
||||||
@ -52,11 +52,11 @@ export class Set<T> {
|
|||||||
|
|
||||||
for (var index: usize = 0, limit: usize = this.__size; index < limit; ++index) {
|
for (var index: usize = 0, limit: usize = this.__size; index < limit; ++index) {
|
||||||
if (load<T>(this.__memory + index * sizeof<T>()) == value) {
|
if (load<T>(this.__memory + index * sizeof<T>()) == value) {
|
||||||
if (index + 1 < this.__size) {
|
if (index + 1 < limit) {
|
||||||
move_memory(
|
move_memory(
|
||||||
this.__memory + index * sizeof<T>(),
|
this.__memory + index * sizeof<T>(),
|
||||||
this.__memory + (index + 1) * sizeof<T>(),
|
this.__memory + (index + 1) * sizeof<T>(),
|
||||||
this.__size - index - 1
|
limit - index - 1
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
--this.__size;
|
--this.__size;
|
||||||
|
@ -63,11 +63,9 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i64.eq
|
(i64.eq
|
||||||
(i64.shl
|
(i64.shl
|
||||||
@ -77,8 +75,6 @@
|
|||||||
(i64.const 0)
|
(i64.const 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(f64.ne
|
(f64.ne
|
||||||
(tee_local $7
|
(tee_local $7
|
||||||
@ -90,8 +86,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
@ -517,11 +511,9 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.shl
|
(i32.shl
|
||||||
@ -531,8 +523,6 @@
|
|||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(f32.ne
|
(f32.ne
|
||||||
(tee_local $7
|
(tee_local $7
|
||||||
@ -544,8 +534,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
|
15
tests/compiler/function-expression.optimized.wat
Normal file
15
tests/compiler/function-expression.optimized.wat
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(type $v (func))
|
||||||
|
(table 3 3 anyfunc)
|
||||||
|
(elem (i32.const 0) $start~anonymous|0 $start~anonymous|0 $start~someName|2)
|
||||||
|
(memory $0 1)
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start~someName|2)
|
||||||
|
(func $start~anonymous|0 (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
(func $start~someName|2 (; 1 ;) (type $v)
|
||||||
|
(nop)
|
||||||
|
)
|
||||||
|
)
|
11
tests/compiler/function-expression.ts
Normal file
11
tests/compiler/function-expression.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
var f1 = function(a: i32): i32 {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
f1;
|
||||||
|
var f2 = (a: i32): i32 => {
|
||||||
|
return a;
|
||||||
|
};
|
||||||
|
f2;
|
||||||
|
var f3 = function someName(): void {
|
||||||
|
};
|
||||||
|
f3;
|
36
tests/compiler/function-expression.untouched.wat
Normal file
36
tests/compiler/function-expression.untouched.wat
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
(module
|
||||||
|
(type $ii (func (param i32) (result i32)))
|
||||||
|
(type $v (func))
|
||||||
|
(global $function-expression/f1 (mut i32) (i32.const 0))
|
||||||
|
(global $function-expression/f2 (mut i32) (i32.const 1))
|
||||||
|
(global $function-expression/f3 (mut i32) (i32.const 2))
|
||||||
|
(global $HEAP_BASE i32 (i32.const 4))
|
||||||
|
(table 3 3 anyfunc)
|
||||||
|
(elem (i32.const 0) $start~anonymous|0 $start~anonymous|1 $start~someName|2)
|
||||||
|
(memory $0 1)
|
||||||
|
(export "memory" (memory $0))
|
||||||
|
(start $start)
|
||||||
|
(func $start~anonymous|0 (; 0 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(return
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $start~anonymous|1 (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
||||||
|
(return
|
||||||
|
(get_local $0)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
(func $start~someName|2 (; 2 ;) (type $v)
|
||||||
|
)
|
||||||
|
(func $start (; 3 ;) (type $v)
|
||||||
|
(drop
|
||||||
|
(get_global $function-expression/f1)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(get_global $function-expression/f2)
|
||||||
|
)
|
||||||
|
(drop
|
||||||
|
(get_global $function-expression/f3)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
@ -229,15 +229,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $9
|
(tee_local $9
|
||||||
(i32.lt_s
|
(i32.lt_s
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $9)
|
(get_local $9)
|
||||||
(i32.gt_s
|
(i32.gt_s
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
|
@ -16,10 +16,7 @@
|
|||||||
(local $1 f64)
|
(local $1 f64)
|
||||||
(drop
|
(drop
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
(unreachable)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
@ -36,10 +33,7 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
@ -56,19 +50,13 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $0
|
(tee_local $0
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
@ -94,10 +82,7 @@
|
|||||||
)
|
)
|
||||||
(set_global $logical/i
|
(set_global $logical/i
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
@ -121,11 +106,8 @@
|
|||||||
)
|
)
|
||||||
(set_global $logical/i
|
(set_global $logical/i
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -24,10 +24,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.rem_u
|
(i32.rem_u
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
function test(a: i32, b: i32): void {
|
function test(a: u32, b: u32): void {
|
||||||
|
|
||||||
// signed
|
// signed
|
||||||
assert(<i8>(a + b) == <i8>(<i8>a + <i8>b));
|
assert(<i8>(a + b) == <i8>(<i8>a + <i8>b));
|
||||||
|
@ -111,10 +111,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.rem_u
|
(i32.rem_u
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1959,11 +1956,9 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i64.eq
|
(i64.eq
|
||||||
(i64.shl
|
(i64.shl
|
||||||
@ -1973,8 +1968,6 @@
|
|||||||
(i64.const 0)
|
(i64.const 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(f64.ne
|
(f64.ne
|
||||||
(tee_local $7
|
(tee_local $7
|
||||||
@ -1986,8 +1979,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
@ -2413,11 +2404,9 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $8
|
(tee_local $8
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.shl
|
(i32.shl
|
||||||
@ -2427,8 +2416,6 @@
|
|||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(f32.ne
|
(f32.ne
|
||||||
(tee_local $7
|
(tee_local $7
|
||||||
@ -2440,8 +2427,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $8)
|
(get_local $8)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
@ -4161,10 +4146,7 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
(unreachable)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
)
|
||||||
@ -4181,10 +4163,7 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
@ -4201,19 +4180,13 @@
|
|||||||
)
|
)
|
||||||
(drop
|
(drop
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $0
|
(tee_local $0
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
(unreachable)
|
(unreachable)
|
||||||
)
|
)
|
||||||
@ -4239,10 +4212,7 @@
|
|||||||
)
|
)
|
||||||
(set_global $logical/i
|
(set_global $logical/i
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
@ -4266,11 +4236,8 @@
|
|||||||
)
|
)
|
||||||
(set_global $logical/i
|
(set_global $logical/i
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
(i32.const 0)
|
(i32.const 0)
|
||||||
)
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -61,15 +61,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $4
|
(tee_local $4
|
||||||
(i32.gt_u
|
(i32.gt_u
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.lt_s
|
(i32.lt_s
|
||||||
(grow_memory
|
(grow_memory
|
||||||
(select
|
(select
|
||||||
@ -476,10 +473,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.and
|
(i32.and
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.const 3)
|
(i32.const 3)
|
||||||
@ -2279,7 +2273,6 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $3
|
(tee_local $3
|
||||||
(i32.le_u
|
(i32.le_u
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -2289,8 +2282,6 @@
|
|||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
(i32.le_u
|
(i32.le_u
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -2607,10 +2598,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.load8_u
|
(i32.load8_u
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
|
@ -62,15 +62,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $4
|
(tee_local $4
|
||||||
(i32.gt_u
|
(i32.gt_u
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.lt_s
|
(i32.lt_s
|
||||||
(grow_memory
|
(grow_memory
|
||||||
(select
|
(select
|
||||||
@ -135,10 +132,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.and
|
(i32.and
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.const 3)
|
(i32.const 3)
|
||||||
@ -1938,7 +1932,6 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $3
|
(tee_local $3
|
||||||
(i32.le_u
|
(i32.le_u
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -1948,8 +1941,6 @@
|
|||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
(i32.le_u
|
(i32.le_u
|
||||||
(i32.add
|
(i32.add
|
||||||
|
@ -53,15 +53,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $4
|
(tee_local $4
|
||||||
(i32.gt_u
|
(i32.gt_u
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.lt_s
|
(i32.lt_s
|
||||||
(grow_memory
|
(grow_memory
|
||||||
(select
|
(select
|
||||||
|
@ -16,19 +16,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -38,8 +34,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -62,15 +56,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -137,23 +128,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -163,8 +149,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -174,8 +158,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -311,19 +293,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -333,8 +311,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -357,15 +333,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -456,23 +429,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -482,8 +450,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -493,8 +459,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -636,19 +600,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -658,8 +618,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -682,15 +640,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -737,23 +692,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -763,8 +713,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -774,8 +722,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -905,19 +851,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -927,8 +869,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -951,15 +891,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1008,23 +945,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1034,8 +966,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1045,8 +975,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1176,19 +1104,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1198,8 +1122,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1222,15 +1144,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1277,23 +1196,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1303,8 +1217,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1314,8 +1226,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1445,19 +1355,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1467,8 +1373,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1491,15 +1395,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1546,23 +1447,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1572,8 +1468,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1583,8 +1477,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 8)
|
(i32.const 8)
|
||||||
@ -1714,19 +1606,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1736,8 +1624,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1760,15 +1646,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1815,23 +1698,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1841,8 +1719,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1852,8 +1728,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -1983,19 +1857,15 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -2005,8 +1875,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -2029,15 +1897,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -2084,23 +1949,18 @@
|
|||||||
(i32.eqz
|
(i32.eqz
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $1
|
(tee_local $1
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -2110,8 +1970,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
@ -2121,8 +1979,6 @@
|
|||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.const 4)
|
(i32.const 4)
|
||||||
|
@ -2193,9 +2193,7 @@
|
|||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
(i32.load offset=8
|
(get_local $3)
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
(call "$(lib)/memory/move_memory"
|
(call "$(lib)/memory/move_memory"
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -2221,9 +2219,7 @@
|
|||||||
)
|
)
|
||||||
(i32.sub
|
(i32.sub
|
||||||
(i32.sub
|
(i32.sub
|
||||||
(i32.load offset=8
|
(get_local $3)
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
)
|
)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
|
@ -59,15 +59,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $4
|
(tee_local $4
|
||||||
(i32.gt_u
|
(i32.gt_u
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.lt_s
|
(i32.lt_s
|
||||||
(grow_memory
|
(grow_memory
|
||||||
(select
|
(select
|
||||||
@ -132,10 +129,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.and
|
(i32.and
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.const 3)
|
(i32.const 3)
|
||||||
@ -1935,7 +1929,6 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $3
|
(tee_local $3
|
||||||
(i32.le_u
|
(i32.le_u
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -1945,8 +1938,6 @@
|
|||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
(i32.le_u
|
(i32.le_u
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -2506,9 +2497,7 @@
|
|||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
)
|
)
|
||||||
(i32.load offset=8
|
(get_local $3)
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
(call "$(lib)/memory/move_memory"
|
(call "$(lib)/memory/move_memory"
|
||||||
(i32.add
|
(i32.add
|
||||||
@ -2534,9 +2523,7 @@
|
|||||||
)
|
)
|
||||||
(i32.sub
|
(i32.sub
|
||||||
(i32.sub
|
(i32.sub
|
||||||
(i32.load offset=8
|
(get_local $3)
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
)
|
)
|
||||||
(i32.const 1)
|
(i32.const 1)
|
||||||
|
@ -114,10 +114,7 @@
|
|||||||
(loop $continue|0
|
(loop $continue|0
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(i32.load8_u
|
(i32.load8_u
|
||||||
(get_local $0)
|
(get_local $0)
|
||||||
@ -635,15 +632,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $6
|
(tee_local $6
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 48)
|
(i32.const 48)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.gt_s
|
(i32.gt_s
|
||||||
(get_local $2)
|
(get_local $2)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
@ -771,15 +765,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $6
|
(tee_local $6
|
||||||
(i32.lt_s
|
(i32.lt_s
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
(i32.const 2)
|
(i32.const 2)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $6)
|
(get_local $6)
|
||||||
(i32.gt_s
|
(i32.gt_s
|
||||||
(get_local $1)
|
(get_local $1)
|
||||||
@ -821,15 +812,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $6
|
(tee_local $6
|
||||||
(i32.ge_s
|
(i32.ge_s
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 48)
|
(i32.const 48)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.le_s
|
(i32.le_s
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 57)
|
(i32.const 57)
|
||||||
@ -847,15 +835,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $6
|
(tee_local $6
|
||||||
(i32.ge_s
|
(i32.ge_s
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 65)
|
(i32.const 65)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.le_s
|
(i32.le_s
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 90)
|
(i32.const 90)
|
||||||
@ -876,15 +861,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $6
|
(tee_local $6
|
||||||
(i32.ge_s
|
(i32.ge_s
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 97)
|
(i32.const 97)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.le_s
|
(i32.le_s
|
||||||
(get_local $4)
|
(get_local $4)
|
||||||
(i32.const 122)
|
(i32.const 122)
|
||||||
@ -1119,15 +1101,12 @@
|
|||||||
(if
|
(if
|
||||||
(i32.and
|
(i32.and
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $6
|
(tee_local $6
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
(i32.const 69)
|
(i32.const 69)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(get_local $6)
|
(get_local $6)
|
||||||
(i32.eq
|
(i32.eq
|
||||||
(get_local $3)
|
(get_local $3)
|
||||||
|
@ -1,327 +0,0 @@
|
|||||||
(module
|
|
||||||
(type $ii (func (param i32) (result i32)))
|
|
||||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
|
||||||
(type $iiv (func (param i32 i32)))
|
|
||||||
(type $iiiv (func (param i32 i32 i32)))
|
|
||||||
(type $iv (func (param i32)))
|
|
||||||
(type $v (func))
|
|
||||||
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
|
|
||||||
(memory $0 1)
|
|
||||||
(data (i32.const 4) "\07\00\00\00t\00l\00s\00f\00.\00t\00s")
|
|
||||||
(export "control$construct" (func $tlsf/control$construct))
|
|
||||||
(export "memory" (memory $0))
|
|
||||||
(start $start)
|
|
||||||
(func $tlsf/fls (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
|
||||||
(select
|
|
||||||
(i32.sub
|
|
||||||
(i32.const 31)
|
|
||||||
(i32.clz
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/ffs (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
|
||||||
(select
|
|
||||||
(i32.ctz
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/block$set_next_free (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/block$set_prev_free (; 4 ;) (type $iiv) (param $0 i32) (param $1 i32)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 12)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$set_fl_bitmap (; 5 ;) (type $iiv) (param $0 i32) (param $1 i32)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 16)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$set_sl_bitmap (; 6 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
|
||||||
(if
|
|
||||||
(i32.ge_u
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 23)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 162)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 20)
|
|
||||||
)
|
|
||||||
(i32.shl
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$set_block (; 7 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
|
||||||
(if
|
|
||||||
(i32.ge_u
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 23)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 173)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.ge_u
|
|
||||||
(get_local $2)
|
|
||||||
(i32.const 32)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 174)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 112)
|
|
||||||
)
|
|
||||||
(i32.shl
|
|
||||||
(i32.add
|
|
||||||
(i32.shl
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 5)
|
|
||||||
)
|
|
||||||
(get_local $2)
|
|
||||||
)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $3)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$construct (; 8 ;) (type $iv) (param $0 i32)
|
|
||||||
(local $1 i32)
|
|
||||||
(local $2 i32)
|
|
||||||
(call $tlsf/block$set_next_free
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(call $tlsf/block$set_prev_free
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(call $tlsf/control$set_fl_bitmap
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(loop $continue|0
|
|
||||||
(if
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 23)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $tlsf/control$set_sl_bitmap
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(set_local $2
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(loop $continue|1
|
|
||||||
(if
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $2)
|
|
||||||
(i32.const 32)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $tlsf/control$set_block
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $1)
|
|
||||||
(get_local $2)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(set_local $2
|
|
||||||
(i32.add
|
|
||||||
(get_local $2)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br $continue|1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(set_local $1
|
|
||||||
(i32.add
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br $continue|0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $start (; 9 ;) (type $v)
|
|
||||||
(if
|
|
||||||
(i32.ne
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 10)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 11)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.ne
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const -2147483640)
|
|
||||||
)
|
|
||||||
(i32.const 31)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 12)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.ne
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const 2147483647)
|
|
||||||
)
|
|
||||||
(i32.const 30)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 13)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.ne
|
|
||||||
(call $tlsf/ffs
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 20)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(call $tlsf/ffs
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 21)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.ne
|
|
||||||
(call $tlsf/ffs
|
|
||||||
(i32.const -2147483648)
|
|
||||||
)
|
|
||||||
(i32.const 31)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 22)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(call $tlsf/control$construct
|
|
||||||
(i32.load
|
|
||||||
(i32.const 4)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
@ -1,190 +0,0 @@
|
|||||||
// An unfinished implementation of tlsf in low-level AssemblyScript.
|
|
||||||
// Useful as a compiler test in this state, but nothing more.
|
|
||||||
// based upon: https://github.com/mattconte/tlsf/blob/master/tlsf.c (BSD)
|
|
||||||
|
|
||||||
/** Finds the index of the least bit set. */
|
|
||||||
function fls(word: u32): i32 {
|
|
||||||
return !word ? -1: 31 - clz<i32>(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(fls(0) == -1);
|
|
||||||
assert(fls(1) == 0);
|
|
||||||
assert(fls(0x80000008) == 31);
|
|
||||||
assert(fls(0x7FFFFFFF) == 30);
|
|
||||||
|
|
||||||
/** Finds the index of the first bit set. */
|
|
||||||
function ffs(word: u32): i32 {
|
|
||||||
return !word ? -1 : ctz<i32>(word);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(ffs(0) == -1);
|
|
||||||
assert(ffs(1) == 0);
|
|
||||||
assert(ffs(0x80000000) == 31);
|
|
||||||
|
|
||||||
// Align allocated blocks to 8 bytes so that any native type is aligned
|
|
||||||
|
|
||||||
const ALIGN_SIZE_LOG2: i32 = 3;
|
|
||||||
const ALIGN_SIZE: i32 = 1 << ALIGN_SIZE_LOG2;
|
|
||||||
|
|
||||||
assert(ALIGN_SIZE == 8);
|
|
||||||
|
|
||||||
// Define bitmap constants
|
|
||||||
|
|
||||||
const SL_INDEX_COUNT_LOG2: i32 = 5;
|
|
||||||
const FL_INDEX_MAX: i32 = 30;
|
|
||||||
const SL_INDEX_COUNT: i32 = 1 << SL_INDEX_COUNT_LOG2;
|
|
||||||
const FL_INDEX_SHIFT: i32 = SL_INDEX_COUNT_LOG2 + ALIGN_SIZE_LOG2;
|
|
||||||
const FL_INDEX_COUNT: i32 = FL_INDEX_MAX - FL_INDEX_SHIFT + 1;
|
|
||||||
const SMALL_BLOCK_SIZE: i32 = 1 << FL_INDEX_SHIFT;
|
|
||||||
|
|
||||||
// struct block_header_t {
|
|
||||||
// struct block_header_t* prev_phys_block;
|
|
||||||
// size_t tagged_size;
|
|
||||||
// struct block_header_t* next_free;
|
|
||||||
// struct block_header_t* prev_free;
|
|
||||||
// }
|
|
||||||
|
|
||||||
const BLOCK$PREV_PHYS_BLOCK_OFFSET: usize = 0;
|
|
||||||
const BLOCK$TAGGED_SIZE_OFFSET: usize = BLOCK$PREV_PHYS_BLOCK_OFFSET + sizeof<usize>();
|
|
||||||
const BLOCK$NEXT_FREE_OFFSET: usize = BLOCK$TAGGED_SIZE_OFFSET + sizeof<usize>();
|
|
||||||
const BLOCK$PREV_FREE_OFFSET: usize = BLOCK$NEXT_FREE_OFFSET + sizeof<usize>();
|
|
||||||
const BLOCK$SIZE: usize = BLOCK$PREV_FREE_OFFSET + sizeof<usize>();
|
|
||||||
|
|
||||||
const BLOCK_HEADER_FREE_BIT: u32 = 1 << 0;
|
|
||||||
const BLOCK_HEADER_PREV_FREE_BIT: u32 = 1 << 1;
|
|
||||||
const BLOCK_OVERHEAD: usize = sizeof<usize>();
|
|
||||||
const BLOCK_START_OFFSET: usize = BLOCK$TAGGED_SIZE_OFFSET + sizeof<usize>();
|
|
||||||
const BLOCK_SIZE_MIN: usize = BLOCK$SIZE - BLOCK_OVERHEAD;
|
|
||||||
const BLOCK_SIZE_MAX: usize = 1 << (<usize>FL_INDEX_MAX);
|
|
||||||
|
|
||||||
function block$get_prev_phys_block(block: usize): usize {
|
|
||||||
return load<usize>(block + BLOCK$PREV_PHYS_BLOCK_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$set_prev_phys_block(block: usize, value: usize): void {
|
|
||||||
store<usize>(block + BLOCK$PREV_PHYS_BLOCK_OFFSET, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$get_tagged_size(block: usize): usize {
|
|
||||||
return load<usize>(block + BLOCK$TAGGED_SIZE_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$set_tagged_size(block: usize, value: usize): void {
|
|
||||||
store<usize>(block + BLOCK$TAGGED_SIZE_OFFSET, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_size(block: usize): usize {
|
|
||||||
return block$get_tagged_size(block) & ~(BLOCK_HEADER_FREE_BIT | BLOCK_HEADER_PREV_FREE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_set_size(block: usize, value: usize): void {
|
|
||||||
store<usize>(block + BLOCK$TAGGED_SIZE_OFFSET, value | (block$get_tagged_size(block) & (BLOCK_HEADER_FREE_BIT | BLOCK_HEADER_PREV_FREE_BIT)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$get_next_free(block: usize): usize {
|
|
||||||
return load<usize>(block + BLOCK$NEXT_FREE_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$set_next_free(block: usize, value: usize): void {
|
|
||||||
store<usize>(block + BLOCK$NEXT_FREE_OFFSET, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$get_prev_free(block: usize): usize {
|
|
||||||
return load<usize>(block + BLOCK$PREV_FREE_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block$set_prev_free(block: usize, value: usize): void {
|
|
||||||
store<usize>(block + BLOCK$PREV_FREE_OFFSET, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_is_last(block: usize): bool {
|
|
||||||
return block_size(block) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_is_free(block: usize): bool {
|
|
||||||
return (block$get_tagged_size(block) & BLOCK_HEADER_FREE_BIT) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_set_free(block: usize): void {
|
|
||||||
store<usize>(block + BLOCK$TAGGED_SIZE_OFFSET, block$get_tagged_size(block) | BLOCK_HEADER_FREE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_set_used(block: usize): void {
|
|
||||||
store<usize>(block + BLOCK$TAGGED_SIZE_OFFSET, block$get_tagged_size(block) & ~BLOCK_HEADER_FREE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_is_prev_free(block: usize): bool {
|
|
||||||
return (block$get_tagged_size(block) & BLOCK_HEADER_PREV_FREE_BIT) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_set_prev_free(block: usize): void {
|
|
||||||
store<usize>(block + BLOCK$TAGGED_SIZE_OFFSET, block$get_tagged_size(block) | BLOCK_HEADER_PREV_FREE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_set_prev_used(block: usize): void {
|
|
||||||
store<usize>(block + BLOCK$TAGGED_SIZE_OFFSET, block$get_tagged_size(block) & ~BLOCK_HEADER_PREV_FREE_BIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_from_ptr(ptr: usize): usize {
|
|
||||||
return ptr - BLOCK_START_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
function block_to_ptr(block: usize): usize {
|
|
||||||
return block + BLOCK_START_OFFSET;
|
|
||||||
}
|
|
||||||
|
|
||||||
// struct control_t {
|
|
||||||
// block_header_t block_null;
|
|
||||||
// unsigned int fl_bitmap;
|
|
||||||
// unsigned int sl_bitmap[FL_INDEX_COUNT];
|
|
||||||
// block_header_t* blocks[FL_INDEX_COUNT][SL_INDEX_COUNT];
|
|
||||||
// }
|
|
||||||
|
|
||||||
const CONTROL$FL_BITMAP_OFFSET: usize = BLOCK$SIZE;
|
|
||||||
const CONTROL$SL_BITMAP_OFFSET: usize = CONTROL$FL_BITMAP_OFFSET + sizeof<u32>();
|
|
||||||
const CONTROL$BLOCKS_OFFSET: usize = CONTROL$SL_BITMAP_OFFSET + FL_INDEX_COUNT * sizeof<u32>();
|
|
||||||
const CONTROL$SIZE: usize = CONTROL$BLOCKS_OFFSET + FL_INDEX_COUNT * SL_INDEX_COUNT * sizeof<u32>();
|
|
||||||
|
|
||||||
function control$get_fl_bitmap(ptr: usize): u32 {
|
|
||||||
return load<u32>(ptr + CONTROL$FL_BITMAP_OFFSET);
|
|
||||||
}
|
|
||||||
|
|
||||||
function control$set_fl_bitmap(ptr: usize, value: u32): void {
|
|
||||||
store<u32>(ptr + CONTROL$FL_BITMAP_OFFSET, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function control$get_sl_bitmap(ptr: usize, flIndex: usize): u32 {
|
|
||||||
assert(flIndex < FL_INDEX_COUNT);
|
|
||||||
return load<u32>(ptr + CONTROL$SL_BITMAP_OFFSET + flIndex * sizeof<u32>());
|
|
||||||
}
|
|
||||||
|
|
||||||
function control$set_sl_bitmap(ptr: usize, flIndex: usize, value: u32): void {
|
|
||||||
assert(flIndex < FL_INDEX_COUNT);
|
|
||||||
store<u32>(ptr + CONTROL$SL_BITMAP_OFFSET + flIndex * sizeof<u32>(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function control$get_block(ptr: usize, flIndex: usize, slIndex: usize): usize {
|
|
||||||
assert(flIndex < FL_INDEX_COUNT);
|
|
||||||
assert(slIndex < SL_INDEX_COUNT);
|
|
||||||
return load<usize>(ptr + CONTROL$BLOCKS_OFFSET + (flIndex * SL_INDEX_COUNT + slIndex) * sizeof<usize>());
|
|
||||||
}
|
|
||||||
|
|
||||||
function control$set_block(ptr: usize, flIndex: usize, slIndex: usize, value: usize): void {
|
|
||||||
assert(flIndex < FL_INDEX_COUNT);
|
|
||||||
assert(slIndex < SL_INDEX_COUNT);
|
|
||||||
store<usize>(ptr + CONTROL$BLOCKS_OFFSET + (flIndex * SL_INDEX_COUNT + slIndex) * sizeof<usize>(), value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear structure and point all empty lists at the null block. */
|
|
||||||
export function control$construct(ptr: usize): void {
|
|
||||||
block$set_next_free(ptr, ptr);
|
|
||||||
block$set_prev_free(ptr, ptr);
|
|
||||||
control$set_fl_bitmap(ptr, 0);
|
|
||||||
for (var flIndex: usize = 0; flIndex < FL_INDEX_COUNT; ++flIndex) {
|
|
||||||
control$set_sl_bitmap(ptr, flIndex, 0);
|
|
||||||
for (var slIndex: usize = 0; slIndex < SL_INDEX_COUNT; ++slIndex)
|
|
||||||
control$set_block(ptr, flIndex, slIndex, ptr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
control$construct(load<usize>(sizeof<usize>())); // get HEAP_OFFSET and initialize there
|
|
@ -1,412 +0,0 @@
|
|||||||
(module
|
|
||||||
(type $ii (func (param i32) (result i32)))
|
|
||||||
(type $iiiiv (func (param i32 i32 i32 i32)))
|
|
||||||
(type $i (func (result i32)))
|
|
||||||
(type $iiv (func (param i32 i32)))
|
|
||||||
(type $iiiv (func (param i32 i32 i32)))
|
|
||||||
(type $iv (func (param i32)))
|
|
||||||
(type $v (func))
|
|
||||||
(import "env" "abort" (func $abort (param i32 i32 i32 i32)))
|
|
||||||
(global $tlsf/ALIGN_SIZE_LOG2 i32 (i32.const 3))
|
|
||||||
(global $tlsf/ALIGN_SIZE i32 (i32.const 8))
|
|
||||||
(global $tlsf/SL_INDEX_COUNT_LOG2 i32 (i32.const 5))
|
|
||||||
(global $tlsf/FL_INDEX_MAX i32 (i32.const 30))
|
|
||||||
(global $tlsf/SL_INDEX_COUNT i32 (i32.const 32))
|
|
||||||
(global $tlsf/FL_INDEX_SHIFT i32 (i32.const 8))
|
|
||||||
(global $tlsf/FL_INDEX_COUNT i32 (i32.const 23))
|
|
||||||
(global $tlsf/SMALL_BLOCK_SIZE i32 (i32.const 256))
|
|
||||||
(global $tlsf/BLOCK$PREV_PHYS_BLOCK_OFFSET i32 (i32.const 0))
|
|
||||||
(global $tlsf/BLOCK$TAGGED_SIZE_OFFSET i32 (i32.const 4))
|
|
||||||
(global $tlsf/BLOCK$NEXT_FREE_OFFSET i32 (i32.const 8))
|
|
||||||
(global $tlsf/BLOCK$PREV_FREE_OFFSET i32 (i32.const 12))
|
|
||||||
(global $tlsf/BLOCK$SIZE i32 (i32.const 16))
|
|
||||||
(global $tlsf/BLOCK_HEADER_FREE_BIT i32 (i32.const 1))
|
|
||||||
(global $tlsf/BLOCK_HEADER_PREV_FREE_BIT i32 (i32.const 2))
|
|
||||||
(global $tlsf/BLOCK_OVERHEAD i32 (i32.const 4))
|
|
||||||
(global $tlsf/BLOCK_START_OFFSET i32 (i32.const 8))
|
|
||||||
(global $tlsf/BLOCK_SIZE_MIN i32 (i32.const 12))
|
|
||||||
(global $tlsf/BLOCK_SIZE_MAX i32 (i32.const 1073741824))
|
|
||||||
(global $tlsf/CONTROL$FL_BITMAP_OFFSET i32 (i32.const 16))
|
|
||||||
(global $tlsf/CONTROL$SL_BITMAP_OFFSET i32 (i32.const 20))
|
|
||||||
(global $tlsf/CONTROL$BLOCKS_OFFSET i32 (i32.const 112))
|
|
||||||
(global $tlsf/CONTROL$SIZE i32 (i32.const 3056))
|
|
||||||
(global $HEAP_BASE i32 (i32.const 24))
|
|
||||||
(memory $0 1)
|
|
||||||
(data (i32.const 4) "\07\00\00\00t\00l\00s\00f\00.\00t\00s\00")
|
|
||||||
(export "control$construct" (func $tlsf/control$construct))
|
|
||||||
(export "memory" (memory $0))
|
|
||||||
(start $start)
|
|
||||||
(func $tlsf/fls (; 1 ;) (type $ii) (param $0 i32) (result i32)
|
|
||||||
(return
|
|
||||||
(if (result i32)
|
|
||||||
(i32.eqz
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
(i32.sub
|
|
||||||
(i32.const 31)
|
|
||||||
(i32.clz
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/ffs (; 2 ;) (type $ii) (param $0 i32) (result i32)
|
|
||||||
(return
|
|
||||||
(if (result i32)
|
|
||||||
(i32.eqz
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
(i32.ctz
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/block$set_next_free (; 3 ;) (type $iiv) (param $0 i32) (param $1 i32)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/block$set_prev_free (; 4 ;) (type $iiv) (param $0 i32) (param $1 i32)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 12)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$set_fl_bitmap (; 5 ;) (type $iiv) (param $0 i32) (param $1 i32)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 16)
|
|
||||||
)
|
|
||||||
(get_local $1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$set_sl_bitmap (; 6 ;) (type $iiiv) (param $0 i32) (param $1 i32) (param $2 i32)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 23)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 162)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 20)
|
|
||||||
)
|
|
||||||
(i32.mul
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 4)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $2)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$set_block (; 7 ;) (type $iiiiv) (param $0 i32) (param $1 i32) (param $2 i32) (param $3 i32)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 23)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 173)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $2)
|
|
||||||
(i32.const 32)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 174)
|
|
||||||
(i32.const 2)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(i32.store
|
|
||||||
(i32.add
|
|
||||||
(i32.add
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 112)
|
|
||||||
)
|
|
||||||
(i32.mul
|
|
||||||
(i32.add
|
|
||||||
(i32.mul
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 32)
|
|
||||||
)
|
|
||||||
(get_local $2)
|
|
||||||
)
|
|
||||||
(i32.const 4)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(get_local $3)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $tlsf/control$construct (; 8 ;) (type $iv) (param $0 i32)
|
|
||||||
(local $1 i32)
|
|
||||||
(local $2 i32)
|
|
||||||
(call $tlsf/block$set_next_free
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(call $tlsf/block$set_prev_free
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(call $tlsf/control$set_fl_bitmap
|
|
||||||
(get_local $0)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(block $break|0
|
|
||||||
(set_local $1
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(loop $continue|0
|
|
||||||
(if
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 23)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(block
|
|
||||||
(call $tlsf/control$set_sl_bitmap
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(block $break|1
|
|
||||||
(set_local $2
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(loop $continue|1
|
|
||||||
(if
|
|
||||||
(i32.lt_u
|
|
||||||
(get_local $2)
|
|
||||||
(i32.const 32)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $tlsf/control$set_block
|
|
||||||
(get_local $0)
|
|
||||||
(get_local $1)
|
|
||||||
(get_local $2)
|
|
||||||
(get_local $0)
|
|
||||||
)
|
|
||||||
(set_local $2
|
|
||||||
(i32.add
|
|
||||||
(get_local $2)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br $continue|1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(set_local $1
|
|
||||||
(i32.add
|
|
||||||
(get_local $1)
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(br $continue|0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(func $start (; 9 ;) (type $v)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 10)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 11)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const -2147483640)
|
|
||||||
)
|
|
||||||
(i32.const 31)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 12)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/fls
|
|
||||||
(i32.const 2147483647)
|
|
||||||
)
|
|
||||||
(i32.const 30)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 13)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/ffs
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(i32.const -1)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 20)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/ffs
|
|
||||||
(i32.const 1)
|
|
||||||
)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 21)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(call $tlsf/ffs
|
|
||||||
(i32.const -2147483648)
|
|
||||||
)
|
|
||||||
(i32.const 31)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 22)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(if
|
|
||||||
(i32.eqz
|
|
||||||
(i32.eq
|
|
||||||
(i32.const 8)
|
|
||||||
(i32.const 8)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(block
|
|
||||||
(call $abort
|
|
||||||
(i32.const 0)
|
|
||||||
(i32.const 4)
|
|
||||||
(i32.const 29)
|
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(unreachable)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
(call $tlsf/control$construct
|
|
||||||
(i32.load
|
|
||||||
(i32.const 4)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
@ -219,7 +219,6 @@
|
|||||||
(loop $continue|3
|
(loop $continue|3
|
||||||
(if
|
(if
|
||||||
(if (result i32)
|
(if (result i32)
|
||||||
(i32.ne
|
|
||||||
(tee_local $0
|
(tee_local $0
|
||||||
(block (result i32)
|
(block (result i32)
|
||||||
(set_local $0
|
(set_local $0
|
||||||
@ -234,8 +233,6 @@
|
|||||||
(get_local $0)
|
(get_local $0)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
(i32.const 0)
|
|
||||||
)
|
|
||||||
(block (result i32)
|
(block (result i32)
|
||||||
(set_global $while/m
|
(set_global $while/m
|
||||||
(i32.add
|
(i32.add
|
||||||
|
Reference in New Issue
Block a user