Igor, surely if you're writing primitives that do context manipulation these should be internal to Interpreter, just like the block value and process/semaphore primitives. IMO its a really really bad idea to expose contexts through InterpreterProxy.
(& redirecting to vm-dev) On Sat, May 1, 2010 at 7:32 AM, Igor Stasenko <[hidden email]> wrote: Hello guys, |
On 3 May 2010 03:56, Eliot Miranda <[hidden email]> wrote: > > Igor, > surely if you're writing primitives that do context manipulation these should be internal to Interpreter, just like the block value and process/semaphore primitives. IMO its a really really bad idea to expose contexts through InterpreterProxy. > (& redirecting to vm-dev) > In NativeBoost, i need a callback to be able to a) change the current context b) call Interpret. So, its not directly accessible by primitive, but a callback function, called by foreign function. An FFI-support functions - callbackEnter/callbackLeave is just a setjmp/longjmp wrappers. The callbackEnter are not changing a context directly, but simply yielding the current Process, assuming that callback signaled a semaphore, and there are some process in image, which waits on that sema. So, to handle a callback, this requires an additional work at language side, like establishing the process + semaphore . A proxy functions, added to support Alien, however, switching contexts directly. I like it more, except that i can't use them in my own code, because #sendInvokeCallback:Stack:Registers:Jmpbuf: using an Alien special object and sends a message to it for activating a callback: sendInvokeCallback: thunkPtr Stack: stackPtr Registers: regsPtr Jmpbuf: jmpBufPtr .... receiver := self splObj: ClassAlien. lkupClass := self fetchClassOfNonInt: receiver. ... A second function (used to return from callback) is much more like what i need: reestablishContextPriorToCallback: callbackContext "callbackContext is an activation of invokeCallback:stack:registers:jmpbuf:. Its sender is the interpreter's state prior to the callback. Reestablish that state." | calloutContext | self export: true. (self fetchClassOf: callbackContext) ~~ (self splObj: ClassMethodContext) ifTrue: [^false]. calloutContext := self fetchPointer: SenderIndex ofObject: callbackContext. self newActiveContext: calloutContext. ^true if it were written in more generic form: swapActiveContext: newContext self export: true. | oldContext | (self fetchClassOf: newContext) ~~ (self splObj: ClassMethodContext) ifTrue: [^ 0 ]. oldContext := activeContext. self newActiveContext: newContext. ^ oldContext so, then along with callInterpreter() this is all i need to support callbacks. I even don't need a setjmp/longjmp, since they are trivial to implement directly in native code: pushad/popad + couple of flow control instructions :) I think i'll patch VMMaker to add that exported function (swapActiveContext: ) and at language side, if NativeBoost won't be able to find this exported function in VM, it will fall back to use of proxy's callbackEnter/callbackLeave. -- Best regards, Igor Stasenko AKA sig. |
Free forum by Nabble | Edit this page |