<br><br><div class="gmail_quote">On Fri, Nov 20, 2009 at 3:26 AM, Gary Dunn <span dir="ltr">&lt;<a href="mailto:osp@aloha.com">osp@aloha.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
I can report progress but no solution.<br>
<br>
1. Since ffi-test-main failed to build with a simple &quot;make&quot; I had<br>
assumed I needed to use libffi. I added a print statement to show the<br>
values at the point of failure at line 361, the CHECK statement:<br>
<div class="im"><br>
    ffiInitialize();<br>
    for (ul= 0;  ul &lt; 15;  ++ul)<br>
      ffiPushSingleFloat(fa[ul]);<br>
    GO(FFITypeSingleFloat, many);<br>
    f= ffiReturnFloatValue();<br>
    ffiCleanup();<br>
</div>    printf(&quot;%g %g %g %g\n&quot;, f, ff, f - ff, FLT_EPSILON);<br>
<div class="im">    CHECK(f - ff &lt; FLT_EPSILON);<br>
<br>
</div>It gave f and ff to be identical, f - ff zero, and FLT_EPSILON a very<br>
small value. The strange thing was that the test did not fail. I<br>
commented out my print statement and it failed. Weird.<br>
<br>
I noticed I was not seeing the output from puts statements. Recalling<br>
that this is typically a macro I looked to see if it had been defined,<br>
and found this near the top of the file:<br>
<br>
#if 0<br>
# define dprintf(ARGS)  printf ARGS<br>
# define puts(ARG)      puts(ARG)<br>
#else<br>
# define dprintf(ARGS)<br>
# define puts(ARG)<br>
#endif<br>
<br>
I changed the zero to one and the output was verbose. No failure, even<br>
with my print statement commented out.<br>
<br>
I suspect there is some tricky coding here that works on some versions<br>
of C and not others. The preprocessor, especially.<br>
<br>
So I got to wondering why make without args failed. I traced the problem<br>
to these lines from the Makefile<br>
<br>
CPU=    $(shell ./ffi-config -cpu)<br>
ABI=    $(shell ./ffi-config -abi)<br>
LIB=    $(shell ./ffi-config -lib)<br>
<br>
Running them manually gave x86, sysv and blank, but<br>
<br>
OBJ=    ffi-test-main.o ffi-test.o $(CPU)-$(ABI).o $(CPU)-$(ABI)-asm.o<br>
<br>
resolved to ffi-test-main.o ffi-test.o -.o --asm.o<br>
<br>
which caused make to complain that it did not know how to make -.o.<br>
<br>
I substituted like this<br>
<br>
#OBJ=    ffi-test-main.o ffi-test.o $(CPU)-$(ABI).o $(CPU)-$(ABI)-asm.o<br>
OBJ=   ffi-test-main.o ffi-test.o x86-sysv.o x86-sysv-asm.o<br>
<br>
and the build completed.<br>
<br>
Eventually I figured out that the shell construct works in gnu make.<br>
FreeBSD does not use gnu make. It is available as gmake. I put back the<br>
Makefile and used gmake and got a good build.<br>
<br>
The results are inconclusive. The output is<br>
<br>
slate01# ./main<br>
passed ffi assertions (0 failed)<br>
Problem passing 64bit structures<br>
<br>
Is that because I am not using a 64bit CPU? Is that a show stopper?<br>
Apparently not.<br>
<br>
The thing is, this does not fix the real problem. If I load my 3.9 image<br>
and install the FFI package from SqueakMap, then run the FFI-Tests in<br>
SUnit runner I get 21 run, 0 passes, 0 expected failures, 0 failures, 21<br>
errors, 0 unexpected passes. When I click on a result and open a<br>
debugger I find<br>
<br>
Error: Unable to find function address<br>
<br>
invokeWithArguments: argArray<br>
        &quot;Manually invoke the receiver, representing an external function.&quot;<br>
        &lt;primitive: &#39;primitiveCalloutWithArgs&#39; module:&#39;SqueakFFIPrims&#39;&gt;<br>
        ^self externalCallFailed<br>
<br>
<br>
<br>
externalCallFailed<br>
        &quot;Raise an error after a failed call to an external function&quot;<br>
        | errCode |<br>
        errCode := ExternalFunction getLastError. &quot;this allows us to look at<br>
the actual error code&quot;<br>
        ^self error: (ExternalFunction errorMessageFor: errCode).<br>
<br>
<br>
<br>
error: aString<br>
        &quot;Throw a generic Error exception.&quot;<br>
<br>
        ^Error new signal: aString<br>
