Browse Source

Fixed block context home contexts

Nicolas Petton 12 năm trước cách đây
mục cha
commit
1cb1af086d
10 tập tin đã thay đổi với 181 bổ sung44 xóa
  1. 56 6
      js/Compiler-IR.deploy.js
  2. 79 9
      js/Compiler-IR.js
  3. 2 2
      js/IDE.deploy.js
  4. 4 4
      js/IDE.js
  5. 4 6
      js/Kernel-Methods.deploy.js
  6. 9 11
      js/Kernel-Methods.js
  7. 4 1
      js/boot.js
  8. 19 1
      st/Compiler-IR.st
  9. 1 1
      st/IDE.st
  10. 3 3
      st/Kernel-Methods.st

+ 56 - 6
js/Compiler-IR.deploy.js

@@ -608,6 +608,17 @@ return smalltalk.withContext(function($ctx1) { 
return false;
 }),
 smalltalk.IRInstruction);
 
+smalltalk.addMethod(
+"_isMethod",
+smalltalk.method({
+selector: "isMethod",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, function($ctx1) {$ctx1.fill(self,"isMethod", [], {}, smalltalk.IRInstruction)})}
+}),
+smalltalk.IRInstruction);
+
 smalltalk.addMethod(
 "_isReturn",
 smalltalk.method({
@@ -663,6 +674,19 @@ return smalltalk.withContext(function($ctx1) { 
return false;
 }),
 smalltalk.IRInstruction);
 
+smalltalk.addMethod(
+"_method",
+smalltalk.method({
+selector: "method",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._parent())._method();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"method", [], {}, smalltalk.IRInstruction)})}
+}),
+smalltalk.IRInstruction);
+
 smalltalk.addMethod(
 "_parent",
 smalltalk.method({
@@ -1002,6 +1026,17 @@ return $1;
 }),
 smalltalk.IRMethod);
 
+smalltalk.addMethod(
+"_isMethod",
+smalltalk.method({
+selector: "isMethod",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return true;
+}, function($ctx1) {$ctx1.fill(self,"isMethod", [], {}, smalltalk.IRMethod)})}
+}),
+smalltalk.IRMethod);
+
 smalltalk.addMethod(
 "_messageSends",
 smalltalk.method({
@@ -1026,6 +1061,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"messageSends:", [aCollection], {
 }),
 smalltalk.IRMethod);
 
+smalltalk.addMethod(
+"_method",
+smalltalk.method({
+selector: "method",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"method", [], {}, smalltalk.IRMethod)})}
+}),
+smalltalk.IRMethod);
+
 smalltalk.addMethod(
 "_scope_",
 smalltalk.method({
@@ -2250,7 +2298,7 @@ smalltalk.method({
 selector: "nextPutBlockContextFor:during:",
 fn: function (anIRClosure,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7,$8;
 $1=self;
 _st($1)._nextPutAll_(_st(_st("return smalltalk.withContext(function(").__comma(_st(_st(anIRClosure)._scope())._alias())).__comma(") {"));
 $2=_st($1)._nextPutAll_(_st((smalltalk.String || String))._cr());
@@ -2260,9 +2308,9 @@ _st($3)._nextPutAll_(_st(_st("}, function(").__comma(_st(_st(anIRClosure)._scope
 $4=_st($3)._nextPutAll_(_st(_st(_st(anIRClosure)._scope())._alias()).__comma(".fillBlock(["));
 _st(_st(anIRClosure)._arguments())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._nextPutAll_(_st(each)._asVariableName());
-}, function($ctx2) {$ctx2.fillBlock([each], {})})}),(function(){
+}, function($ctx2) {$ctx2.fillBlock([each], {},$ctx1)})}),(function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._nextPutAll_(",");
-}, function($ctx2) {$ctx2.fillBlock([], {})})}));
+}, function($ctx2) {$ctx2.fillBlock([], {},$ctx1)})}));
 _st(self)._nextPutAll_("], {");
 _st(_st(anIRClosure)._tempDeclarations())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
