<div dir="ltr"><div dir="ltr"><div dir="ltr">Hi Ken,<div><br></div><div>    this all looks fine.  I see one minor slip.  You're supplied</div><div><br></div><div><div>ThreadedFFICalloutStateForARM64>>instVarNamesAndTypesForTranslationDo: aBinaryBlock</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>"enumerate aBinaryBlock with the names and C type strings for the inst vars to include in a ThreadedFFICalloutState struct."</div><div><br></div><div><span class="gmail-Apple-tab-span" style="white-space:pre">        </span>superclass instVarNamesAndTypesForTranslationDo: aBinaryBlock.</div><div><span class="gmail-Apple-tab-span" style="white-space:pre"> </span>self instVarNames do:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">          </span>[:ivn|</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">         </span>aBinaryBlock</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                   </span>value: ivn</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                     </span>value: (ivn caseOf: {</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                          </span>['integerRegisters']<span class="gmail-Apple-tab-span" style="white-space:pre">  </span>-> [{#sqLong. '[NumIntRegArgs]'}].</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                          </span>['floatRegisters']<span class="gmail-Apple-tab-span" style="white-space:pre">    </span>-> [{#double. '[NumFloatRegArgs]'}] }</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                       </span>otherwise:</div><div><span class="gmail-Apple-tab-span" style="white-space:pre">                                             </span>[#sqLong])]</div></div><div><br></div><div>which differs from the 32-bit ARM one in using double vs float and sqLong vs sqInt.  Using double vs long is correct.   But using sqLong is unnecessary, since in 64-bits saint is equal to sqLong, so I would have written it using saint instead.  But it's fine as is.  I just wanted you to know that in 64-bits sqInt must be a signed 64-bit type (at least in the VMMaker.oscog fork).</div></div></div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Sun, Jan 20, 2019 at 6:40 PM <<a href="mailto:commits@source.squeak.org">commits@source.squeak.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"> <br>
Eliot Miranda uploaded a new version of VMMaker to project VM Maker Inbox:<br>
<a href="http://source.squeak.org/VMMakerInbox/VMMaker.oscog-KenD.2509.mcz" rel="noreferrer" target="_blank">http://source.squeak.org/VMMakerInbox/VMMaker.oscog-KenD.2509.mcz</a><br>
<br>
==================== Summary ====================<br>
<br>
Name: VMMaker.oscog-KenD.2509<br>
Author: KenD<br>
Time: 20 January 2019, 7:38:17.915054 pm<br>
UUID: adac22d0-d981-4329-85ee-a8cf5647f645<br>
Ancestors: VMMaker.oscog-eem.2508<br>
<br>
Saved Progress in arm64ffi<br>
<br>
=============== Diff against VMMaker.oscog-eem.2508 ===============<br>
<br>
Item was changed:<br>
  ----- Method: RiscOSVMMaker class>>generateSqueakStackVM (in category 'configurations') -----<br>
  generateSqueakStackVM<br>
        "RISC OS version; build needed plugins, make sure filename tweaking is used"<br>
  "RiscOSVMMaker generateSqueakStackVM"<br>
        ^self<br>
                generate: StackInterpreter<br>
                to: (FileDirectory default directoryNamed: 'stacksrc') fullName<br>
                platformDir: (FileDirectory default directoryNamed: 'platforms') fullName<br>
