Parcourir la source

more debugger and context improvements

Nicolas Petton il y a 11 ans
Parent
commit
65d9f69bc5

+ 56 - 11
js/Compiler-Interpreter.deploy.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Compiler-Interpreter');
-smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'innerContext', 'pc', 'locals', 'method', 'ast', 'interpreter', 'methodContext'], 'Compiler-Interpreter');
+smalltalk.addClass('AIContext', smalltalk.Object, ['outerContext', 'innerContext', 'homeContext', 'pc', 'locals', 'method', 'ast', 'interpreter', 'methodContext', 'homeMethodContext'], 'Compiler-Interpreter');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "arguments",
@@ -54,16 +54,41 @@ selector: "home",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._homeContext();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"home",{},smalltalk.AIContext)})},
+messageSends: ["homeContext"]}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "homeContext",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
-$2=self._isBlockContext();
-if(smalltalk.assert($2)){
-$1=_st(self._outerContext())._methodContext();
+$2=self["@homeContext"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@homeContext"]=_st(self["@homeMethodContext"])._aiContext();
+$1=self["@homeContext"];
 } else {
-$1=self;
+$1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"home",{},smalltalk.AIContext)})},
-messageSends: ["ifTrue:ifFalse:", "methodContext", "outerContext", "isBlockContext"]}),
+}, function($ctx1) {$ctx1.fill(self,"homeContext",{},smalltalk.AIContext)})},
+messageSends: ["ifNil:", "aiContext"]}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "homeContext:",
+fn: function (aContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@homeContext"]=aContext;
+return self}, function($ctx1) {$ctx1.fill(self,"homeContext:",{aContext:aContext},smalltalk.AIContext)})},
+messageSends: []}),
 smalltalk.AIContext);
 
 smalltalk.addMethod(
@@ -87,6 +112,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 self["@methodContext"]=aMethodContext;
+self["@homeMethodContext"]=_st(aMethodContext)._home();
 self._pc_(_st(aMethodContext)._pc());
 self._receiver_(_st(aMethodContext)._receiver());
 self._method_(_st(aMethodContext)._method());
@@ -108,7 +134,7 @@ return _st(self._locals())._at_put_(key,value);
 }, function($ctx2) {$ctx2.fillBlock({key:key,value:value},$ctx1)})}));
 };
 return self}, function($ctx1) {$ctx1.fill(self,"initializeFromMethodContext:",{aMethodContext:aMethodContext},smalltalk.AIContext)})},
-messageSends: ["pc:", "pc", "receiver:", "receiver", "method:", "method", "ifNotNil:", "outerContext:", "fromMethodContext:", "outerContext", "class", "methodContext", "keysAndValuesDo:", "at:put:", "locals"]}),
+messageSends: ["home", "pc:", "pc", "receiver:", "receiver", "method:", "method", "ifNotNil:", "outerContext", "methodContext", "outerContext:", "fromMethodContext:", "class", "keysAndValuesDo:", "locals", "at:put:"]}),
 smalltalk.AIContext);
 
 smalltalk.addMethod(
@@ -129,7 +155,7 @@ if(! smalltalk.assert($3)){
 self._setupInterpreter_(self["@interpreter"]);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"initializeInterpreter",{},smalltalk.AIContext)})},
-messageSends: ["context:", "new", "node:", "retrieveNode", "yourself", "ifFalse:", "setupInterpreter:", "isBlockContext", "innerContext"]}),
+messageSends: ["context:", "new", "node:", "retrieveNode", "yourself", "ifFalse:", "isBlockContext", "innerContext", "setupInterpreter:"]}),
 smalltalk.AIContext);
 
 smalltalk.addMethod(
@@ -383,7 +409,7 @@ $1=_st(self._method())._selector();
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"selector",{},smalltalk.AIContext)})},
-messageSends: ["ifNotNil:", "selector", "method"]}),
+messageSends: ["ifNotNil:", "method", "selector"]}),
 smalltalk.AIContext);
 
 smalltalk.addMethod(
@@ -398,7 +424,7 @@ return _st(anInterpreter)._push_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(anInterpreter)._push_(_st(self._innerContext())._receiver());
 return self}, function($ctx1) {$ctx1.fill(self,"setupInterpreter:",{anInterpreter:anInterpreter},smalltalk.AIContext)})},