$5=self;
@@ -2270,10 +2318,12 @@ _st($5)._nextPutAll_(_st(_st(each)._name())._asVariableName());
 _st($5)._nextPutAll_(":");
 $6=_st($5)._nextPutAll_(_st(_st(each)._name())._asVariableName());
 return $6;
-}, function($ctx2) {$ctx2.fillBlock([each], {})})}),(function(){
+}, function($ctx2) {$ctx2.fillBlock([each], {},$ctx1)})}),(function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._nextPutAll_(",");
-}, function($ctx2) {$ctx2.fillBlock([], {})})}));
-_st(self)._nextPutAll_("})})");
+}, function($ctx2) {$ctx2.fillBlock([], {},$ctx1)})}));
+$7=self;
+_st($7)._nextPutAll_("},");
+$8=_st($7)._nextPutAll_(_st(_st(_st(_st(anIRClosure)._method())._scope())._alias()).__comma(")})"));
 return self}, function($ctx1) {$ctx1.fill(self,"nextPutBlockContextFor:during:", [anIRClosure,aBlock], {}, smalltalk.JSStream)})}
 }),
 smalltalk.JSStream);

+ 79 - 9
js/Compiler-IR.js

@@ -770,6 +770,22 @@ referencedClasses: []
 }),
 smalltalk.IRInstruction);
 
+smalltalk.addMethod(
+"_isMethod",
+smalltalk.method({
+selector: "isMethod",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return false;
+}, function($ctx1) {$ctx1.fill(self,"isMethod", [], {}, smalltalk.IRInstruction)})},
+args: [],
+source: "isMethod\x0a\x09^ false",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
 smalltalk.addMethod(
 "_isReturn",
 smalltalk.method({
@@ -850,6 +866,24 @@ referencedClasses: []
 }),
 smalltalk.IRInstruction);
 
+smalltalk.addMethod(
+"_method",
+smalltalk.method({
+selector: "method",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=_st(_st(self)._parent())._method();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"method", [], {}, smalltalk.IRInstruction)})},
+args: [],
+source: "method\x0a\x09^ self parent method",
+messageSends: ["method", "parent"],
+referencedClasses: []
+}),
+smalltalk.IRInstruction);
+
 smalltalk.addMethod(
 "_parent",
 smalltalk.method({
@@ -1315,6 +1349,22 @@ referencedClasses: ["Set"]
 }),
 smalltalk.IRMethod);
 
+smalltalk.addMethod(
+"_isMethod",
+smalltalk.method({
+selector: "isMethod",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return true;
+}, function($ctx1) {$ctx1.fill(self,"isMethod", [], {}, smalltalk.IRMethod)})},
+args: [],
+source: "isMethod\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
 smalltalk.addMethod(
 "_messageSends",
 smalltalk.method({
@@ -1349,6 +1399,24 @@ referencedClasses: []
 }),
 smalltalk.IRMethod);
 
