Skip to content

Commit 831054d

Browse files
authored
Rework inlining logic (AssemblyScript#463)
1 parent 01cade1 commit 831054d

40 files changed

+13990
-9165
lines changed

src/builtins.ts

Lines changed: 69 additions & 61 deletions
Large diffs are not rendered by default.

src/compiler.ts

Lines changed: 441 additions & 474 deletions
Large diffs are not rendered by default.

src/program.ts

Lines changed: 243 additions & 251 deletions
Large diffs are not rendered by default.

src/resolver.ts

Lines changed: 35 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@ import {
2525
DecoratorFlags,
2626
FieldPrototype,
2727
Field,
28-
Global
28+
Global,
29+
Flow
2930
} from "./program";
3031

3132
import {
@@ -355,22 +356,26 @@ export class Resolver extends DiagnosticEmitter {
355356
/** Resolves an identifier to the element it refers to. */
356357
resolveIdentifier(
357358
identifier: IdentifierExpression,
359+
flow: Flow | null,
358360
context: Element | null,
359361
reportMode: ReportMode = ReportMode.REPORT
360362
): Element | null {
361363
var name = identifier.text;
362364
var element: Element | null;
363365

366+
if (flow) {
367+
let local = flow.lookupLocal(name);
368+
if (local) {
369+
this.currentThisExpression = null;
370+
this.currentElementExpression = null;
371+
return local;
372+
}
373+
}
374+
364375
if (context) {
365376

366377
switch (context.kind) {
367-
case ElementKind.FUNCTION: { // search locals, use prototype
368-
element = (<Function>context).flow.getScopedLocal(name);
369-
if (element) {
370-
this.currentThisExpression = null;
371-
this.currentElementExpression = null;
372-
return element;
373-
}
378+
case ElementKind.FUNCTION: { // use prototype
374379
context = (<Function>context).prototype.parent;
375380
break;
376381
}
@@ -433,13 +438,13 @@ export class Resolver extends DiagnosticEmitter {
433438
/** Resolves a property access to the element it refers to. */
434439
resolvePropertyAccess(
435440
propertyAccess: PropertyAccessExpression,
436-
contextualFunction: Function,
441+
flow: Flow,
437442
contextualType: Type,
438443
reportMode: ReportMode = ReportMode.REPORT
439444
): Element | null {
440445
// start by resolving the lhs target (expression before the last dot)
441446
var targetExpression = propertyAccess.expression;
442-
var target = this.resolveExpression(targetExpression, contextualFunction, contextualType, reportMode); // reports
447+
var target = this.resolveExpression(targetExpression, flow, contextualType, reportMode); // reports
443448
if (!target) return null;
444449

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

566571
resolveElementAccess(
567572
elementAccess: ElementAccessExpression,
568-
contextualFunction: Function,
573+
flow: Flow,
569574
contextualType: Type,
570575
reportMode: ReportMode = ReportMode.REPORT
571576
): Element | null {
572577
var targetExpression = elementAccess.expression;
573-
var target = this.resolveExpression(targetExpression, contextualFunction, contextualType, reportMode);
578+
var target = this.resolveExpression(targetExpression, flow, contextualType, reportMode);
574579
if (!target) return null;
575580
switch (target.kind) {
576581
case ElementKind.GLOBAL: if (!this.ensureResolvedLazyGlobal(<Global>target, reportMode)) return null;
@@ -685,7 +690,7 @@ export class Resolver extends DiagnosticEmitter {
685690

686691
resolveExpression(
687692
expression: Expression,
688-
contextualFunction: Function,
693+
flow: Flow,
689694
contextualType: Type = Type.void,
690695
reportMode: ReportMode = ReportMode.REPORT
691696
): Element | null {
@@ -697,14 +702,14 @@ export class Resolver extends DiagnosticEmitter {
697702
if ((<AssertionExpression>expression).assertionKind == AssertionKind.NONNULL) {
698703
return this.resolveExpression(
699704
(<AssertionExpression>expression).expression,
700-
contextualFunction,
705+
flow,
701706
contextualType,
702707
reportMode
703708
);
704709
}
705710
let type = this.resolveType(
706711
assert((<AssertionExpression>expression).toType),
707-
contextualFunction.flow.contextualTypeArguments,
712+
flow.contextualTypeArguments,
708713
reportMode
709714
);
710715
if (!type) return null;
@@ -733,7 +738,7 @@ export class Resolver extends DiagnosticEmitter {
733738
}
734739
return this.resolveExpression(
735740
operand,
736-
contextualFunction,
741+
flow,
737742
contextualType,
738743
reportMode
739744
);
@@ -743,7 +748,7 @@ export class Resolver extends DiagnosticEmitter {
743748
case Token.MINUS_MINUS: {
744749
return this.resolveExpression(
745750
(<UnaryPrefixExpression>expression).operand,
746-
contextualFunction,
751+
flow,
747752
contextualType,
748753
reportMode
749754
);
@@ -754,7 +759,7 @@ export class Resolver extends DiagnosticEmitter {
754759
case Token.TILDE: {
755760
let resolvedOperand = this.resolveExpression(
756761
(<UnaryPrefixExpression>expression).operand,
757-
contextualFunction,
762+
flow,
758763
contextualType,
759764
reportMode
760765
);
@@ -772,7 +777,7 @@ export class Resolver extends DiagnosticEmitter {
772777
case Token.MINUS_MINUS: {
773778
return this.resolveExpression(
774779
(<UnaryPostfixExpression>expression).operand,
775-
contextualFunction,
780+
flow,
776781
contextualType,
777782
reportMode
778783
);
@@ -788,15 +793,15 @@ export class Resolver extends DiagnosticEmitter {
788793
throw new Error("not implemented");
789794
}
790795
case NodeKind.THIS: { // -> Class / ClassPrototype
791-
if (contextualFunction.flow.is(FlowFlags.INLINE_CONTEXT)) {
792-
let explicitLocal = contextualFunction.flow.getScopedLocal("this");
796+
if (flow.is(FlowFlags.INLINE_CONTEXT)) {
797+
let explicitLocal = flow.lookupLocal("this");
793798
if (explicitLocal) {
794799
this.currentThisExpression = null;
795800
this.currentElementExpression = null;
796801
return explicitLocal;
797802
}
798803
}
799-
let parent = contextualFunction.parent;
804+
let parent = flow.parentFunction.parent;
800805
if (parent) {
801806
this.currentThisExpression = null;
802807
this.currentElementExpression = null;
@@ -811,15 +816,15 @@ export class Resolver extends DiagnosticEmitter {
811816
return null;
812817
}
813818
case NodeKind.SUPER: { // -> Class
814-
if (contextualFunction.flow.is(FlowFlags.INLINE_CONTEXT)) {
815-
let explicitLocal = contextualFunction.flow.getScopedLocal("super");
819+
if (flow.is(FlowFlags.INLINE_CONTEXT)) {
820+
let explicitLocal = flow.lookupLocal("super");
816821
if (explicitLocal) {
817822
this.currentThisExpression = null;
818823
this.currentElementExpression = null;
819824
return explicitLocal;
820825
}
821826
}
822-
let parent = contextualFunction.parent;
827+
let parent = flow.actualFunction.parent;
823828
if (parent && parent.kind == ElementKind.CLASS && (parent = (<Class>parent).base)) {
824829
this.currentThisExpression = null;
825830
this.currentElementExpression = null;
@@ -834,7 +839,7 @@ export class Resolver extends DiagnosticEmitter {
834839
return null;
835840
}
836841
case NodeKind.IDENTIFIER: {
837-
return this.resolveIdentifier(<IdentifierExpression>expression, contextualFunction, reportMode);
842+
return this.resolveIdentifier(<IdentifierExpression>expression, flow, flow.actualFunction, reportMode);
838843
}
839844
case NodeKind.LITERAL: {
840845
switch ((<LiteralExpression>expression).literalKind) {
@@ -871,28 +876,28 @@ export class Resolver extends DiagnosticEmitter {
871876
case NodeKind.PROPERTYACCESS: {
872877
return this.resolvePropertyAccess(
873878
<PropertyAccessExpression>expression,
874-
contextualFunction,
879+
flow,
875880
contextualType,
876881
reportMode
877882
);
878883
}
879884
case NodeKind.ELEMENTACCESS: {
880885
return this.resolveElementAccess(
881886
<ElementAccessExpression>expression,
882-
contextualFunction,
887+
flow,
883888
contextualType,
884889
reportMode
885890
);
886891
}
887892
case NodeKind.CALL: {
888893
let targetExpression = (<CallExpression>expression).expression;
889-
let target = this.resolveExpression(targetExpression, contextualFunction, contextualType, reportMode);
894+
let target = this.resolveExpression(targetExpression, flow, contextualType, reportMode);
890895
if (!target) return null;
891896
if (target.kind == ElementKind.FUNCTION_PROTOTYPE) {
892897
let instance = this.resolveFunctionInclTypeArguments(
893898
<FunctionPrototype>target,
894899
(<CallExpression>expression).typeArguments,
895-
makeMap<string,Type>(contextualFunction.flow.contextualTypeArguments),
900+
makeMap<string,Type>(flow.contextualTypeArguments),
896901
expression,
897902
reportMode
898903
);

tests/compiler/binary.untouched.wat

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1249,7 +1249,9 @@
12491249
local.get $8
12501250
else
12511251
local.get $1
1252-
local.get $1
1252+
local.set $9
1253+
local.get $9
1254+
local.get $9
12531255
f32.ne
12541256
end
12551257
i32.const 0
@@ -2531,7 +2533,9 @@
25312533
local.get $8
25322534
else
25332535
local.get $1
2534-
local.get $1
2536+
local.set $9
2537+
local.get $9
2538+
local.get $9
25352539
f64.ne
25362540
end
25372541
i32.const 0

tests/compiler/inlining-recursive.untouched.wat

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616
call $inlining-recursive/bar
1717
)
1818
(func $inlining-recursive/bar (; 2 ;) (type $v)
19-
call $inlining-recursive/baz
19+
block $inlining-recursive/bar|inlined.0
20+
call $inlining-recursive/baz
21+
end
2022
)
2123
(func $null (; 3 ;) (type $v)
2224
)

0 commit comments

Comments
 (0)