Trying to build alien plugin in linux

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

Re: Trying to build alien plugin in linux

johnmci

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 



It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 



Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 




That's all for now, thanks!

Javier.

On Mon, Feb 22, 2010 at 4:32 PM, John M McIntosh <[hidden email]> wrote:
You've not loaded 
Name: Alien-VMMaker-Support-John M McIntosh.8
Author: John M McIntosh
Time: 11 January 2010, 12:53:14 am
UUID: 6953c7ab-4924-48b0-9984-f15ec7fb7d2b

into your vmmaker image

so it's not build the interp.c pieces.


On 2010-02-22, at 8:18 AM, Javier Pimás wrote:

internalIsImmutable

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================





_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Fernando olivero

On Feb 23, 2010, at 4:19 AM, John M McIntosh wrote:

>
> On 2010-02-22, at 6:48 PM, Javier Pimás wrote:
>
>>
>
>> Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:
>>
>> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".
>>
>> What should I do about that? ignore it?
>
> Well it seems to be related to
>
> ((Smalltalk includesKey: #ObjectMemory)
> and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
> [self error: 'index probably wrong'].
>
> Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for.
> Why don't you try it in a regular Pharo image versus your VMMaker image.

Great work Jorge! Nice to know you won the battle against VMMaker!

The ensure in special objects array error, has to do with some missing classes as John pointed out.

The smalltalk special objects array has hardcoded indexes for some relevant classes ( Globals) in the system.
In the alien configuration i've just ensured that the size should be 53, before loading Alien, because the Alien code installs itself in that array at positions 54 and 55.



_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Mariano Martinez Peck
Torsten and JB: it would be cool to create a new metacello configuration version with this new version of VMMaker, puting the fix about the baseHeaderSize and integrating JB fixes to VMMaker.

Cheers

Mariano

On Tue, Feb 23, 2010 at 7:55 AM, Fernando olivero <[hidden email]> wrote:

On Feb 23, 2010, at 4:19 AM, John M McIntosh wrote:

>
> On 2010-02-22, at 6:48 PM, Javier Pimás wrote:
>
>>
>
>> Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:
>>
>> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".
>>
>> What should I do about that? ignore it?
>
> Well it seems to be related to
>
>       ((Smalltalk includesKey: #ObjectMemory)
>        and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
>               [self error: 'index probably wrong'].
>
> Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for.
> Why don't you try it in a regular Pharo image versus your VMMaker image.

Great work Jorge! Nice to know you won the battle against VMMaker!

The ensure in special objects array error, has to do with some missing classes as John pointed out.

The smalltalk special objects array has hardcoded indexes for some relevant classes ( Globals) in the system.
In the alien configuration i've just ensured that the size should be 53, before loading Alien, because the Alien code installs itself in that array at positions 54 and 55.



_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Torsten Bergmann
Havent followed this thread and currently lacking some time.
The VMMaker config is changeable, so go ahead.

Take care that it also works in latest Squeak trunk.
Since most VM maintainers use Squeak to build the VM this is
essential to follow their progress.

Would also be a great move if Alien would be available on Windows -
this would open the door to interfacing with Win technologies like
COM or .NET (and therefore wake more commercial interest in Pharo).
Having Alien on major OS platforms would also allow to use Smalltalk<->
Java bridging technologies like JavaConnect/JNIPort,

Bye
T.

-------- Original-Nachricht --------
> Datum: Tue, 23 Feb 2010 10:08:55 +0100
> Von: Mariano Martinez Peck <[hidden email]>
> An: [hidden email]
> CC: Arnaud Jean-Baptiste <[hidden email]>, Torsten Bergmann <[hidden email]>
> Betreff: Re: [Pharo-project] Trying to build alien plugin in linux

> Torsten and JB: it would be cool to create a new metacello configuration
> version with this new version of VMMaker, puting the fix about the
> baseHeaderSize and integrating JB fixes to VMMaker.
>
> Cheers
>
> Mariano
>
> On Tue, Feb 23, 2010 at 7:55 AM, Fernando olivero
> <[hidden email]>wrote:
>
> >
> > On Feb 23, 2010, at 4:19 AM, John M McIntosh wrote:
> >
> > >
> > > On 2010-02-22, at 6:48 PM, Javier Pimás wrote:
> > >
> > >>
> > >
> > >> Lastly, as I said when I loaded Alien Core the first time, I got this
> > error while loading it:
> > >>
> > >> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".
> > >>
> > >> What should I do about that? ignore it?
> > >
> > > Well it seems to be related to
> > >
> > >       ((Smalltalk includesKey: #ObjectMemory)
> > >        and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien
> > ifAbsent: []) ~~ (index - 1)]) ifTrue:
> > >               [self error: 'index probably wrong'].
> > >
> > > Usually people don't have ObjectMemory loaded in their image, and I"m
> not
> > sure what it is check for.
> > > Why don't you try it in a regular Pharo image versus your VMMaker
> image.
> >
> > Great work Jorge! Nice to know you won the battle against VMMaker!
> >
> > The ensure in special objects array error, has to do with some missing
> > classes as John pointed out.
> >
> > The smalltalk special objects array has hardcoded indexes for some
> relevant
> > classes ( Globals) in the system.
> > In the alien configuration i've just ensured that the size should be 53,
> > before loading Alien, because the Alien code installs itself in that
> array
> > at positions 54 and 55.
> >
> >
> >
> > _______________________________________________
> > Pharo-project mailing list
> > [hidden email]
> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
> >

--
NEU: Mit GMX DSL über 1000,- ¿ sparen!
http://portal.gmx.net/de/go/dsl02

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Stéphane Ducasse
I hope that we will get an engineer paid by inria but this will not be before september 2010.
we should get some news in a couple of weeks.
Stef

On Feb 23, 2010, at 10:51 AM, Torsten Bergmann wrote:

> Havent followed this thread and currently lacking some time.
> The VMMaker config is changeable, so go ahead.
>
> Take care that it also works in latest Squeak trunk.
> Since most VM maintainers use Squeak to build the VM this is
> essential to follow their progress.
>
> Would also be a great move if Alien would be available on Windows -
> this would open the door to interfacing with Win technologies like
> COM or .NET (and therefore wake more commercial interest in Pharo).
> Having Alien on major OS platforms would also allow to use Smalltalk<->
> Java bridging technologies like JavaConnect/JNIPort,
>
> Bye
> T.
>
> -------- Original-Nachricht --------
>> Datum: Tue, 23 Feb 2010 10:08:55 +0100
>> Von: Mariano Martinez Peck <[hidden email]>
>> An: [hidden email]
>> CC: Arnaud Jean-Baptiste <[hidden email]>, Torsten Bergmann <[hidden email]>
>> Betreff: Re: [Pharo-project] Trying to build alien plugin in linux
>
>> Torsten and JB: it would be cool to create a new metacello configuration
>> version with this new version of VMMaker, puting the fix about the
>> baseHeaderSize and integrating JB fixes to VMMaker.
>>
>> Cheers
>>
>> Mariano
>>
>> On Tue, Feb 23, 2010 at 7:55 AM, Fernando olivero
>> <[hidden email]>wrote:
>>
>>>
>>> On Feb 23, 2010, at 4:19 AM, John M McIntosh wrote:
>>>
>>>>
>>>> On 2010-02-22, at 6:48 PM, Javier Pimás wrote:
>>>>
>>>>>
>>>>
>>>>> Lastly, as I said when I loaded Alien Core the first time, I got this
>>> error while loading it:
>>>>>
>>>>> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".
>>>>>
>>>>> What should I do about that? ignore it?
>>>>
>>>> Well it seems to be related to
>>>>
>>>>      ((Smalltalk includesKey: #ObjectMemory)
>>>>       and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien
>>> ifAbsent: []) ~~ (index - 1)]) ifTrue:
>>>>              [self error: 'index probably wrong'].
>>>>
>>>> Usually people don't have ObjectMemory loaded in their image, and I"m
>> not
>>> sure what it is check for.
>>>> Why don't you try it in a regular Pharo image versus your VMMaker
>> image.
>>>
>>> Great work Jorge! Nice to know you won the battle against VMMaker!
>>>
>>> The ensure in special objects array error, has to do with some missing
>>> classes as John pointed out.
>>>
>>> The smalltalk special objects array has hardcoded indexes for some
>> relevant
>>> classes ( Globals) in the system.
>>> In the alien configuration i've just ensured that the size should be 53,
>>> before loading Alien, because the Alien code installs itself in that
>> array
>>> at positions 54 and 55.
>>>
>>>
>>>
>>> _______________________________________________
>>> Pharo-project mailing list
>>> [hidden email]
>>> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
>>>
>
> --
> NEU: Mit GMX DSL über 1000,- ¿ sparen!
> http://portal.gmx.net/de/go/dsl02
>
> _______________________________________________
> Pharo-project mailing list
> [hidden email]
> http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
In reply to this post by johnmci


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?


--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
In reply to this post by Fernando olivero


On Tue, Feb 23, 2010 at 3:55 AM, Fernando olivero <[hidden email]> wrote:

On Feb 23, 2010, at 4:19 AM, John M McIntosh wrote:

>
> On 2010-02-22, at 6:48 PM, Javier Pimás wrote:
>
>>
>
>> Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:
>>
>> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".
>>
>> What should I do about that? ignore it?
>
> Well it seems to be related to
>
>       ((Smalltalk includesKey: #ObjectMemory)
>        and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
>               [self error: 'index probably wrong'].
>
> Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for.
> Why don't you try it in a regular Pharo image versus your VMMaker image.

Great work Jorge! Nice to know you won the battle against VMMaker!


Haha, it's Javier but you were very close, keep trying :P
 
The ensure in special objects array error, has to do with some missing classes as John pointed out.

The smalltalk special objects array has hardcoded indexes for some relevant classes ( Globals) in the system.
In the alien configuration i've just ensured that the size should be 53, before loading Alien, because the Alien code installs itself in that array at positions 54 and 55.


Before loading my image has 50 items, last one being #run:with:in:. After loading alien I've got 55. The new ones are:

[51] : nil
[52] : nil
[53] : Alien
[54] : #invokeCallback:stack:registers:jmpbuf:
[55] : UnsafeAlien

Other strange stuff is that while inspecting (Smalltalk at: #Interpreter) classPool I found that

[#PrimErrBadArgument] : nil
[#PrimErrBadIndex] : nil
[#PrimErrBadNumArgs] : nil
[#PrimErrBadReceiver] : nil
[#PrimErrGenericFailure] : nil
[#PrimErrInappropriate] : nil
[#PrimErrNoCMemory] : nil
[#PrimErrNoMemory] : nil
[#PrimErrNoModification] : nil
[#PrimErrNotFound] : nil
[#PrimErrTableIndex] : nil
[#PrimErrUnsupported] : nil
[#PrimNoErr] : nil

Which means that initializePrimitiveErrorCodes hasn't been called, which explains why special object #52 is nil. Analysing it a bit more I discover that initializePrimitiveErrorCodes has no senders, is that right?


Regards,
             Javier.



_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project



--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Mariano Martinez Peck
In reply to this post by Torsten Bergmann


On Tue, Feb 23, 2010 at 10:51 AM, Torsten Bergmann <[hidden email]> wrote:
Havent followed this thread and currently lacking some time.
The VMMaker config is changeable, so go ahead.


Done. We do it together with JB.

Name: ConfigurationOfVMMaker-MarianoMartinezPeck.7
Author: MarianoMartinezPeck
Time: 25 February 2010, 1:06:10 pm
UUID: dca6ccf9-51d0-4ba0-9c71-e0261518ecad
Ancestors: ConfigurationOfVMMaker-MarianoMartinezPeck.6

New version and baseline 1.2 as development. It integrate JeanBatipste fixes to VMMaker for pharo



 
Take care that it also works in latest Squeak trunk.
Since most VM maintainers use Squeak to build the VM this is
essential to follow their progress.

Would also be a great move if Alien would be available on Windows -
this would open the door to interfacing with Win technologies like
COM or .NET (and therefore wake more commercial interest in Pharo).
Having Alien on major OS platforms would also allow to use Smalltalk<->
Java bridging technologies like JavaConnect/JNIPort,

Bye
T.

-------- Original-Nachricht --------
> Datum: Tue, 23 Feb 2010 10:08:55 +0100
> Von: Mariano Martinez Peck <[hidden email]>
> An: [hidden email]
> CC: Arnaud Jean-Baptiste <[hidden email]>, Torsten Bergmann <[hidden email]>
> Betreff: Re: [Pharo-project] Trying to build alien plugin in linux

> Torsten and JB: it would be cool to create a new metacello configuration
> version with this new version of VMMaker, puting the fix about the
> baseHeaderSize and integrating JB fixes to VMMaker.
>
> Cheers
>
> Mariano
>
> On Tue, Feb 23, 2010 at 7:55 AM, Fernando olivero
> <[hidden email]>wrote:
>
> >
> > On Feb 23, 2010, at 4:19 AM, John M McIntosh wrote:
> >
> > >
> > > On 2010-02-22, at 6:48 PM, Javier Pimás wrote:
> > >
> > >>
> > >
> > >> Lastly, as I said when I loaded Alien Core the first time, I got this
> > error while loading it:
> > >>
> > >> Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".
> > >>
> > >> What should I do about that? ignore it?
> > >
> > > Well it seems to be related to
> > >
> > >       ((Smalltalk includesKey: #ObjectMemory)
> > >        and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien
> > ifAbsent: []) ~~ (index - 1)]) ifTrue:
> > >               [self error: 'index probably wrong'].
> > >
> > > Usually people don't have ObjectMemory loaded in their image, and I"m
> not
> > sure what it is check for.
> > > Why don't you try it in a regular Pharo image versus your VMMaker
> image.
> >
> > Great work Jorge! Nice to know you won the battle against VMMaker!
> >
> > The ensure in special objects array error, has to do with some missing
> > classes as John pointed out.
> >
> > The smalltalk special objects array has hardcoded indexes for some
> relevant
> > classes ( Globals) in the system.
> > In the alien configuration i've just ensured that the size should be 53,
> > before loading Alien, because the Alien code installs itself in that
> array
> > at positions 54 and 55.
> >
> >
> >
> > _______________________________________________
> > Pharo-project mailing list
> > [hidden email]
> > http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
> >

--
NEU: Mit GMX DSL über 1000,- ż sparen!
http://portal.gmx.net/de/go/dsl02


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
In reply to this post by melkyades
Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

johnmci
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================





_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
Ok, this is way nicer. The line that was missing and that seems to solve all this is

self initializeSpecialObjectIndices.

which I think should be placed in Alien>>#initialize just before

self ensureInSpecialObjectsArray.

but then I don't know why it should ensure anything that is done just before.

With that I it's really close to work. After a few hours I understood the way tests are done. In Alien plugin you integrated a couple of exported functions (ffiTest*), which you then call in the tests. These funcs do simple stuff like adding and returning the result, so you can compare, am I right?

Then I realized that (at least in linux) the tests won't work if you compile as internal (there won't be a .so, so you won't be able to load the C test functions!).

Now with the small fix I added, and compiling as external, I can see that it's actually almost almost working, buuuut I get these test results: 36 run, 17 passed, 19 failures, 0 errors (had to remove testCallingSquenceString because it crashed the VM). Notice that before I got 20 errors and 0 failures. This is because the results are wrong.


I debugged the code with ddd to see what's happening, and I can see that everything is going nice before the actual function call, that is done in dabusiness.h.

    funcAlien = interpreterProxy->stackValue(funcOffset);
    f = *(void **)startOfParameterData(funcAlien);

#if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should it?)
    /* cut stack back to start of aligned args */
    setsp(argstart);
#endif
    r = f();

I took as example test #ffiTestLongLong10a2:, which calls ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2).

dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 12 0). I have to admit that I don't fully understand whats happening with the stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking of a calling convention problem. Here it's why:

In some run I have: &argvec[0] is pos 0aa0 (this is actually direction inside the stack, near it's top). Just before assembly CALL ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., and current stack frame starting at 0a88 and going lower, 0a84, etc. That may be ok, but when I look into the ffiTestLongLong10a2 assembly it is trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd in ebp-20, ...) when it should adding, looking in greater positions (previous stack frame, arg1 is in ebp+18). This has to be some simple calling convention stuff, but I don't know how to solve it, any ideas?.

Thanks for reading,
                          Javier.


On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh <[hidden email]> wrote:
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Eliot Miranda-2


2010/3/3 Javier Pimás <[hidden email]>
Ok, this is way nicer. The line that was missing and that seems to solve all this is

self initializeSpecialObjectIndices.

which I think should be placed in Alien>>#initialize just before

self ensureInSpecialObjectsArray.

but then I don't know why it should ensure anything that is done just before.

With that I it's really close to work. After a few hours I understood the way tests are done. In Alien plugin you integrated a couple of exported functions (ffiTest*), which you then call in the tests. These funcs do simple stuff like adding and returning the result, so you can compare, am I right?

Then I realized that (at least in linux) the tests won't work if you compile as internal (there won't be a .so, so you won't be able to load the C test functions!).

Now with the small fix I added, and compiling as external, I can see that it's actually almost almost working, buuuut I get these test results: 36 run, 17 passed, 19 failures, 0 errors (had to remove testCallingSquenceString because it crashed the VM). Notice that before I got 20 errors and 0 failures. This is because the results are wrong.


I debugged the code with ddd to see what's happening, and I can see that everything is going nice before the actual function call, that is done in dabusiness.h.

    funcAlien = interpreterProxy->stackValue(funcOffset);
    f = *(void **)startOfParameterData(funcAlien);

#if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should it?)
    /* cut stack back to start of aligned args */
    setsp(argstart);
#endif
    r = f();

I took as example test #ffiTestLongLong10a2:, which calls ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2).

dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 12 0). I have to admit that I don't fully understand whats happening with the stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking of a calling convention problem. Here it's why:

In some run I have: &argvec[0] is pos 0aa0 (this is actually direction inside the stack, near it's top). Just before assembly CALL ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., and current stack frame starting at 0a88 and going lower, 0a84, etc. That may be ok, but when I look into the ffiTestLongLong10a2 assembly it is trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd in ebp-20, ...) when it should adding, looking in greater positions (previous stack frame, arg1 is in ebp+18). This has to be some simple calling convention stuff, but I don't know how to solve it, any ideas?.

Subtracting from ebp is for accessing locals, adding to ebp for accessing arguments.  Are you sure you're not misinterpreting a local access as an argument access?



Thanks for reading,
                          Javier.


On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh <[hidden email]> wrote:
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
Exactly, that's what confuses me most! The function doesn't even have locals:

EXPORT(LONGLONG) ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2) {
    return c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+i1 + i2;
}

I'm quite sure it's substracting because I see the memory contents, and the disassembly is this (notice how it accumulates the result in edx):

    0x75d32725 <ffiTestLongLong10a2+308>:   movsbl -0x1c(%ebp),%edx
    0x75d32729 <ffiTestLongLong10a2+312>:   movsbl -0x20(%ebp),%eax
    0x75d3272d <ffiTestLongLong10a2+316>:   add    %eax,%edx
    0x75d3272f <ffiTestLongLong10a2+318>:   movsbl -0x24(%ebp),%eax
    0x75d32733 <ffiTestLongLong10a2+322>:   add    %eax,%edx
    0x75d32735 <ffiTestLongLong10a2+324>:   movsbl -0x28(%ebp),%eax
    0x75d32739 <ffiTestLongLong10a2+328>:   add    %eax,%edx
    0x75d3273b <ffiTestLongLong10a2+330>:   movsbl -0x2c(%ebp),%eax
    0x75d3273f <ffiTestLongLong10a2+334>:   add    %eax,%edx
    0x75d32741 <ffiTestLongLong10a2+336>:   movsbl -0x30(%ebp),%eax
    0x75d32745 <ffiTestLongLong10a2+340>:   add    %eax,%edx
    0x75d32747 <ffiTestLongLong10a2+342>:   movsbl -0x34(%ebp),%eax
    0x75d3274b <ffiTestLongLong10a2+346>:   add    %eax,%edx
    0x75d3274d <ffiTestLongLong10a2+348>:   movsbl -0x38(%ebp),%eax
    0x75d32751 <ffiTestLongLong10a2+352>:   add    %eax,%edx
    0x75d32753 <ffiTestLongLong10a2+354>:   movsbl -0x3c(%ebp),%eax
    0x75d32757 <ffiTestLongLong10a2+358>:   add    %eax,%edx
    0x75d32759 <ffiTestLongLong10a2+360>:   movsbl -0x40(%ebp),%eax
    0x75d3275d <ffiTestLongLong10a2+364>:   lea    (%edx,%eax,1),%eax
    0x75d32760 <ffiTestLongLong10a2+367>:   mov    %eax,%edx
    0x75d32762 <ffiTestLongLong10a2+369>:   sar    $0x1f,%edx
    0x75d32765 <ffiTestLongLong10a2+372>:   add    -0x48(%ebp),%eax
    0x75d32768 <ffiTestLongLong10a2+375>:   adc    -0x44(%ebp),%edx
    0x75d3276b <ffiTestLongLong10a2+378>:   add    -0x50(%ebp),%eax
    0x75d3276e <ffiTestLongLong10a2+381>:   adc    -0x4c(%ebp),%edx
    0x75d32771 <ffiTestLongLong10a2+384>:   add    $0xbc,%esp
    0x75d32777 <ffiTestLongLong10a2+390>:   pop    %ebx
    0x75d32778 <ffiTestLongLong10a2+391>:   pop    %esi
    0x75d32779 <ffiTestLongLong10a2+392>:   pop    %edi
    0x75d3277a <ffiTestLongLong10a2+393>:   pop    %ebp
    0x75d3277b <ffiTestLongLong10a2+394>:   ret

This is really weird! Why could gcc compiled it flipped? I'll continue looking.

Regards,
           Javier.

2010/3/3 Eliot Miranda <[hidden email]>


2010/3/3 Javier Pimás <[hidden email]>

Ok, this is way nicer. The line that was missing and that seems to solve all this is

self initializeSpecialObjectIndices.

which I think should be placed in Alien>>#initialize just before

self ensureInSpecialObjectsArray.

but then I don't know why it should ensure anything that is done just before.

With that I it's really close to work. After a few hours I understood the way tests are done. In Alien plugin you integrated a couple of exported functions (ffiTest*), which you then call in the tests. These funcs do simple stuff like adding and returning the result, so you can compare, am I right?

Then I realized that (at least in linux) the tests won't work if you compile as internal (there won't be a .so, so you won't be able to load the C test functions!).

Now with the small fix I added, and compiling as external, I can see that it's actually almost almost working, buuuut I get these test results: 36 run, 17 passed, 19 failures, 0 errors (had to remove testCallingSquenceString because it crashed the VM). Notice that before I got 20 errors and 0 failures. This is because the results are wrong.


I debugged the code with ddd to see what's happening, and I can see that everything is going nice before the actual function call, that is done in dabusiness.h.

    funcAlien = interpreterProxy->stackValue(funcOffset);
    f = *(void **)startOfParameterData(funcAlien);

#if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should it?)
    /* cut stack back to start of aligned args */
    setsp(argstart);
#endif
    r = f();

I took as example test #ffiTestLongLong10a2:, which calls ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2).

dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 12 0). I have to admit that I don't fully understand whats happening with the stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking of a calling convention problem. Here it's why:

In some run I have: &argvec[0] is pos 0aa0 (this is actually direction inside the stack, near it's top). Just before assembly CALL ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., and current stack frame starting at 0a88 and going lower, 0a84, etc. That may be ok, but when I look into the ffiTestLongLong10a2 assembly it is trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd in ebp-20, ...) when it should adding, looking in greater positions (previous stack frame, arg1 is in ebp+18). This has to be some simple calling convention stuff, but I don't know how to solve it, any ideas?.

Subtracting from ebp is for accessing locals, adding to ebp for accessing arguments.  Are you sure you're not misinterpreting a local access as an argument access?



Thanks for reading,
                          Javier.


On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh <[hidden email]> wrote:
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project



--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
Wiiiiiii. All tests passing now!!

You were right, this func had so many variables that gcc was reserving some local space to do some intermediate calculations.

To make the story short defining
# define STACK_ALIGN_BYTES 16
solved it.

After a lot of debugging I discovered that alloca was aligning the stack, allocating more space than necesary, and placing the args not starting from esp but from esp plus some offset. Adding getsp(argvec) to move argvec to the top of the stack didn't solve the problem because the code that pushes the args also overwrites it (don't know why, it's like alloca augmented the frame in the middle?).

So, that define fixed everything, and

#if __APPLE__ && __MACH__ && __i386__
# define STACK_ALIGN_BYTES 16
#endif

should be changed accordingly (to something I don't know what). In my case I'm using gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1.

Thanks for all the help!

Regards,
           Javier.


On Wed, Mar 3, 2010 at 2:36 PM, Javier Pimás <[hidden email]> wrote:
Exactly, that's what confuses me most! The function doesn't even have locals:

EXPORT(LONGLONG) ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2) {
    return c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+i1 + i2;
}

I'm quite sure it's substracting because I see the memory contents, and the disassembly is this (notice how it accumulates the result in edx):

    0x75d32725 <ffiTestLongLong10a2+308>:   movsbl -0x1c(%ebp),%edx
    0x75d32729 <ffiTestLongLong10a2+312>:   movsbl -0x20(%ebp),%eax
    0x75d3272d <ffiTestLongLong10a2+316>:   add    %eax,%edx
    0x75d3272f <ffiTestLongLong10a2+318>:   movsbl -0x24(%ebp),%eax
    0x75d32733 <ffiTestLongLong10a2+322>:   add    %eax,%edx
    0x75d32735 <ffiTestLongLong10a2+324>:   movsbl -0x28(%ebp),%eax
    0x75d32739 <ffiTestLongLong10a2+328>:   add    %eax,%edx
    0x75d3273b <ffiTestLongLong10a2+330>:   movsbl -0x2c(%ebp),%eax
    0x75d3273f <ffiTestLongLong10a2+334>:   add    %eax,%edx
    0x75d32741 <ffiTestLongLong10a2+336>:   movsbl -0x30(%ebp),%eax
    0x75d32745 <ffiTestLongLong10a2+340>:   add    %eax,%edx
    0x75d32747 <ffiTestLongLong10a2+342>:   movsbl -0x34(%ebp),%eax
    0x75d3274b <ffiTestLongLong10a2+346>:   add    %eax,%edx
    0x75d3274d <ffiTestLongLong10a2+348>:   movsbl -0x38(%ebp),%eax
    0x75d32751 <ffiTestLongLong10a2+352>:   add    %eax,%edx
    0x75d32753 <ffiTestLongLong10a2+354>:   movsbl -0x3c(%ebp),%eax
    0x75d32757 <ffiTestLongLong10a2+358>:   add    %eax,%edx
    0x75d32759 <ffiTestLongLong10a2+360>:   movsbl -0x40(%ebp),%eax
    0x75d3275d <ffiTestLongLong10a2+364>:   lea    (%edx,%eax,1),%eax
    0x75d32760 <ffiTestLongLong10a2+367>:   mov    %eax,%edx
    0x75d32762 <ffiTestLongLong10a2+369>:   sar    $0x1f,%edx
    0x75d32765 <ffiTestLongLong10a2+372>:   add    -0x48(%ebp),%eax
    0x75d32768 <ffiTestLongLong10a2+375>:   adc    -0x44(%ebp),%edx
    0x75d3276b <ffiTestLongLong10a2+378>:   add    -0x50(%ebp),%eax
    0x75d3276e <ffiTestLongLong10a2+381>:   adc    -0x4c(%ebp),%edx
    0x75d32771 <ffiTestLongLong10a2+384>:   add    $0xbc,%esp
    0x75d32777 <ffiTestLongLong10a2+390>:   pop    %ebx
    0x75d32778 <ffiTestLongLong10a2+391>:   pop    %esi
    0x75d32779 <ffiTestLongLong10a2+392>:   pop    %edi
    0x75d3277a <ffiTestLongLong10a2+393>:   pop    %ebp
    0x75d3277b <ffiTestLongLong10a2+394>:   ret

This is really weird! Why could gcc compiled it flipped? I'll continue looking.

Regards,
           Javier.

2010/3/3 Eliot Miranda <[hidden email]>



2010/3/3 Javier Pimás <[hidden email]>

Ok, this is way nicer. The line that was missing and that seems to solve all this is

self initializeSpecialObjectIndices.

which I think should be placed in Alien>>#initialize just before

self ensureInSpecialObjectsArray.

but then I don't know why it should ensure anything that is done just before.

With that I it's really close to work. After a few hours I understood the way tests are done. In Alien plugin you integrated a couple of exported functions (ffiTest*), which you then call in the tests. These funcs do simple stuff like adding and returning the result, so you can compare, am I right?

Then I realized that (at least in linux) the tests won't work if you compile as internal (there won't be a .so, so you won't be able to load the C test functions!).

Now with the small fix I added, and compiling as external, I can see that it's actually almost almost working, buuuut I get these test results: 36 run, 17 passed, 19 failures, 0 errors (had to remove testCallingSquenceString because it crashed the VM). Notice that before I got 20 errors and 0 failures. This is because the results are wrong.


I debugged the code with ddd to see what's happening, and I can see that everything is going nice before the actual function call, that is done in dabusiness.h.

    funcAlien = interpreterProxy->stackValue(funcOffset);
    f = *(void **)startOfParameterData(funcAlien);

#if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should it?)
    /* cut stack back to start of aligned args */
    setsp(argstart);
#endif
    r = f();

I took as example test #ffiTestLongLong10a2:, which calls ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2).

dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 12 0). I have to admit that I don't fully understand whats happening with the stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking of a calling convention problem. Here it's why:

In some run I have: &argvec[0] is pos 0aa0 (this is actually direction inside the stack, near it's top). Just before assembly CALL ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., and current stack frame starting at 0a88 and going lower, 0a84, etc. That may be ok, but when I look into the ffiTestLongLong10a2 assembly it is trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd in ebp-20, ...) when it should adding, looking in greater positions (previous stack frame, arg1 is in ebp+18). This has to be some simple calling convention stuff, but I don't know how to solve it, any ideas?.

Subtracting from ebp is for accessing locals, adding to ebp for accessing arguments.  Are you sure you're not misinterpreting a local access as an argument access?



Thanks for reading,
                          Javier.


On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh <[hidden email]> wrote:
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

melkyades
Also I have the theory that the problem may be related to some -fomit-frame-pointer hidden in some place that forces code to use references relative to esp instead of ebp.

On Fri, Mar 5, 2010 at 1:20 AM, Javier Pimás <[hidden email]> wrote:
Wiiiiiii. All tests passing now!!

You were right, this func had so many variables that gcc was reserving some local space to do some intermediate calculations.

To make the story short defining
# define STACK_ALIGN_BYTES 16
solved it.

After a lot of debugging I discovered that alloca was aligning the stack, allocating more space than necesary, and placing the args not starting from esp but from esp plus some offset. Adding getsp(argvec) to move argvec to the top of the stack didn't solve the problem because the code that pushes the args also overwrites it (don't know why, it's like alloca augmented the frame in the middle?).

So, that define fixed everything, and

#if __APPLE__ && __MACH__ && __i386__
# define STACK_ALIGN_BYTES 16
#endif

should be changed accordingly (to something I don't know what). In my case I'm using gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1.

Thanks for all the help!

Regards,
           Javier.



On Wed, Mar 3, 2010 at 2:36 PM, Javier Pimás <[hidden email]> wrote:
Exactly, that's what confuses me most! The function doesn't even have locals:

EXPORT(LONGLONG) ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2) {
    return c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+i1 + i2;
}

I'm quite sure it's substracting because I see the memory contents, and the disassembly is this (notice how it accumulates the result in edx):

    0x75d32725 <ffiTestLongLong10a2+308>:   movsbl -0x1c(%ebp),%edx
    0x75d32729 <ffiTestLongLong10a2+312>:   movsbl -0x20(%ebp),%eax
    0x75d3272d <ffiTestLongLong10a2+316>:   add    %eax,%edx
    0x75d3272f <ffiTestLongLong10a2+318>:   movsbl -0x24(%ebp),%eax
    0x75d32733 <ffiTestLongLong10a2+322>:   add    %eax,%edx
    0x75d32735 <ffiTestLongLong10a2+324>:   movsbl -0x28(%ebp),%eax
    0x75d32739 <ffiTestLongLong10a2+328>:   add    %eax,%edx
    0x75d3273b <ffiTestLongLong10a2+330>:   movsbl -0x2c(%ebp),%eax
    0x75d3273f <ffiTestLongLong10a2+334>:   add    %eax,%edx
    0x75d32741 <ffiTestLongLong10a2+336>:   movsbl -0x30(%ebp),%eax
    0x75d32745 <ffiTestLongLong10a2+340>:   add    %eax,%edx
    0x75d32747 <ffiTestLongLong10a2+342>:   movsbl -0x34(%ebp),%eax
    0x75d3274b <ffiTestLongLong10a2+346>:   add    %eax,%edx
    0x75d3274d <ffiTestLongLong10a2+348>:   movsbl -0x38(%ebp),%eax
    0x75d32751 <ffiTestLongLong10a2+352>:   add    %eax,%edx
    0x75d32753 <ffiTestLongLong10a2+354>:   movsbl -0x3c(%ebp),%eax
    0x75d32757 <ffiTestLongLong10a2+358>:   add    %eax,%edx
    0x75d32759 <ffiTestLongLong10a2+360>:   movsbl -0x40(%ebp),%eax
    0x75d3275d <ffiTestLongLong10a2+364>:   lea    (%edx,%eax,1),%eax
    0x75d32760 <ffiTestLongLong10a2+367>:   mov    %eax,%edx
    0x75d32762 <ffiTestLongLong10a2+369>:   sar    $0x1f,%edx
    0x75d32765 <ffiTestLongLong10a2+372>:   add    -0x48(%ebp),%eax
    0x75d32768 <ffiTestLongLong10a2+375>:   adc    -0x44(%ebp),%edx
    0x75d3276b <ffiTestLongLong10a2+378>:   add    -0x50(%ebp),%eax
    0x75d3276e <ffiTestLongLong10a2+381>:   adc    -0x4c(%ebp),%edx
    0x75d32771 <ffiTestLongLong10a2+384>:   add    $0xbc,%esp
    0x75d32777 <ffiTestLongLong10a2+390>:   pop    %ebx
    0x75d32778 <ffiTestLongLong10a2+391>:   pop    %esi
    0x75d32779 <ffiTestLongLong10a2+392>:   pop    %edi
    0x75d3277a <ffiTestLongLong10a2+393>:   pop    %ebp
    0x75d3277b <ffiTestLongLong10a2+394>:   ret

This is really weird! Why could gcc compiled it flipped? I'll continue looking.

Regards,
           Javier.

2010/3/3 Eliot Miranda <[hidden email]>



2010/3/3 Javier Pimás <[hidden email]>

Ok, this is way nicer. The line that was missing and that seems to solve all this is

self initializeSpecialObjectIndices.

which I think should be placed in Alien>>#initialize just before

self ensureInSpecialObjectsArray.

but then I don't know why it should ensure anything that is done just before.

With that I it's really close to work. After a few hours I understood the way tests are done. In Alien plugin you integrated a couple of exported functions (ffiTest*), which you then call in the tests. These funcs do simple stuff like adding and returning the result, so you can compare, am I right?

Then I realized that (at least in linux) the tests won't work if you compile as internal (there won't be a .so, so you won't be able to load the C test functions!).

Now with the small fix I added, and compiling as external, I can see that it's actually almost almost working, buuuut I get these test results: 36 run, 17 passed, 19 failures, 0 errors (had to remove testCallingSquenceString because it crashed the VM). Notice that before I got 20 errors and 0 failures. This is because the results are wrong.


I debugged the code with ddd to see what's happening, and I can see that everything is going nice before the actual function call, that is done in dabusiness.h.

    funcAlien = interpreterProxy->stackValue(funcOffset);
    f = *(void **)startOfParameterData(funcAlien);

#if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should it?)
    /* cut stack back to start of aligned args */
    setsp(argstart);
#endif
    r = f();

I took as example test #ffiTestLongLong10a2:, which calls ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2).

dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 12 0). I have to admit that I don't fully understand whats happening with the stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking of a calling convention problem. Here it's why:

In some run I have: &argvec[0] is pos 0aa0 (this is actually direction inside the stack, near it's top). Just before assembly CALL ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., and current stack frame starting at 0a88 and going lower, 0a84, etc. That may be ok, but when I look into the ffiTestLongLong10a2 assembly it is trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd in ebp-20, ...) when it should adding, looking in greater positions (previous stack frame, arg1 is in ebp+18). This has to be some simple calling convention stuff, but I don't know how to solve it, any ideas?.

Subtracting from ebp is for accessing locals, adding to ebp for accessing arguments.  Are you sure you're not misinterpreting a local access as an argument access?



Thanks for reading,
                          Javier.


On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh <[hidden email]> wrote:
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
Reply | Threaded
Open this post in threaded view
|

Re: Trying to build alien plugin in linux

Eliot Miranda-2


2010/3/4 Javier Pimás <[hidden email]>
Also I have the theory that the problem may be related to some -fomit-frame-pointer hidden in some place that forces code to use references relative to esp instead of ebp.

Ah, that's *very* important.  The plugin must *not* be built with -fomi-frame-pointer.  In fact it needs -fno-omit-frame-pointer adding to Makefile.inc et al to ensure it always includes the frame pointer.

 


On Fri, Mar 5, 2010 at 1:20 AM, Javier Pimás <[hidden email]> wrote:
Wiiiiiii. All tests passing now!!

You were right, this func had so many variables that gcc was reserving some local space to do some intermediate calculations.

To make the story short defining
# define STACK_ALIGN_BYTES 16
solved it.

After a lot of debugging I discovered that alloca was aligning the stack, allocating more space than necesary, and placing the args not starting from esp but from esp plus some offset. Adding getsp(argvec) to move argvec to the top of the stack didn't solve the problem because the code that pushes the args also overwrites it (don't know why, it's like alloca augmented the frame in the middle?).

So, that define fixed everything, and

#if __APPLE__ && __MACH__ && __i386__
# define STACK_ALIGN_BYTES 16
#endif

should be changed accordingly (to something I don't know what). In my case I'm using gcc (Ubuntu 4.4.1-4ubuntu9) 4.4.1.

Thanks for all the help!

Regards,
           Javier.



On Wed, Mar 3, 2010 at 2:36 PM, Javier Pimás <[hidden email]> wrote:
Exactly, that's what confuses me most! The function doesn't even have locals:

EXPORT(LONGLONG) ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2) {
    return c1+c2+c3+c4+c5+c6+c7+c8+c9+c10+i1 + i2;
}

I'm quite sure it's substracting because I see the memory contents, and the disassembly is this (notice how it accumulates the result in edx):

    0x75d32725 <ffiTestLongLong10a2+308>:   movsbl -0x1c(%ebp),%edx
    0x75d32729 <ffiTestLongLong10a2+312>:   movsbl -0x20(%ebp),%eax
    0x75d3272d <ffiTestLongLong10a2+316>:   add    %eax,%edx
    0x75d3272f <ffiTestLongLong10a2+318>:   movsbl -0x24(%ebp),%eax
    0x75d32733 <ffiTestLongLong10a2+322>:   add    %eax,%edx
    0x75d32735 <ffiTestLongLong10a2+324>:   movsbl -0x28(%ebp),%eax
    0x75d32739 <ffiTestLongLong10a2+328>:   add    %eax,%edx
    0x75d3273b <ffiTestLongLong10a2+330>:   movsbl -0x2c(%ebp),%eax
    0x75d3273f <ffiTestLongLong10a2+334>:   add    %eax,%edx
    0x75d32741 <ffiTestLongLong10a2+336>:   movsbl -0x30(%ebp),%eax
    0x75d32745 <ffiTestLongLong10a2+340>:   add    %eax,%edx
    0x75d32747 <ffiTestLongLong10a2+342>:   movsbl -0x34(%ebp),%eax
    0x75d3274b <ffiTestLongLong10a2+346>:   add    %eax,%edx
    0x75d3274d <ffiTestLongLong10a2+348>:   movsbl -0x38(%ebp),%eax
    0x75d32751 <ffiTestLongLong10a2+352>:   add    %eax,%edx
    0x75d32753 <ffiTestLongLong10a2+354>:   movsbl -0x3c(%ebp),%eax
    0x75d32757 <ffiTestLongLong10a2+358>:   add    %eax,%edx
    0x75d32759 <ffiTestLongLong10a2+360>:   movsbl -0x40(%ebp),%eax
    0x75d3275d <ffiTestLongLong10a2+364>:   lea    (%edx,%eax,1),%eax
    0x75d32760 <ffiTestLongLong10a2+367>:   mov    %eax,%edx
    0x75d32762 <ffiTestLongLong10a2+369>:   sar    $0x1f,%edx
    0x75d32765 <ffiTestLongLong10a2+372>:   add    -0x48(%ebp),%eax
    0x75d32768 <ffiTestLongLong10a2+375>:   adc    -0x44(%ebp),%edx
    0x75d3276b <ffiTestLongLong10a2+378>:   add    -0x50(%ebp),%eax
    0x75d3276e <ffiTestLongLong10a2+381>:   adc    -0x4c(%ebp),%edx
    0x75d32771 <ffiTestLongLong10a2+384>:   add    $0xbc,%esp
    0x75d32777 <ffiTestLongLong10a2+390>:   pop    %ebx
    0x75d32778 <ffiTestLongLong10a2+391>:   pop    %esi
    0x75d32779 <ffiTestLongLong10a2+392>:   pop    %edi
    0x75d3277a <ffiTestLongLong10a2+393>:   pop    %ebp
    0x75d3277b <ffiTestLongLong10a2+394>:   ret

This is really weird! Why could gcc compiled it flipped? I'll continue looking.

Regards,
           Javier.

2010/3/3 Eliot Miranda <[hidden email]>



2010/3/3 Javier Pimás <[hidden email]>

Ok, this is way nicer. The line that was missing and that seems to solve all this is

self initializeSpecialObjectIndices.

which I think should be placed in Alien>>#initialize just before

self ensureInSpecialObjectsArray.

but then I don't know why it should ensure anything that is done just before.

With that I it's really close to work. After a few hours I understood the way tests are done. In Alien plugin you integrated a couple of exported functions (ffiTest*), which you then call in the tests. These funcs do simple stuff like adding and returning the result, so you can compare, am I right?

Then I realized that (at least in linux) the tests won't work if you compile as internal (there won't be a .so, so you won't be able to load the C test functions!).

Now with the small fix I added, and compiling as external, I can see that it's actually almost almost working, buuuut I get these test results: 36 run, 17 passed, 19 failures, 0 errors (had to remove testCallingSquenceString because it crashed the VM). Notice that before I got 20 errors and 0 failures. This is because the results are wrong.


I debugged the code with ddd to see what's happening, and I can see that everything is going nice before the actual function call, that is done in dabusiness.h.

    funcAlien = interpreterProxy->stackValue(funcOffset);
    f = *(void **)startOfParameterData(funcAlien);

#if STACK_ALIGN_BYTES (in my compiled code it is'nt defined, should it?)
    /* cut stack back to start of aligned args */
    setsp(argstart);
#endif
    r = f();

I took as example test #ffiTestLongLong10a2:, which calls ffiTestLongLong10a2(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8, char c9, char c10, LONGLONG i1, LONGLONG i2).

dabusiness.h allocated 56 bytes in argvec (10*4 for chars + 2*8 for longlong), which then fills correctly (ddd says 1 2 3 4 5 6 7 8 9 10 11 0 12 0). I have to admit that I don't fully understand whats happening with the stack then, but ffiTestLongLong10a2 gets its arguments wrong. I'm thinking of a calling convention problem. Here it's why:

In some run I have: &argvec[0] is pos 0aa0 (this is actually direction inside the stack, near it's top). Just before assembly CALL ffiTestLongLong10a2 I have ebp=0b68, and after the call it is pushed and replaced with esp, which is 0a88. Then, we have, args at 0aa0, 0aa4, ..., and current stack frame starting at 0a88 and going lower, 0a84, etc. That may be ok, but when I look into the ffiTestLongLong10a2 assembly it is trying to find the arguments by *substracting* to ebp (arg1 in ebp-1c, 2nd in ebp-20, ...) when it should adding, looking in greater positions (previous stack frame, arg1 is in ebp+18). This has to be some simple calling convention stuff, but I don't know how to solve it, any ideas?.

Subtracting from ebp is for accessing locals, adding to ebp for accessing arguments.  Are you sure you're not misinterpreting a local access as an argument access?



Thanks for reading,
                          Javier.


On Mon, Mar 1, 2010 at 9:05 PM, John M McIntosh <[hidden email]> wrote:
It would be missing, propose a change set.

I would think people usually don't use VMMaker images as their daily work image. 

So take image, load vmaker, load vmaker stuff for alien, make alien plugin. 

got to my work image that doesn't have vmmaker in it, 
load alien support stuf, you don't need the alien-vmmaker-support btw. 
run tests. 



On 2010-03-01, at 3:36 PM, Javier Pimás wrote:

Hi, I'm still trying to advance with this. Don't know what caused the ObjectMemory classPools but it seems to be away now, maybe I did some mistake last time.

The thing is that now I have in ObjectMemory classPools all the original ones plus 4 new elements, which I think were added with this Alien-VMMaker-Support override:

ObjectMemory>>#initialize
initialize
    #( #ClassAlien #ClassUnsafeAlien #InvokeCallbackSelector #SelectorAttemptToAssign)
    do: [:c |
        [ObjectMemory addClassVarName: c] ifError: []].

the thing is that it never assigns them any value, so my theory is that there's some code missing? Then in Interpreter it happens something quite similar. Interpreter>>#initialize does this:

...

    #(#PrimErrBadArgument #PrimErrBadIndex #PrimErrBadNumArgs #PrimErrBadReceiver     #PrimErrGenericFailure #PrimErrInappropriate #PrimErrNoCMemory #PrimErrNoMemory     #PrimErrNoModification #PrimErrNotFound #PrimErrTableIndex #PrimErrUnsupported #PrimNoErr )
    do: [:c |
        [Interpreter addClassVarName: c] ifError: []].

    #(#primFailCode)
        do: [:i |  [Interpreter addInstVarName: i] ifError: []].

...

but then never calls initializePrimitiveErrorCodes, which would set the vars to a meaningfull value.


In conclusion, the question would be, where is this missing initialization code?

Hope you can help, thanks!

Javier.

On Tue, Feb 23, 2010 at 4:39 PM, Javier Pimás <[hidden email]> wrote:


On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <[hidden email]> wrote:

On 2010-02-22, at 6:48 PM, Javier Pimás wrote:

Nice!!!!!!!! It's compiling now. Now, I loaded tests, and here are the results:

37 run, 17 passed, 0 failures, 20 errors.

TestCallingSequenceChar10Long2
TestCallingSequenceChar2LongLong2
TestCallingSequenceChar8Long2
TestCallingSequenceChar9Long2
TestCallingSequenceCharLongLong2
TestCallingSequenceChars
TestCallingSequenceDoubles14
TestCallingSequenceDoubles2
TestCallingSequenceFloats13
TestCallingSequenceFloats14
TestCallingSequenceFloats2
TestCallingSequenceFloats2WithInteger
TestCallingSequenceFloats2WithInteger2
TestCallingSequenceFloats7
TestCallingSequenceInt
TestCallingSequenceInt8
TestCallingSequenceIntWithFloatArgs
TestCallingSequenceLongLong2
TestCallingSequenceShort
TestCallingSequenceString

Oh look SUnits, great stuff (*cough* well I wrote most of them). 


Cool, this is really really useful (although I sometimes find wrting tests boring ;) ).


It is failing in places where it does primLoadLibrary: 'IA32ABI'. Why should it try to load itself, if it's compiled as an internal plugin? I compiled it as external too but didn't work either.

Well it compiled, but that doesn't mean it works. In fact the error means the plugin code is never loaded, or is callable. 
Now one thing to consider is that the plugin load fails, because it can't find it. (external usage). 
Or because (internal and external plugin)  the VM Version and the plugin version don't match. 

Look for your definition of 
#define VM_PROXY_MINOR 8

It should be 8 or higher for compiling BOTH the VM and the Plugin. 
Since the sqVirtualMachine.h is in the IA32ABI folder maybe there is mass confusion about which header is being used? 

If for example your VM say it's a VM_PROXY_MINOR of 7, then it won't work with a plugin compiled with VM_PROXY_MINOR = 8. 
It silently fails... Well actually it gives the primLoadLibrary failure, but good luck in guessing why... 

Well, I just overwrote sqVirtualMachine.c/h in Cross/vm, shouldn't have I? It wouldn't compile if I didn't and its sets it to 8. Is it defined in any other place?




Other question, can classic FFI and Alien live nicely together (I mean have x plugin use classic FFI while y uses Alien)?


yes. 

One more: should I use IA32ABIPlugin or IA32ABIPluginAttic? You can't have both in, right?

One is a subclass of the other. I use the IA32ABIPluginAttic one. 

Ok, what is the difference between them? a performance issue? everything works the same I choose one or the other?
 


Syntax highligthing is broken for Alien primitive methods like these:

<primitive: 'primUnsignedShortAtPut' error: errorCode module: 'IA32ABI'>

Lastly, as I said when I loaded Alien Core the first time, I got this error while loading it:

Alien class>>#ensureInSpecialObjectsArray: "Index probably wrong".

What should I do about that? ignore it?

Well it seems to be related to 

((Smalltalk includesKey: #ObjectMemory)
and: [((Smalltalk at: #ObjectMemory) classPool at: #ClassAlien ifAbsent: []) ~~ (index - 1)]) ifTrue:
[self error: 'index probably wrong'].

Usually people don't have ObjectMemory loaded in their image, and I"m not sure what it is check for. 
Why don't you try it in a regular Pharo image versus your VMMaker image. 


In Pharo 1.0RC2 without any change, ObjectMemory doesn't exist. When I load VMMaker it's downloaded from monticello, but obviously, #ClassAlien isn't defined inside

(Smalltalk at: #ObjectMemory) classPool

Interestingly, after load alien, #ClassAlien gets added as a key, but all values of (Smalltalk at: #ObjectMemory) classPool are set to nil, like this:

(Smalltalk at: #ObjectMemory) classPool inspect:

- size : 119
[#AllButHashBits] : nil
[#AllButMarkBit] : nil
[#AllButMarkBitAndTypeMask] : nil
[#AllButRootBit] : nil
[#AllButTypeMask] : nil
...
[#ClassAlien] : nil
...


Any ideas?



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

--
===========================================================================
John M. McIntosh <[hidden email]>   Twitter:  squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================







--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires



--
Javier Pimás
Ciudad de Buenos Aires

_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project


_______________________________________________
Pharo-project mailing list
[hidden email]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project
12