[squeak-dev] Simulation discrepancy with #return:

=?EUC-KR?B?sK3B+L/A?= jinoh67 at gmail.com
Thu Mar 15 09:50:06 UTC 2012


I think if it interprets pushThisContext and a push and a send to #return:,
It have to simulate return of the value of the push (next to
pushThisContext) but I don't know how to hack it.

- Jin-oh -
2012. 3. 14. ¿ÀÀü 3:37¿¡ "Eliot Miranda" <eliot.miranda at gmail.com>´ÔÀÌ ÀÛ¼º:

> Hi Yoshiki,  Hi Hans-Martin, Hi All,
>
> On Tue, Mar 13, 2012 at 10:25 AM, Yoshiki Ohshima <Yoshiki.Ohshima at acm.org
> > wrote:
>
>> At Tue, 13 Mar 2012 10:08:12 -0700,
>> Eliot Miranda wrote:
>> >
>> > In this case runUntilErrorOrReturnFrom: aContext should return the
>> sender of the activation of Foo>test and the result to be returned (42).
>>  But instead it answers the activation of Foo>test
>> > and nil.  Hence the return in ContextPart>return: isn't simulated and
>> control passes to the next statement, ^666.
>> >
>> > Once again I'm drawn into the bowels of runUntilErrorOrReturnFrom:
>> > :) It is my nemesis.
>>
>> This seems close to the realm of magic to me.  Thank you for looking
>> into it!
>>
>
> Alas, I find it near to magic too.  I understand what's going on.  The
> terminateTo: call in resume: doesn't trip the unwind-protect
> in runUntilErrorOrReturnFrom: (as it shouldn't; terminateTo: specifically
> doesn't run unwinds by design).  So runUntilErrorOrReturnFrom: doesn't
> answer the right context to resume.  It answers Foo>test instead of
> Foo>test's sender.
>
> What I don't understand is what is a valid criterion for determining these
> cases.  I can hack the method, special casing it for ContextPart>return:
> and ContextPart>resume:, but that's not acceptable.  So if anyone has the
> desire to pair on this let me know.  Perhaps we could have a go at it over
> skype sometime soon (not today; already blown a lot of time looking at this
> ;) ).
>
> In any case I've attached two versions of runUntilErrorOrReturnFrom:, one
> instrumented, one not, containing a hack that gets the right answer (in
> this case).  Yoshiki, you might play with the uninstrumented one to get you
> going.  Hans-Martin, I think you're one of very few people who could shed
> light on this.
>
> To use the instrumented one (which prints its arguments and halts between
> evaluation and deciding what to return) step the debugger up to e.g. the
> send of return:, inspect thisContext (the context about to be sent return:)
> and set ContextPart's class var QuickStep to that context (in the inspector
> evaluate QuickStep := self).  Then do step.
>
> At least the hack doesn't make things worse; the tests appear the same.
>
> So one thing to do is to play with the hack, ad see if it causes problems.
>  Another thing to do is to think about the criterion in the
> hacked runUntilErrorOrReturnFrom: when one should return from the
> receiver's receiver, rather from aSender's sender.
>
> I'm cc'ing the Pharo list.  Here's Yoshiki's original message and a
> substantive reply of mine:
>
>
> On Tue, Mar 13, 2012 at 3:27 AM, Yoshiki Ohshima <Yoshiki.Ohshima at acm.org>
>  wrote:
>
>>  Hello,
>
>>
> I noticed that step executing the following code in debugger yields
>
>> different results:
>
>>
> -------------------
>
>> test
>
>>
>        3 < 4 ifTrue: [
>
>>                thisContext return: 42].
>
>>        ^ 666.
>
>> -------------------
>
>>
> In the normal execution, you get 42 as expected, but if you debug it
>
>> and step execute, #return: does not actually return and you get 666.
>
>>
> It appears that the primitive for #terminateTo: is the culprit...
>
> -- Yoshiki
>
> On Tue, Mar 13, 2012 at 10:08 AM, Eliot Miranda <eliot.miranda at gmail.com>
>  wrote:
>
>> Hi Yoshiki,
>
> From what I can see so far it is the return value from
> runUntilErrorOrReturnFrom: in complete: when the debugger executes test's
> return: call.  i.e. the debugged process is in Foo>>test at pc 43:
>
> 37 <22> pushConstant: 3
> 38 <23> pushConstant: 4
> 39 <B2> send: <
> 40 <9B> jumpFalse: 45
> 41 <89> pushThisContext:
> 42 <21> pushConstant: 42
> 43 <E0> send: return:
> 44 <87> pop
> 45 <24> pushConstant: 666
> 46 <7C> returnTop
>
> The stack in the debugger is
> Process>>complete:
> Process>>completeStep:
> Debugger>>doStep
>
>
>
> and Process>complete: is
>
> complete: aContext
> "Run self until aContext is popped or an unhandled error is raised.
>  Return self's new top context, unless an unhandled error was raised then
> return the signaler context (rather than open a debugger)."
>
> | ctxt pair error |
> ctxt := suspendedContext.
> suspendedContext := nil.  "disable this process while running its stack in
> active process below"
>  pair := ctxt runUntilErrorOrReturnFrom: aContext.
> suspendedContext := pair first.
> error := pair second.
>  error ifNotNil: [^ error signalerContext].
> ^ suspendedContext
>
> where the receiver is the activation of Foo>test, and aContext is the
> activation of ContextPart>return: (whose receiver is also the receiver of
> complete:, the activation of Foo>test).
>
> In this case runUntilErrorOrReturnFrom: aContext should return the sender
> of the activation of Foo>test and the result to be returned (42).  But
> instead it answers the activation of Foo>test and nil.  Hence the return in
> ContextPart>return: isn't simulated and control passes to the next
> statement, ^666.
>
> Once again I'm drawn into the bowels of runUntilErrorOrReturnFrom: :) It
> is my nemesis.
> --
> best,
> Eliot
> --
> best,
> Eliot
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20120315/a9493ba5/attachment.htm


More information about the Squeak-dev mailing list