Skip to content

Rework inlining logic #463

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Feb 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 69 additions & 61 deletions src/builtins.ts

Large diffs are not rendered by default.

915 changes: 441 additions & 474 deletions src/compiler.ts

Large diffs are not rendered by default.

494 changes: 243 additions & 251 deletions src/program.ts

Large diffs are not rendered by default.

65 changes: 35 additions & 30 deletions src/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ import {
DecoratorFlags,
FieldPrototype,
Field,
Global
Global,
Flow
} from "./program";

import {
Expand Down Expand Up @@ -355,22 +356,26 @@ export class Resolver extends DiagnosticEmitter {
/** Resolves an identifier to the element it refers to. */
resolveIdentifier(
identifier: IdentifierExpression,
flow: Flow | null,
context: Element | null,
reportMode: ReportMode = ReportMode.REPORT
): Element | null {
var name = identifier.text;
var element: Element | null;

if (flow) {
let local = flow.lookupLocal(name);
if (local) {
this.currentThisExpression = null;
this.currentElementExpression = null;
return local;
}
}

if (context) {

switch (context.kind) {
case ElementKind.FUNCTION: { // search locals, use prototype
element = (<Function>context).flow.getScopedLocal(name);
if (element) {
this.currentThisExpression = null;
this.currentElementExpression = null;
return element;
}
case ElementKind.FUNCTION: { // use prototype
context = (<Function>context).prototype.parent;
break;
}
Expand Down Expand Up @@ -433,13 +438,13 @@ export class Resolver extends DiagnosticEmitter {
/** Resolves a property access to the element it refers to. */
resolvePropertyAccess(
propertyAccess: PropertyAccessExpression,
contextualFunction: Function,
flow: Flow,
contextualType: Type,
reportMode: ReportMode = ReportMode.REPORT
): Element | null {
// start by resolving the lhs target (expression before the last dot)
var targetExpression = propertyAccess.expression;
var target = this.resolveExpression(targetExpression, contextualFunction, contextualType, reportMode); // reports
var target = this.resolveExpression(targetExpression, flow, contextualType, reportMode); // reports
if (!target) return null;

// at this point we know exactly what the target is, so look up the element within
Expand Down Expand Up @@ -565,12 +570,12 @@ export class Resolver extends DiagnosticEmitter {

resolveElementAccess(
elementAccess: ElementAccessExpression,
contextualFunction: Function,
flow: Flow,
contextualType: Type,
reportMode: ReportMode = ReportMode.REPORT
): Element | null {
var targetExpression = elementAccess.expression;
var target = this.resolveExpression(targetExpression, contextualFunction, contextualType, reportMode);
var target = this.resolveExpression(targetExpression, flow, contextualType, reportMode);
if (!target) return null;
switch (target.kind) {
case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(<Global>target, reportMode)) return null;
Expand Down Expand Up @@ -685,7 +690,7 @@ export class Resolver extends DiagnosticEmitter {

resolveExpression(
expression: Expression,
contextualFunction: Function,
flow: Flow,
contextualType: Type = Type.void,
reportMode: ReportMode = ReportMode.REPORT
): Element | null {
Expand All @@ -697,14 +702,14 @@ export class Resolver extends DiagnosticEmitter {
if ((<AssertionExpression>expression).assertionKind == AssertionKind.NONNULL) {
return this.resolveExpression(
(<AssertionExpression>expression).expression,
contextualFunction,
flow,
contextualType,
reportMode
);
}
let type = this.resolveType(
assert((<AssertionExpression>expression).toType),
contextualFunction.flow.contextualTypeArguments,
flow.contextualTypeArguments,
reportMode
);
if (!type) return null;
Expand Down Expand Up @@ -733,7 +738,7 @@ export class Resolver extends DiagnosticEmitter {
}
return this.resolveExpression(
operand,
contextualFunction,
flow,
contextualType,
reportMode
);
Expand All @@ -743,7 +748,7 @@ export class Resolver extends DiagnosticEmitter {
case Token.MINUS_MINUS: {
return this.resolveExpression(
(<UnaryPrefixExpression>expression).operand,
contextualFunction,
flow,
contextualType,
reportMode
);
Expand All @@ -754,7 +759,7 @@ export class Resolver extends DiagnosticEmitter {
case Token.TILDE: {
let resolvedOperand = this.resolveExpression(
(<UnaryPrefixExpression>expression).operand,
contextualFunction,
flow,
contextualType,
reportMode
);
Expand All @@ -772,7 +777,7 @@ export class Resolver extends DiagnosticEmitter {
case Token.MINUS_MINUS: {
return this.resolveExpression(
(<UnaryPostfixExpression>expression).operand,
contextualFunction,
flow,
contextualType,
reportMode
);
Expand All @@ -788,15 +793,15 @@ export class Resolver extends DiagnosticEmitter {
throw new Error("not implemented");
}
case NodeKind.THIS: { // -> Class / ClassPrototype
if (contextualFunction.flow.is(FlowFlags.INLINE_CONTEXT)) {
let explicitLocal = contextualFunction.flow.getScopedLocal("this");
if (flow.is(FlowFlags.INLINE_CONTEXT)) {
let explicitLocal = flow.lookupLocal("this");
if (explicitLocal) {
this.currentThisExpression = null;
this.currentElementExpression = null;
return explicitLocal;
}
}
let parent = contextualFunction.parent;
let parent = flow.parentFunction.parent;
if (parent) {
this.currentThisExpression = null;
this.currentElementExpression = null;
Expand All @@ -811,15 +816,15 @@ export class Resolver extends DiagnosticEmitter {
return null;
}
case NodeKind.SUPER: { // -> Class
if (contextualFunction.flow.is(FlowFlags.INLINE_CONTEXT)) {
let explicitLocal = contextualFunction.flow.getScopedLocal("super");
if (flow.is(FlowFlags.INLINE_CONTEXT)) {
let explicitLocal = flow.lookupLocal("super");
if (explicitLocal) {
this.currentThisExpression = null;
this.currentElementExpression = null;
return explicitLocal;
}
}
let parent = contextualFunction.parent;
let parent = flow.actualFunction.parent;
if (parent && parent.kind == ElementKind.CLASS && (parent = (<Class>parent).base)) {
this.currentThisExpression = null;
this.currentElementExpression = null;
Expand All @@ -834,7 +839,7 @@ export class Resolver extends DiagnosticEmitter {
return null;
}
case NodeKind.IDENTIFIER: {
return this.resolveIdentifier(<IdentifierExpression>expression, contextualFunction, reportMode);
return this.resolveIdentifier(<IdentifierExpression>expression, flow, flow.actualFunction, reportMode);
}
case NodeKind.LITERAL: {
switch ((<LiteralExpression>expression).literalKind) {
Expand Down Expand Up @@ -871,28 +876,28 @@ export class Resolver extends DiagnosticEmitter {
case NodeKind.PROPERTYACCESS: {
return this.resolvePropertyAccess(
<PropertyAccessExpression>expression,
contextualFunction,
flow,
contextualType,
reportMode
);
}
case NodeKind.ELEMENTACCESS: {
return this.resolveElementAccess(
<ElementAccessExpression>expression,
contextualFunction,
flow,
contextualType,
reportMode
);
}
case NodeKind.CALL: {
let targetExpression = (<CallExpression>expression).expression;
let target = this.resolveExpression(targetExpression, contextualFunction, contextualType, reportMode);
let target = this.resolveExpression(targetExpression, flow, contextualType, reportMode);
if (!target) return null;
if (target.kind == ElementKind.FUNCTION_PROTOTYPE) {
let instance = this.resolveFunctionInclTypeArguments(
<FunctionPrototype>target,
(<CallExpression>expression).typeArguments,
makeMap<string,Type>(contextualFunction.flow.contextualTypeArguments),
makeMap<string,Type>(flow.contextualTypeArguments),
expression,
reportMode
);
Expand Down
8 changes: 6 additions & 2 deletions tests/compiler/binary.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -1249,7 +1249,9 @@
local.get $8
else
local.get $1
local.get $1
local.set $9
local.get $9
local.get $9
f32.ne
end
i32.const 0
Expand Down Expand Up @@ -2531,7 +2533,9 @@
local.get $8
else
local.get $1
local.get $1
local.set $9
local.get $9
local.get $9
f64.ne
end
i32.const 0
Expand Down
4 changes: 3 additions & 1 deletion tests/compiler/inlining-recursive.untouched.wat
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@
call $inlining-recursive/bar
)
(func $inlining-recursive/bar (; 2 ;) (type $v)
call $inlining-recursive/baz
block $inlining-recursive/bar|inlined.0
call $inlining-recursive/baz
end
)
(func $null (; 3 ;) (type $v)
)
Expand Down
Loading