<html>
  <head>
    <meta content="text/html; charset=windows-1252"
      http-equiv="Content-Type">
  </head>
  <body bgcolor="#FFFFFF" text="#000000">
    This community needs a repository for plugins. A directory at
    <a class="moz-txt-link-freetext" href="http://ftp.squeak.org">http://ftp.squeak.org</a> ought to do it. <br>
    <br>
    If I want to try Alien I need the plugin. Where am I going to get
    that? I could get VMMaker, read NewSqueakIA32ABIPlugin three times
    to see it is not saying Newspeak and realize it compiles a plugin
    called IA32ABI, which - coincidentally - is the name of the plugin
    the error Alien exampleCqsort will gives me. (NewSqueakIA32ABIPlugin
    class&gt;&gt; moduleName returns IA32ABI). <br>
    <br>
    Does anybody know what the Genie plugin does? Does Paul DeBrucker
    need to store a BerkeleyDB plugin dll he got by emailing somebody on
    GitHub? <br>
    <br>
    If I understand this correctly, if such a directory existed, then
    all a person would need to do to try the above Alien code would be
    to download a pre-compiled plugin from - say -
    <a class="moz-txt-link-freetext" href="http://ftp.squeak/plugins/Alien/fooVersion">http://ftp.squeak/plugins/Alien/fooVersion</a>, put it in their VM
    directory and start the image. Then check with SmalltalkImage
    current listLoadedModules to see if you're ready to go. <br>
    <br>
    I nominate Fabio Niephaus to be the person the community can send
    pre-compiled plugins for inclusion in such a directory. Eliot's been
    banging away about Alien for some time [1]. If a person could go,
    get the plugin and give the code shot, he could have more productive
    conversations about Alien. <br>
    <br>
    So, if, Eliot, you have a pre-compiled plugin for Alien, perhaps in
    an idle moment, you could email it to Fabio? And when, Fabio, you've
    created the directory in <a class="moz-txt-link-freetext" href="http://ftp.squeak.org">http://ftp.squeak.org</a> you could announce it
    here on Squeak-dev? <br>
    <br>
    FWIW,<br>
    <br>
    Chris <br>
    <br>
    [1] <a class="moz-txt-link-freetext" href="http://wiki.squeak.org/squeak/uploads/6100/">http://wiki.squeak.org/squeak/uploads/6100/</a><br>
    <br>
    <div class="moz-cite-prefix">On 2015-09-03 7:07 PM, Eliot Miranda
      wrote:<br>
    </div>
    <blockquote