+               excluding: #(AsynchFilePlugin BrokenPlugin CroquetPlugin FFIPlugin IA32ABIPlugin ImmX11Plugin InternetConfigPlugin JoystickTabletPlugin MIDIPlugin MacMenubarPlugin Mpeg3Plugin NewsqueakIA32ABIPlugin QuicktimePlugin SerialPlugin  TestOSAPlugin ThreadedARMFFIPlugin ThreadedARMFFI64Plugin ThreadedFFIPlugin ThreadedIA32FFIPlugin ThreadedPPCBEFFIPlugin UUIDPlugin VMProfileMacSupportPlugin)!<br>
-               excluding: #(AsynchFilePlugin BrokenPlugin CroquetPlugin FFIPlugin IA32ABIPlugin ImmX11Plugin InternetConfigPlugin JoystickTabletPlugin MIDIPlugin MacMenubarPlugin Mpeg3Plugin NewsqueakIA32ABIPlugin QuicktimePlugin SerialPlugin  TestOSAPlugin ThreadedARMFFIPlugin ThreadedFFIPlugin ThreadedIA32FFIPlugin ThreadedPPCBEFFIPlugin UUIDPlugin VMProfileMacSupportPlugin)!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin class>>calloutStateClass (in category 'translation') -----<br>
+ calloutStateClass<br>
+       ^ThreadedFFICalloutStateForARM64!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushDoubleFloat:in: (in category 'marshalling') -----<br>
+ ffiPushDoubleFloat: value in: calloutState<br>
+       <var: #value type: #double><br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: #always><br>
+ <br>
+       calloutState floatRegisterIndex < (NumFloatRegArgs - 1)<br>
+               ifTrue:<br>
+                       [(self cCoerceSimple: <br>
+                               (self addressOf: (calloutState floatRegisters at: calloutState floatRegisterIndex)) <br>
+                                        to: 'double*')<br>
+                               at: 0<br>
+                               put: value.<br>
+                        calloutState floatRegisterIndex: calloutState floatRegisterIndex + 2]<br>
+               ifFalse:<br>
+                       [calloutState currentArg + self wordSize > calloutState limit ifTrue:<br>
+                               [^FFIErrorCallFrameTooBig].<br>
+                        calloutState floatRegisterIndex: NumFloatRegArgs.<br>
+                        interpreterProxy storeFloatAtPointer: calloutState currentArg from: value.<br>
+                        calloutState currentArg: calloutState currentArg + self wordSize].<br>
+       ^0!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushSignedInt:in: (in category 'marshalling') -----<br>
+ ffiPushSignedInt: value in: calloutState<br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: true><br>
+       calloutState integerRegisterIndex < NumIntRegArgs<br>
+               ifTrue:<br>
+                       [calloutState integerRegisters <br>
+                               at: calloutState integerRegisterIndex <br>
+                               put: (self cCoerceSimple: value to: #sqLong).<br>
+                        calloutState integerRegisterIndex: calloutState integerRegisterIndex + 1]<br>
+               ifFalse:<br>
+                       [calloutState currentArg + self wordSize > calloutState limit ifTrue:<br>
+                               [^FFIErrorCallFrameTooBig].<br>
+                        interpreterProxy longAt: calloutState currentArg put: value.<br>
+                        calloutState currentArg: calloutState currentArg + self wordSize].<br>
+       ^0<br>
+ !<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushSignedLongLong:in: (in category 'marshalling') -----<br>
+ ffiPushSignedLongLong: value in: calloutState<br>
+       <var: #value type: #sqLong><br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: true><br>
+       calloutState integerRegisterIndex < NumIntRegArgs<br>
+               ifTrue:<br>
+                       [calloutState integerRegisters <br>
+                               at: calloutState integerRegisterIndex <br>
+                               put: (self cCoerceSimple: value to: #sqLong).<br>
+                        calloutState integerRegisterIndex: calloutState integerRegisterIndex + 1]<br>
+               ifFalse:<br>
+                       [calloutState currentArg + self wordSize > calloutState limit ifTrue: [^FFIErrorCallFrameTooBig].<br>
+                        interpreterProxy longAt: calloutState currentArg put: value.<br>
+                        calloutState currentArg: calloutState currentArg + self wordSize].<br>
+       ^0!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushSingleFloat:in: (in category 'marshalling') -----<br>
+ ffiPushSingleFloat: value in: calloutState<br>
+       <var: #value type: #float><br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: #always><br>
+       calloutState floatRegisterIndex < NumFloatRegArgs<br>
+               ifTrue: <br>
+                       [calloutState floatRegisters <br>
+                               at: calloutState floatRegisterIndex <br>
+                               put: (self cCoerceSimple: value to: #double).<br>
+                        calloutState floatRegisterIndex: calloutState floatRegisterIndex + 2]<br>
+               ifFalse:<br>
+                       [calloutState currentArg + self wordSize > calloutState limit ifTrue:<br>
+                               [^FFIErrorCallFrameTooBig].<br>
+                        interpreterProxy storeSingleFloatAtPointer: calloutState currentArg from: value.<br>
+                        calloutState currentArg: calloutState currentArg + self wordSize].<br>
+       ^0!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushStructure:ofSize:typeSpec:ofLength:in: (in category 'marshalling') -----<br>
+ ffiPushStructure: pointer ofSize: structSize typeSpec: argSpec ofLength: argSpecSize in: calloutState<br>
+       <var: #pointer type: #'void *'><br>
+       <var: #argSpec type: #'sqInt *'><br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: true><br>
+       | availableRegisterSpace stackPartSize roundedSize |<br>
+ <br>
+       availableRegisterSpace := (NumIntRegArgs - calloutState integerRegisterIndex) * self wordSize.<br>
+       stackPartSize := structSize.<br>
+       availableRegisterSpace > 0<br>
+               ifTrue: <br>
+                       [structSize <= availableRegisterSpace<br>
+                               ifTrue:<br>
+                                       ["all in registers"<br>
+                                        stackPartSize := 0.<br>
+                                        self <br>
+                                               memcpy: (self cCoerceSimple: (self addressOf: (calloutState integerRegisters at: calloutState integerRegisterIndex)) to: 'void *') <br>
+                                               _: pointer <br>
+                                               _: structSize.<br>
+                                        calloutState integerRegisterIndex: calloutState integerRegisterIndex + (structSize + 3 bitShift: -2) ]<br>
+                               ifFalse:<br>
+                                       ["If no previous co-processor candidate arg has already been pushed on the stack, then split the struct between registers and stack.<br>
+                                         Otherwise push entire struct on stack."<br>
+                                        calloutState currentArg = calloutState argVector<br>
+                                               ifTrue: <br>
+                                                       [stackPartSize := structSize - availableRegisterSpace.<br>
+                                                       self <br>
+                                                               memcpy: (self cCoerceSimple: (self addressOf: (calloutState integerRegisters at: calloutState integerRegisterIndex)) to: 'void *') <br>
+                                                               _: pointer <br>
+                                                               _: availableRegisterSpace]<br>
+                                               ifFalse:<br>
+                                                       [availableRegisterSpace := 0].<br>
+                                       calloutState integerRegisterIndex: NumIntRegArgs]].<br>
+ <br>
+       stackPartSize > 0<br>
+               ifTrue: <br>
+                       [roundedSize := stackPartSize + 3 bitClear: 3.<br>
+                        calloutState currentArg + roundedSize > calloutState limit ifTrue:<br>
+                                [^FFIErrorCallFrameTooBig].<br>
+                        self memcpy: calloutState currentArg _: (self addressOf: ((self cCoerceSimple: pointer to: 'char *') at: availableRegisterSpace)) _: stackPartSize.<br>
+                        calloutState currentArg: calloutState currentArg + roundedSize].<br>
+       ^0!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushUnsignedInt:in: (in category 'marshalling') -----<br>
+ ffiPushUnsignedInt: value in: calloutState<br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: true><br>
+       calloutState integerRegisterIndex < NumIntRegArgs<br>
+               ifTrue:<br>
+                       [calloutState integerRegisters <br>
+                               at: calloutState integerRegisterIndex <br>
+                               put:  (self cCoerceSimple: value to: #usqLong).<br>
+                        calloutState integerRegisterIndex: calloutState integerRegisterIndex + 1]<br>
+               ifFalse:<br>
+                       [calloutState currentArg + self wordSize > calloutState limit ifTrue:<br>
+                               [^FFIErrorCallFrameTooBig].<br>
+                        interpreterProxy longAt: calloutState currentArg put: value.<br>
+                        calloutState currentArg: calloutState currentArg + self wordSize].<br>
+       ^0<br>
+ <br>
+ !<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedARM64FFIPlugin>>ffiPushUnsignedLongLong:in: (in category 'marshalling') -----<br>
+ ffiPushUnsignedLongLong: value in: calloutState<br>
+       <var: #value type: #usqLong><br>
+       <var: #calloutState type: #'CalloutState *'><br>
+       <inline: true><br>
+       calloutState integerRegisterIndex < NumIntRegArgs<br>
+               ifTrue:<br>
+                       [calloutState integerRegisters <br>
+                               at: calloutState integerRegisterIndex <br>
+                               put:(self cCoerceSimple: value to: #usqLong).<br>
+                        calloutState integerRegisterIndex: calloutState integerRegisterIndex + 1]<br>
+               ifFalse:<br>
+                       [calloutState currentArg + self wordSize > calloutState limit ifTrue: [^FFIErrorCallFrameTooBig].<br>
+                        interpreterProxy longAt: calloutState currentArg put: value.<br>
+                        calloutState currentArg: calloutState currentArg + self wordSize].<br>
+       ^0<br>
+ !<br>
<br>
Item was added:<br>
+ ThreadedFFICalloutStateForARM subclass: #ThreadedFFICalloutStateForARM64<br>
+       instanceVariableNames: ''<br>
+       classVariableNames: ''<br>
+       poolDictionaries: ''<br>
+       category: 'VMMaker-Plugins-FFI'!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedFFICalloutStateForARM64 class>>instVarNamesAndTypesForTranslationDo: (in category 'translation') -----<br>
+ instVarNamesAndTypesForTranslationDo: aBinaryBlock<br>
+       "enumerate aBinaryBlock with the names and C type strings for the inst vars to include in a ThreadedFFICalloutState struct."<br>
+ <br>
+       superclass instVarNamesAndTypesForTranslationDo: aBinaryBlock.<br>
+       self instVarNames do:<br>
+               [:ivn|<br>
+               aBinaryBlock<br>
+                       value: ivn<br>
+                       value: (ivn caseOf: {<br>
+                                               ['integerRegisters']    -> [{#sqLong. '[NumIntRegArgs]'}].<br>
+                                               ['floatRegisters']      -> [{#double. '[NumFloatRegArgs]'}] }<br>
+                                       otherwise:<br>
+                                               [#sqLong])]!<br>
<br>
Item was added:<br>
+ ----- Method: ThreadedFFICalloutStateForARM64>>initialize (in category 'initialize-release') -----<br>
+ initialize<br>
+       super initialize.<br>
+       "Override with proper # regs"<br>
+       integerRegisters := CArrayAccessor on: (Array new: ThreadedARM64FFIPlugin numIntRegArgs).<br>
+       floatRegisters     := CArrayAccessor on: (Array new: ThreadedARM64FFIPlugin numFloatRegArgs)!<br>
<br>
Item was changed:<br>
  ----- Method: ThreadedFFIPlugin class>>preambleCCode (in category 'translation') -----<br>
  preambleCCode<br>
        "For a source of builtin defines grep for builtin_define in a gcc release config directory.<br>
         See See platforms/Cross/vm/sqCogStackAlignment.h for per-platform definitions for<br>
         STACK_ALIGN_BYTES MUST_ALIGN_STACK et al."<br>
        ^'<br>
  #include "sqAssert.h" /* for assert */<br>
  #define ThreadedFFIPlugin 1 /* to filter-out unwanted declarations from sqFFI.h */<br>
  #include "sqFFI.h" /* for logging and surface functions */<br>
  #include "sqCogStackAlignment.h" /* for STACK_ALIGN_BYTES and getsp() */<br>
<br>
  #ifdef _MSC_VER<br>
  # define alloca _alloca<br>
  #endif<br>
  #if defined(__GNUC__) && (defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__))<br>
  # define setsp(sp) asm volatile ("movl %0,%%esp" : : "m"(sp))<br>
  # elif defined(__GNUC__) && (defined(__amd64__) || defined(__x86_64__) ||  defined(__amd64) || defined(__x86_64))<br>
  # define setsp(sp) asm volatile ("movq %0,%%rsp" : : "m"(sp))<br>
+ # elif defined(__arm64__) || defined(__aarch64__) || defined(ARM64)<br>
+         /* <a href="https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm" rel="noreferrer" target="_blank">https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Extended-Asm</a><br>
+          * <a href="http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/index.html" rel="noreferrer" target="_blank">http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/index.html</a><br>
+          */<br>
+ #  if __GNUC__<br>
+ #   define getfp() ({ usqIntptr_t fp;                                                           \<br>
+                                           asm volatile ("mov x0, x29" : "=r"(x29) : );  \<br>
+                                           fp; })<br>
+ #   define getsp() ({ usqIntptr_t sp;                                                           \<br>
+                                           asm volatile ("mov x0, sp" : "=r"(sp) : );    \<br>
+                                           sp; })<br>
+ # define setsp(sp) asm volatile ("ldr x16, %0 \n\t" "mov sp, x16"  : : "m"(sp) )<br>
+ #  endif<br>
  # elif defined(__GNUC__) && (defined(__arm__))<br>
  # define setsp(sp) asm volatile ("ldr %%sp, %0" : : "m"(sp))<br>
  #endif<br>
  #if !!defined(getsp)<br>
  # define getsp() 0<br>
  #endif <br>
  #if !!defined(setsp)<br>
  # define setsp(ignored) 0<br>
  #endif <br>
<br>
  #if !!defined(STACK_ALIGN_BYTES)<br>
  #  define STACK_ALIGN_BYTES 0<br>
  #endif /* !!defined(STACK_ALIGN_BYTES) */<br>
<br>
  /* For ABI that require stack alignment greater than natural word size */<br>
  #define MUST_ALIGN_STACK (STACK_ALIGN_BYTES > sizeof(void*))<br>
<br>
  #if defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__)<br>
  /* Both Mac OS X x86 and Win32 x86 return structs of a power of two in size<br>
   * less than or equal to eight bytes in length in registers. Linux never does so.<br>
   */<br>
  # if __linux__<br>
  #     define WIN32_X86_STRUCT_RETURN 0<br>
  # else<br>
  #     define WIN32_X86_STRUCT_RETURN 1<br>
  # endif<br>
  # if _WIN32<br>
  #     define PLATFORM_API_USES_CALLEE_POPS_CONVENTION 1<br>
  # endif<br>
  # elif defined(__amd64__) || defined(__x86_64__) ||  defined(__amd64) || defined(__x86_64)<br>
  # if _WIN32 | _WIN64<br>
  #     define PLATFORM_API_USES_CALLEE_POPS_CONVENTION 1<br>
  # endif<br>
  #endif /* defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__) */<br>
<br>
  #if !!defined(ALLOCA_LIES_SO_SETSP_BEFORE_CALL)<br>
  # if defined(__MINGW32__) && !!defined(__clang__) && (__GNUC__ >= 3) && (defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__))<br>
      /*<br>
       * cygwin -mno-cygwin (MinGW) gcc 3.4.x''s alloca is a library routine that answers<br>
       * %esp + xx, so the outgoing stack is offset by one or more word if uncorrected.<br>
       * Grab the actual stack pointer to correct.<br>
       */<br>
  #     define ALLOCA_LIES_SO_SETSP_BEFORE_CALL 1<br>
  # else<br>
  #     define ALLOCA_LIES_SO_SETSP_BEFORE_CALL 0<br>
  # endif<br>
  #endif /* !!defined(ALLOCA_LIES_SO_SETSP_BEFORE_CALL) */<br>
<br>
  #if !!defined(PLATFORM_API_USES_CALLEE_POPS_CONVENTION)<br>
  # define PLATFORM_API_USES_CALLEE_POPS_CONVENTION 0<br>
  #endif<br>
<br>
  /* This alignment stuff is a hack for integerAt:put:size:signed:/primitiveFFIIntegerAt[Put].<br>
   * The assumption right now is that all processors support unaligned access.  That only<br>
   * holds true for x86, x86-64 & ARMv6 & later.  But this keeps us going until we can address<br>
   * it properly.<br>
   */<br>
  #define unalignedShortAt(a) shortAt(a)<br>
  #define unalignedShortAtput(a,v) shortAtput(a,v)<br>
  #define unalignedLong32At(a) long32At(a)<br>
  #define unalignedLong32Atput(a,v) long32Atput(a,v)<br>
  #define unalignedLong64At(a) long64At(a)<br>
  #define unalignedLong64Atput(a,v) long64Atput(a,v)<br>
<br>
  /* The dispatchOn:in:with:with: generates an unwanted call on error.  Just squash it. */<br>
  #define error(foo) 0<br>
  #ifndef SQUEAK_BUILTIN_PLUGIN<br>
  /* but print assert failures. */<br>
  void<br>
  warning(char *s) { /* Print an error message but don''t exit. */<br>
        printf("\n%s\n", s);<br>
  }<br>
  #endif<br>
<br>
  /* sanitize */<br>
  #ifdef SQUEAK_BUILTIN_PLUGIN<br>
  # define EXTERN <br>
  #else<br>
  # define EXTERN extern<br>
  #endif<br>
  '!<br>
<br>
Item was changed:<br>
  ----- Method: VMMaker class>>generateVMPlugins (in category 'configurations') -----<br>
  generateVMPlugins<br>
        ^VMMaker<br>
                generatePluginsTo: self sourceTree, '/src'<br>
                options: #()<br>
                platformDir: self sourceTree, '/platforms'<br>
                including:#(    ADPCMCodecPlugin AsynchFilePlugin<br>
                                        BalloonEnginePlugin B3DAcceleratorPlugin B3DEnginePlugin BMPReadWriterPlugin BitBltSimulation<br>
                                        BochsIA32Plugin BochsX64Plugin<br>
                                        CameraPlugin CroquetPlugin DeflatePlugin DropPlugin<br>
                                        "Cryptography Plugins:" DESPlugin DSAPlugin MD5Plugin SHA256Plugin<br>
                                        "FT2Plugin" FFTPlugin FileCopyPlugin FilePlugin FileAttributesPlugin FloatArrayPlugin FloatMathPlugin<br>
                                        GeniePlugin GdbARMPlugin HostWindowPlugin IA32ABIPlugin ImmX11Plugin InternetConfigPlugin<br>
                                        JPEGReadWriter2Plugin JPEGReaderPlugin JoystickTabletPlugin KlattSynthesizerPlugin<br>
                                        LargeIntegersPlugin LocalePlugin MIDIPlugin MacMenubarPlugin Matrix2x3Plugin<br>
                                        MiscPrimitivePlugin Mpeg3Plugin QuicktimePlugin RePlugin<br>
                                        ScratchPlugin SecurityPlugin SerialPlugin SocketPlugin<br>
                                        SoundCodecPlugin SoundGenerationPlugin SoundPlugin SqueakSSLPlugin StarSqueakPlugin<br>
+                                       ThreadedFFIPlugin ThreadedARMFFIPlugin ThreadedARM64FFIPlugin ThreadedIA32FFIPlugin<br>
+                                       ThreadedX64SysVFFIPlugin ThreadedX64Win64FFIPlugin<br>
-                                       ThreadedFFIPlugin ThreadedARMFFIPlugin ThreadedIA32FFIPlugin ThreadedX64SysVFFIPlugin ThreadedX64Win64FFIPlugin<br>
                                        UnicodePlugin UnixAioPlugin UUIDPlugin UnixOSProcessPlugin<br>
                                        Win32OSProcessPlugin VMProfileLinuxSupportPlugin VMProfileMacSupportPlugin WeDoPlugin<br>
                                        XDisplayControlPlugin)!<br>
<br>
</blockquote></div><br clear="all"><div><br></div>-- <br><div dir="ltr" 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>