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 <
[email protected]> 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
> <[email protected]>wrote:
>
>>
>>
>> On Tue, Feb 23, 2010 at 12:19 AM, John M McIntosh <
>> [email protected]> 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 <[email protected]> Twitter:
> squeaker68882
> Corporate Smalltalk Consulting Ltd. http://www.smalltalkconsulting.com
> ===========================================================================
>
>
>
>
>
--
Javier Pimás
Ciudad de Buenos Aires
_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project