+smalltalk.addMethod(
+"_method",
+smalltalk.method({
+selector: "method",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"method", [], {}, smalltalk.IRMethod)})},
+args: [],
+source: "method\x0a\x09^ self",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.IRMethod);
+
 smalltalk.addMethod(
 "_scope_",
 smalltalk.method({
@@ -2741,7 +2809,7 @@ return _st($4)._nextPutFunctionWith_arguments_($5,_st(anIRMethod)._arguments());
 _st($1)._nextPutMethodDeclaration_with_($2,$3);
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRMethod:", [anIRMethod], {}, smalltalk.IRJSTranslator)})},
 args: ["anIRMethod"],
-source: "visitIRMethod: anIRMethod\x0a\x09self stream\x0a\x09\x09nextPutMethodDeclaration: anIRMethod \x0a\x09\x09with: [ self stream \x0a\x09\x09\x09nextPutFunctionWith: [ \x0a            \x09self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |\x0a    \x09\x09\x09\x09each name asVariableName ]).\x0a            \x09self stream nextPutContextFor: anIRMethod during: [\x0a\x09\x09\x09\x09anIRMethod internalVariables notEmpty ifTrue: [\x0a\x09\x09\x09\x09\x09self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |\x0a\x09\x09\x09\x09\x09\x09each variable alias ]) ].\x0a\x09\x09\x09\x09anIRMethod scope hasNonLocalReturn \x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09self stream nextPutNonLocalReturnHandlingWith: [\x0a\x09\x09\x09\x09\x09\x09\x09super visitIRMethod: anIRMethod ]]\x0a\x09\x09\x09\x09\x09ifFalse: [ super visitIRMethod: anIRMethod ]]]\x0a\x09\x09\x09arguments: anIRMethod arguments ]",
+source: "visitIRMethod: anIRMethod\x0a\x0a\x09self stream\x0a\x09\x09nextPutMethodDeclaration: anIRMethod \x0a\x09\x09with: [ self stream \x0a\x09\x09\x09nextPutFunctionWith: [ \x0a            \x09self stream nextPutVars: (anIRMethod tempDeclarations collect: [ :each |\x0a    \x09\x09\x09\x09each name asVariableName ]).\x0a            \x09self stream nextPutContextFor: anIRMethod during: [\x0a\x09\x09\x09\x09anIRMethod internalVariables notEmpty ifTrue: [\x0a\x09\x09\x09\x09\x09self stream nextPutVars: (anIRMethod internalVariables asArray collect: [ :each |\x0a\x09\x09\x09\x09\x09\x09each variable alias ]) ].\x0a\x09\x09\x09\x09anIRMethod scope hasNonLocalReturn \x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09self stream nextPutNonLocalReturnHandlingWith: [\x0a\x09\x09\x09\x09\x09\x09\x09super visitIRMethod: anIRMethod ]]\x0a\x09\x09\x09\x09\x09ifFalse: [ super visitIRMethod: anIRMethod ]]]\x0a\x09\x09\x09arguments: anIRMethod arguments ]",
 messageSends: ["nextPutMethodDeclaration:with:", "nextPutFunctionWith:arguments:", "nextPutVars:", "collect:", "asVariableName", "name", "tempDeclarations", "stream", "nextPutContextFor:during:", "ifTrue:", "alias", "variable", "asArray", "internalVariables", "notEmpty", "ifTrue:ifFalse:", "nextPutNonLocalReturnHandlingWith:", "visitIRMethod:", "hasNonLocalReturn", "scope", "arguments"],
 referencedClasses: []
 }),
@@ -3025,7 +3093,7 @@ selector: "nextPutBlockContextFor:during:",
 category: 'streaming',
 fn: function (anIRClosure,aBlock){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$3,$4,$5,$6,$7,$8;
 $1=self;
 _st($1)._nextPutAll_(_st(_st("return smalltalk.withContext(function(").__comma(_st(_st(anIRClosure)._scope())._alias())).__comma(") {"));
 $2=_st($1)._nextPutAll_(_st((smalltalk.String || String))._cr());
@@ -3035,9 +3103,9 @@ _st($3)._nextPutAll_(_st(_st("}, function(").__comma(_st(_st(anIRClosure)._scope
 $4=_st($3)._nextPutAll_(_st(_st(_st(anIRClosure)._scope())._alias()).__comma(".fillBlock(["));
 _st(_st(anIRClosure)._arguments())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._nextPutAll_(_st(each)._asVariableName());
-}, function($ctx2) {$ctx2.fillBlock([each], {})})}),(function(){
+}, function($ctx2) {$ctx2.fillBlock([each], {},$ctx1)})}),(function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._nextPutAll_(",");
-}, function($ctx2) {$ctx2.fillBlock([], {})})}));
+}, function($ctx2) {$ctx2.fillBlock([], {},$ctx1)})}));
 _st(self)._nextPutAll_("], {");
 _st(_st(anIRClosure)._tempDeclarations())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
$5=self;
@@ -3045,14 +3113,16 @@ _st($5)._nextPutAll_(_st(_st(each)._name())._asVariableName());
 _st($5)._nextPutAll_(":");
 $6=_st($5)._nextPutAll_(_st(_st(each)._name())._asVariableName());
 return $6;
