[squeak-dev] Will Newspeak be callable by external programs?
John M McIntosh
johnmci at smalltalkconsulting.com
Sun Feb 8 21:59:12 UTC 2009
Ok, let me ramble.
Well in the far past for the macintosh we built a plugin for the
browser.
The plugin used the netscape browser api to interface to the netscape
and IE browser.
When the plugin was loaded it would set things up, and start running
the bytecode interpreter.
The VM can be viewed as endless loop, however it is possible to exit
the loop and return to the caller
and of course save the interpreter stack state. Later the caller
reenters the interpreter loop and continues
execution.
This logic still exists see
http://isqueak.org/browserPluginReturnIfNeeded
In the early part of the decade I change the logic a bit so that the
interpreter was spin off as a separate pthread within
the browser to give us better performance and visual updating.
The Hydra VM still exploits this idea of returning from the
interpreter loop where it does
lockInterpreter(intr); /* lock interpreter mutex before entering loop
*/
while (1)
{
interpret(intr);
// give a chance other threads to do something
unlockInterpreter(intr);
lockInterpreter(intr);
pokeAtTimer(intr);
handleEvents(intr);
}
In this case the interpret() is the endless bytecode interpreter loop,
which is exited, then the handleEvents
pulls inter-interpeter events off the queue and we re-enter the
interpreter. The other point is the program setups each
VM on a seperate pthread.
The iPhone VM actually runs the VM in a background thread
// Run the squeak process in a worker thread
[NSThread detachNewThreadSelector: @selector(runSqueak)
toTarget: self.squeakApplication
withObject: NULL];
For the current Unix and macintosh browser plugin we take a different
approach where the plugin launches a separate
Squeak VM process and uses pipes and shared memory to move items of
interest between the two process. So UI gestures enter the browser
plugin
and are sent by a pipe to the squeak process, the squeak process
interpreters them, and does updates to it's internal Screen. For the
unix port that's
a X11 screen hosted by the browser, for the carbon VM it's more
complicated and has to us a shared memory location and pipe to ask the
browser
plugin to draw the screen within the address space of the browser.
Lastly the VM can make requests back to the browser, say to download a
file, again
by sending a message via the pipe.
Astute macintosh folks might note for years now the Squeak carbon app
will act as a Service, if you have a Squeak image that contains the
macintosh services logic
it's possible for you to select smalltalk code in TextEdit, then say
Services->Squeak DoIt and Squeak will get the services request, do it,
and return the results.
Now for your problem.
(a) You want to run the VM, you can choose to run the VM either as
part of a currently executing caller thread, or as a pthread, or as a
separate process.
(b) You need to choose if you want to start the VM, execute some sort
of startup script & data, return results, and quit.
(b) or pass a request to execute something, and return the result
somehow. There are many ways to do that, file based message passing,
pipes, queues, shared memory, etc....
The Alien FFI work, or the older FFI logic will help you extract
information from memory and/or call API routines hosted by the
operating system or any other loadable DLL.
The Alien FFI work has logic to let you call back to a squeak method
from a blocking API call that requires you to provide executable entry
points, an example given
is the sort callback where the executable entry point you provide is a
smalltalk method to compare floating point numbers.
What I'd suggest is having your plugin start the VM as a separate
pthread with a thread safe queue, and location for the squeak external
semaphore number. Your Squeak image would startup and wait on the
semaphore. Later when your CAD system invokes the plugin with lots of
parameter data you build a queue object, put it on the queue, trigger
the squeak semaphore and wait.... , once the waiting ends you have
someway to pull the results that Squeak has made for you, likely
populate the queue item with return data, and or of course the squeak
vm could have manipulated the data to no end.
I'll note for the Objective-C bridge I'm working on for the iPhone has
this chunk of code below (original donated by Avi)
What happens here is a message send occurs to a squeak proxy object,
if the message selector is one we
are interested in we set a pthread conditional lock to :0, then unlock
to 1, then signal the squeak semaphore.
the waiting squeak process then locks to condition 1, and the
objective C code below then attempts an unlock to
condition 2 and will block as the squeak process runs using the
NSInvocation instance which contains information
about the message send, all the parms and has the ability to set the
return value. Effectively we have the entire message
implementation in Smalltalk. Once the Smalltalk logic completes it
unlocks condition with condition 2 which lets the ockWhenCondition: 2
thus letting the forwardInvocation: terminate.
In this case the SqueakProxy instance is being sent messages on the
main thread, and the squeak VM is on another thread
the conditional lock control which thread gets executed and the
invocation instance variable is the shared object.
So what about NSDate? The issue with passing data to complex third
party is how long do you wait for the third party
to complete the request. What if your Smalltalk logic is flawed, and
you get a walkback? Do you wait and time out or
do you return a bad value event by trapping the unhandled walkback?
- (void) forwardInvocation: (NSInvocation*) anInvocation
{
NSDate *timeout;
if (![sigs containsObject: NSStringFromSelector([anInvocation
selector])]) {
return;
}
if([lock lockWhenCondition: 0 beforeDate: (timeout = [[NSDate alloc]
initWithTimeIntervalSinceNow: 3])])
{
[lock unlockWithCondition: 1];
[timeout release];
invocation = [anInvocation retain];
interpreterProxy->signalSemaphoreWithIndex(sem);
if([lock lockWhenCondition: 2 beforeDate: (timeout = [[NSDate alloc]
initWithTimeIntervalSinceNow: 4])])
{
[timeout release];
[invocation release];
[lock unlockWithCondition: 0];
}
else
{
[timeout release];
[invocation release];
[lock unlockWithCondition: 0];
}
}
else
{
[timeout release];
//NSLog(@"failed lock 0");
}
}
On 8-Feb-09, at 11:28 AM, askoh wrote:
>
> For about a year now, I have been asking if Squeak can be called by
> external
> programs, if it can be controlled by a non-Squeak program, if it can
> be used
> to make plugins or addons in CAD programs. And I have not received
> an answer
> that says that it is possible now nor anyone working on that for the
> future.
> If Alien FFI can do it I would be most happy to try it immediately.
> Can the
> author of Alien FFI give an authoritative answer to its capability
> to do the
> above? Is there documentation to describe how? Thanks in advance.
>
> All the best,
> Aik-Siong Koh
--
=
=
=
========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com>
Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com
=
=
=
========================================================================
More information about the Squeak-dev
mailing list
|