@@ -355,16 +355,26 @@ export const enum RuntimeFeatures {
355355 setArgumentsLength = 1 << 6
356356}
357357
358+ /** Imported default names of compiler-generated elements. */
359+ export namespace ImportNames {
360+ /** Name of the default namespace */
361+ export const DefaultNamespace = "env" ;
362+ /** Name of the memory instance, if imported. */
363+ export const Memory = "memory" ;
364+ /** Name of the table instance, if imported. */
365+ export const Table = "table" ;
366+ }
367+
358368/** Exported names of compiler-generated elements. */
359369export namespace ExportNames {
370+ /** Name of the memory instance, if exported. */
371+ export const Memory = "memory" ;
372+ /** Name of the table instance, if exported. */
373+ export const Table = "table" ;
360374 /** Name of the argumentsLength varargs helper global. */
361375 export const argumentsLength = "__argumentsLength" ;
362376 /** Name of the alternative argumentsLength setter function. */
363377 export const setArgumentsLength = "__setArgumentsLength" ;
364- /** Name of the memory instance, if exported. */
365- export const memory = "memory" ;
366- /** Name of the table instance, if exported. */
367- export const table = "table" ;
368378}
369379
370380/** Functions to export if `--exportRuntime` is set. */
@@ -639,25 +649,84 @@ export class Compiler extends DiagnosticEmitter {
639649 }
640650 }
641651
642- this . memoryOffset = memoryOffset ;
652+ // setup default memory & table
653+ this . initDefaultMemory ( memoryOffset ) ;
654+ this . initDefaultTable ( ) ;
643655
644- // check that we didn't exceed lowMemoryLimit already
645- var lowMemoryLimit32 = this . options . lowMemoryLimit ;
646- if ( lowMemoryLimit32 ) {
647- let lowMemoryLimit = i64_new ( lowMemoryLimit32 & ~ 15 ) ;
648- if ( i64_gt ( memoryOffset , lowMemoryLimit ) ) {
649- this . error (
650- DiagnosticCode . Low_memory_limit_exceeded_by_static_data_0_1 ,
651- null , i64_to_string ( memoryOffset ) , i64_to_string ( lowMemoryLimit )
656+ // expose the arguments length helper if there are varargs exports
657+ if ( this . runtimeFeatures & RuntimeFeatures . setArgumentsLength ) {
658+ module . addFunction ( BuiltinNames . setArgumentsLength , TypeRef . I32 , TypeRef . None , null ,
659+ module . global_set ( this . ensureArgumentsLength ( ) , module . local_get ( 0 , TypeRef . I32 ) )
660+ ) ;
661+ module . addFunctionExport ( BuiltinNames . setArgumentsLength , ExportNames . setArgumentsLength ) ;
662+ }
663+
664+ // NOTE: no more element compiles from here. may go to the start function!
665+
666+ // compile the start function if not empty or if explicitly requested
667+ var startIsEmpty = ! startFunctionBody . length ;
668+ var exportStart = options . exportStart ;
669+ if ( ! startIsEmpty || exportStart != null ) {
670+ let signature = startFunctionInstance . signature ;
671+ if ( ! startIsEmpty && exportStart != null ) {
672+ module . addGlobal ( BuiltinNames . started , TypeRef . I32 , true , module . i32 ( 0 ) ) ;
673+ startFunctionBody . unshift (
674+ module . global_set ( BuiltinNames . started , module . i32 ( 1 ) )
675+ ) ;
676+ startFunctionBody . unshift (
677+ module . if (
678+ module . global_get ( BuiltinNames . started , TypeRef . I32 ) ,
679+ module . return ( )
680+ )
652681 ) ;
653682 }
683+ let funcRef = module . addFunction (
684+ startFunctionInstance . internalName ,
685+ signature . paramRefs ,
686+ signature . resultRefs ,
687+ typesToRefs ( startFunctionInstance . additionalLocals ) ,
688+ module . flatten ( startFunctionBody )
689+ ) ;
690+ startFunctionInstance . finalize ( module , funcRef ) ;
691+ if ( exportStart == null ) module . setStart ( funcRef ) ;
692+ else {
693+ if ( ! isIdentifier ( exportStart ) || module . hasExport ( exportStart ) ) {
694+ this . error (
695+ DiagnosticCode . Start_function_name_0_is_invalid_or_conflicts_with_another_export ,
696+ this . program . nativeRange , exportStart
697+ ) ;
698+ } else {
699+ module . addFunctionExport ( startFunctionInstance . internalName , exportStart ) ;
700+ }
701+ }
654702 }
655703
656- // set up memory
704+ // Run custom passes
705+ if ( hasShadowStack ) {
706+ this . shadowStack . walkModule ( ) ;
707+ }
708+ if ( program . lookup ( "ASC_RTRACE" ) != null ) {
709+ new RtraceMemory ( this ) . walkModule ( ) ;
710+ }
711+
712+ return module ;
713+ }
714+
715+ private initDefaultMemory ( memoryOffset : i64 ) : void {
716+ this . memoryOffset = memoryOffset ;
717+
718+ var options = this . options ;
719+ var module = this . module ;
720+ var memorySegments = this . memorySegments ;
721+
657722 var initialPages : u32 = 0 ;
658- if ( this . options . memoryBase /* is specified */ || this . memorySegments . length ) {
723+ var maximumPages = Module . UNLIMITED_MEMORY ;
724+ var isSharedMemory = false ;
725+
726+ if ( options . memoryBase /* is specified */ || memorySegments . length ) {
659727 initialPages = u32 ( i64_low ( i64_shr_u ( i64_align ( memoryOffset , 0x10000 ) , i64_new ( 16 ) ) ) ) ;
660728 }
729+
661730 if ( options . initialMemory ) {
662731 if ( options . initialMemory < initialPages ) {
663732 this . error (
@@ -669,7 +738,7 @@ export class Compiler extends DiagnosticEmitter {
669738 initialPages = options . initialMemory ;
670739 }
671740 }
672- var maximumPages = Module . UNLIMITED_MEMORY ;
741+
673742 if ( options . maximumMemory ) {
674743 if ( options . maximumMemory < initialPages ) {
675744 this . error (
@@ -681,7 +750,7 @@ export class Compiler extends DiagnosticEmitter {
681750 maximumPages = options . maximumMemory ;
682751 }
683752 }
684- var isSharedMemory = false ;
753+
685754 if ( options . sharedMemory ) {
686755 isSharedMemory = true ;
687756 if ( ! options . maximumMemory ) {
@@ -699,21 +768,52 @@ export class Compiler extends DiagnosticEmitter {
699768 isSharedMemory = false ;
700769 }
701770 }
771+
772+ // check that we didn't exceed lowMemoryLimit already
773+ var lowMemoryLimit32 = options . lowMemoryLimit ;
774+ if ( lowMemoryLimit32 ) {
775+ let lowMemoryLimit = i64_new ( lowMemoryLimit32 & ~ 15 ) ;
776+ if ( i64_gt ( memoryOffset , lowMemoryLimit ) ) {
777+ this . error (
778+ DiagnosticCode . Low_memory_limit_exceeded_by_static_data_0_1 ,
779+ null , i64_to_string ( memoryOffset ) , i64_to_string ( lowMemoryLimit )
780+ ) ;
781+ }
782+ }
783+
784+ // Just stubbed memory. Will update later in finalizeMemory
702785 module . setMemory (
703786 initialPages ,
704787 maximumPages ,
705- this . memorySegments ,
788+ memorySegments ,
706789 options . target ,
707- options . exportMemory ? ExportNames . memory : null ,
790+ options . exportMemory ? ExportNames . Memory : null ,
791+ CommonNames . DefaultMemory ,
708792 isSharedMemory
709793 ) ;
710794
711795 // import memory if requested (default memory is named '0' by Binaryen)
712- if ( options . importMemory ) module . addMemoryImport ( "0" , "env" , "memory" , isSharedMemory ) ;
796+ if ( options . importMemory ) {
797+ module . addMemoryImport (
798+ CommonNames . DefaultMemory ,
799+ ImportNames . DefaultNamespace ,
800+ ImportNames . Memory ,
801+ isSharedMemory
802+ ) ;
803+ }
804+ }
805+
806+ private initDefaultTable ( ) : void {
807+ var options = this . options ;
808+ var module = this . module ;
713809
714810 // import and/or export table if requested (default table is named '0' by Binaryen)
715811 if ( options . importTable ) {
716- module . addTableImport ( "0" , "env" , "table" ) ;
812+ module . addTableImport (
813+ CommonNames . DefaultTable ,
814+ ImportNames . DefaultNamespace ,
815+ ImportNames . Table
816+ ) ;
717817 if ( options . pedantic && options . willOptimize ) {
718818 this . pedantic (
719819 DiagnosticCode . Importing_the_table_disables_some_indirect_call_optimizations ,
@@ -722,7 +822,7 @@ export class Compiler extends DiagnosticEmitter {
722822 }
723823 }
724824 if ( options . exportTable ) {
725- module . addTableExport ( "0" , ExportNames . table ) ;
825+ module . addTableExport ( CommonNames . DefaultTable , ExportNames . Table ) ;
726826 if ( options . pedantic && options . willOptimize ) {
727827 this . pedantic (
728828 DiagnosticCode . Exporting_the_table_disables_some_indirect_call_optimizations ,
@@ -732,80 +832,33 @@ export class Compiler extends DiagnosticEmitter {
732832 }
733833
734834 // set up function table (first elem is blank)
735- var tableBase = this . options . tableBase ;
835+ var tableBase = options . tableBase ;
736836 if ( ! tableBase ) tableBase = 1 ; // leave first elem blank
837+ var functionTable = this . functionTable ;
737838 var functionTableNames = new Array < string > ( functionTable . length ) ;
738839 for ( let i = 0 , k = functionTable . length ; i < k ; ++ i ) {
739840 functionTableNames [ i ] = functionTable [ i ] . internalName ;
740841 }
741842
742- var tableSize = tableBase + functionTable . length ;
743- module . addFunctionTable (
744- "0" ,
745- tableSize ,
843+ var initialTableSize = < Index > tableBase + functionTable . length ;
844+ var maximumTableSize = Module . UNLIMITED_TABLE ;
845+
846+ if ( ! ( options . importTable || options . exportTable ) ) {
746847 // use fixed size for non-imported and non-exported tables
747- options . importTable || options . exportTable ? Module . UNLIMITED_TABLE : tableSize ,
848+ maximumTableSize = initialTableSize ;
849+ if ( options . willOptimize ) {
850+ // Hint for directize pass which indicate table's content will not change
851+ // and can be better optimized
852+ module . setPassArgument ( "directize-initial-contents-immutable" , "true" ) ;
853+ }
854+ }
855+ module . addFunctionTable (
856+ CommonNames . DefaultTable ,
857+ initialTableSize ,
858+ maximumTableSize ,
748859 functionTableNames ,
749860 module . i32 ( tableBase )
750861 ) ;
751-
752- // expose the arguments length helper if there are varargs exports
753- if ( this . runtimeFeatures & RuntimeFeatures . setArgumentsLength ) {
754- module . addFunction ( BuiltinNames . setArgumentsLength , TypeRef . I32 , TypeRef . None , null ,
755- module . global_set ( this . ensureArgumentsLength ( ) , module . local_get ( 0 , TypeRef . I32 ) )
756- ) ;
757- module . addFunctionExport ( BuiltinNames . setArgumentsLength , ExportNames . setArgumentsLength ) ;
758- }
759-
760- // NOTE: no more element compiles from here. may go to the start function!
761-
762- // compile the start function if not empty or if explicitly requested
763- var startIsEmpty = ! startFunctionBody . length ;
764- var exportStart = options . exportStart ;
765- if ( ! startIsEmpty || exportStart != null ) {
766- let signature = startFunctionInstance . signature ;
767- if ( ! startIsEmpty && exportStart != null ) {
768- module . addGlobal ( BuiltinNames . started , TypeRef . I32 , true , module . i32 ( 0 ) ) ;
769- startFunctionBody . unshift (
770- module . global_set ( BuiltinNames . started , module . i32 ( 1 ) )
771- ) ;
772- startFunctionBody . unshift (
773- module . if (
774- module . global_get ( BuiltinNames . started , TypeRef . I32 ) ,
775- module . return ( )
776- )
777- ) ;
778- }
779- let funcRef = module . addFunction (
780- startFunctionInstance . internalName ,
781- signature . paramRefs ,
782- signature . resultRefs ,
783- typesToRefs ( startFunctionInstance . additionalLocals ) ,
784- module . flatten ( startFunctionBody )
785- ) ;
786- startFunctionInstance . finalize ( module , funcRef ) ;
787- if ( exportStart == null ) module . setStart ( funcRef ) ;
788- else {
789- if ( ! isIdentifier ( exportStart ) || module . hasExport ( exportStart ) ) {
790- this . error (
791- DiagnosticCode . Start_function_name_0_is_invalid_or_conflicts_with_another_export ,
792- this . program . nativeRange , exportStart
793- ) ;
794- } else {
795- module . addFunctionExport ( startFunctionInstance . internalName , exportStart ) ;
796- }
797- }
798- }
799-
800- // Run custom passes
801- if ( hasShadowStack ) {
802- this . shadowStack . walkModule ( ) ;
803- }
804- if ( program . lookup ( "ASC_RTRACE" ) != null ) {
805- new RtraceMemory ( this ) . walkModule ( ) ;
806- }
807-
808- return module ;
809862 }
810863
811864 // === Exports ==================================================================================
0 commit comments