diff --git a/src/compiler.ts b/src/compiler.ts index c3341934b5..3113f4468c 100644 --- a/src/compiler.ts +++ b/src/compiler.ts @@ -358,8 +358,8 @@ export class Compiler extends DiagnosticEmitter { skippedAutoreleases: Set = new Set(); /** Current inline functions stack. */ inlineStack: Function[] = []; - /** Lazily compiled library functions. */ - lazyLibraryFunctions: Set = new Set(); + /** Lazily compiled functions. */ + lazyFunctions: Set = new Set(); /** Pending class-specific instanceof helpers. */ pendingClassInstanceOf: Set = new Set(); /** Functions potentially involving a virtual call. */ @@ -490,20 +490,20 @@ export class Compiler extends DiagnosticEmitter { program.registerConstantInteger("__GC_ALL_ACYCLIC", Type.bool, i64_new(1, 0)); } - // compile lazy library functions - var lazyLibraryFunctions = this.lazyLibraryFunctions; + // compile lazy functions + var lazyFunctions = this.lazyFunctions; do { let functionsToCompile = new Array(); // TODO: for (let instance of lazyLibraryFunctions) { - for (let _values = Set_values(lazyLibraryFunctions), i = 0, k = _values.length; i < k; ++i) { + for (let _values = Set_values(lazyFunctions), i = 0, k = _values.length; i < k; ++i) { let instance = unchecked(_values[i]); functionsToCompile.push(instance); } - lazyLibraryFunctions.clear(); + lazyFunctions.clear(); for (let i = 0, k = functionsToCompile.length; i < k; ++i) { this.compileFunction(unchecked(functionsToCompile[i]), true); } - } while (lazyLibraryFunctions.size); + } while (lazyFunctions.size); // compile pending class-specific instanceof helpers // TODO: for (let prototype of this.pendingClassInstanceOf.values()) { @@ -759,7 +759,7 @@ export class Compiler extends DiagnosticEmitter { global.identifierNode.range ); } else { - this.module.addGlobalExport(element.internalName, prefix + name); + if (element.is(CommonFlags.COMPILED)) this.module.addGlobalExport(element.internalName, prefix + name); } break; } @@ -916,7 +916,7 @@ export class Compiler extends DiagnosticEmitter { // TODO: for (let element of exports.values()) { for (let _values = Map_values(exports), i = 0, k = _values.length; i < k; ++i) { let element = unchecked(_values[i]); - this.compileElement(element); + if (!element.hasDecorator(DecoratorFlags.LAZY)) this.compileElement(element); } } var exportsStar = file.exportsStar; @@ -1349,7 +1349,7 @@ export class Compiler extends DiagnosticEmitter { if (!forceStdAlternative) { if (instance.hasDecorator(DecoratorFlags.BUILTIN)) return true; if (instance.hasDecorator(DecoratorFlags.LAZY)) { - this.lazyLibraryFunctions.add(instance); + this.lazyFunctions.add(instance); return true; } } diff --git a/src/program.ts b/src/program.ts index 67da15e8dd..44b08ee489 100644 --- a/src/program.ts +++ b/src/program.ts @@ -2239,7 +2239,7 @@ export class Program extends DiagnosticEmitter { validDecorators |= DecoratorFlags.EXTERNAL; } else { validDecorators |= DecoratorFlags.INLINE; - if (declaration.range.source.isLibrary) { + if (declaration.range.source.isLibrary || declaration.is(CommonFlags.EXPORT)) { validDecorators |= DecoratorFlags.LAZY; } } diff --git a/tests/compiler/exports-lazy.json b/tests/compiler/exports-lazy.json new file mode 100644 index 0000000000..b1da366ff4 --- /dev/null +++ b/tests/compiler/exports-lazy.json @@ -0,0 +1,5 @@ +{ + "asc_flags": [ + "--runtime none" + ] +} \ No newline at end of file diff --git a/tests/compiler/exports-lazy.optimized.wat b/tests/compiler/exports-lazy.optimized.wat new file mode 100644 index 0000000000..b1c73fc7f9 --- /dev/null +++ b/tests/compiler/exports-lazy.optimized.wat @@ -0,0 +1,13 @@ +(module + (type $none_=>_none (func)) + (memory $0 1) + (data (i32.const 1024) "\0c\00\00\00\01\00\00\00\00\00\00\00\0c\00\00\00\01\00\00\00\02\00\00\00\03") + (data (i32.const 1056) "\10\00\00\00\01\00\00\00\03\00\00\00\10\00\00\00\10\04\00\00\10\04\00\00\0c\00\00\00\03") + (global $exports-lazy/lazyGlobalUsed i32 (i32.const 1072)) + (export "memory" (memory $0)) + (export "lazyGlobalUsed" (global $exports-lazy/lazyGlobalUsed)) + (export "lazyFuncUsed" (func $~start)) + (func $~start + nop + ) +) diff --git a/tests/compiler/exports-lazy.ts b/tests/compiler/exports-lazy.ts new file mode 100644 index 0000000000..8453d06b72 --- /dev/null +++ b/tests/compiler/exports-lazy.ts @@ -0,0 +1,9 @@ +@lazy export const lazyGlobalUnused: i32[] = [1,2,3]; + +@lazy export const lazyGlobalUsed: i32[] = [1,2,3]; +lazyGlobalUsed; + +@lazy export function lazyFuncUnused(): void {} + +@lazy export function lazyFuncUsed(): void {} +lazyFuncUsed(); diff --git a/tests/compiler/exports-lazy.untouched.wat b/tests/compiler/exports-lazy.untouched.wat new file mode 100644 index 0000000000..64df15c7a9 --- /dev/null +++ b/tests/compiler/exports-lazy.untouched.wat @@ -0,0 +1,25 @@ +(module + (type $none_=>_none (func)) + (memory $0 1) + (data (i32.const 16) "\0c\00\00\00\01\00\00\00\00\00\00\00\0c\00\00\00\01\00\00\00\02\00\00\00\03\00\00\00") + (data (i32.const 48) "\10\00\00\00\01\00\00\00\03\00\00\00\10\00\00\00 \00\00\00 \00\00\00\0c\00\00\00\03\00\00\00") + (table $0 1 funcref) + (global $exports-lazy/lazyGlobalUsed i32 (i32.const 64)) + (export "memory" (memory $0)) + (export "lazyGlobalUsed" (global $exports-lazy/lazyGlobalUsed)) + (export "lazyFuncUsed" (func $exports-lazy/lazyFuncUsed)) + (start $~start) + (func $start:exports-lazy + (local $0 i32) + (local $1 i32) + global.get $exports-lazy/lazyGlobalUsed + drop + call $exports-lazy/lazyFuncUsed + ) + (func $~start + call $start:exports-lazy + ) + (func $exports-lazy/lazyFuncUsed + nop + ) +)