[Vm-dev] Re: [squeak-dev] Obtaining a current context in primitive

Igor Stasenko siguctua at gmail.com
Mon May 3 09:33:07 UTC 2010


On 3 May 2010 03:56, Eliot Miranda <eliot.miranda at 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.


-- 
Best regards,
Igor Stasenko AKA sig.


More information about the Vm-dev mailing list