-messageSends: ["do:", "push:", "reversed", "arguments", "innerContext", "receiver"]}),
+messageSends: ["do:", "reversed", "arguments", "innerContext", "push:", "receiver"]}),
 smalltalk.AIContext);
 
 
@@ -2052,6 +2078,25 @@ smalltalk.Interpreter);
 
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "aiContext",
+fn: function (){
+var self=this;
+function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self._basicAt_("aiContext");
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._basicAt_put_("aiContext",_st($AIContext())._fromMethodContext_(self));
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"aiContext",{},smalltalk.MethodContext)})},
+messageSends: ["ifNil:", "basicAt:", "basicAt:put:", "fromMethodContext:"]}),
+smalltalk.MethodContext);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "interpreter:continue:",

+ 73 - 13
js/Compiler-Interpreter.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Compiler-Interpreter');
-smalltalk.addClass('AIContext', smalltalk.NodeVisitor, ['outerContext', 'innerContext', 'pc', 'locals', 'method', 'ast', 'interpreter', 'methodContext'], 'Compiler-Interpreter');
+smalltalk.addClass('AIContext', smalltalk.Object, ['outerContext', 'innerContext', 'homeContext', 'pc', 'locals', 'method', 'ast', 'interpreter', 'methodContext', 'homeMethodContext'], 'Compiler-Interpreter');
 smalltalk.AIContext.comment="I am like a `MethodContext`, used by the `ASTInterpreter`.\x0aUnlike a `MethodContext`, my instances are not read-only.\x0a\x0aWhen debugging, my instances are created by copying the current `MethodContext` (thisContext)";
 smalltalk.addMethod(
 smalltalk.method({
@@ -71,18 +71,53 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._homeContext();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"home",{},smalltalk.AIContext)})},
+args: [],
+source: "home\x0a\x09^ self homeContext",
+messageSends: ["homeContext"],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "homeContext",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
-$2=self._isBlockContext();
-if(smalltalk.assert($2)){
-$1=_st(self._outerContext())._methodContext();
+$2=self["@homeContext"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@homeContext"]=_st(self["@homeMethodContext"])._aiContext();
+$1=self["@homeContext"];
 } else {
-$1=self;
+$1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"home",{},smalltalk.AIContext)})},
+}, function($ctx1) {$ctx1.fill(self,"homeContext",{},smalltalk.AIContext)})},
 args: [],
-source: "home\x0a\x09^ self isBlockContext \x0a\x09\x09ifTrue: [ self outerContext methodContext ]\x0a\x09\x09ifFalse: [ self ]",
-messageSends: ["ifTrue:ifFalse:", "methodContext", "outerContext", "isBlockContext"],
+source: "homeContext\x0a\x09^ homeContext ifNil: [ homeContext := homeMethodContext aiContext ]",
+messageSends: ["ifNil:", "aiContext"],
+referencedClasses: []
+}),
+smalltalk.AIContext);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "homeContext:",
+category: 'accessing',
+fn: function (aContext){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@homeContext"]=aContext;
+return self}, function($ctx1) {$ctx1.fill(self,"homeContext:",{aContext:aContext},smalltalk.AIContext)})},
+args: ["aContext"],
+source: "homeContext: aContext\x0a\x09homeContext := aContext",
+messageSends: [],
 referencedClasses: []
 }),
 smalltalk.AIContext);
@@ -114,6 +149,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
 self["@methodContext"]=aMethodContext;
+self["@homeMethodContext"]=_st(aMethodContext)._home();
 self._pc_(_st(aMethodContext)._pc());
 self._receiver_(_st(aMethodContext)._receiver());
 self._method_(_st(aMethodContext)._method());
@@ -136,8 +172,8 @@ return _st(self._locals())._at_put_(key,value);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"initializeFromMethodContext:",{aMethodContext:aMethodContext},smalltalk.AIContext)})},
 args: ["aMethodContext"],