-}, function($ctx2) {$ctx2.fillBlock([each], {})})}),(function(){
+}, function($ctx2) {$ctx2.fillBlock([each], {},$ctx1)})}),(function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._nextPutAll_(",");
-}, function($ctx2) {$ctx2.fillBlock([], {})})}));
-_st(self)._nextPutAll_("})})");
+}, function($ctx2) {$ctx2.fillBlock([], {},$ctx1)})}));
+$7=self;
+_st($7)._nextPutAll_("},");
+$8=_st($7)._nextPutAll_(_st(_st(_st(_st(anIRClosure)._method())._scope())._alias()).__comma(")})"));
 return self}, function($ctx1) {$ctx1.fill(self,"nextPutBlockContextFor:during:", [anIRClosure,aBlock], {}, smalltalk.JSStream)})},
 args: ["anIRClosure", "aBlock"],
-source: "nextPutBlockContextFor: anIRClosure during: aBlock\x0a\x09self \x0a    \x09nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; \x0a        nextPutAll: String cr.\x0a    \x0a    aBlock value.\x0a    \x0a    self \x0a    \x09nextPutAll: '}, function(', anIRClosure scope alias, ') {';\x0a        nextPutAll: anIRClosure scope alias, '.fillBlock(['.\x0a    \x0a    anIRClosure arguments \x0a    \x09do: [ :each | self nextPutAll: each asVariableName ]\x0a      \x09separatedBy: [ self nextPutAll: ','  ].\x0a    self nextPutAll: '], {'.\x0a    \x0a    anIRClosure tempDeclarations \x0a    \x09do: [ :each |\x0a    \x09\x09self \x0a        \x09\x09nextPutAll: each name asVariableName;\x0a           \x09 \x09nextPutAll: ':';\x0a        \x09\x09nextPutAll: each name asVariableName]\x0a\x09\x09separatedBy: [ self nextPutAll: ',' ].\x0a    \x0a    self\x0a    \x09nextPutAll: '})})'",
-messageSends: ["nextPutAll:", ",", "alias", "scope", "cr", "value", "do:separatedBy:", "asVariableName", "arguments", "name", "tempDeclarations"],
+source: "nextPutBlockContextFor: anIRClosure during: aBlock\x0a\x09self \x0a    \x09nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; \x0a        nextPutAll: String cr.\x0a    \x0a    aBlock value.\x0a    \x0a    self \x0a    \x09nextPutAll: '}, function(', anIRClosure scope alias, ') {';\x0a        nextPutAll: anIRClosure scope alias, '.fillBlock(['.\x0a    \x0a    anIRClosure arguments \x0a    \x09do: [ :each | self nextPutAll: each asVariableName ]\x0a      \x09separatedBy: [ self nextPutAll: ','  ].\x0a    self nextPutAll: '], {'.\x0a    \x0a    anIRClosure tempDeclarations \x0a    \x09do: [ :each |\x0a    \x09\x09self \x0a        \x09\x09nextPutAll: each name asVariableName;\x0a           \x09 \x09nextPutAll: ':';\x0a        \x09\x09nextPutAll: each name asVariableName]\x0a\x09\x09separatedBy: [ self nextPutAll: ',' ].\x0a    \x0a    self\x0a    \x09nextPutAll: '},';\x0a        nextPutAll:  anIRClosure method scope alias, ')})'",
+messageSends: ["nextPutAll:", ",", "alias", "scope", "cr", "value", "do:separatedBy:", "asVariableName", "arguments", "name", "tempDeclarations", "method"],
 referencedClasses: ["String"]
 }),
 smalltalk.JSStream);

+ 2 - 2
js/IDE.deploy.js

@@ -3199,12 +3199,12 @@ $2=li;
 _st($2)._with_(_st(aContext)._asString());
 $3=_st($2)._onClick_((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._selectContext_(aContext);
-}, function($ctx2) {$ctx2.fillBlock([], {})})}));
+}, function($ctx2) {$ctx2.fillBlock([], {},$ctx1)})}));
 $4=_st(aContext)._home();
 if(($receiver = $4) == nil || $receiver == undefined){
 $4;
 } else {
-_st(self)._renderContext_on_(_st(aContext)._home(),html);
+_st(self)._renderContext_on_(_st(aContext)._outerContext(),html);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"renderContext:on:", [aContext,html], {li:li}, smalltalk.Debugger)})}
 }),

