[Newbies] FFI, pragma and co...

Bert Freudenberg bert at impara.de
Mon Aug 21 11:58:02 UTC 2006


cdrick schrieb:
> Can anyone indicate me pointers or maybe simple examples to understant 
> that better ?
> in general for the extension mechanism <   >
> 
> This is something I found "strange" when I first see them in smalltalk 
> where everything is an object ;).
> Primitives are objects ?

Everything is an object, and objects communicate by sending messages. So 
an object sends a message, which invokes a method, which in turn sends 
messages. But at some point, you have to actually get to the bits in the 
machine. That's what the "primitives" are for - they are methods 
executed directly by the virtual machine rather than by sending messages.

For example, to add two numbers, the message "+" is sent. Look at the 
implementors of "+" (select a "+" and press Cmd-m). Most "+" methods are 
regular methods, but some are a primitive. Like, SmallInteger>>+ is 
implemented by primitive number 1, it's a very basic operation:

+ aNumber
	<primitive: 1>
	^ super + aNumber

The code following the primitive declaration is executed only if the 
primitive fails. In this case, the primitive will fail if the argument 
is not a SmallInteger, too, so a more general addition method is used 
instead. Like, if the argument is a large integer it is broken down to 
smaller ones and added separately (invoking the primitive again).

These "numbered primitives" are hard-coded in the virtual machine's 
interpreter. They are essential for running Squeak.

Additionally, we have "named primitives" which reside in plugins, so 
called "virtual machine modules". An example is playing sound - the 
sound data has to be delivered to the machine's sound card:

primSoundPlaySamples: count from: aSampleBuffer startingAt: index
	<primitive: 'primitiveSoundPlaySamples' module: 'SoundPlugin'>
	^ self primitiveFailed

A module is written in C (though often the C code is generated from 
Squeak code) and needs to be compiled with a C compiler. Some modules 
are linked into the VM, some are external. You can list all currently 
used modules using "Smalltalk listLoadedModules".

To access a function from a C library without the need to write a 
module, we have FFI primitives:

	puts: aString
		<cdecl: void 'puts' (char*) module: 'libSystem.dylib'>
		^ExternalFunction externalCallFailed

When called, FFI looks up the function "puts" in "libSystem.dylib", 
converts the Smalltalk string to a C char*, and calls the function with 
it. This is for Mac OS X, on Linux, you would use "libc.so.1" and on 
Windows, I don't know, maybe "system32.dll" - FFI calls are very 
platform-specific. Also, they can crash Squeak easily. That's the reason 
the basic Squeak system does not use FFI at all, it is used for specific 
applications only, which have to deal with the platform issues.

So primitives generally are the gateway to the world outside Smalltalk's 
objects.

Additionally, some primitives are optional, they are only used to speed 
up lengthy computations. Like searching in a string or adding large 
numbers (ever tried "1000 factorial" ?). If the primitive is not 
available, the Smalltalk code will be executed instead.

- Bert -


More information about the Beginners mailing list