-source: "initializeFromMethodContext: aMethodContext\x0a\x09methodContext := aMethodContext.\x0a\x09\x0a\x09self pc: aMethodContext pc.\x0a\x09self receiver: aMethodContext receiver.\x0a\x09self method: aMethodContext method.\x0a\x09aMethodContext outerContext ifNotNil: [ :outer |\x0a\x09\x09\x22If the method context is nil, the block was defined in JS, so ignore it\x22\x0a\x09\x09outer methodContext ifNotNil: [\x0a\x09\x09\x09self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].\x0a\x09\x09\x09aMethodContext locals keysAndValuesDo: [ :key :value |\x0a\x09\x09\x09\x09self locals at: key put: value ] ]",
-messageSends: ["pc:", "pc", "receiver:", "receiver", "method:", "method", "ifNotNil:", "outerContext:", "fromMethodContext:", "outerContext", "class", "methodContext", "keysAndValuesDo:", "at:put:", "locals"],
+source: "initializeFromMethodContext: aMethodContext\x0a\x09methodContext := aMethodContext.\x0a\x09homeMethodContext := aMethodContext home.\x0a\x0a\x09self pc: aMethodContext pc.\x0a\x09self receiver: aMethodContext receiver.\x0a\x09self method: aMethodContext method.\x0a\x09aMethodContext outerContext ifNotNil: [ :outer |\x0a\x09\x09\x22If the method context is nil, the block was defined in JS, so ignore it\x22\x0a\x09\x09outer methodContext ifNotNil: [\x0a\x09\x09\x09self outerContext: (self class fromMethodContext: aMethodContext outerContext) ].\x0a\x09\x09\x09aMethodContext locals keysAndValuesDo: [ :key :value |\x0a\x09\x09\x09\x09self locals at: key put: value ] ]",
+messageSends: ["home", "pc:", "pc", "receiver:", "receiver", "method:", "method", "ifNotNil:", "outerContext", "methodContext", "outerContext:", "fromMethodContext:", "class", "keysAndValuesDo:", "locals", "at:put:"],
 referencedClasses: []
 }),
 smalltalk.AIContext);
@@ -163,7 +199,7 @@ self._setupInterpreter_(self["@interpreter"]);
 return self}, function($ctx1) {$ctx1.fill(self,"initializeInterpreter",{},smalltalk.AIContext)})},
 args: [],
 source: "initializeInterpreter\x0a\x09interpreter := Interpreter new\x0a\x09\x09context: self;\x0a\x09\x09node: self retrieveNode;\x0a\x09\x09yourself.\x0a\x09self innerContext isBlockContext ifFalse: [\x0a\x09\x09self setupInterpreter: interpreter ]",
-messageSends: ["context:", "new", "node:", "retrieveNode", "yourself", "ifFalse:", "setupInterpreter:", "isBlockContext", "innerContext"],
+messageSends: ["context:", "new", "node:", "retrieveNode", "yourself", "ifFalse:", "isBlockContext", "innerContext", "setupInterpreter:"],
 referencedClasses: ["Interpreter"]
 }),
 smalltalk.AIContext);
@@ -507,7 +543,7 @@ return $1;
 }, function($ctx1) {$ctx1.fill(self,"selector",{},smalltalk.AIContext)})},
 args: [],
 source: "selector\x0a\x09^ self method ifNotNil: [ \x0a\x09\x09self method selector ]",
-messageSends: ["ifNotNil:", "selector", "method"],
+messageSends: ["ifNotNil:", "method", "selector"],
 referencedClasses: []
 }),
 smalltalk.AIContext);
@@ -527,7 +563,7 @@ _st(anInterpreter)._push_(_st(self._innerContext())._receiver());
 return self}, function($ctx1) {$ctx1.fill(self,"setupInterpreter:",{anInterpreter:anInterpreter},smalltalk.AIContext)})},
 args: ["anInterpreter"],
 source: "setupInterpreter: anInterpreter\x0a\x09\x22Push the send args and receiver to the interpreter stack\x22\x0a\x09\x0a\x09self innerContext arguments reversed do: [ :each | \x0a\x09\x09anInterpreter push: each ].\x0a\x09\x09\x0a\x09anInterpreter push: (self innerContext receiver)",
