Fix invalid flow switch when inlining optional arguments into a call, see #632

This commit is contained in:
dcode 2019-06-05 19:29:44 +02:00
parent eaea26b7ae
commit 72e519885d
2 changed files with 24 additions and 20 deletions

View File

@ -101,7 +101,7 @@ Besides demangling classes exported from your entry file to a handy object struc
``` ```
* **__start**(): `void`<br /> * **__start**(): `void`<br />
Explicit start function if the `--explicit-start` option is used. Must be called before any other exports if present. Explicit start function if the `--explicitStart` option is used. Must be called before any other exports if present.
* **__allocString**(str: `string`): `number`<br /> * **__allocString**(str: `string`): `number`<br />
Allocates a new string in the module's memory and returns a reference (pointer) to it. Allocates a new string in the module's memory and returns a reference (pointer) to it.

View File

@ -2660,11 +2660,7 @@ export class Compiler extends DiagnosticEmitter {
// === Expressions ============================================================================== // === Expressions ==============================================================================
/** /** Compiles the value of an inlined constant element. */
* Compiles the value of an inlined constant element.
* @param retainType If true, the annotated type of the constant is retained. Otherwise, the value
* is precomputed according to context.
*/
compileInlineConstant( compileInlineConstant(
element: VariableLikeElement, element: VariableLikeElement,
contextualType: Type, contextualType: Type,
@ -6717,27 +6713,35 @@ export class Compiler extends DiagnosticEmitter {
for (let i = numArguments; i < maxArguments; ++i) { for (let i = numArguments; i < maxArguments; ++i) {
let initializer = parameterNodes[i].initializer; let initializer = parameterNodes[i].initializer;
if (initializer) { if (initializer) {
let resolved: Element | null; if (nodeIsConstantValue(initializer.kind)) {
if (
nodeIsConstantValue(initializer.kind) ||
(
(resolved = this.resolver.resolveExpression(initializer, instance.flow, parameterTypes[i])) &&
(
resolved.kind == ElementKind.GLOBAL
// resolved.kind == ElementKind.FUNCTION_TARGET
)
)
) { // inline into the call
let previousFlow = this.currentFlow;
this.currentFlow = instance.flow;
operands.push(this.compileExpression( operands.push(this.compileExpression(
<Expression>parameterNodes[i].initializer, <Expression>parameterNodes[i].initializer,
parameterTypes[i], parameterTypes[i],
ContextualFlags.IMPLICIT ContextualFlags.IMPLICIT
)); ));
this.currentFlow = previousFlow;
continue; continue;
} }
let resolved = this.resolver.resolveExpression(initializer, instance.flow, parameterTypes[i]);
if (resolved) {
if (resolved.kind == ElementKind.GLOBAL) {
let global = <Global>resolved;
if (this.compileGlobal(global)) {
if (global.is(CommonFlags.INLINED)) {
operands.push(
this.compileInlineConstant(global, parameterTypes[i], ContextualFlags.IMPLICIT)
);
} else {
operands.push(
this.convertExpression(
module.global_get(global.internalName, global.type.toNativeType()),
global.type, parameterTypes[i], false, false, initializer
)
);
}
continue;
}
}
}
} }
operands.push(parameterTypes[i].toNativeZero(module)); operands.push(parameterTypes[i].toNativeZero(module));
allOptionalsAreConstant = false; allOptionalsAreConstant = false;