Переглянути джерело

Block contexts improvement: home is now different from outerContext

Nicolas Petton 11 роки тому
батько
коміт
555a0caff4

+ 2 - 2
js/Compiler-IR.deploy.js

@@ -2321,9 +2321,9 @@ return _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(")})"));
+$8=_st($7)._nextPutAll_(_st(_st(_st(_st(anIRClosure)._scope())._outerScope())._alias()).__comma(")})"));
 return self}, function($ctx1) {$ctx1.fill(self,"nextPutBlockContextFor:during:",{anIRClosure:anIRClosure,aBlock:aBlock},smalltalk.JSStream)})},
-messageSends: ["nextPutAll:", ",", "alias", "scope", "lf", "value", "do:separatedBy:", "asVariableName", "locals", "method"]}),
+messageSends: ["nextPutAll:", ",", "alias", "scope", "lf", "value", "do:separatedBy:", "asVariableName", "locals", "outerScope"]}),
 smalltalk.JSStream);
 
 smalltalk.addMethod(

+ 3 - 3
js/Compiler-IR.js

@@ -3096,11 +3096,11 @@ return _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(")})"));
+$8=_st($7)._nextPutAll_(_st(_st(_st(_st(anIRClosure)._scope())._outerScope())._alias()).__comma(")})"));
 return self}, function($ctx1) {$ctx1.fill(self,"nextPutBlockContextFor:during:",{anIRClosure:anIRClosure,aBlock:aBlock},smalltalk.JSStream)})},
 args: ["anIRClosure", "aBlock"],
-source: "nextPutBlockContextFor: anIRClosure during: aBlock\x0a\x09self\x0a\x09\x09nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; lf.\x0a\x09\x0a\x09aBlock value.\x0a\x09\x0a\x09self\x0a\x09\x09nextPutAll: '}, function(', anIRClosure scope alias, ') {';\x0a\x09\x09nextPutAll: anIRClosure scope alias, '.fillBlock({'.\x0a\x09\x0a\x09anIRClosure locals\x0a\x09\x09do: [ :each |\x0a\x09\x09\x09self\x0a\x09\x09\x09\x09nextPutAll: each asVariableName;\x0a\x09\x09\x09\x09nextPutAll: ':';\x0a\x09\x09\x09\x09nextPutAll: each asVariableName]\x0a\x09\x09separatedBy: [ self nextPutAll: ',' ].\x0a\x09\x0a\x09self\x0a\x09\x09nextPutAll: '},';\x0a\x09\x09nextPutAll: anIRClosure method scope alias, ')})'",
-messageSends: ["nextPutAll:", ",", "alias", "scope", "lf", "value", "do:separatedBy:", "asVariableName", "locals", "method"],
+source: "nextPutBlockContextFor: anIRClosure during: aBlock\x0a\x09self\x0a\x09\x09nextPutAll: 'return smalltalk.withContext(function(', anIRClosure scope alias, ') {'; lf.\x0a\x09\x0a\x09aBlock value.\x0a\x09\x0a\x09self\x0a\x09\x09nextPutAll: '}, function(', anIRClosure scope alias, ') {';\x0a\x09\x09nextPutAll: anIRClosure scope alias, '.fillBlock({'.\x0a\x09\x0a\x09anIRClosure locals\x0a\x09\x09do: [ :each |\x0a\x09\x09\x09self\x0a\x09\x09\x09\x09nextPutAll: each asVariableName;\x0a\x09\x09\x09\x09nextPutAll: ':';\x0a\x09\x09\x09\x09nextPutAll: each asVariableName]\x0a\x09\x09separatedBy: [ self nextPutAll: ',' ].\x0a\x09\x0a\x09self\x0a\x09\x09nextPutAll: '},';\x0a\x09\x09nextPutAll: anIRClosure scope outerScope alias, ')})'",
+messageSends: ["nextPutAll:", ",", "alias", "scope", "lf", "value", "do:separatedBy:", "asVariableName", "locals", "outerScope"],
 referencedClasses: []
 }),
 smalltalk.JSStream);

+ 23 - 11
js/Kernel-Methods.deploy.js

@@ -1041,13 +1041,13 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=_st(self)._isBlockContext();
 if(smalltalk.assert($2)){
-$1=_st(_st("a block (in ").__comma(_st(_st(_st(_st(self)._methodContext())._receiver())._class())._printString())).__comma(")");
+$1=_st(_st("a block (in ").__comma(_st(_st(self)._methodContext())._asString())).__comma(")");
 } else {
-$1=_st(_st(_st(_st(_st(self)._receiver())._class())._printString()).__comma(" >> ")).__comma(_st(self)._selector());
+$1=_st(_st(_st(_st(_st(self)._receiver())._class())._name()).__comma(" >> ")).__comma(_st(self)._selector());
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asString",{},smalltalk.MethodContext)})},
-messageSends: ["ifTrue:ifFalse:", ",", "printString", "class", "receiver", "methodContext", "selector", "isBlockContext"]}),
+messageSends: ["ifTrue:ifFalse:", ",", "asString", "methodContext", "selector", "name", "class", "receiver", "isBlockContext"]}),
 smalltalk.MethodContext);
 
 smalltalk.addMethod(
@@ -1056,7 +1056,7 @@ selector: "home",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return self.methodContext || self.homeContext;
+return self.homeContext;
 return self}, function($ctx1) {$ctx1.fill(self,"home",{},smalltalk.MethodContext)})},
 messageSends: []}),
 smalltalk.MethodContext);