-messageSends: ["do:", "push:", "reversed", "arguments", "innerContext", "receiver"],
+messageSends: ["do:", "reversed", "arguments", "innerContext", "push:", "receiver"],
 referencedClasses: []
 }),
 smalltalk.AIContext);
@@ -2702,6 +2738,30 @@ smalltalk.Interpreter);
 
 
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "aiContext",
+category: '*Compiler-Interpreter',
+fn: function (){
+var self=this;
+function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self._basicAt_("aiContext");
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._basicAt_put_("aiContext",_st($AIContext())._fromMethodContext_(self));
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"aiContext",{},smalltalk.MethodContext)})},
+args: [],
+source: "aiContext\x0a\x09^ (self basicAt: 'aiContext') ifNil: [\x0a\x09\x09self basicAt: 'aiContext' put: (AIContext fromMethodContext: self) ]",
+messageSends: ["ifNil:", "basicAt:", "basicAt:put:", "fromMethodContext:"],
+referencedClasses: ["AIContext"]
+}),
+smalltalk.MethodContext);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "interpreter:continue:",

+ 2 - 3
js/Helios-Debugger.deploy.js

@@ -541,12 +541,11 @@ smalltalk.method({
 selector: "initializeFromContext:",
 fn: function (aMethodContext){
 var self=this;
-function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
 return smalltalk.withContext(function($ctx1) { 
-self["@rootContext"]=_st($AIContext())._fromMethodContext_(aMethodContext);
+self["@rootContext"]=_st(aMethodContext)._aiContext();
 self._initializeContexts();
 return self}, function($ctx1) {$ctx1.fill(self,"initializeFromContext:",{aMethodContext:aMethodContext},smalltalk.HLDebuggerModel)})},
-messageSends: ["fromMethodContext:", "initializeContexts"]}),
+messageSends: ["aiContext", "initializeContexts"]}),
 smalltalk.HLDebuggerModel);
 
 smalltalk.addMethod(

+ 4 - 5
js/Helios-Debugger.js

@@ -709,15 +709,14 @@ selector: "initializeFromContext:",
 category: 'initialization',
 fn: function (aMethodContext){
 var self=this;
-function $AIContext(){return smalltalk.AIContext||(typeof AIContext=="undefined"?nil:AIContext)}
 return smalltalk.withContext(function($ctx1) { 
-self["@rootContext"]=_st($AIContext())._fromMethodContext_(aMethodContext);
+self["@rootContext"]=_st(aMethodContext)._aiContext();
 self._initializeContexts();
 return self}, function($ctx1) {$ctx1.fill(self,"initializeFromContext:",{aMethodContext:aMethodContext},smalltalk.HLDebuggerModel)})},
 args: ["aMethodContext"],
-source: "initializeFromContext: aMethodContext\x0a\x09rootContext := AIContext fromMethodContext: aMethodContext.\x0a\x09self initializeContexts",
-messageSends: ["fromMethodContext:", "initializeContexts"],
-referencedClasses: ["AIContext"]
+source: "initializeFromContext: aMethodContext\x0a\x09rootContext := aMethodContext aiContext.\x0a\x09self initializeContexts",
+messageSends: ["aiContext", "initializeContexts"],
+referencedClasses: []
 }),
 smalltalk.HLDebuggerModel);
 

+ 5 - 5
js/Kernel-Methods.deploy.js

@@ -1148,17 +1148,17 @@ if(! smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-$4=self._home();
+$4=self._outerContext();
 if(($receiver = $4) == nil || $receiver == undefined){
 $3=$4;
 } else {
-var home;
-home=$receiver;
-$3=_st(home)._methodContext();
+var outer;
+outer=$receiver;
+$3=_st(outer)._methodContext();
 };
 return $3;
 }, function($ctx1) {$ctx1.fill(self,"methodContext",{},smalltalk.MethodContext)})},