+ 4 - 4
js/IDE.js

@@ -4020,17 +4020,17 @@ $2=li;
 _st($2)._with_(_st(aContext)._asString());
 $3=_st($2)._onClick_((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._selectContext_(aContext);
-}, function($ctx2) {$ctx2.fillBlock([], {})})}));
+}, function($ctx2) {$ctx2.fillBlock([], {},$ctx1)})}));
 $4=_st(aContext)._home();
 if(($receiver = $4) == nil || $receiver == undefined){
 $4;
 } else {
-_st(self)._renderContext_on_(_st(aContext)._home(),html);
+_st(self)._renderContext_on_(_st(aContext)._outerContext(),html);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"renderContext:on:", [aContext,html], {li:li}, smalltalk.Debugger)})},
 args: ["aContext", "html"],
-source: "renderContext: aContext on: html\x0a\x09| li |\x0a\x09li := html li.\x0a\x09selectedContext = aContext ifTrue: [\x0a\x09\x09li class: 'selected'].\x0a\x09li \x0a\x09\x09with: aContext asString;\x0a\x09\x09onClick: [self selectContext: aContext].\x0a\x09aContext home ifNotNil: [self renderContext: aContext home on: html]",
-messageSends: ["li", "ifTrue:", "class:", "=", "with:", "asString", "onClick:", "selectContext:", "ifNotNil:", "renderContext:on:", "home"],
+source: "renderContext: aContext on: html\x0a\x09| li |\x0a\x09li := html li.\x0a\x09selectedContext = aContext ifTrue: [\x0a\x09\x09li class: 'selected'].\x0a\x09li \x0a\x09\x09with: aContext asString;\x0a\x09\x09onClick: [self selectContext: aContext].\x0a\x09aContext home ifNotNil: [self renderContext: aContext outerContext on: html]",
+messageSends: ["li", "ifTrue:", "class:", "=", "with:", "asString", "onClick:", "selectContext:", "ifNotNil:", "renderContext:on:", "outerContext", "home"],
 referencedClasses: []
 }),
 smalltalk.Debugger);

+ 4 - 6
js/Kernel-Methods.deploy.js

@@ -749,7 +749,7 @@ smalltalk.method({
 selector: "home",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self.homeContext;
+return smalltalk.withContext(function($ctx1) { 
return self.methodContext || self.homeContext;
 return self}, function($ctx1) {$ctx1.fill(self,"home", [], {}, smalltalk.MethodContext)})}
 }),
 smalltalk.MethodContext);
@@ -803,7 +803,7 @@ if(! smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-$3=_st(self)._outerContext();
+$3=_st(self)._home();
 return $3;
 }, function($ctx1) {$ctx1.fill(self,"methodContext", [], {}, smalltalk.MethodContext)})}
 }),
@@ -815,10 +815,8 @@ smalltalk.method({
 selector: "outerContext",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(self)._home();
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"outerContext", [], {}, smalltalk.MethodContext)})}
+return smalltalk.withContext(function($ctx1) { 
return self.homeContext;
+return self}, function($ctx1) {$ctx1.fill(self,"outerContext", [], {}, smalltalk.MethodContext)})}
 }),
 smalltalk.MethodContext);
 

+ 9 - 11
js/Kernel-Methods.js

@@ -1025,10 +1025,10 @@ selector: "home",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self.homeContext;
+return smalltalk.withContext(function($ctx1) { 
return self.methodContext || self.homeContext;
 return self}, function($ctx1) {$ctx1.fill(self,"home", [], {}, smalltalk.MethodContext)})},
 args: [],
-source: "home\x0a\x09<return self.homeContext>",
+source: "home\x0a\x09<return self.methodContext || self.homeContext>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -1099,12 +1099,12 @@ if(! smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-$3=_st(self)._outerContext();
+$3=_st(self)._home();
 return $3;
 }, function($ctx1) {$ctx1.fill(self,"methodContext", [], {}, smalltalk.MethodContext)})},
 args: [],
