Properly inline getters; Simplify blocks when last statement returns

This commit is contained in:
dcodeIO
2018-06-22 15:26:59 +02:00
parent 525795b354
commit 7a8995b18b
75 changed files with 5090 additions and 6836 deletions

View File

@ -1413,6 +1413,20 @@ export class UnaryPrefixExpression extends UnaryExpression {
// statements
export function isLastStatement(statement: Statement): bool {
var parent = assert(statement.parent);
if (parent.kind == NodeKind.BLOCK) {
let statements = (<BlockStatement>parent).statements;
if (statements[statements.length - 1] === statement) {
switch (assert(parent.parent).kind) {
case NodeKind.FUNCTIONDECLARATION:
case NodeKind.METHODDECLARATION: return true;
}
}
}
return false;
}
/** Base class of all statement nodes. */
export abstract class Statement extends Node { }

View File

@ -128,7 +128,8 @@ import {
UnaryPrefixExpression,
FieldDeclaration,
nodeIsConstantValue
nodeIsConstantValue,
isLastStatement
} from "./ast";
import {
@ -1486,11 +1487,17 @@ export class Compiler extends DiagnosticEmitter {
this.currentFunction.flow = blockFlow;
var stmts = this.compileStatements(statements);
var lastType: NativeType;
var stmt = stmts.length == 0
? this.module.createNop()
: stmts.length == 1
? stmts[0]
: this.module.createBlock(null, stmts, NativeType.None);
: this.module.createBlock(null, stmts,
// if the last expression is a value, annotate the block's return value
(lastType = getExpressionType(stmts[stmts.length - 1])) == NativeType.None
? NativeType.None
: lastType
);
// Switch back to the parent flow
var parentFlow = blockFlow.leaveBranchOrScope();
@ -1776,6 +1783,9 @@ export class Compiler extends DiagnosticEmitter {
if (!flow.canOverflow(expr, returnType)) flow.set(FlowFlags.RETURNS_WRAPPED);
}
// If the last statement anyway, make it the block's return value
if (isLastStatement(statement)) return expr ? expr : module.createNop();
// When inlining, break to the end of the inlined function's block (no need to wrap)
return flow.is(FlowFlags.INLINE_CONTEXT)
? module.createBreak(assert(flow.returnLabel), 0, expr)
@ -6440,6 +6450,7 @@ export class Compiler extends DiagnosticEmitter {
)) {
return module.createUnreachable();
}
let inline = (instance.decoratorFlags & DecoratorFlags.INLINE) != 0;
if (instance.is(CommonFlags.INSTANCE)) {
let parent = assert(instance.parent);
assert(parent.kind == ElementKind.CLASS);
@ -6450,10 +6461,10 @@ export class Compiler extends DiagnosticEmitter {
WrapMode.NONE
);
this.currentType = signature.returnType;
return this.compileCallDirect(instance, [], propertyAccess, thisExpr);
return this.compileCallDirect(instance, [], propertyAccess, thisExpr, inline);
} else {
this.currentType = signature.returnType;
return this.compileCallDirect(instance, [], propertyAccess);
return this.compileCallDirect(instance, [], propertyAccess, 0, inline);
}
} else {
this.error(