@@ -1080,7 +1080,7 @@ selector: "locals",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return self.locals;
+return self.locals || {};
 return self}, function($ctx1) {$ctx1.fill(self,"locals",{},smalltalk.MethodContext)})},
 messageSends: []}),
 smalltalk.MethodContext);
@@ -1091,11 +1091,16 @@ selector: "method",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $2,$1;
+$2=_st(self)._methodContext();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=$2;
+} else {
 $1=_st(_st(_st(_st(self)._methodContext())._receiver())._class())._lookupSelector_(_st(_st(self)._methodContext())._selector());
+};
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"method",{},smalltalk.MethodContext)})},
-messageSends: ["lookupSelector:", "selector", "methodContext", "class", "receiver"]}),
+messageSends: ["ifNotNil:", "lookupSelector:", "selector", "methodContext", "class", "receiver"]}),
 smalltalk.MethodContext);
 
 smalltalk.addMethod(
@@ -1104,16 +1109,23 @@ selector: "methodContext",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3;
+var $1,$2,$4,$3;
 $1=_st(self)._isBlockContext();
 if(! smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-$3=_st(self)._home();
+$4=_st(self)._home();
+if(($receiver = $4) == nil || $receiver == undefined){
+$3=$4;
+} else {
+var home;
+home=$receiver;
+$3=_st(home)._methodContext();
+};
 return $3;
 }, function($ctx1) {$ctx1.fill(self,"methodContext",{},smalltalk.MethodContext)})},
-messageSends: ["ifFalse:", "isBlockContext", "home"]}),
+messageSends: ["ifFalse:", "isBlockContext", "ifNotNil:", "methodContext", "home"]}),
 smalltalk.MethodContext);
 
 smalltalk.addMethod(
@@ -1122,7 +1134,7 @@ selector: "outerContext",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return self.homeContext;
+return self.outerContext || self.homeContext;
 return self}, function($ctx1) {$ctx1.fill(self,"outerContext",{},smalltalk.MethodContext)})},
 messageSends: []}),
 smalltalk.MethodContext);

+ 29 - 17
js/Kernel-Methods.js

@@ -1413,15 +1413,15 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=_st(self)._isBlockContext();
 if(smalltalk.assert($2)){
-$1=_st(_st("a block (in ").__comma(_st(_st(_st(_st(self)._methodContext())._receiver())._class())._printString())).__comma(")");
+$1=_st(_st("a block (in ").__comma(_st(_st(self)._methodContext())._asString())).__comma(")");
 } else {
-$1=_st(_st(_st(_st(_st(self)._receiver())._class())._printString()).__comma(" >> ")).__comma(_st(self)._selector());
+$1=_st(_st(_st(_st(_st(self)._receiver())._class())._name()).__comma(" >> ")).__comma(_st(self)._selector());
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asString",{},smalltalk.MethodContext)})},
 args: [],
-source: "asString\x0a\x09^self isBlockContext\x0a\x09\x09ifTrue: [ 'a block (in ', self methodContext receiver class printString, ')' ]\x0a\x09\x09ifFalse: [ self receiver class printString, ' >> ', self selector ]",
-messageSends: ["ifTrue:ifFalse:", ",", "printString", "class", "receiver", "methodContext", "selector", "isBlockContext"],
+source: "asString\x0a\x09^self isBlockContext\x0a\x09\x09ifTrue: [ 'a block (in ', self methodContext asString, ')' ]\x0a\x09\x09ifFalse: [ self receiver class name, ' >> ', self selector ]",
+messageSends: ["ifTrue:ifFalse:", ",", "asString", "methodContext", "selector", "name", "class", "receiver", "isBlockContext"],
 referencedClasses: []
 }),
 smalltalk.MethodContext);
@@ -1433,10 +1433,10 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return self.methodContext || self.homeContext;
+return self.homeContext;
 return self}, function($ctx1) {$ctx1.fill(self,"home",{},smalltalk.MethodContext)})},
 args: [],
-source: "home\x0a\x09<return self.methodContext || self.homeContext>",
+source: "home\x0a\x09<return self.homeContext>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -1467,10 +1467,10 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return self.locals;
+return self.locals || {};
 return self}, function($ctx1) {$ctx1.fill(self,"locals",{},smalltalk.MethodContext)})},
 args: [],
