@@ -471,7 +471,7 @@ function logloads(loads) {
471
471
/***/
472
472
if ( linkSet . loader . loaderObj . execute === false ) {
473
473
var loads = [ ] . concat ( linkSet . loads ) ;
474
- for ( var i = 0 ; i < loads . length ; i ++ ) {
474
+ for ( var i = 0 , l = loads . length ; i < l ; i ++ ) {
475
475
var load = loads [ i ] ;
476
476
load . module = load . kind == 'dynamic' ? {
477
477
module : _newModule ( { } )
@@ -575,7 +575,7 @@ function logloads(loads) {
575
575
// now add it to the group to indicate its been seen
576
576
groups [ load . groupIndex ] . push ( load ) ;
577
577
578
- for ( var i = 0 ; i < loads . length ; i ++ ) {
578
+ for ( var i = 0 , l = loads . length ; i < l ; i ++ ) {
579
579
var loadDep = loads [ i ] ;
580
580
581
581
// dependencies not found are already linked
@@ -661,77 +661,80 @@ function logloads(loads) {
661
661
}
662
662
}
663
663
664
+
665
+ // custom module records for binding graph
666
+ // store linking module records in a separate table
667
+ var moduleRecords = { } ;
668
+ function getOrCreateModuleRecord ( name ) {
669
+ return moduleRecords [ name ] || ( moduleRecords [ name ] = {
670
+ name : name ,
671
+ dependencies : [ ] ,
672
+ module : new Module ( ) , // start from an empty module and extend
673
+ importers : [ ] ,
674
+ evaluated : false
675
+ } ) ;
676
+ }
677
+
664
678
// custom declarative linking function
665
679
function linkDeclarativeModule ( load , loads , loader ) {
666
680
if ( load . module )
667
681
return ;
668
682
669
- // declare the module with an empty depMap
670
- var depMap = [ ] ;
671
-
672
- var registryEntry = load . declare . call ( __global , depMap ) ;
673
-
674
- var moduleDependencies = [ ] ;
675
-
676
- // module is just a plain object, until we evaluate it
677
- var module = registryEntry . exports ;
678
-
679
- console . assert ( ! load . module , 'Load module already declared!' ) ;
683
+ var module = load . module = getOrCreateModuleRecord ( load . name ) ;
684
+ var moduleObj = load . module . module ;
685
+
686
+ var registryEntry = load . declare . call ( __global , function ( name , value ) {
687
+ // NB This should be an Object.defineProperty, but that is very slow.
688
+ // By disaling this module write-protection we gain performance.
689
+ // It could be useful to allow an option to enable or disable this.
690
+ moduleObj [ name ] = value ;
691
+
692
+ for ( var i = 0 , l = module . importers . length ; i < l ; i ++ ) {
693
+ var importerModule = module . importers [ i ] ;
694
+ if ( importerModule . setters ) {
695
+ var importerIndex = importerModule . dependencies . indexOf ( module ) ;
696
+ if ( importerIndex != - 1 ) {
697
+ var setter = importerModule . setters [ importerIndex ] ;
698
+ setter ( moduleObj ) ;
699
+ }
700
+ }
701
+ }
702
+ return value ;
703
+ } ) ;
680
704
681
- load . module = {
682
- name : load . name ,
683
- dependencies : moduleDependencies ,
684
- execute : registryEntry . execute ,
685
- exports : module ,
686
- evaluated : false
687
- } ;
705
+ // setup our setters and execution function
706
+ load . module . setters = registryEntry . setters ;
707
+ load . module . execute = registryEntry . execute ;
688
708
689
709
// now link all the module dependencies
690
710
// amending the depMap as we go
691
- for ( var i = 0 ; i < load . dependencies . length ; i ++ ) {
711
+ for ( var i = 0 , l = load . dependencies . length ; i < l ; i ++ ) {
692
712
var depName = load . dependencies [ i ] . value ;
693
- var depModule ;
694
- // if dependency already a module, use that
695
- if ( loader . modules [ depName ] ) {
696
- depModule = loader . modules [ depName ] ;
697
- }
698
- else {
713
+ var depModule = getOrCreateModuleRecord ( depName ) ;
714
+
715
+ depModule . importers . push ( module ) ;
716
+
717
+ // if not already a module in the registry, try and link it now
718
+ if ( ! loader . modules [ depName ] ) {
719
+
720
+ // get the dependency load record
699
721
for ( var j = 0 ; j < loads . length ; j ++ ) {
700
722
if ( loads [ j ] . name != depName )
701
723
continue ;
702
724
703
725
// only link if already not already started linking (stops at circular / dynamic)
704
726
if ( ! loads [ j ] . module )
705
727
linkDeclarativeModule ( loads [ j ] , loads , loader ) ;
706
-
707
- depModule = loads [ j ] . module ;
708
728
}
709
729
}
710
730
711
- var depModuleModule = depModule . exports || depModule . module ;
712
-
713
731
console . assert ( depModule , 'Dependency module not found!' ) ;
714
732
715
- if ( registryEntry . exportStar && indexOf . call ( registryEntry . exportStar , load . dependencies [ i ] . key ) != - 1 ) {
716
- // we are exporting * from this dependency
717
- ( function ( depModuleModule ) {
718
- for ( var p in depModuleModule ) ( function ( p ) {
719
- // if the property is already defined throw?
720
- defineProperty ( module , p , {
721
- enumerable : true ,
722
- get : function ( ) {
723
- return depModuleModule [ p ] ;
724
- } ,
725
- set : function ( value ) {
726
- depModuleModule [ p ] = value ;
727
- }
728
- } ) ;
729
- } ) ( p ) ;
730
- } ) ( depModuleModule ) ;
731
- }
733
+ module . dependencies . push ( depModule ) ;
732
734
733
- moduleDependencies . push ( depModule ) ;
734
- depMap [ i ] = depModuleModule ;
735
+ // run the setter for this dependency
736
+ if ( module . setters [ i ] )
737
+ module . setters [ i ] ( depModule . module ) ;
735
738
}
736
739
737
740
load . status = 'linked' ;
@@ -759,6 +762,7 @@ function logloads(loads) {
759
762
* module.module bound module object
760
763
* module.execute execution function for module
761
764
* module.dependencies list of module objects for dependencies
765
+ * See getOrCreateModuleRecord for all properties
762
766
*
763
767
*/
764
768
function doExecute ( module ) {
@@ -787,7 +791,7 @@ function logloads(loads) {
787
791
var deps = module . dependencies ;
788
792
var err ;
789
793
790
- for ( var i = 0 ; i < deps . length ; i ++ ) {
794
+ for ( var i = 0 , l = deps . length ; i < l ; i ++ ) {
791
795
var dep = deps [ i ] ;
792
796
if ( indexOf . call ( seen , dep ) == - 1 ) {
793
797
err = ensureEvaluated ( dep , seen , loader ) ;
@@ -807,7 +811,13 @@ function logloads(loads) {
807
811
err = doExecute ( module ) ;
808
812
if ( err )
809
813
module . failed = true ;
810
- module . module = _newModule ( module . exports ) ;
814
+
815
+ // spec variation
816
+ // we don't create a new module here because it was created and ammended
817
+ // we just disable further extensions instead
818
+ if ( Object . preventExtensions )
819
+ Object . preventExtensions ( module . module ) ;
820
+
811
821
module . execute = undefined ;
812
822
return err ;
813
823
}
0 commit comments