[Vm-dev] defensive error checking in a BlockContext environment for [:n | n = 1 ifTrue: [1] ifFalse:[(factorial value: n-1) * n]]

Bob Arning arning315 at comcast.net
Sun Dec 15 19:43:28 UTC 2013


Not sure which version VM you are looking at, but long ago, it was:

primitiveValueWithArgs

     | argumentArray blockContext blockArgumentCount arrayArgumentCount 
initialIP |
     argumentArray _ self popStack.
     blockContext _ self popStack.
     blockArgumentCount _ self argumentCountOfBlock: blockContext.
     self assertClassOf: argumentArray is: (self splObj: ClassArray).
     successFlag ifTrue: [
         arrayArgumentCount _ self fetchWordLengthOf: argumentArray.
         self success: (arrayArgumentCount = blockArgumentCount
***and: [(self fetchPointer: CallerIndex ofObject: blockContext) = 
nilObj])**]. <<<re-entrant detection**
**.*..

So, your snippet looks close, but not quite there.

Cheers,
Bob

On 12/15/13 11:25 AM, gettimothy wrote:
>   
>
>
> Please shoot this down, if it is incorrect. (no details necessary, 
> just a yes,no is sufficient)
>
> In the discussion 
> <http://www.mirandabanda.org/cogblog/category/cog/page/14/>on the 
> re-entrant problem for BlockContexts regarding this code:
>
>         | factorial |
>         factorial := [:n| n = 1 ifTrue: [1] ifFalse: [(factorial 
> value: n - 1) * n]].
>         (1 to: 10) collect: factorial
>
> This statement: "The block can’t be reentered without overwriting the 
> sender field, preventing return to the first caller. "
>
> Does *not* mean that the bock is reentered, the sender field is 
> over-written and when we get to n=10 stage things go kablooie.
> What happens is the coders detect this condition and the primitive 
> code  will *not allow* a sender to be over-written.
> The error that is thrown is *purposeful and defensive*
>
> I don't know what I am looking at yet, but I think that error check 
> happens here:
>
> Interpreter >> primitiveValueWithArgs
>     | argumentArray blockContext blockArgumentCount arrayArgumentCount 
> initialIP |
>     argumentArray _ self popStack.
>     blockContext _ self popStack.
>     blockArgumentCount _ self argumentCountOfBlock: blockContext.
> *    "If the argArray isnt actually an Array we ahve to unpop the 
> above two"
>     (self isArray: argumentArray) ifFalse: [self unPop:2. ^self 
> primitiveFail].
> *.....
>
>
> Sound about right?
>
> thx.
>
> tty

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20131215/b369c2cb/attachment.htm


More information about the Vm-dev mailing list