[Vm-dev] Push/pop considered harmful

Andreas Raab andreas.raab at gmx.de
Tue Mar 3 07:24:07 UTC 2009

Folks -

Ever since we started to use the Stack VM we had a series of subtle 
crashes, many of which we could trace to stack imbalances (i.e., 
mismatching numbers of push/pops in primitives). Since the Stack VM is 
much more affected by this we have been looking to fix these issues once 
and for all.

One thing that occurred to us is that practically all primitives do the 
same: They pop the number of arguments and they push an optional return 
value. There are many ways in which this can get wrong, sometimes it's a 
subtle early return, sometimes the fact that the primitive has actually 
failed before the prim returns etc.

One thing that all of the uses (in plugins) have in common that all the 
plugin *really* needs to do, is to provide a return value and leave the 
push/pop to be done by the VM. In this case the stack invariants 
wouldn't even be exposed to the plugin.

What we are doing right now is along those lines - basically we are 
replacing push/pop in the interpreter proxy by variants that don't 
actually do push and pop. Rather than that, pop is ignored (it only 
remembers how many times you popped so we can track inconsistencies) and 
push remembers the return value.

This should definitely be replaced at some point by a proper 
#primitiveReturnValue: call. I was wondering what people think about the 
possibility of automatically rewriting plugins to fix those uses? It 
should be reasonably easy to find all the uses of "interpreterProxy pop: 
foo" and just remove them and replace "interpreterProxy 
push[Float|Int]:" with "interpreterProxy primitiveReturn[Float|Int]:".

   - Andreas

More information about the Vm-dev mailing list