mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 07:02:13 +00:00
Skip inlining and emit a warning when trying to inline a function into itself
This commit is contained in:
parent
3b0fd9aac2
commit
4b8500355a
2
dist/asc.js
vendored
2
dist/asc.js
vendored
File diff suppressed because one or more lines are too long
2
dist/asc.js.map
vendored
2
dist/asc.js.map
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
@ -54,7 +54,6 @@ import {
|
||||
import {
|
||||
ReportMode
|
||||
} from "./resolver";
|
||||
import { CommonFlags } from "./common";
|
||||
|
||||
/** Compiles a call to a built-in function. */
|
||||
export function compileCall(
|
||||
@ -73,7 +72,7 @@ export function compileCall(
|
||||
ret: ExpressionRef;
|
||||
|
||||
// NOTE that some implementations below make use of the select expression where straight-forward.
|
||||
// whether worth or not should probably be tested once/ it's known if/how embedders handle it.
|
||||
// whether worth or not should probably be tested once it's known if/how embedders handle it.
|
||||
// search: createSelect
|
||||
|
||||
switch (prototype.internalName) {
|
||||
|
@ -265,6 +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 enum in compilation. */
|
||||
currentEnum: Enum | null = null;
|
||||
/** Current type in compilation. */
|
||||
@ -5257,7 +5259,21 @@ export class Compiler extends DiagnosticEmitter {
|
||||
// Inline if explicitly requested
|
||||
if (inline) {
|
||||
assert(!instance.is(CommonFlags.TRAMPOLINE)); // doesn't make sense
|
||||
return this.compileCallInlineUnchecked(instance, argumentExpressions, reportNode, thisArg);
|
||||
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
|
||||
);
|
||||
}
|
||||
} else {
|
||||
this.currentInlineFunction = instance;
|
||||
let ret = this.compileCallInlineUnchecked(instance, argumentExpressions, reportNode, thisArg);
|
||||
this.currentInlineFunction = null;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise compile to just a call
|
||||
|
@ -26,6 +26,7 @@ export enum DiagnosticCode {
|
||||
An_allocator_must_be_declared_to_allocate_memory_Try_importing_allocator_arena_or_allocator_tlsf = 214,
|
||||
Optional_parameter_must_have_an_initializer = 215,
|
||||
Constructor_of_class_0_must_not_require_any_arguments = 216,
|
||||
Function_0_cannot_be_inlined_into_itself = 217,
|
||||
Unterminated_string_literal = 1002,
|
||||
Identifier_expected = 1003,
|
||||
_0_expected = 1005,
|
||||
@ -142,6 +143,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
||||
case 214: return "An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.";
|
||||
case 215: return "Optional parameter must have an initializer.";
|
||||
case 216: return "Constructor of class '{0}' must not require any arguments.";
|
||||
case 217: return "Function '{0}' cannot be inlined into itself.";
|
||||
case 1002: return "Unterminated string literal.";
|
||||
case 1003: return "Identifier expected.";
|
||||
case 1005: return "'{0}' expected.";
|
||||
|
@ -18,6 +18,7 @@
|
||||
"An allocator must be declared to allocate memory. Try importing allocator/arena or allocator/tlsf.": 214,
|
||||
"Optional parameter must have an initializer.": 215,
|
||||
"Constructor of class '{0}' must not require any arguments.": 216,
|
||||
"Function '{0}' cannot be inlined into itself.": 217,
|
||||
|
||||
"Unterminated string literal.": 1002,
|
||||
"Identifier expected.": 1003,
|
||||
|
4
std/assembly/index.d.ts
vendored
4
std/assembly/index.d.ts
vendored
@ -304,9 +304,9 @@ declare function isReference<T>(value?: any): value is object | string;
|
||||
declare function isString<T>(value?: any): value is string | String;
|
||||
/** Tests if the specified type *or* expression can be used as an array. Compiles to a constant. */
|
||||
declare function isArray<T>(value?: any): value is Array<any>;
|
||||
/** Tests if the specified expression resolves to a defined element. */
|
||||
/** Tests if the specified expression resolves to a defined element. Compiles to a constant. */
|
||||
declare function isDefined(expression: any): bool;
|
||||
/** Tests if the specified expression evaluates to a constant value. */
|
||||
/** Tests if the specified expression evaluates to a constant value. Compiles to a constant. */
|
||||
declare function isConstant(expression: any): bool;
|
||||
/** Traps if the specified value is not true-ish, otherwise returns the (non-nullable) value. */
|
||||
declare function assert<T>(isTrueish: T, message?: string): T & object; // any better way to model `: T != null`?
|
||||
|
9
tests/compiler/inlining-recursive.optimized.wat
Normal file
9
tests/compiler/inlining-recursive.optimized.wat
Normal file
@ -0,0 +1,9 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(memory $0 0)
|
||||
(export "foo" (func $inlining-recursive/foo))
|
||||
(export "memory" (memory $0))
|
||||
(func $inlining-recursive/foo (; 0 ;) (type $v)
|
||||
(call $inlining-recursive/foo)
|
||||
)
|
||||
)
|
4
tests/compiler/inlining-recursive.ts
Normal file
4
tests/compiler/inlining-recursive.ts
Normal file
@ -0,0 +1,4 @@
|
||||
@inline
|
||||
export function foo(): void {
|
||||
foo();
|
||||
}
|
12
tests/compiler/inlining-recursive.untouched.wat
Normal file
12
tests/compiler/inlining-recursive.untouched.wat
Normal file
@ -0,0 +1,12 @@
|
||||
(module
|
||||
(type $v (func))
|
||||
(global $HEAP_BASE i32 (i32.const 8))
|
||||
(memory $0 0)
|
||||
(export "foo" (func $inlining-recursive/foo))
|
||||
(export "memory" (memory $0))
|
||||
(func $inlining-recursive/foo (; 0 ;) (type $v)
|
||||
(block $inlining-recursive/foo|inlined.0
|
||||
(call $inlining-recursive/foo)
|
||||
)
|
||||
)
|
||||
)
|
Loading…
x
Reference in New Issue
Block a user