Explorar o código

Now <jsOverride:args:> works in interpreter.

Herby Vojčík %!s(int64=4) %!d(string=hai) anos
pai
achega
cabb6e24c6
Modificáronse 2 ficheiros con 76 adicións e 4 borrados
  1. 61 3
      lang/src/Compiler-Interpreter.js
  2. 15 1
      lang/src/Compiler-Interpreter.st

+ 61 - 3
lang/src/Compiler-Interpreter.js

@@ -2827,6 +2827,52 @@ return self;
 }; }),
 }; }),
 $globals.ASTInterpreter);
 $globals.ASTInterpreter);
 
 
+$core.addMethod(
+$core.method({
+selector: "sendJavaScript:superMessage:switcher:to:",
+protocol: "private",
+//>>excludeStart("ide", pragmas.excludeIdeData);
+args: ["aString", "aMessage", "aJSFunction", "anObject"],
+source: "sendJavaScript: aString superMessage: aMessage switcher: aJSFunction to: anObject\x0a\x09| methodBlock parent |\x0a\x09\x0a\x09parent := self context method methodClass superPrototype.\x0a\x09parent ifNil: [ ^ self messageNotUnderstood: aMessage receiver: anObject ].\x0a\x09\x0a\x09methodBlock := (parent at: aString)\x0a\x09\x09ifNil: [ ^ self messageNotUnderstood: aMessage receiver: anObject ].\x0a\x09\x09\x0a\x09^ methodBlock applyTo: anObject arguments: (aJSFunction applyTo: nil arguments: aMessage arguments)",
+referencedClasses: [],
+//>>excludeEnd("ide");
+pragmas: [],
+messageSends: ["superPrototype", "methodClass", "method", "context", "ifNil:", "messageNotUnderstood:receiver:", "at:", "applyTo:arguments:", "arguments"]
+}, function ($methodClass){ return function (aString,aMessage,aJSFunction,anObject){
+var self=this,$self=this;
+var methodBlock,parent;
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+return $core.withContext(function($ctx1) {
+//>>excludeEnd("ctx");
+var $1,$2;
+parent=$recv($recv($recv($self._context())._method())._methodClass())._superPrototype();
+$1=parent;
+if($1 == null || $1.a$nil){
+return [$self._messageNotUnderstood_receiver_(aMessage,anObject)
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx1.sendIdx["messageNotUnderstood:receiver:"]=1
+//>>excludeEnd("ctx");
+][0];
+} else {
+$1;
+}
+$2=$recv(parent)._at_(aString);
+if($2 == null || $2.a$nil){
+return $self._messageNotUnderstood_receiver_(aMessage,anObject);
+} else {
+methodBlock=$2;
+}
+return [$recv(methodBlock)._applyTo_arguments_(anObject,$recv(aJSFunction)._applyTo_arguments_(nil,$recv(aMessage)._arguments()))
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx1.sendIdx["applyTo:arguments:"]=1
+//>>excludeEnd("ctx");
+][0];
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+}, function($ctx1) {$ctx1.fill(self,"sendJavaScript:superMessage:switcher:to:",{aString:aString,aMessage:aMessage,aJSFunction:aJSFunction,anObject:anObject,methodBlock:methodBlock,parent:parent})});
+//>>excludeEnd("ctx");
+}; }),
+$globals.ASTInterpreter);
+
 $core.addMethod(
 $core.addMethod(
 $core.method({
 $core.method({
 selector: "sendJavaScript:superMessage:to:",
 selector: "sendJavaScript:superMessage:to:",
@@ -3347,17 +3393,18 @@ selector: "visitSendNode:",
 protocol: "visiting",
 protocol: "visiting",
 //>>excludeStart("ide", pragmas.excludeIdeData);
 //>>excludeStart("ide", pragmas.excludeIdeData);
 args: ["aNode"],
 args: ["aNode"],
-source: "visitSendNode: aNode\x0a\x09| receiver args message result |\x0a\x09\x0a\x09args := aNode arguments collect: [ :each | self pop ].\x0a\x09receiver := self peek.\x0a\x09\x0a\x09message := self\x0a\x09\x09messageFromSendNode: aNode\x0a\x09\x09arguments: args reversed.\x0a\x09\x0a\x09result := aNode superSend\x0a\x09\x09ifFalse: [ message sendTo: receiver ]\x0a\x09\x09ifTrue: [ aNode receiver binding isJavaScriptSuper\x0a\x09\x09\x09ifFalse: [ self sendSuperMessage: message to: receiver ]\x0a\x09\x09\x09ifTrue: [ self sendJavaScript: aNode javaScriptSelector superMessage: message to: receiver ] ].\x0a\x09\x0a\x09\x22For cascade sends, push the reciever if the send is not the last one\x22\x0a\x09aNode isSideEffect ifFalse: [ self pop; push: result ]",
+source: "visitSendNode: aNode\x0a\x09| receiver args message result |\x0a\x09\x0a\x09args := aNode arguments collect: [ :each | self pop ].\x0a\x09receiver := self peek.\x0a\x09\x0a\x09message := self\x0a\x09\x09messageFromSendNode: aNode\x0a\x09\x09arguments: args reversed.\x0a\x09\x0a\x09result := aNode superSend\x0a\x09\x09ifFalse: [ message sendTo: receiver ]\x0a\x09\x09ifTrue: [ aNode receiver binding isJavaScriptSuper\x0a\x09\x09\x09ifFalse: [ self sendSuperMessage: message to: receiver ]\x0a\x09\x09\x09ifTrue: [ aNode argumentSwitcher\x0a\x09\x09\x09\x09ifNil: [ self sendJavaScript: aNode javaScriptSelector superMessage: message to: receiver ]\x0a\x09\x09\x09\x09ifNotNil: [ :switcher | self sendJavaScript: aNode javaScriptSelector superMessage: message switcher: switcher to: receiver ] ] ].\x0a\x09\x0a\x09\x22For cascade sends, push the reciever if the send is not the last one\x22\x0a\x09aNode isSideEffect ifFalse: [ self pop; push: result ]",
 referencedClasses: [],
 referencedClasses: [],
 //>>excludeEnd("ide");
 //>>excludeEnd("ide");
 pragmas: [],
 pragmas: [],
-messageSends: ["collect:", "arguments", "pop", "peek", "messageFromSendNode:arguments:", "reversed", "ifFalse:ifTrue:", "superSend", "sendTo:", "isJavaScriptSuper", "binding", "receiver", "sendSuperMessage:to:", "sendJavaScript:superMessage:to:", "javaScriptSelector", "ifFalse:", "isSideEffect", "push:"]
+messageSends: ["collect:", "arguments", "pop", "peek", "messageFromSendNode:arguments:", "reversed", "ifFalse:ifTrue:", "superSend", "sendTo:", "isJavaScriptSuper", "binding", "receiver", "sendSuperMessage:to:", "ifNil:ifNotNil:", "argumentSwitcher", "sendJavaScript:superMessage:to:", "javaScriptSelector", "sendJavaScript:superMessage:switcher:to:", "ifFalse:", "isSideEffect", "push:"]
 }, function ($methodClass){ return function (aNode){
 }, function ($methodClass){ return function (aNode){
 var self=this,$self=this;
 var self=this,$self=this;
 var receiver,args,message,result;
 var receiver,args,message,result;
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx1) {
 return $core.withContext(function($ctx1) {
 //>>excludeEnd("ctx");
 //>>excludeEnd("ctx");
+var $1;
 args=$recv($recv(aNode)._arguments())._collect_((function(each){
 args=$recv($recv(aNode)._arguments())._collect_((function(each){
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 //>>excludeStart("ctx", pragmas.excludeDebugContexts);
 return $core.withContext(function($ctx2) {
 return $core.withContext(function($ctx2) {
@@ -3375,7 +3422,18 @@ receiver=$self._peek();
 message=$self._messageFromSendNode_arguments_(aNode,$recv(args)._reversed());
 message=$self._messageFromSendNode_arguments_(aNode,$recv(args)._reversed());
 if($core.assert($recv(aNode)._superSend())){
 if($core.assert($recv(aNode)._superSend())){
 if($core.assert($recv($recv($recv(aNode)._receiver())._binding())._isJavaScriptSuper())){
 if($core.assert($recv($recv($recv(aNode)._receiver())._binding())._isJavaScriptSuper())){
-result=$self._sendJavaScript_superMessage_to_($recv(aNode)._javaScriptSelector(),message,receiver);
+$1=$recv(aNode)._argumentSwitcher();
+if($1 == null || $1.a$nil){
+result=$self._sendJavaScript_superMessage_to_([$recv(aNode)._javaScriptSelector()
+//>>excludeStart("ctx", pragmas.excludeDebugContexts);
+,$ctx1.sendIdx["javaScriptSelector"]=1
+//>>excludeEnd("ctx");
+][0],message,receiver);
+} else {
+var switcher;
+switcher=$1;
+result=$self._sendJavaScript_superMessage_switcher_to_($recv(aNode)._javaScriptSelector(),message,switcher,receiver);
+}
 } else {
 } else {
 result=$self._sendSuperMessage_to_(message,receiver);
 result=$self._sendSuperMessage_to_(message,receiver);
 }
 }

+ 15 - 1
lang/src/Compiler-Interpreter.st

@@ -736,6 +736,18 @@ messageNotUnderstood: aMessage receiver: anObject
 		signal
 		signal
 !
 !
 
 
+sendJavaScript: aString superMessage: aMessage switcher: aJSFunction to: anObject
+	| methodBlock parent |
+	
+	parent := self context method methodClass superPrototype.
+	parent ifNil: [ ^ self messageNotUnderstood: aMessage receiver: anObject ].
+	
+	methodBlock := (parent at: aString)
+		ifNil: [ ^ self messageNotUnderstood: aMessage receiver: anObject ].
+		
+	^ methodBlock applyTo: anObject arguments: (aJSFunction applyTo: nil arguments: aMessage arguments)
+!
+
 sendJavaScript: aString superMessage: aMessage to: anObject
 sendJavaScript: aString superMessage: aMessage to: anObject
 	| methodBlock parent |
 	| methodBlock parent |
 	
 	
@@ -888,7 +900,9 @@ visitSendNode: aNode
 		ifFalse: [ message sendTo: receiver ]
 		ifFalse: [ message sendTo: receiver ]
 		ifTrue: [ aNode receiver binding isJavaScriptSuper
 		ifTrue: [ aNode receiver binding isJavaScriptSuper
 			ifFalse: [ self sendSuperMessage: message to: receiver ]
 			ifFalse: [ self sendSuperMessage: message to: receiver ]
-			ifTrue: [ self sendJavaScript: aNode javaScriptSelector superMessage: message to: receiver ] ].
+			ifTrue: [ aNode argumentSwitcher
+				ifNil: [ self sendJavaScript: aNode javaScriptSelector superMessage: message to: receiver ]
+				ifNotNil: [ :switcher | self sendJavaScript: aNode javaScriptSelector superMessage: message switcher: switcher to: receiver ] ] ].
 	
 	
 	"For cascade sends, push the reciever if the send is not the last one"
 	"For cascade sends, push the reciever if the send is not the last one"
 	aNode isSideEffect ifFalse: [ self pop; push: result ]
 	aNode isSideEffect ifFalse: [ self pop; push: result ]