Initial module level function exports

This commit is contained in:
dcodeIO 2017-12-02 23:33:01 +01:00
parent 9e053f311e
commit eaf9253b96
8 changed files with 33 additions and 18 deletions

View File

@ -346,6 +346,8 @@ export class Compiler extends DiagnosticEmitter {
this.startFunctionBody.push(this.module.createSetGlobal(internalName, initializer));
} else
this.module.addGlobal(internalName, nativeType, element.isMutable, initializer);
// if (element.globalExportName != null && element.hasConstantValue && !initializeInStart)
// this.module.addGlobalExport(element.internalName, element.globalExportName);
return element.isCompiled = true;
}
@ -401,19 +403,21 @@ export class Compiler extends DiagnosticEmitter {
const element: Element | null = <Element | null>this.program.elements.get(internalName);
if (!element || element.kind != ElementKind.FUNCTION_PROTOTYPE)
throw new Error("unexpected missing function");
this.compileFunctionUsingTypeArguments(<FunctionPrototype>element, typeArguments, contextualTypeArguments, alternativeReportNode);
const instance: Function | null = this.compileFunctionUsingTypeArguments(<FunctionPrototype>element, typeArguments, contextualTypeArguments, alternativeReportNode);
if (instance && declaration.range.source.isEntry && declaration.parent == declaration.range.source && hasModifier(ModifierKind.EXPORT, declaration.modifiers))
this.module.addExport(instance.internalName, declaration.identifier.name);
}
compileFunctionUsingTypeArguments(prototype: FunctionPrototype, typeArguments: TypeNode[], contextualTypeArguments: Map<string,Type> | null = null, alternativeReportNode: Node | null = null) {
compileFunctionUsingTypeArguments(prototype: FunctionPrototype, typeArguments: TypeNode[], contextualTypeArguments: Map<string,Type> | null = null, alternativeReportNode: Node | null = null): Function | null {
const instance: Function | null = prototype.resolveInclTypeArguments(typeArguments, contextualTypeArguments, alternativeReportNode); // reports
if (!instance)
return;
this.compileFunction(instance);
return null;
return this.compileFunction(instance) ? instance : null;
}
compileFunction(instance: Function): void {
compileFunction(instance: Function): bool {
if (instance.isCompiled)
return;
return true;
const declaration: FunctionDeclaration | null = instance.template.declaration;
if (!declaration)
@ -421,7 +425,7 @@ export class Compiler extends DiagnosticEmitter {
if (!declaration.statements) {
this.error(DiagnosticCode.Function_implementation_is_missing_or_not_immediately_following_the_declaration, declaration.identifier.range);
return;
return false;
}
instance.isCompiled = true;
@ -446,8 +450,7 @@ export class Compiler extends DiagnosticEmitter {
typeRef = this.module.addFunctionType(signatureNameParts.join(""), binaryenResultType, binaryenParamTypes);
const internalName: string = instance.internalName;
this.module.addFunction(internalName, typeRef, typesToNativeTypes(instance.additionalLocals), this.module.createBlock(null, stmts, NativeType.None));
if (instance.globalExportName != null)
this.module.addExport(internalName, <string>instance.globalExportName);
return true;
}
// namespaces
@ -544,8 +547,11 @@ export class Compiler extends DiagnosticEmitter {
break;
case ElementKind.FUNCTION_PROTOTYPE:
if (!(<FunctionPrototype>element).isGeneric)
this.compileFunctionUsingTypeArguments(<FunctionPrototype>element, []);
if (!(<FunctionPrototype>element).isGeneric) {
const functionInstance: Function | null = this.compileFunctionUsingTypeArguments(<FunctionPrototype>element, []);
if (functionInstance && statement.range.source.isEntry)
this.module.addExport(functionInstance.internalName, member.externalIdentifier.name);
}
break;
case ElementKind.GLOBAL:

View File

@ -686,7 +686,6 @@ export abstract class Element {
kind: ElementKind;
program: Program;
internalName: string;
globalExportName: string | null = null;
isCompiled: bool = false;
isImport: bool = false;
isBuiltin: bool = false;
@ -710,7 +709,6 @@ export class Namespace extends Element {
}
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : false; }
get isGlobalExport(): bool { return this.declaration ? this.globalExportName != null : /* internals aren't exports */ false; }
}
/** An enum. */
@ -726,7 +724,6 @@ export class Enum extends Namespace {
}
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't exports */ false; }
get isGlobalExport(): bool { return this.globalExportName != null; }
get isConstant(): bool { return this.declaration ? hasModifier(ModifierKind.CONST, this.declaration.modifiers) : /* internals are const */ true; }
}
@ -763,7 +760,6 @@ export class Global extends Element {
}
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't exports */ false; }
get isGlobalExport(): bool { return this.globalExportName != null; }
get isMutable(): bool { return this.declaration ? !hasModifier(ModifierKind.CONST, this.declaration.modifiers) : /* internals are immutable */ false; }
}
@ -812,7 +808,6 @@ export class FunctionPrototype extends Element {
}
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't file-level exports */ false; }
get isGlobalExport(): bool { return this.declaration ? this.globalExportName != null : /* internals aren't global exports */ false; }
get isInstance(): bool { return this.classPrototype != null; }
get isGetter(): bool { return this.declaration ? hasModifier(ModifierKind.GET, this.declaration.modifiers) : /* internals aren't getters */ false; }
get isSetter(): bool { return this.declaration ? hasModifier(ModifierKind.SET, this.declaration.modifiers) : /* internals aren't setters */ false; }
@ -986,7 +981,6 @@ export class FieldPrototype extends Element {
}
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't file-level exports */ false; }
get isGlobalExport(): bool { return this.declaration ? this.globalExportName != null : /* internals aren't global exports */ false; }
}
/** A resolved instance field. */
@ -1022,7 +1016,6 @@ export class ClassPrototype extends Namespace {
}
get isExport(): bool { return this.declaration ? hasModifier(ModifierKind.EXPORT, this.declaration.modifiers) : /* internals aren't file-level exports */ false; }
get isGlobalExport(): bool { return this.declaration ? this.globalExportName != null : /* internals aren't global exports */ false; }
resolve(typeArguments: Type[], contextualTypeArguments: Map<string,Type> | null): Class {
const key: string = typesToString(typeArguments, "", "");

View File

@ -2,6 +2,8 @@
(type $iv (func (param i32)))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "loopDo" (func $do/loopDo))
(export "loopDoInDo" (func $do/loopDoInDo))
(export "memory" (memory $0))
(func $do/loopDo (; 0 ;) (type $iv) (param $0 i32)
(block $break$1.1

View File

@ -4,6 +4,8 @@
(global $export/b (mut i32) (i32.const 2))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "add" (func $export/add))
(export "renamed_sub" (func $export/sub))
(export "memory" (memory $0))
(func $export/add (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)
(return

View File

@ -2,6 +2,9 @@
(type $ii (func (param i32) (result i32)))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "ifThenElse" (func $if/ifThenElse))
(export "ifThen" (func $if/ifThen))
(export "ifThenElseBlock" (func $if/ifThenElseBlock))
(export "memory" (memory $0))
(func $if/ifThenElse (; 0 ;) (type $ii) (param $0 i32) (result i32)
(if

View File

@ -3,6 +3,10 @@
(type $v (func))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "add" (func $export/add))
(export "renamed_sub" (func $export/sub))
(export "renamed_add" (func $export/add))
(export "rerenamed_sub" (func $export/sub))
(export "memory" (memory $0))
(start $start)
(func $export/add (; 0 ;) (type $iii) (param $0 i32) (param $1 i32) (result i32)

View File

@ -2,6 +2,9 @@
(type $ii (func (param i32) (result i32)))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "doSwitch" (func $switch/doSwitch))
(export "doSwitchDefaultFirst" (func $switch/doSwitchDefaultFirst))
(export "doSwitchDefaultOmitted" (func $switch/doSwitchDefaultOmitted))
(export "memory" (memory $0))
(func $switch/doSwitch (; 0 ;) (type $ii) (param $0 i32) (result i32)
(local $1 i32)

View File

@ -2,6 +2,8 @@
(type $iv (func (param i32)))
(memory $0 1)
(data (i32.const 4) "\08\00\00\00")
(export "loopWhile" (func $while/loopWhile))
(export "loopWhileInWhile" (func $while/loopWhileInWhile))
(export "memory" (memory $0))
(func $while/loopWhile (; 0 ;) (type $iv) (param $0 i32)
(block $break$1.1