Unfortunately, any system .. including Neko and any other
VM .. which wishes to allow extensions to the API which call
C, and which also wishes to allow callbacks into the VM ..
is affected by this problem. The C stack gets in the way
of neutral control transfer. So even if it is implemented
in the Neko VM .. it will never work properly with C extensions
that need to callback into the VM.
What I was thinking is using the current exceptions implementation but
with a special form using $callc/$yield.
f = function(delta) {
var x = 0;
while true {
x += delta;
$yield(x);
}
}
$callcc(f,1);
The $callcc is setting the "return point" of the continuation and is
entering it. $yield will throw an exception up to the $callcc point.
Like this it is some kind of parallel exception mecanism.
The big difference is that $callcc will return the yield'ed value AND
the continuation of f. It means that the VM stack between call/cc and
yield is captured and returned as a new function that can be called
again using either $callcc or just a normal call (in that case the
$yield will go through it to the previous $callcc).
The only problem here as you point out is that it doesn't play well with
the C stack if there is callbacks, unless maybe you save it at the same
time :
- save the vm stack
- save the C stack
- save a setjmp buffer
then when calling back:
- push back the vm stack
- push back the C stack
- longjmp to the yield C function
That might be quite tricky to implement.
Nicolas
---
Neko : One VM to run them all