Browse Source

Kernel does not setup whole thisContext chain.

MethodContext accessors lazy-setup home / outer contexts.
Herby Vojčík 4 years ago
parent
commit
07c088720e
3 changed files with 52 additions and 11 deletions
  1. 1 3
      lang/base/kernel-runtime.js
  2. 45 6
      lang/src/Kernel-Methods.js
  3. 6 2
      lang/src/Kernel-Methods.st

+ 1 - 3
lang/base/kernel-runtime.js

@@ -387,9 +387,7 @@ define(['./junk-drawer'], function ($goodies) {
 
             st.getThisContext = function () {
                 if (!thisContext) return null;
-                for (var frame = thisContext; frame; frame = frame.outerContext || frame.homeContext) {
-                    frame.setup(frame);
-                }
+                thisContext.setup(thisContext);
                 return thisContext;
             };
         }

+ 45 - 6
lang/src/Kernel-Methods.js

@@ -2470,15 +2470,52 @@ selector: "home",
 protocol: "accessing",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "home\x0a\x09^ homeContext",
+source: "home\x0a\x09^ homeContext ifNotNil: [ :c | c hydrated ]",
 referencedClasses: [],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: []
+messageSends: ["ifNotNil:", "hydrated"]
 }, function ($methodClass){ return function (){
 var self=this,$self=this;
-return $self.homeContext;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1;
+$1=$self.homeContext;
+if($1 == null || $1.a$nil){
+return $1;
+} else {
+var c;
+c=$1;
+return $recv(c)._hydrated();
+}
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"home",{})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.MethodContext);
 
+$core.addMethod(
+$core.method({
+selector: "hydrated",
+protocol: "accessing",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: [],
+source: "hydrated\x0a\x09<inlineJS: 'if (!$self.selector && !$self.outerContext) $self.setup(self); return self;'>",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [["inlineJS:", ["if (!$self.selector && !$self.outerContext) $self.setup(self); return self;"]]],
+messageSends: []
+}, function ($methodClass){ return function (){
+var self=this,$self=this;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+if (!$self.selector && !$self.outerContext) $self.setup(self); return self;;
+return self;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"hydrated",{})});
+//>>excludeEnd("ctx");
 }; }),
 $globals.MethodContext);
 
@@ -2535,11 +2572,11 @@ selector: "outerContext",
 protocol: "accessing",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: [],
-source: "outerContext\x0a\x09^ outerContext ifNil: [ self home ]",
+source: "outerContext\x0a\x09^ outerContext ifNil: [ self home ] ifNotNil: [ :c | c hydrated ]",
 referencedClasses: [],
 //>>excludeEnd("ide");
 pragmas: [],
-messageSends: ["ifNil:", "home"]
+messageSends: ["ifNil:ifNotNil:", "home", "hydrated"]
 }, function ($methodClass){ return function (){
 var self=this,$self=this;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
@@ -2550,7 +2587,9 @@ $1=$self.outerContext;
 if($1 == null || $1.a$nil){
 return $self._home();
 } else {
-return $1;
+var c;
+c=$1;
+return $recv(c)._hydrated();
 }
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 }, function($ctx1) {$ctx1.fill(self,"outerContext",{})});

+ 6 - 2
lang/src/Kernel-Methods.st

@@ -648,7 +648,11 @@ evaluatedSelector
 !
 
 home
-	^ homeContext
+	^ homeContext ifNotNil: [ :c | c hydrated ]
+!
+
+hydrated
+	<inlineJS: 'if (!!$self.selector && !!$self.outerContext) $self.setup(self); return self;'>
 !
 
 index
@@ -660,7 +664,7 @@ locals
 !
 
 outerContext
-	^ outerContext ifNil: [ self home ]
+	^ outerContext ifNil: [ self home ] ifNotNil: [ :c | c hydrated ]
 !
 
 selector