cite="mid:CAC20JE0JwYecL5onq-=-vL_Vs7nY13sjDX9Xn_s+2mk+pp+J-w@mail.gmail.com"
      type="cite">
      <div dir="ltr">Hi Craig,
        <div><br>
        </div>
        <div>    you need Alien-eem.24</div>
        <div><br>
        </div>
        <div>Here's Alien class&gt;&gt;exampleCqsort</div>
        <div><span class="" style="white-space:pre">        </span>"Call the
          libc qsort function (which requires a callback)."</div>
        <div><span class="" style="white-space:pre">        </span>"Alien
          exampleCqsort"</div>
        <div><span class="" style="white-space:pre">        </span>"(Time
          millisecondsToRun: [100 timesRepeat: [Alien exampleCqsort]]) /
          100.0"</div>
        <div><span class="" style="white-space:pre">        </span>| cb rand
          nElements sizeofDouble values orig sort |</div>
        <div><span class="" style="white-space:pre">        </span>rand :=
          Random new.</div>
        <div><span class="" style="white-space:pre">        </span>values :=
          Alien newC: (nElements := 100) * (sizeofDouble := 8).</div>
        <div><span class="" style="white-space:pre">        </span>1 to: values
          dataSize by: sizeofDouble do:</div>
        <div><span class="" style="white-space:pre">                </span>[:i| values
          doubleAt: i put: rand next].</div>
        <div><span class="" style="white-space:pre">        </span>orig := (1
          to: values dataSize by: sizeofDouble) collect: [:i| values
          doubleAt: i].</div>
        <div><span class="" style="white-space:pre">        </span>cb :=
          Callback</div>
        <div><span class="" style="white-space:pre">                        </span>signature:
           #(int (*)(const void *, const void *))</div>
        <div><span class="" style="white-space:pre">                        </span>block: [
          :arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1)) sign].</div>
        <div><span class="" style="white-space:pre">        </span>(Alien
          lookup: 'qsort' inLibrary: Alien libcName)</div>
        <div><span class="" style="white-space:pre">                </span>primFFICallResult:
          nil</div>
        <div><span class="" style="white-space:pre">                </span>with:
          values pointer</div>
        <div><span class="" style="white-space:pre">                </span>with:
          nElements</div>
        <div><span class="" style="white-space:pre">                </span>with:
          sizeofDouble</div>
        <div><span class="" style="white-space:pre">                </span>with: cb
          thunk.</div>
        <div><span class="" style="white-space:pre">        </span>sort := (1
          to: values dataSize by: sizeofDouble) collect: [:i| values
          doubleAt: i].</div>
        <div><span class="" style="white-space:pre">        </span>values free.</div>
        <div><span class="" style="white-space:pre">        </span>^orig -&gt;
          sort</div>
        <div><br>
        </div>
        <div>The above example uses Alien to make the callout.  To use
          it with the FFI simply pass cb pointer as the argument as is
          done above.</div>
        <div><br>
        </div>
        <div><br>
        </div>
        <div>Implementation:</div>
        <div><br>
        </div>
        <div>The way that it works is in two parts</div>
        <div>- the VM passes up a pointer to a structure from which all
          arguments, stacked and in registers (because the VM has copied
          the register args into the struct) can be accessed, and
          through which the result can be returned.</div>
        <div>- the image level provides marshalling methods that match
          the signature in the callback</div>
        <div><br>
        </div>
        <div>So e.g. with a callback of<br>
        </div>
        <div>
          <div><span class="" style="white-space:pre">                </span>Callback</div>
          <div><span class="" style="white-space:pre">                        </span>signature:
             #(int (*)(const void *, const void *))</div>
          <div><span class="" style="white-space:pre">                        </span>block: [
            :arg1 :arg2 | ((arg1 doubleAt: 1) - (arg2 doubleAt: 1))
            sign]</div>
        </div>
        <div>the marshalling methods are in Callback's signature
          protocol:</div>
        <div><br>
        </div>
        <div>Callback&gt;&gt;voidstarvoidstarRetint: callbackContext sp:
          spAlien</div>
        <div><span class="" style="white-space:pre">        </span>&lt;signature:
          #(int (*)(const void *, const void *)) abi: 'IA32'&gt;</div>
        <div><span class="" style="white-space:pre">        </span>^callbackContext
          wordResult:</div>
        <div><span class="" style="white-space:pre">                </span>(block</div>
        <div><span class="" style="white-space:pre">                        </span>value:
          (Alien forPointer: (spAlien unsignedLongAt: 1))</div>
        <div><span class="" style="white-space:pre">                        </span>value:
          (Alien forPointer: (spAlien unsignedLongAt: 5)))</div>
        <div><br>
        </div>
        <div>where spAlien is an Alien pointing to a
          VMCallbackContext32.</div>
        <div><br>
        </div>
        <div>For ARM support we would add</div>
        <div><br>
        </div>
        <div>Callback&gt;&gt;voidstarvoidstarRetint: callbackContext sp:
          spAlien intRegArgs: regsAlien</div>
        <div><span class="" style="white-space:pre">        </span>&lt;signature:
          #(int (*)(const void *, const void *)) abi: 'ARMV5'&gt;</div>
        <div><span class="" style="white-space:pre">        </span>^callbackContext
          wordResult:</div>
        <div><span class="" style="white-space:pre">                </span>(block</div>
        <div><span class=""><span class="" style="white-space:pre">                        </span>value:
            (Alien forPointer: (</span>regsAlien<span class=""> unsignedLongAt:
            1))</span></div>
        <div><span class=""><span class="" style="white-space:pre">                        </span>value:
            (Alien forPointer: (</span>regsAlien<span class=""> unsignedLongAt:
            5)))</span></div>
        <div><span class=""><br>
          </span></div>
        <div><span class="">Basically the idea is that the selector of
            the method doesn't matter except for the number of
            arguments.  What's important is the pragma which defines the
            signature and the ABI for which this is a valid marshalling
            method.</span></div>
        <div><span class=""><br>
          </span></div>
        <div><span class="">When the callback is instantiated, Callback
            introspects to find the marshalling </span><span class="">method that
            matches the signature.  If one doesn't already exist you can
            write one.  Hopefully we'll write an ABI compiler that will
            automatically generate these marshalling </span>methods
          according to the platform's ABI, but for now its a manual
          process.  But at least it's open and flexible.  When the
          callback is invoked the evaluator is performed with the
          current callbackContext and pointer(s) to the arguments. 
          There is a 32-bit and a 64-bit callback context, and it can
          have a stack pointer, integer register args and floating point
          register args.  So it's general enough for any callback.</div>
        <div><br>
        </div>
        <div>To pass back the result, a value is assigned into the
          struct via the accessor in the marshalling method and control
          returns to teh point where teh callback comes in, and this
          uses a primitive to return.  Inside the callbackCOntext is a
          jmpbuf from a setjmp.  The primitive longjmp's back to the
          entry point in the VM which extracts the result and the code
          for the kind of result and returns:</div>
        <div><br>
        </div>
        <div>Callback class&gt;&gt;invokeCallbackContext:
          vmCallbackContextAddress "&lt;Integer&gt;"
          "^&lt;FFICallbackReturnValue&gt;"</div>
        <div><span class="" style="white-space:pre">        </span>"The
          low-level entry-point for callbacks sent from the VM/IA32ABI
          plugin.</div>
        <div><span class="" style="white-space:pre">        </span> Return via
          primReturnFromContext:through:.  thisContext's sender is the</div>
        <div><span class="" style="white-space:pre">        </span> call-out
          context."</div>
        <div><span class="" style="white-space:pre">        </span>|
          callbackAlien type |</div>
        <div><span class="" style="white-space:pre">        </span>callbackAlien
          := (Smalltalk wordSize = 4</div>
        <div><span class="" style="white-space:pre">                                                </span>ifTrue:
          [VMCallbackContext32]</div>
        <div><span class="" style="white-space:pre">                                                </span>ifFalse:
          [VMCallbackContext64])</div>
        <div><span class="" style="white-space:pre">                                                        </span>atAddress:
          vmCallbackContextAddress.</div>
        <div><span class="" style="white-space:pre">        </span>[type :=
          Callback evaluateCallbackForContext: callbackAlien]</div>
        <div><span class="" style="white-space:pre">                </span>ifCurtailed:
          [self error: 'attempt to non-local return across a callback'].</div>
        <div><span class="" style="white-space:pre">        </span>type ifNil:</div>
        <div><span class="" style="white-space:pre">                </span>[type := 1.
          callbackAlien wordResult: -1].</div>
        <div><span class="" style="white-space:pre">        </span>callbackAlien
          primReturnAs: type fromContext: thisContext</div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On Thu, Sep 3, 2015 at 5:22 AM, Craig
          Latta <span dir="ltr">&lt;<a moz-do-not-send="true"
              href="mailto:craig@netjam.org" target="_blank">craig@netjam.org</a>&gt;</span>
          wrote:<br>
          <blockquote class="gmail_quote" style="margin:0 0 0
            .8ex;border-left:1px #ccc solid;padding-left:1ex"><br>
            Hi all--<br>
            <br>
                 I'd like to use a C shared library via FFI from Squeak
            or Pharo.<br>
            Specifically, I want to call a C function which takes as one
            of its<br>
            parameters a pointer to an array of callback function
            addresses. Does<br>
            one of the FFI approaches floating around handle that, and
            provide a<br>
            relatively pleasant mapping between Smalltalk block closures
            and C<br>
            callback function addresses?<br>
            <br>
                 I was doing this so far in GemStone, but apparently its
            FFI only<br>
            supports passing callback function addresses one at a time
            as direct<br>
            parameters of C callouts. I suppose I could write a wrapper
            C library<br>
            around the one I really want to use, that provides the
            callback setup<br>
            interface that GemStone expects, but whenever I have to
            write actual C<br>
            code I start to think "Hm, why don't I just use a Smalltalk
            VM for which<br>
            I have the source?" :)  All the fancy distributed
            object-database stuff<br>
            that my project also wants can wait for a bit.<br>
            <br>
            <br>
                 thanks!<br>
            <br>
            -C<br>
            <br>
            --<br>
            Craig Latta<br>
            <a moz-do-not-send="true" href="http://netjam.org"
              rel="noreferrer" target="_blank">netjam.org</a><br>
            <a moz-do-not-send="true"
              href="tel:%2B31%20%20%206%202757%207177"
              value="+31627577177">+31 6 2757 7177</a> (SMS ok)<br>
            <a moz-do-not-send="true"
              href="tel:%2B%201%20415%20%20287%203547"
              value="+14152873547">+ 1 415 287 3547</a> (no SMS)<br>
            <br>
            <br>
          </blockquote>
        </div>
        <br>
        <br clear="all">
        <div><br>
        </div>
        -- <br>
        <div class="gmail_signature">
          <div dir="ltr">
            <div><span style="font-size:small;border-collapse:separate">
                <div>_,,,^..^,,,_<br>
                </div>
                <div>best, Eliot</div>
              </span></div>
          </div>
        </div>
      </div>
      <br>
      <fieldset class="mimeAttachmentHeader"></fieldset>
      <br>
      <pre wrap="">
</pre>
    </blockquote>
    <br>
  </body>
</html>