-source: "methodContext\x0a\x09self isBlockContext ifFalse: [ ^ self ].\x0a    \x0a    ^ self outerContext",
-messageSends: ["ifFalse:", "isBlockContext", "outerContext"],
+source: "methodContext\x0a\x09self isBlockContext ifFalse: [ ^ self ].\x0a    \x0a    ^ self home",
+messageSends: ["ifFalse:", "isBlockContext", "home"],
 referencedClasses: []
 }),
 smalltalk.MethodContext);
@@ -1116,13 +1116,11 @@ selector: "outerContext",
 category: 'accessing',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1;
-$1=_st(self)._home();
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"outerContext", [], {}, smalltalk.MethodContext)})},
+return smalltalk.withContext(function($ctx1) { 
return self.homeContext;
+return self}, function($ctx1) {$ctx1.fill(self,"outerContext", [], {}, smalltalk.MethodContext)})},
 args: [],
-source: "outerContext\x0a\x09^ self home",
-messageSends: ["home"],
+source: "outerContext\x0a\x09<return self.homeContext>",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.MethodContext);

+ 4 - 1
js/boot.js

@@ -746,9 +746,12 @@ SmalltalkMethodContext.prototype.fill = function(receiver, selector, args, local
     this.lookupClass = lookupClass;
 };
 
-SmalltalkMethodContext.prototype.fillBlock = function(args, locals) {
+SmalltalkMethodContext.prototype.fillBlock = function(args, locals, ctx) {
     this.args        = args || [];
     this.locals      = locals || {};
+    if(ctx) {
+        this.methodContext = ctx;
+    }
 };
 
 SmalltalkMethodContext.prototype.init = function() {

+ 19 - 1
st/Compiler-IR.st

@@ -264,6 +264,10 @@ instructions
 	^ instructions ifNil: [ instructions := OrderedCollection new ]
 !
 
+method
+	^ self parent method
+!
+
 parent
 	^ parent
 !
@@ -316,6 +320,10 @@ isLocalReturn
 	^ false
 !
 
+isMethod
+	^ false
+!
+
 isReturn
 	^ false
 !
@@ -462,6 +470,10 @@ internalVariables
 	^ internalVariables ifNil: [ internalVariables := Set new ]
 !
 
+isMethod
+	^ true
+!
+
 messageSends
 	^ messageSends
 !
@@ -470,6 +482,10 @@ messageSends: aCollection
 	messageSends := aCollection
 !
 
+method
+	^ self
+!
+
 scope: aScope
 	super scope: aScope.
 	aScope instruction: self
@@ -911,6 +927,7 @@ visitIRDynamicDictionary: anIRDynamicDictionary
 !
 
 visitIRMethod: anIRMethod
+
 	self stream
 		nextPutMethodDeclaration: anIRMethod 
 		with: [ self stream 
@@ -1049,7 +1066,8 @@ nextPutBlockContextFor: anIRClosure during: aBlock
 		separatedBy: [ self nextPutAll: ',' ].
     
     self
-    	nextPutAll: '})})'
+    	nextPutAll: '},';
+        nextPutAll:  anIRClosure method scope alias, ')})'
 !
 
 nextPutClosureWith: aBlock arguments: anArray

+ 1 - 1
st/IDE.st

@@ -1461,7 +1461,7 @@ renderContext: aContext on: html
 	li 
 		with: aContext asString;
 		onClick: [self selectContext: aContext].
-	aContext home ifNotNil: [self renderContext: aContext home on: html]
+	aContext home ifNotNil: [self renderContext: aContext outerContext on: html]
 !
 
 renderTopPanelOn: html

+ 3 - 3
st/Kernel-Methods.st

@@ -366,7 +366,7 @@ asString
 !
 
 home
-	<return self.homeContext>
+	<return self.methodContext || self.homeContext>
 !
 
 locals
@@ -380,11 +380,11 @@ method
 methodContext
 	self isBlockContext ifFalse: [ ^ self ].
     
-    ^ self outerContext
+    ^ self home
 !
 
 outerContext
-	^ self home
+	<return self.homeContext>
 !
 
 pc