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 siguctua@gmail.com wrote:
Hello guys,
i am looking for a way, how i can obtain an activeContext oop in my primitive function. An activeContext variable is directly accessible for interpreter code, but not for plugins. So, i need some indirect way to retrieve it, to avoid patching the Interpreter for exposing it.
What i actually want is to switch an active context to a different one, but remember a previously active, so it can be restored later.
-- Best regards, Igor Stasenko AKA sig.
On 3 May 2010 03:56, Eliot Miranda eliot.miranda@gmail.com 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.
vm-dev@lists.squeakfoundation.org