FFI, pragma and co...

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

FFI, pragma and co...

cedreek
Hi

As some of us, I'm following the two lists (dev and beginner..) and there is a long interesting discusion about pragma, FFI, primitive...  but I don't really know them ;)  exept what I found on wikipedia lol

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 ?

Thanks in advance

Cédrick

ps: I'm interested in Pragma as it's a kind of metadata as far as I have understood. But how to use them ?

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

Bert Freudenberg-3
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 -
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

stéphane ducasse-2
>
> 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.

look at @
the point creation method is sped up using an optional primitive call.

@ y
        "Primitive. Answer a Point whose x value is the receiver and whose y
        value is the argument. Optional. No Lookup. See Object documentation
        whatIsAPrimitive."

        <primitive: 18>
        ^Point x: self y: y


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

cedreek
In reply to this post by Bert Freudenberg-3
really thanks Bert ;)
clear explanation... I had dome vague ideas but thats far clearer now

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".

SmalltalkImage current listLoadedModules
for me on 3.9

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.

ok :)

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" ?).

yes :)
thought it was 100% object power . A bit dissapointed ;)

euhh actually, I don't see any primitive call in Integer>>factorial , only a recursive function... did I miss somrthing ?


Integer>>factorial
    "Answer the factorial of the receiver."

    self = 0 ifTrue: [^ 1].
    self > 0 ifTrue: [^ self * (self - 1) factorial].
    self error: 'Not valid for negative integers'

Thanks again Bert

Cédrick


ps: Considering pragma, is there any classical uses that can be interesting to do to work at the meta level... like Id' like to tag instance variables according to their meaning in my application. I have no idea on how to use pragma for that...

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

cedreek
In reply to this post by stéphane ducasse-2


look at @
the point creation method is sped up using an optional primitive call.

@ y
        "Primitive. Answer a Point whose x value is the receiver and whose y
        value is the argument. Optional. No Lookup. See Object documentation
        whatIsAPrimitive."

        <primitive: 18>
        ^Point x: self y: y

(a) Time millisecondsToRun:[50000 timesRepeat: [1@1]]  ->  12

then I commentet the primitive call to see the diffirence in Number>>@
and I saw no difference...
so I put a self halt in @

and the method isn't stopped when I redo (a).

but if I do that in a worspace:

|a|
a := 1. self halt.
Time millisecondsToRun:[50000 timesRepeat: [1@(a+1)]].

It stops and then the halt in #@ works ok ...

any idea of what I did wrong ?

Thanks
Cédrick


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

Damien Cassou-3
cdrick wrote:

> (a) Time millisecondsToRun:[50000 timesRepeat: [1@1]]  ->  12
>
> then I commentet the primitive call to see the diffirence in Number>>@
> and I saw no difference...
> so I put a self halt in @
>
> and the method isn't stopped when I redo (a).
>
> but if I do that in a worspace:
>
> |a|
> a := 1. self halt.
> Time millisecondsToRun:[50000 timesRepeat: [1@(a+1)]].
>
> It stops and then the halt in #@ works ok ...
>
> any idea of what I did wrong ?

The computer optimize some calls by inlining the method code (I don't
know for #@). If this is the case, the code of #@ is directly written
into your method and the original code is never executed.

But again, I don't know if this your problem, just an idea
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

Damien Cassou-3
In reply to this post by cedreek
cdrick wrote:
> ps: Considering pragma, is there any classical uses that can be
> interesting to do to work at the meta level... like Id' like to tag
> instance variables according to their meaning in my application. I have
> no idea on how to use pragma for that...

Pragmas *may* only be implemented for methods. It seems to be the case
in Visual Works. Do you want an explanation for methods ?
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

cedreek


Pragmas *may* only be implemented for methods. It seems to be the case
in Visual Works. Do you want an explanation for methods ?

yes if you can :)
beacause I use getters and setters for my iv :)

Thanks

Cédrick



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

Bert Freudenberg-3
In reply to this post by cedreek
Am 21.08.2006 um 15:59 schrieb cdrick:
> euhh actually, I don't see any primitive call in  
> Integer>>factorial , only a recursive function... did I miss  
> somrthing ?

No, #factorial is a regular method, but LargeInteger arithmetics is  
accelerated by LargeIntegerPlugin. You could try

        [10000 factorial] timeToRun

with and without the primitives.

- Bert -

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

Damien Cassou-3
In reply to this post by cedreek
cdrick wrote:
>
>
>     Pragmas *may* only be implemented for methods. It seems to be the case
>     in Visual Works. Do you want an explanation for methods ?
>
>
> yes if you can :)