-source: "locals\x0a\x09<return self.locals>",
+source: "locals\x0a\x09<return self.locals || {}>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -1483,13 +1483,18 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
+var $2,$1;
+$2=_st(self)._methodContext();
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=$2;
+} else {
 $1=_st(_st(_st(_st(self)._methodContext())._receiver())._class())._lookupSelector_(_st(_st(self)._methodContext())._selector());
+};
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"method",{},smalltalk.MethodContext)})},
 args: [],
-source: "method\x0a\x09^self methodContext receiver class lookupSelector: self methodContext selector",
-messageSends: ["lookupSelector:", "selector", "methodContext", "class", "receiver"],
+source: "method\x0a\x09^ self methodContext ifNotNil: [\x0a\x09\x09self methodContext receiver class lookupSelector: self methodContext selector ]",
+messageSends: ["ifNotNil:", "lookupSelector:", "selector", "methodContext", "class", "receiver"],
 referencedClasses: []
 }),
 smalltalk.MethodContext);
@@ -1501,18 +1506,25 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3;
+var $1,$2,$4,$3;
 $1=_st(self)._isBlockContext();
 if(! smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-$3=_st(self)._home();
+$4=_st(self)._home();
+if(($receiver = $4) == nil || $receiver == undefined){
+$3=$4;
+} else {
+var home;
+home=$receiver;
+$3=_st(home)._methodContext();
+};
 return $3;
 }, function($ctx1) {$ctx1.fill(self,"methodContext",{},smalltalk.MethodContext)})},
 args: [],
-source: "methodContext\x0a\x09self isBlockContext ifFalse: [ ^ self ].\x0a\x09\x0a\x09^ self home",
-messageSends: ["ifFalse:", "isBlockContext", "home"],
+source: "methodContext\x0a\x09self isBlockContext ifFalse: [ ^ self ].\x0a\x09\x0a\x09^ self home ifNotNil: [ :home |\x0a\x09\x09home methodContext ]",
+messageSends: ["ifFalse:", "isBlockContext", "ifNotNil:", "methodContext", "home"],
 referencedClasses: []
 }),
 smalltalk.MethodContext);
@@ -1524,10 +1536,10 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-return self.homeContext;
+return self.outerContext || self.homeContext;
 return self}, function($ctx1) {$ctx1.fill(self,"outerContext",{},smalltalk.MethodContext)})},
 args: [],
-source: "outerContext\x0a\x09<return self.homeContext>",
+source: "outerContext\x0a\x09<return self.outerContext || self.homeContext>",
 messageSends: [],
 referencedClasses: []
 }),

+ 1 - 1
js/boot.js

@@ -771,7 +771,7 @@ SmalltalkMethodContext.prototype.fill = function(receiver, selector, locals, loo
 
 SmalltalkMethodContext.prototype.fillBlock = function(locals, ctx) {
     this.locals        = locals || {};
-    this.methodContext = ctx;
+    this.outerContext  = ctx;
 };
 
 SmalltalkMethodContext.prototype.init = function() {

+ 1 - 1
st/Compiler-IR.st

@@ -1049,7 +1049,7 @@ nextPutBlockContextFor: anIRClosure during: aBlock
 	
 	self
 		nextPutAll: '},';
-		nextPutAll: anIRClosure method scope alias, ')})'
+		nextPutAll: anIRClosure scope outerScope alias, ')})'
 !
 
 nextPutClassRefFunction: aString

+ 9 - 7
st/Kernel-Methods.st

@@ -538,25 +538,27 @@ My instances are JavaScript `SmalltalkMethodContext` objects defined in `boot.js
 !MethodContext methodsFor: 'accessing'!
 
 home
-	<return self.methodContext || self.homeContext>
+	<return self.homeContext>
 !
 
 locals
-	<return self.locals>
+	<return self.locals || {}>
 !
 
 method
-	^self methodContext receiver class lookupSelector: self methodContext selector
+	^ self methodContext ifNotNil: [
+		self methodContext receiver class lookupSelector: self methodContext selector ]
 !
 
 methodContext
 	self isBlockContext ifFalse: [ ^ self ].
 	
-	^ self home
+	^ self home ifNotNil: [ :home |
+		home methodContext ]
 !
 
 outerContext
-	<return self.homeContext>
+	<return self.outerContext || self.homeContext>
 !
 
 pc
@@ -587,8 +589,8 @@ temps
 
 asString
 	^self isBlockContext
-		ifTrue: [ 'a block (in ', self methodContext receiver class printString, ')' ]
-		ifFalse: [ self receiver class printString, ' >> ', self selector ]
+		ifTrue: [ 'a block (in ', self methodContext asString, ')' ]
+		ifFalse: [ self receiver class name, ' >> ', self selector ]
 ! !
 
 !MethodContext methodsFor: 'printing'!