Dan, and all squeakers
However, execute... 3 perform: #zork: with: 4 and look at the debugger state. The message is fairly nicely packaged up ...snip...
when #zork: is sent to 3; the VM build aMessage (a Message with selector: zork: and arguments: (4 )) as a side effect for handling the #doesNotUnderstand: exeption. Then the debugger can show the message (and the receiver handle the exeption because this message has been created by the VM); but the #perform: does not generates message nor context. Please note that if you evaluate "3 perform: #zork: with: 4" in a workspace you will see the UndefinedObject>>Doit method and the SmallInteger(Object)>>doesNotUnderstand: method; but the SmallInteger(Object)>>perform: method will be absent!. The debugger show you the #perform: because he has the message built by the VM to handle the #doesNotUnderstand:.
In my problem the message is always implemented in the receiver using a litte method that connect to the server and download the real method only when needed; then the message does not fail (with #doesNotUnderstand:).
Attached to this mail you will find a little example to see the problem I'm trying to solve (in a non-dirty way). Please fileIn this change set and evaluate the expression: SwapperTest new test The test will fail when a #perform: message is sent. WARNING: do NOT save your image and reload the changeset prior to testing again.
Ale.
---------- De: Dan Ingalls[SMTP:DanI@wdi.disney.com] Enviado: Martes 25 de Agosto de 1998 09:58 Para: Alejandro F. Reimondo Cc: squeak@cs.uiuc.edu Asunto: Re: RV: "thisContext selector" (the revenge)
Ale -
I'm on the road and can't send a careful answer until later. However, execute...
3 perform: #zork: with: 4
and look at the debugger state. The message is fairly nicely packaged up and will even proceed properly if you define zork: before proceeding. So I would spend a while looking at what the debugger does. It should ultimately answer your need.
- Dan
what happens when you send a #perform: message? It is solved in a primitive method that sends the message inside the VM; activating a new method context to solve the performed message. Then, when I look for the sent message in the context, the message found is #perform:... and the activated method is NOT the #perform implementation Ouch! The #perform: implementation does not create a MethodContext because it is a primitive method! mmm... When I search in the contexts (actual and the sender's context) I can find the #perform: selector, but the arguments are missing ( has been absorbed by primitive) Provably the problem will be difficult to solve with the contexts information only...
Is there any known (easy) way to solve the #perform: problem?
thanks. Ale.
Attachment converted: Cog:SwapOut.zip (pZIP/pZIP) (0000E167)
Ale (and those who are following this adventure) -
I must apologize that my previous reply did not answer your real need. Also, I must apologize that I don't have a means right now to unzip the file you sent. However, I do think I understand enough of what you are trying to do to help with the next step.
The situation is that you have a single "stub" method installed in nearly every method slot in the system, whose sole function is to restore the proper method by some means, and then continue execution. You have managed to make this work normally, but the perform primitive slides its arguments down in the stack, obliterating the original selector, thus making it impossible to identify the proper method to be restored.
So, try this:
1. Define parallel methods to all the primitive perform methods with names such as primitivePerform:, primitivePerform:with:, and so on. All these methods may be identified by executing... Smalltalk browseAllSelect: [:m | m primitive between: 83 and: 84]
2. Redefine the current perform methods so that they simply make an indirect call on the new primitivePerform methods. For instance...
<Object>perform: aSymbol with: anObject "Access to the perform primitive passes indirectly through this method so that trapped calls on swapped out methods may have access to the selector."
^ self primitivePerform: aSymbol with: anObject
3. In your stub method, if the selector sent is found to be one of the perform selectors, then you can find the real selector in the (now accessible) intermediate activation of the non-primitive perform method.
Have fun!
- Dan
squeak-dev@lists.squeakfoundation.org