Hi Bert,

On Wed, May 6, 2009 at 3:34 AM, Bert Freudenberg <bert@freudenbergs.de> wrote:


On 06.05.2009, at 02:36, David T. Lewis wrote:


On Tue, May 05, 2009 at 11:37:43AM -0700, John M McIntosh wrote:

Folks should try the fix and see

Ihttp://idisk.mac.com/bertfreudenberg-Public/temp

Double-click EtoysToGo.app and drop in wendy.pr  for it to explode,
well or not after the fix is applied.

I did not try the exploding wendy.pr test,

Well what I uploaded there is just our not-yet-finished "Etoys To Go" project that's supposed to be runnable from an USB flash drive, on any platform. The VMs for Win and Linux there are not yet updated. Etoys actually does not need closure support (yet) but a feature to resolve relative directories (so the user data will also land on the flash drive). John put that feature in his 4.0 series which supports closures, so I needed to use that one. And then I noticed it blows up on entering sandbox mode.


but your ClosureVMPopKiller-M7349
definitely fixes some stack balance bugs, so I loaded it in the VMMaker project
on SqS in VMMaker-dtl.122.

The Mantis 7349 issue is marked as status "testing" since I did not actually
perform the wendy.pr test. I'll move it to "resolved" next week if no one cites
evidence to the contrary.

r.e. your notes in Mantis 7349:
was there not some recovery code for unbalanced stacks somewhere? My
concern is there other example of this which we not yet crashed over.
So how would we fix the VM to avoid? Or do we need to check all the plugin
prim code for coding issues.

Yes there are sure to be more unbalanced stack bugs, and yes somebody should
probably check all the plugin code. Most likely nobody will get around to doing
that but no worries, the stack VM seems to do an excellent job of finding
these bugs :)


How costly would it be to always do this:

       interpreterProxy pop: interpreterProxy methodArgumentCount + 1 thenPush: result

or

       interpreterProxy pop: interpreterProxy methodArgumentCount

to return self?

Do  the right thing:

     interpreterProxy pop: interpreterProxy methodArgumentCount + 1 thenPush: result

It is not hugely expensive compared to the other costs associated with the primitive call, and the interpreterProxy indirection.

In Cog & the StackVM we check the argument count of primitive calls on return and fail the primitive if the stack is incorrect.  So checking is easier.

But my main reason for suggesting you do the right thing is that soon enough the execution machinery is going to change and get substantially faster.  Igor has some good ideas for eliminating interpreterProxy, deferring whether one uses function pointers or direct references to functions until the time a plugin is compiled, and this makes all these calls much faster.  You would still write

        interpreterProxy pop: interpreterProxy methodArgumentCount + 1 thenPush: result

but the code generator would spit out

...
#if EXTERNAL
void (*popthenPush)(sqInt,sqInt);
sqInt (*methodArgumentCount);
#endif
...
         popThenPush(methodArgumentCount() + 1, result);

and the function pointers would be intialized in the plugin initializer.

I want eventually to get away from explicit stack manipulation in plugins and write them all rather like smart plugins and have the code generator create vanilla C functions for them, with varargs for primitives that need them.  Primitives would return their result, returning 0 (all zeros) to indicate failure.  This would eliminate calls on interpreterProxy for argument access and return, leaving conversion, allocation etc.  Combining this with Igor's scheme should be a fair bit faster and cleaner than what we have now.

So at least for the moment go for correctness and use smart syntax plugins as much as possible.