Pragmas are annotations for your methods. This annotations allows the
developer to categorize its methods.

For exemple, Lukas uses naming conventions to retrieve "description"
methods (in fact, you can now use pragmas but forget that otherwise my
explanation is useless :-)). The selector has to start with #description
to be a description selector:

Symbol>>isDescriptionSelector
   "Answer wheter the receiver is a method selector following the naming
conventions of a  description selector."
   ^ self ~= #description
        and: [ self beginsWith: #description ]


This is a solution. But sometime, you would like to start a method with
'description' and this should not be a description method (or you do it
by mistake).

Pragmas can be used to solve this problem. You then will annotate your
method to tell the system that this methods are description methods. You
do it like this:

MyObject class>>firstName
   <description>
   ^ MAStringDescription auto: 'firstName' label: 'First name'


Then, when you want to collect all the description methods in a class,
you will use the methods in the protocol 'finding' of the Pragma class
(class side).

Pragma allNamed: #description in: yourObject class

This returns a collection of Pragmas (compiled methods, selector and
class) in which the pragma #description has been used in the class of
yourObject.


You can use pragmas with arguments too like in:

<selector: #something inClass: 'a class name'>

only literals are allowed as arguments.

With this, you can find all methods using the pragma #selector:inClass:
and you can do whatever you want with the argument values.

Writing this, I noticed that Pragmas means a lot of things for me (I
used the word a lot in the mail and for different purposes). I may have
to read again a documentation about this but I think the idea is here.

Is it clear ?

> beacause I use getters and setters for my iv :)


And pragmas won't help you in my opinion, I don't see any relation :-)
Why don't you want getters and setters ?



Hope this is your last question of the day, I already answered 4 of them
and I'm tired now :-D


See you soon
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

Roel Wuyts
In reply to this post by Damien Cassou-3
I can confirm that VisualWorks only implements pragmas for methods,  
nothing else.

On 21 Aug 2006, at 18:33, Damien Cassou wrote:

> cdrick wrote:
>> ps: Considering pragma, is there any classical uses that can be  
>> interesting to do to work at the meta level... like Id' like to  
>> tag instance variables according to their meaning in my  
>> application. I have no idea on how to use pragma for that...
>
> Pragmas *may* only be implemented for methods. It seems to be the  
> case in Visual Works. Do you want an explanation for methods ?
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: FFI, pragma and co...

cedreek
In reply to this post by Damien Cassou-3
> Symbol>>isDescriptionSelector

>    "Answer wheter the receiver is a method selector following the naming
> conventions of a  description selector."
>    ^ self ~= #description
>         and: [ self beginsWith: #description ]
>
>
> This is a solution. But sometime, you would like to start a method with
> 'description' and this should not be a description method (or you do it
> by mistake).
>
> Pragmas can be used to solve this problem. You then will annotate your
> method to tell the system that this methods are description methods. You
> do it like this:
>
> MyObject class>>firstName
>    <description>
>    ^ MAStringDescription auto: 'firstName' label: 'First name'
>
>
yes that's why I fiind that interesting.. clearer


> Then, when you want to collect all the description methods in a class,
> you will use the methods in the protocol 'finding' of the Pragma class
> (class side).
>
> Pragma allNamed: #description in: yourObject class
>
> This returns a collection of Pragmas (compiled methods, selector and
> class) in which the pragma #description has been used in the class of
> yourObject.
>
this is cool ;)  I'm manipulating them a bit right now
>

>
> Is it clear ?

yes more thanks ;)

>
> > beacause I use getters and setters for my iv :)
>
>
> And pragmas won't help you in my opinion, I don't see any relation :-)
> Why don't you want getters and setters ?
>
yes I wasn't clear. But as accesors are methods, I can use pragma to
tag indirectly my instance variable. Just an idea of somethink that
can be useful to me.
I trying to make a kind of (small) knowledge management system, maybe
more a kind of case based reasoning tool (ie. entities are composed of
attributes or descriptors upon which the system reason..) and one
simple solution for me is to directly use instance variables for these
descriptors (and then I can tag to process them)...

I'm trying to see all kind of solution I could choose... even if right
now I'm more trying to use dedicated Descriptor class...

I think one of the limitation I have (but I'll probably open a post on
that one day) is that I need attributes as first-class entities and
instance variable are not (are they ?)

>
>
> Hope this is your last question of the day, I already answered 4 of them
> and I'm tired now :-D

this was ;)  I have days like that  :d

Squeak REALLY rocks

Cédrick

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners