Also handle indirect recursive inlining

This commit is contained in:
dcodeIO 2018-07-14 18:21:11 +02:00
parent 4b8500355a
commit 1928f46cb9
6 changed files with 47 additions and 17 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -265,8 +265,8 @@ export class Compiler extends DiagnosticEmitter {
currentFunction: Function;
/** Current outer function in compilation, if compiling a function expression. */
currentOuterFunction: Function | null = null;
/** Current inline function in compilation. */
currentInlineFunction: Function | null = null;
/** Current inline functions stack. */
currentInlineFunctions: Function[] = [];
/** Current enum in compilation. */
currentEnum: Enum | null = null;
/** Current type in compilation. */
@ -5259,20 +5259,16 @@ export class Compiler extends DiagnosticEmitter {
// Inline if explicitly requested
if (inline) {
assert(!instance.is(CommonFlags.TRAMPOLINE)); // doesn't make sense
if (instance === this.currentInlineFunction) {
// skip inlining when trying to inline a function into itself and print a warning when
// instead compiling the function the normal way.
if (instance === this.currentFunction) {
this.warning(
DiagnosticCode.Function_0_cannot_be_inlined_into_itself,
reportNode.range, instance.internalName
);
}
if (this.currentInlineFunctions.includes(instance)) {
this.warning(
DiagnosticCode.Function_0_cannot_be_inlined_into_itself,
reportNode.range, instance.internalName
);
} else {
this.currentInlineFunction = instance;
let ret = this.compileCallInlineUnchecked(instance, argumentExpressions, reportNode, thisArg);
this.currentInlineFunction = null;
return ret;
this.currentInlineFunctions.push(instance);
let expr = this.compileCallInlineUnchecked(instance, argumentExpressions, reportNode, thisArg);
this.currentInlineFunctions.pop();
return expr;
}
}

View File

@ -2,8 +2,16 @@
(type $v (func))
(memory $0 0)
(export "foo" (func $inlining-recursive/foo))
(export "baz" (func $inlining-recursive/baz))
(export "bar" (func $inlining-recursive/bar))
(export "memory" (memory $0))
(func $inlining-recursive/foo (; 0 ;) (type $v)
(call $inlining-recursive/foo)
)
(func $inlining-recursive/baz (; 1 ;) (type $v)
(call $inlining-recursive/bar)
)
(func $inlining-recursive/bar (; 2 ;) (type $v)
(call $inlining-recursive/baz)
)
)

View File

@ -1,4 +1,18 @@
// direct
@inline
export function foo(): void {
foo();
}
// indirect
@inline
export function bar(): void {
baz();
}
@inline
export function baz(): void {
bar();
}

View File

@ -3,10 +3,22 @@
(global $HEAP_BASE i32 (i32.const 8))
(memory $0 0)
(export "foo" (func $inlining-recursive/foo))
(export "baz" (func $inlining-recursive/baz))
(export "bar" (func $inlining-recursive/bar))
(export "memory" (memory $0))
(func $inlining-recursive/foo (; 0 ;) (type $v)
(block $inlining-recursive/foo|inlined.0
(call $inlining-recursive/foo)
)
)
(func $inlining-recursive/baz (; 1 ;) (type $v)
(call $inlining-recursive/bar)
)
(func $inlining-recursive/bar (; 2 ;) (type $v)
(block $inlining-recursive/baz|inlined.0
(block $inlining-recursive/bar|inlined.0
(call $inlining-recursive/baz)
)
)
)
)