<br>
<br>
If the  ffi-test-main.c tests are passing, why are the SUnit tests all<br>
failing? Is that 64bit thing a big deal?<br></blockquote><div><br></div><div>twice as big a deal as 32-bits...  But seriously folks...</div><div><br></div><div>Have you built a SqueakFFIPrims shared object?  Have you installed it in the right directory with other plugins?  Is the export table in SqueakFFIPrims.c correct (calls itself SqueakFFIPrims, includes both primitiveCallout and primitiveCalloutWithArgs as exports).</div>
<div><br></div><div>First try and understand </div><div><br></div><div><span class="Apple-style-span" style="font-family: arial, sans-serif; font-size: 13px; border-collapse: collapse; "><br><br>invokeWithArguments: argArray<br>
       &quot;Manually invoke the receiver, representing an external function.&quot;<br>       &lt;primitive: &#39;primitiveCalloutWithArgs&#39; module:&#39;SqueakFFIPrims&#39;&gt;<br>       ^self externalCallFailed</span></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">and <span class="Apple-style-span" style="font-size: 13px; ">Error: Unable to find function address.</span></span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">The first is a method that includes a spec for calling a plugin primitive, in the SqueakFFIPrims plugin, which could be in a shared object, a dll or a bundle depending on platform.  You&#39;re on linux so it should be in either SqueakFFIPrims or SqueakFFIPrims.so depending on which version of the VM you&#39;re working on.</span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;">The second tells you that, probably the VM is finding the <span class="Apple-style-span" style="font-size: 13px; ">SqueakFFIPrims module but its not finding primitiveCalloutWithArgs within it.  You can check by tracing execution through ioLoadExternalFunctionOfLengthFromModuleOfLength.  Assuming the module is being found you need to find out why the function isn&#39;t being found.</span></span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><span class="Apple-style-span" style="font-size: 13px; ">At the end of SqueakFFIPrims.c you should see a table that looks something like</span></span></font></div>
<div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><br></span></font></div><div><font class="Apple-style-span" face="arial, sans-serif"><span class="Apple-style-span" style="border-collapse: collapse;"><div>
#ifdef SQUEAK_BUILTIN_PLUGIN</div><div><br></div><div>void* SqueakFFIPrims_exports[][3] = {</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;ffiLogCallsTo&quot;, (void*)ffiLogCallsTo},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;getModuleName&quot;, (void*)getModuleName},</div>
<div>    {&quot;SqueakFFIPrims&quot;, &quot;initialiseModule&quot;, (void*)initialiseModule},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveCallout&quot;, (void*)primitiveCallout},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveCalloutWithArgs&quot;, (void*)primitiveCalloutWithArgs},</div>
<div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIAllocate&quot;, (void*)primitiveFFIAllocate},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIDoubleAt&quot;, (void*)primitiveFFIDoubleAt},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIDoubleAtPut&quot;, (void*)primitiveFFIDoubleAtPut},</div>
<div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIFloatAt&quot;, (void*)primitiveFFIFloatAt},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIFloatAtPut&quot;, (void*)primitiveFFIFloatAtPut},</div><div>
    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIFree&quot;, (void*)primitiveFFIFree},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIGetLastError&quot;, (void*)primitiveFFIGetLastError},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIIntegerAt&quot;, (void*)primitiveFFIIntegerAt},</div>
<div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveFFIIntegerAtPut&quot;, (void*)primitiveFFIIntegerAtPut},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;primitiveForceLoad&quot;, (void*)primitiveForceLoad},</div><div>
    {&quot;SqueakFFIPrims&quot;, &quot;primitiveLogCallsTo&quot;, (void*)primitiveLogCallsTo},</div><div>    {&quot;SqueakFFIPrims&quot;, &quot;setInterpreter&quot;, (void*)setInterpreter},</div><div>    {NULL, NULL, NULL}</div>
<div>};</div><div><br></div><div>#endif /* ifdef SQ_BUILTIN_PLUGIN */</div><div><br></div><div>If <span class="Apple-style-span" style="font-size: 13px; ">primitiveCalloutWithArgs is missing then SqueakFFIPrims.c didn&#39;t get generated correctly.  Go back to VMMaker and the FFIPlugin source and try to figure out why.  Note that the table shouldn&#39;t be being used because the plugin is typically used as an external plugin.  If you&#39;re building it in then ignore what follows and reply saying &quot;I want an internal plugin dammit!!&quot;</span></div>
<div><br></div><div>If <span class="Apple-style-span" style="font-size: 13px; ">primitiveCalloutWithArgs isn&#39;t missing then is it being exported form the module?  Use nm on whatever SqueakFFIPrims is compiled to and make sure its exported.  It should have something like the following:</span></div>
<div><br></div><div><div>$ nm Fast.app/Contents/Resources/SqueakFFIPrims.bundle/Contents/MacOS/SqueakFFIPrims | grep primitiveC</div><div>00004200 T _primitiveCallout</div><div>00003750 T _primitiveCalloutWithArgs</div><div>
<br></div><div>If there&#39;s a lowercase t there&#39; figure out why it isn&#39;t being exported.  e.g. EXPORT macro definition, linker commands, etc...</div><div><br></div><div>If it is being exported then you need to start debugging ioLoadSymbolOfLengthFromModule, because that&#39;s failing to extract the address of primitiveCalloutWithArgs from the loaded module.</div>
<div><br></div><div>HTH</div><div>Eliot</div><div><br></div></div></span></font></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<font color="#888888"><br>
<br>
--<br>
</font><div><div></div><div class="h5">Gary Dunn, Honolulu<br>
<a href="mailto:osp@aloha.com">osp@aloha.com</a><br>
<a href="http://openslate.net/" target="_blank">http://openslate.net/</a><br>
<a href="http://e9erust.blogspot.com/" target="_blank">http://e9erust.blogspot.com/</a><br>
Sent from Slate001<br>
<br>
</div></div></blockquote></div><br>