@@ -355,16 +355,26 @@ export const enum RuntimeFeatures {
355
355
setArgumentsLength = 1 << 6
356
356
}
357
357
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
+
358
368
/** Exported names of compiler-generated elements. */
359
369
export 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" ;
360
374
/** Name of the argumentsLength varargs helper global. */
361
375
export const argumentsLength = "__argumentsLength" ;
362
376
/** Name of the alternative argumentsLength setter function. */
363
377
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" ;
368
378
}
369
379
370
380
/** Functions to export if `--exportRuntime` is set. */
@@ -639,25 +649,84 @@ export class Compiler extends DiagnosticEmitter {
639
649
}
640
650
}
641
651
642
- this . memoryOffset = memoryOffset ;
652
+ // setup default memory & table
653
+ this . initDefaultMemory ( memoryOffset ) ;
654
+ this . initDefaultTable ( ) ;
643
655
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
+ )
652
681
) ;
653
682
}
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
+ }
654
702
}
655
703
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
+
657
722
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 ) {
659
727
initialPages = u32 ( i64_low ( i64_shr_u ( i64_align ( memoryOffset , 0x10000 ) , i64_new ( 16 ) ) ) ) ;
660
728
}
729
+
661
730
if ( options . initialMemory ) {
662
731
if ( options . initialMemory < initialPages ) {
663
732
this . error (
@@ -669,7 +738,7 @@ export class Compiler extends DiagnosticEmitter {
669
738
initialPages = options . initialMemory ;
670
739
}
671
740
}
672
- var maximumPages = Module . UNLIMITED_MEMORY ;
741
+
673
742
if ( options . maximumMemory ) {
674
743
if ( options . maximumMemory < initialPages ) {
675
744
this . error (
@@ -681,7 +750,7 @@ export class Compiler extends DiagnosticEmitter {
681
750
maximumPages = options . maximumMemory ;
682
751
}
683
752
}
684
- var isSharedMemory = false ;
753
+
685
754
if ( options . sharedMemory ) {
686
755
isSharedMemory = true ;
687
756
if ( ! options . maximumMemory ) {
@@ -699,21 +768,52 @@ export class Compiler extends DiagnosticEmitter {
699
768
isSharedMemory = false ;
700
769
}
701
770
}
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
702
785
module . setMemory (
703
786
initialPages ,
704
787
maximumPages ,
705
- this . memorySegments ,
788
+ memorySegments ,
706
789
options . target ,
707
- options . exportMemory ? ExportNames . memory : null ,
790
+ options . exportMemory ? ExportNames . Memory : null ,
791
+ CommonNames . DefaultMemory ,
708
792
isSharedMemory
709
793
) ;
710
794
711
795
// 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 ;
713
809
714
810
// import and/or export table if requested (default table is named '0' by Binaryen)
715
811
if ( options . importTable ) {
716
- module . addTableImport ( "0" , "env" , "table" ) ;
812
+ module . addTableImport (
813
+ CommonNames . DefaultTable ,
814
+ ImportNames . DefaultNamespace ,
815
+ ImportNames . Table
816
+ ) ;
717
817
if ( options . pedantic && options . willOptimize ) {
718
818
this . pedantic (
719
819
DiagnosticCode . Importing_the_table_disables_some_indirect_call_optimizations ,
@@ -722,7 +822,7 @@ export class Compiler extends DiagnosticEmitter {
722
822
}
723
823
}
724
824
if ( options . exportTable ) {
725
- module . addTableExport ( "0" , ExportNames . table ) ;
825
+ module . addTableExport ( CommonNames . DefaultTable , ExportNames . Table ) ;
726
826
if ( options . pedantic && options . willOptimize ) {
727
827
this . pedantic (
728
828
DiagnosticCode . Exporting_the_table_disables_some_indirect_call_optimizations ,
@@ -732,80 +832,33 @@ export class Compiler extends DiagnosticEmitter {
732
832
}
733
833
734
834
// set up function table (first elem is blank)
735
- var tableBase = this . options . tableBase ;
835
+ var tableBase = options . tableBase ;
736
836
if ( ! tableBase ) tableBase = 1 ; // leave first elem blank
837
+ var functionTable = this . functionTable ;
737
838
var functionTableNames = new Array < string > ( functionTable . length ) ;
738
839
for ( let i = 0 , k = functionTable . length ; i < k ; ++ i ) {
739
840
functionTableNames [ i ] = functionTable [ i ] . internalName ;
740
841
}
741
842
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 ) ) {
746
847
// 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 ,
748
859
functionTableNames ,
749
860
module . i32 ( tableBase )
750
861
) ;
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 ;
809
862
}
810
863
811
864
// === Exports ==================================================================================
0 commit comments