[squeak-dev] Retrying a message send

Igor Stasenko siguctua at gmail.com
Mon Apr 12 18:56:01 UTC 2010


On 12 April 2010 21:28, Eliot Miranda <eliot.miranda at gmail.com> wrote:
>
>
> On Sun, Apr 11, 2010 at 1:33 AM, Igor Stasenko <siguctua at gmail.com> wrote:
>>
>> Hello,
>>
>> suppose you having a method:
>>
>> foo
>>  <primitive: ... >
>>  self recompileAndRetry
>>
>>
>> a #recompileAndRetry should do following:
>>  1) recompile method #foo and install new version of #foo into class
>>  2) restart execution from callee of #foo, so that it will call the
>> same method again (but its renewed version)
>>
>>
>> This is similar to what debugger does, when you changing a method in
>> code pane and accepting it, except that it restarting a
>> context of called method, instead of restarting from a point where
>> caller context did a message send (and so, if a new method contains a
>> primitive,
>> it will be called by VM).
>>
>> Any ideas, how i can do (2) easily?
>
> One trick is to return the result of compileAndRetry, e.g.
> foo
>  <primitive: ... >
>  ^self recompileAndRetry
> or e.g.
> foo
>  <primitive: ... error: error>
>  (self shouldRecompileAndRetry: error) ifTrue:
>       [^self recompileAndRetry].
>   self primitiveFailed
>
> you then don't need to worry about munging the stack to get it right.  You
> simply answer the result of tail-calling the primitive again at the end of
> recompileAndRetry.  That's what VisualWorks does with FFI and user primitive
> calls that can fail because they're not yet linked.  Searching for symbols
> in libraries and loading libraries is all done with image code invoked from
> e.g. ^self externalCallError: errorCode.

Thanks. That's what i actually came to myself:
- loading library
- loading library function
- generating callout code
- installing the code into a method
- perform the method as a tail-call with same arguments

I just was a little concerned that my method can't see its original
caller (a context which originally made a call),
so a method can't rely on a stack structure.

> HTH
> Eliot
>>
>> My own thoughts is following:
>>
>> recompileAndRetry
>>   | retryCtx retryMethod caller method rcvr |
>>   retryCtx := thisContext sender.
>>   caller := retryCtx sender.
>>
>>   method := retryCtx method.
>>   "here we recompile a method, like following: "
>>   method := method methodClass recompile: method selector.
>>
>>   "now we're resending the same message"
>>   args := Array new: method numArgs.
>>   1 to: args size do: [ :i |  args at: i put: (retryCtx tempAt: i) ].
>>
>>
>>   thisContext terminateTo: caller.
>>   ^ retryCtx receiver perform: method selector arguments: args
>>
>>
>> --
>> Best regards,
>> Igor Stasenko AKA sig.
>>
>
>
>
>
>



-- 
Best regards,
Igor Stasenko AKA sig.



More information about the Squeak-dev mailing list