Hi,
I am playing around with the simulator (e.g., Context class >> #trace:). To make the simulation faster, I'd like to quick-step some message sends. However, I noticed that quick-stepping doesn't work as intended if a quick-stepped send executes a non-local return. Given the following method: Running this method in the simulator using repeated calls to Context >> #step for all non-send-bytecodes and Context >> #quickStep for all send bytecodes works fine except when quick-stepping the send of at:ifPresent: The context returned by quickstepping this send has an empty stack, whereas I would expect the return value of 84 on top of the stack. The root cause, as far as I can see, is Context >> #quickSend:to:with:lookupIn:, which seems to make assumptions in its ifCurtailed: block that appear to not (or no longer) hold true. [1] I have attached a ContextTest class that includes the example method shown above and a failing test. Note that the debugger does _not_ appear to use the Context >> #quickStep mechanism when using the "over" button (in fact, the quickStep method does not appear to be used at all). The debugger uses a different technique, namely Context >> #runUntilErrorOrReturnFrom: (Debugger >> #doStep -> Process >> #completeStep: -> Process >> #complete: -> Context >> #runUntilErrorOrReturnFrom:). I observed the behavior in a fresh Squeak 5.3 image. Best Christian ContextTest.st <http://forum.world.st/file/t372201/ContextTest.st> [1] Below, I have annotated the ifCurtailed: block of Context >> #quickSend:to:with:lookupIn: with my understanding of what it is trying to do and where it goes wrong: ------ I have already tried some things to fix the ifCurtailed: block in Context >> #quickSend:to:with:lookupIn:, but I'm not sure if that's entirely correct either. However, it at least passes the test. -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html |
I'm afraid the code was lost from my message, even though the preview here on
the forum included the code :( (Possibly I shouldn't have wrapped it in "raw" tags [using the More -> Raw Text button of the editor here on the forum]?) Anyways, here's the code again: ... snip ... Given the following method: methodToUseForQuickStepping | dictionary | dictionary := Dictionary new. dictionary at: #foo put: 42. dictionary at: #foo ifPresent: [:value | ^ value * 2]. ^ nil ... snip ... [1] Below, I have annotated the ifCurtailed: block of Context >> #quickSend:to:with:lookupIn: with my understanding of what it is trying to do and where it goes wrong: "This is supposed to be the block context, i.e. the context of the block passed to at:ifPresent:, that just executed the non-local return. However, it is _not_ (bug)" contextToReturnTo := thisContext sender receiver. "Now, given the block context, decrement the pc so that we are right before/at(?) the bytecode that caused the non-local return" contextToReturnTo pc: contextToReturnTo previousPc. "If it is indeed a non-local return (when would it not be??)" contextToReturnTo willReturnTopFromMethod ifTrue: "push the return value onto the stack (tempAt: 1 is the result temporary of the BlockClosure >> ifCurtailed: method" [contextToReturnTo push: (thisContext sender tempAt: 1)]. "Completely unrelated to everything above, escape the handling of ifCurtailed blocks by setting my sender to the sender of #quickSend:to:with:lookupIn:" thisContext swapSender: thisContext home sender. "This is the value that will be returned from #quickSend:to:with:lookupIn:" contextToReturnTo] ------ I have already tried some things to fix the ifCurtailed: block in Context >> #quickSend:to:with:lookupIn:, but I'm not sure if that's entirely correct either. However, it at least passes the test. contextToReturnTo := thisContext receiver sender. "block / method that was returned into" contextToReturnTo push: (thisContext sender tempAt: 1) "return value". thisContext swapSender: thisContext home sender. "Make this block return to the method's sender" contextToReturnTo] -- Sent from: http://forum.world.st/Squeak-Dev-f45488.html |
Free forum by Nabble | Edit this page |