-messageSends: ["ifFalse:", "isBlockContext", "ifNotNil:", "methodContext", "home"]}),
+messageSends: ["ifFalse:", "isBlockContext", "ifNotNil:", "outerContext", "methodContext"]}),
 smalltalk.MethodContext);
 
 smalltalk.addMethod(

+ 6 - 6
js/Kernel-Methods.js

@@ -1555,19 +1555,19 @@ if(! smalltalk.assert($1)){
 $2=self;
 return $2;
 };
-$4=self._home();
+$4=self._outerContext();
 if(($receiver = $4) == nil || $receiver == undefined){
 $3=$4;
 } else {
-var home;
-home=$receiver;
-$3=_st(home)._methodContext();
+var outer;
+outer=$receiver;
+$3=_st(outer)._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 ifNotNil: [ :home |\x0a\x09\x09home methodContext ]",
-messageSends: ["ifFalse:", "isBlockContext", "ifNotNil:", "methodContext", "home"],
+source: "methodContext\x0a\x09self isBlockContext ifFalse: [ ^ self ].\x0a\x09\x0a\x09^ self outerContext ifNotNil: [ :outer |\x0a\x09\x09outer methodContext ]",
+messageSends: ["ifFalse:", "isBlockContext", "ifNotNil:", "outerContext", "methodContext"],
 referencedClasses: []
 }),
 smalltalk.MethodContext);

+ 20 - 6
st/Compiler-Interpreter.st

@@ -1,6 +1,6 @@
 Smalltalk current createPackage: 'Compiler-Interpreter'!
-NodeVisitor subclass: #AIContext
-	instanceVariableNames: 'outerContext innerContext pc locals method ast interpreter methodContext'
+Object subclass: #AIContext
+	instanceVariableNames: 'outerContext innerContext homeContext pc locals method ast interpreter methodContext homeMethodContext'
 	package: 'Compiler-Interpreter'!
 !AIContext commentStamp!
 I am like a `MethodContext`, used by the `ASTInterpreter`.
@@ -11,9 +11,15 @@ When debugging, my instances are created by copying the current `MethodContext`
 !AIContext methodsFor: 'accessing'!
 
 home
-	^ self isBlockContext 
-		ifTrue: [ self outerContext methodContext ]
-		ifFalse: [ self ]
+	^ self homeContext
+!
+
+homeContext
+	^ homeContext ifNil: [ homeContext := homeMethodContext aiContext ]
+!
+
+homeContext: aContext
+	homeContext := aContext
 !
 
 innerContext
@@ -76,7 +82,8 @@ initializeAST
 
 initializeFromMethodContext: aMethodContext
 	methodContext := aMethodContext.
-	
+	homeMethodContext := aMethodContext home.
+
 	self pc: aMethodContext pc.
 	self receiver: aMethodContext receiver.
 	self method: aMethodContext method.
@@ -975,6 +982,13 @@ visitVariableNode: aNode
 		ifFalse: [ self context localAt: aNode value ])
 ! !
 
+!MethodContext methodsFor: '*Compiler-Interpreter'!
+
+aiContext
+	^ (self basicAt: 'aiContext') ifNil: [
+		self basicAt: 'aiContext' put: (AIContext fromMethodContext: self) ]
+! !
+
 !Node methodsFor: '*Compiler-Interpreter'!
 
 interpreter: anInterpreter continue: aBlock

+ 1 - 1
st/Helios-Debugger.st

@@ -314,7 +314,7 @@ initializeContexts
 !
 
 initializeFromContext: aMethodContext
-	rootContext := AIContext fromMethodContext: aMethodContext.
+	rootContext := aMethodContext aiContext.
 	self initializeContexts
 ! !
 

+ 2 - 2
st/Kernel-Methods.st

@@ -576,8 +576,8 @@ method
 methodContext
 	self isBlockContext ifFalse: [ ^ self ].
 	
-	^ self home ifNotNil: [ :home |
-		home methodContext ]
+	^ self outerContext ifNotNil: [ :outer |
+		outer methodContext ]
 !
 
 outerContext