[Vm-dev] [commit] r2377 - Fix checkin snafu;
submit the correct SqueakFFIPrims from ReentrantIA32FFIPlugin
commits at squeakvm.org
commits at squeakvm.org
Fri Apr 1 19:51:41 UTC 2011
Author: eliot
Date: 2011-04-01 12:51:41 -0700 (Fri, 01 Apr 2011)
New Revision: 2377
Modified:
branches/Cog/src/plugins/SqueakFFIPrims/SqueakFFIPrims.c
Log:
Fix checkin snafu; submit the correct SqueakFFIPrims from ReentrantIA32FFIPlugin
Modified: branches/Cog/src/plugins/SqueakFFIPrims/SqueakFFIPrims.c
===================================================================
--- branches/Cog/src/plugins/SqueakFFIPrims/SqueakFFIPrims.c 2011-04-01 19:39:21 UTC (rev 2376)
+++ branches/Cog/src/plugins/SqueakFFIPrims/SqueakFFIPrims.c 2011-04-01 19:51:41 UTC (rev 2377)
@@ -1,9 +1,9 @@
/* Automatically generated by
VMPluginCodeGenerator VMMaker-oscog.54 uuid: 73c095bd-7fa5-4ef9-b9fc-60378cae64c7
from
- ThreadedARMFFIPlugin VMMaker-oscog.54 uuid: 73c095bd-7fa5-4ef9-b9fc-60378cae64c7
+ ReentrantIA32FFIPlugin VMMaker-oscog.54 uuid: 73c095bd-7fa5-4ef9-b9fc-60378cae64c7
*/
-static char __buildInfo[] = "ThreadedARMFFIPlugin VMMaker-oscog.54 uuid: 73c095bd-7fa5-4ef9-b9fc-60378cae64c7 " __DATE__ ;
+static char __buildInfo[] = "ReentrantIA32FFIPlugin VMMaker-oscog.54 uuid: 73c095bd-7fa5-4ef9-b9fc-60378cae64c7 " __DATE__ ;
@@ -53,26 +53,20 @@
# define setsp(ignored) 0
#endif
-#if !defined(STACK_ALIGN_BYTES)
-# if __APPLE__ && __MACH__ && __i386__
-# define STACK_ALIGN_BYTES 16
-# elif __linux__ && __i386__
-# define STACK_ALIGN_BYTES 16
-# elif defined(__amd64__) || defined(__x86_64__) || defined(__amd64) || defined(__x86_64)
-# define STACK_ALIGN_BYTES 16
-# elif defined(powerpc) || defined(__powerpc__) || defined(_POWER) || defined(__POWERPC__) || defined(__PPC__)
-# define STACK_ALIGN_BYTES 16
-# elif defined(__sparc64__) || defined(__sparcv9__) || defined(__sparc_v9__) /* must preceed 32-bit sparc defs */
-# define STACK_ALIGN_BYTES 16
-# elif defined(sparc) || defined(__sparc__) || defined(__sparclite__)
-# define STACK_ALIGN_BYTES 8
-# else
-# define STACK_ALIGN_BYTES 0
-# endif
-#endif /* !defined(STACK_ALIGN_BYTES) */
-
-#if !defined(STACK_OFFSET_BYTES)
-# define STACK_OFFSET_BYTES 0
+#if __APPLE__ && __MACH__ && __i386__
+# define STACK_ALIGN_BYTES 16
+#elif __linux__ && __i386__
+# define STACK_ALIGN_BYTES 16
+#elif defined(__amd64__) || defined(__x86_64__) || defined(__amd64) || defined(__x86_64)
+# define STACK_ALIGN_BYTES 16
+#elif defined(powerpc) || defined(__powerpc__) || defined(_POWER) || defined(__POWERPC__) || defined(__PPC__)
+# define STACK_ALIGN_BYTES 16
+#elif defined(__sparc64__) || defined(__sparcv9__) || defined(__sparc_v9__) /* must preceed 32-bit sparc defs */
+# define STACK_ALIGN_BYTES 16
+#elif defined(sparc) || defined(__sparc__) || defined(__sparclite__)
+# define STACK_ALIGN_BYTES 8
+#else
+# define STACK_ALIGN_BYTES 0
#endif
#if defined(_X86_) || defined(i386) || defined(__i386) || defined(__i386__)
@@ -124,11 +118,9 @@
sqInt ffiRetHeader;
sqInt stringArgIndex;
char *stringArgs[15];
- sqInt regIndex;
- sqInt integerRegisters[8];
} CalloutState;
-#define ThreadedFFICalloutStateForARM CalloutState
+#define ReentrantFFICalloutState CalloutState
@@ -141,7 +133,6 @@
#define ExternalFunctionStackSizeIndex 3
#define FFIAtomicTypeMask 0xF000000
#define FFIAtomicTypeShift 24
-#define FFICallFlagThreaded null
#define FFICallTypeApi 1
#define FFIErrorAddressNotFound 13
#define FFIErrorAttemptToPassVoid 14
@@ -152,6 +143,7 @@
#define FFIErrorBadExternalFunction 17
#define FFIErrorBadExternalLibrary 16
#define FFIErrorBadReturn 10
+#define FFIErrorCallFrameTooBig 19
#define FFIErrorCallType 9
#define FFIErrorCoercionFailed 6
#define FFIErrorIntAsPointer 4
@@ -182,7 +174,6 @@
#define PrimErrBadNumArgs 5
#define PrimErrBadReceiver 2
#define PrimErrNoCMemory 10
-#define PrimErrObjectMayMove 14
/*** Function Prototypes ***/
@@ -194,7 +185,7 @@
static sqInt ffiArgumentSpecClassin(sqInt oop, sqInt argSpec, sqInt argClass, CalloutState *calloutState);
static sqInt ffiAtomicArgByReferenceClassin(sqInt oop, sqInt oopClass, CalloutState *calloutState);
static sqInt ffiAtomicStructByReferenceClassin(sqInt oop, sqInt oopClass, CalloutState *calloutState);
-static sqInt ffiCalloutToSpecOnStackin(void *procAddr, sqInt specOnStack, sqInt calloutState);
+static sqInt ffiCalloutToSpecOnStackin(void *procAddr, sqInt specOnStack, CalloutState *calloutState);
static sqInt ffiCallArgArrayOrNilNumArgs(sqInt externalFunction, sqInt argArrayOrNil, sqInt nArgs);
static sqInt ffiCheckReturnWithin(sqInt retSpec, sqInt retClass, CalloutState *calloutState);
static sqInt ffiContentsOfHandleerrCode(sqInt oop, sqInt errCode);
@@ -207,16 +198,16 @@
static sqInt ffiLoadCalloutModule(sqInt module);
static void ffiLogCallout(sqInt lit);
EXPORT(sqInt) ffiLogCallsTo(char*fileName);
-static sqInt ffiPushDoubleFloatin(sqInt value, sqInt calloutState);
+static sqInt ffiPushDoubleFloatin(double value, CalloutState *calloutState);
static sqInt ffiPushPointerContentsOfin(sqInt oop, CalloutState *calloutState);
-static sqInt ffiPushPointerin(sqInt value, CalloutState *calloutState);
+static sqInt ffiPushPointerin(void *pointer, CalloutState *calloutState);
static sqInt ffiPushSignedBytein(sqInt value, CalloutState *calloutState);
static sqInt ffiPushSignedCharin(sqInt value, CalloutState *calloutState);
static sqInt ffiPushSignedIntin(sqInt value, CalloutState *calloutState);
static sqInt ffiPushSignedLongLongOopin(sqInt oop, CalloutState *calloutState);
-static sqInt ffiPushSignedLongLongin(sqLong value, CalloutState *calloutState);
+static sqInt ffiPushSignedLongLongin(usqLong value, CalloutState *calloutState);
static sqInt ffiPushSignedShortin(sqInt value, CalloutState *calloutState);
-static sqInt ffiPushSingleFloatin(sqInt value, CalloutState *calloutState);
+static sqInt ffiPushSingleFloatin(float value, CalloutState *calloutState);
static sqInt ffiPushStringOfLengthin(char *pointer, sqInt length, CalloutState *calloutState);
static sqInt ffiPushStructureContentsOfin(sqInt oop, CalloutState *calloutState);
static sqInt ffiPushStructureofSizetypeSpecofLengthin(void *pointer, sqInt structSize, sqInt *argSpec, sqInt argSpecSize, CalloutState *calloutState);
@@ -225,12 +216,11 @@
static sqInt ffiPushUnsignedIntin(sqInt value, CalloutState *calloutState);
static sqInt ffiPushUnsignedLongLongOopin(sqInt oop, CalloutState *calloutState);
static sqInt ffiPushUnsignedLongLongin(usqLong value, CalloutState *calloutState);
-static sqInt ffiPushUnsignedLongin(sqInt value, CalloutState *calloutState);
static sqInt ffiPushUnsignedShortin(sqInt value, CalloutState *calloutState);
static sqInt ffiPushVoidin(sqInt ignored, CalloutState *calloutState);
static sqInt ffiReturnCStringFrom(sqInt cPointer);
static sqInt ffiReturnPointerofTypein(usqLong retVal, sqInt retType, CalloutState *calloutState);
-static sqInt ffiReturnStructofTypein(usqLong longLongRet, sqInt ffiRetClass, CalloutState *calloutState);
+static sqInt ffiReturnStructofTypein(usqLong longLongRet, sqInt ffiRetType, CalloutState *calloutState);
static sqInt ffiReturnType(sqInt specOnStack);
static sqInt ffiSupportsCallingConvention(sqInt aCallingConvention);
static sqInt ffiValidateExternalDataAtomicType(sqInt oop, sqInt atomicType);
@@ -238,7 +228,6 @@
EXPORT(const char*) getModuleName(void);
static sqInt halt(void);
EXPORT(sqInt) initialiseModule(void);
-static void initialize(CalloutState * self_in_initialize);
static sqInt isAlien(sqInt anOop);
static sqInt isAtomicType(sqInt typeSpec);
static sqInt isDirectAlien(sqInt oop);
@@ -261,7 +250,6 @@
EXPORT(sqInt) primitiveLogCallsTo(void);
EXPORT(sqInt) primitiveSetManualSurfacePointer(void);
static sqInt registerArgsSlop(void);
-static sqInt returnStructInRegisters(sqInt returnStructSize);
EXPORT(sqInt) setInterpreter(struct VirtualMachine*anInterpreter);
static sqInt sizeField(sqInt oop);
static sqInt startOfData(sqInt oop);
@@ -292,6 +280,7 @@
#define ffiAlloc(bytes) (usqInt)malloc(bytes)
#define ffiFree(pointer) free((void *)(pointer))
#define isCalleePopsConvention(callType) (PLATFORM_API_USES_CALLEE_POPS_CONVENTION && (callType) == FFICallTypeApi)
+#define returnStructInRegisters(sz) (WIN32_X86_STRUCT_RETURN && (sz) <= 8 && !((sz)&((sz)-1)))
static sqInt
@@ -472,12 +461,20 @@
}
if (atomicType == FFITypeSingleFloat) {
/* begin ffiPushSingleFloat:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ storeSingleFloatAtPointerfrom((calloutState->currentArg), floatValue);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
else {
/* begin ffiPushDoubleFloat:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ storeFloatAtPointerfrom((calloutState->currentArg), floatValue);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
}
@@ -510,9 +507,14 @@
sqInt oopClass1;
sqInt oopClass2;
char *pointer;
+ void *pointer1;
+ void *pointer2;
+ void *pointer3;
sqInt ptrAddress;
sqInt ptrClass;
sqInt ptrType;
+ sqInt roundedSize;
+ sqInt roundedSize1;
sqInt spec;
sqInt specOop;
sqInt specType;
@@ -521,9 +523,6 @@
sqInt typeSpec;
sqInt typeSpec1;
sqInt typeSpec2;
- sqInt value;
- sqInt value1;
- sqInt value2;
sqInt valueOop;
sqInt valueOop1;
@@ -599,8 +598,13 @@
structSize = ((calloutState->ffiArgHeader)) & FFIStructSizeMask;
argSpec2 = (calloutState->ffiArgSpec);
argSpecSize = (calloutState->ffiArgSpecSize);
- subclassResponsibility();
- return null;
+ roundedSize = (structSize + 3) & (~3);
+ if ((((calloutState->currentArg)) + roundedSize) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ memcpy((calloutState->currentArg), ((void *) ptrAddress), structSize);
+ (calloutState->currentArg = ((calloutState->currentArg)) + roundedSize);
+ return 0;
}
if (ptrClass == (interpreterProxy->classByteArray())) {
if (!((interpreterProxy->byteSizeOf(valueOop)) == (((calloutState->ffiArgHeader)) & FFIStructSizeMask))) {
@@ -608,16 +612,17 @@
}
ptrAddress = ((int) (interpreterProxy->firstIndexableField(valueOop)));
if (!(((calloutState->ffiArgHeader)) & FFIFlagPointer)) {
- if ((((calloutState->callFlags)) & FFICallFlagThreaded)
- && (interpreterProxy->isYoung(valueOop))) {
- return -PrimErrObjectMayMove;
- }
/* begin ffiPushStructure:ofSize:typeSpec:ofLength:in: */
structSize1 = ((calloutState->ffiArgHeader)) & FFIStructSizeMask;
argSpec1 = (calloutState->ffiArgSpec);
argSpecSize1 = (calloutState->ffiArgSpecSize);
- subclassResponsibility();
- return null;
+ roundedSize1 = (structSize1 + 3) & (~3);
+ if ((((calloutState->currentArg)) + roundedSize1) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ memcpy((calloutState->currentArg), ((void *) ptrAddress), structSize1);
+ (calloutState->currentArg = ((calloutState->currentArg)) + roundedSize1);
+ return 0;
}
if (!((((calloutState->ffiArgHeader)) & FFIStructSizeMask) == 4)) {
return FFIErrorStructSize;
@@ -627,7 +632,11 @@
return FFIErrorInvalidPointer;
}
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ptrAddress);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
return FFIErrorBadArg;
@@ -638,7 +647,11 @@
}
if (oop == (interpreterProxy->nilObject())) {
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), null);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (((calloutState->ffiArgHeader)) & FFIFlagAtomic) {
@@ -732,32 +745,38 @@
((calloutState->stringArgs))[(calloutState->stringArgIndex)] = copy;
(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) + 1);
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), copy);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
atomicType2 = FFITypeUnsignedByte;
}
- if ((((calloutState->callFlags)) & FFICallFlagThreaded)
- && (((!isAlien)
- || (isDirectAlien(oop)))
- && (interpreterProxy->isYoung(oop)))) {
- return -PrimErrObjectMayMove;
- }
if ((atomicType2 == FFITypeVoid)
|| ((((usqInt) atomicType2) >> 1) == (((usqInt) FFITypeSignedByte) >> 1))) {
if (isString
|| (oopClass == (interpreterProxy->classByteArray()))) {
/* begin ffiPushPointer:in: */
- value = interpreterProxy->firstIndexableField(oop);
- error("shouldBeImplemented");
+ pointer1 = interpreterProxy->firstIndexableField(oop);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer1);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (isAlien) {
/* begin ffiPushPointer:in: */
- value1 = pointerForOop(((longAt(oop + BaseHeaderSize)) > 0
+ pointer2 = pointerForOop(((longAt(oop + BaseHeaderSize)) > 0
? (oop + BaseHeaderSize) + BytesPerOop
: longAt((oop + BaseHeaderSize) + BytesPerOop)));
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer2);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (!(atomicType2 == FFITypeVoid)) {
@@ -768,8 +787,12 @@
|| (atomicType2 == FFITypeSingleFloat)) {
if (interpreterProxy->isWords(oop)) {
/* begin ffiPushPointer:in: */
- value2 = interpreterProxy->firstIndexableField(oop);
- error("shouldBeImplemented");
+ pointer3 = interpreterProxy->firstIndexableField(oop);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer3);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
}
@@ -880,12 +903,20 @@
}
if (atomicType1 == FFITypeSingleFloat) {
/* begin ffiPushSingleFloat:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ storeSingleFloatAtPointerfrom((calloutState->currentArg), floatValue);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
else {
/* begin ffiPushDoubleFloat:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ storeFloatAtPointerfrom((calloutState->currentArg), floatValue);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
}
@@ -908,10 +939,10 @@
sqInt isString;
sqInt length;
char *pointer;
+ void *pointer1;
+ void *pointer2;
+ void *pointer3;
sqInt typeSpec;
- sqInt value;
- sqInt value1;
- sqInt value2;
/* begin atomicTypeOf: */
typeSpec = (calloutState->ffiArgHeader);
@@ -939,32 +970,38 @@
((calloutState->stringArgs))[(calloutState->stringArgIndex)] = copy;
(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) + 1);
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), copy);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
atomicType = FFITypeUnsignedByte;
}
- if ((((calloutState->callFlags)) & FFICallFlagThreaded)
- && (((!isAlien)
- || (isDirectAlien(oop)))
- && (interpreterProxy->isYoung(oop)))) {
- return -PrimErrObjectMayMove;
- }
if ((atomicType == FFITypeVoid)
|| ((((usqInt) atomicType) >> 1) == (((usqInt) FFITypeSignedByte) >> 1))) {
if (isString
|| (oopClass == (interpreterProxy->classByteArray()))) {
/* begin ffiPushPointer:in: */
- value = interpreterProxy->firstIndexableField(oop);
- error("shouldBeImplemented");
+ pointer1 = interpreterProxy->firstIndexableField(oop);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer1);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (isAlien) {
/* begin ffiPushPointer:in: */
- value1 = pointerForOop(((longAt(oop + BaseHeaderSize)) > 0
+ pointer2 = pointerForOop(((longAt(oop + BaseHeaderSize)) > 0
? (oop + BaseHeaderSize) + BytesPerOop
: longAt((oop + BaseHeaderSize) + BytesPerOop)));
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer2);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (!(atomicType == FFITypeVoid)) {
@@ -975,8 +1012,12 @@
|| (atomicType == FFITypeSingleFloat)) {
if (interpreterProxy->isWords(oop)) {
/* begin ffiPushPointer:in: */
- value2 = interpreterProxy->firstIndexableField(oop);
- error("shouldBeImplemented");
+ pointer3 = interpreterProxy->firstIndexableField(oop);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer3);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
}
@@ -1062,17 +1103,155 @@
}
-/* Perform the callout, collect the result and and create the return value.
- If a threaded call, disown and own VM around the call. If there are
- floating-point arguments that are passed in registers then call a dummy
- function to load them.
- This *must* be inlined because of the alloca of the outgoing stack frame
- in ffiCall:SpecOnStack:Flags:NumArgs:Args:AndTypes: */
+/* Go out, call this guy and create the return value. This *must* be inlined
+ because of
+ the alloca of the outgoing stack frame in
+ ffiCall:WithFlags:NumArgs:Args:AndTypes:
+ */
static sqInt
-ffiCalloutToSpecOnStackin(void *procAddr, sqInt specOnStack, sqInt calloutState)
+ffiCalloutToSpecOnStackin(void *procAddr, sqInt specOnStack, CalloutState *calloutState)
{
- subclassResponsibility();
+ sqInt argTypes;
+ sqInt argTypes1;
+ sqInt atomicType;
+ sqInt atomicType1;
+ sqInt classOop;
+ char *cString;
+ sqInt ffiRetType;
+ double floatRet;
+ sqInt i;
+ usqLong intRet;
+ sqInt oop;
+ sqInt oop1;
+ sqInt *ptr;
+ sqInt retClass;
+ sqInt retClass1;
+ sqInt retOop;
+ sqInt retOop1;
+ sqInt retType;
+ sqInt specLiteral;
+ sqInt specLiteral1;
+ sqInt strLen;
+ sqInt strOop;
+ char *strPtr;
+ sqInt typeSpec;
+ sqInt typeSpec1;
+
+ if ((0 + (cStackAlignment())) > 0) {
+ setsp((calloutState->argVector));
+ }
+ /* begin atomicTypeOf: */
+ typeSpec = (calloutState->ffiRetHeader);
+ atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ floatRet = dispatchFunctionPointer(((double (*)()) procAddr));
+ }
+ else {
+ intRet = dispatchFunctionPointer(((usqLong (*)()) procAddr));
+ }
+ if (isCalleePopsConvention((calloutState->callFlags))) {
+ setsp((calloutState->argVector));
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
+ /* begin ffiReturnPointer:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral1 = (specOnStack
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes1 = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
+ retType = interpreterProxy->fetchPointerofObject(0, argTypes1);
+ retClass1 = interpreterProxy->fetchPointerofObject(1, retType);
+ if (retClass1 == (interpreterProxy->nilObject())) {
+ /* begin atomicTypeOf: */
+ typeSpec1 = (calloutState->ffiRetHeader);
+ atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+ /* begin ffiReturnCStringFrom: */
+ if ((((usqInt) intRet)) == null) {
+ return interpreterProxy->methodReturnValue(interpreterProxy->nilObject());
+ }
+ cString = ((char *) (((usqInt) intRet)));
+ strLen = 0;
+ while (!((cString[strLen]) == 0)) {
+ strLen += 1;
+ }
+ strOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strLen);
+ strPtr = interpreterProxy->firstIndexableField(strOop);
+ for (i = 0; i <= (strLen - 1); i += 1) {
+ strPtr[i] = (cString[i]);
+ }
+ return interpreterProxy->methodReturnValue(strOop);
+ }
+ interpreterProxy->pushRemappableOop(retType);
+ oop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalAddress(), 4);
+ ptr = interpreterProxy->firstIndexableField(oop1);
+ ptr[0] = (((sqInt) intRet));
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalData(), 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+
+ /* return type */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(1, retOop1, oop1);
+ return interpreterProxy->methodReturnValue(retOop1);
+ }
+ interpreterProxy->pushRemappableOop(retClass1);
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ classOop = interpreterProxy->classByteArray();
+ }
+ else {
+ classOop = interpreterProxy->classExternalAddress();
+ }
+ oop1 = interpreterProxy->instantiateClassindexableSize(classOop, 4);
+ ptr = interpreterProxy->firstIndexableField(oop1);
+ ptr[0] = (((sqInt) intRet));
+
+ /* return class */
+
+ retClass1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(retClass1, 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+ return interpreterProxy->methodReturnValue(retOop1);
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ /* begin ffiReturnStruct:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral = (specOnStack
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
+ ffiRetType = interpreterProxy->fetchPointerofObject(0, argTypes);
+ retClass = interpreterProxy->fetchPointerofObject(1, ffiRetType);
+ retOop = interpreterProxy->instantiateClassindexableSize(retClass, 0);
+ interpreterProxy->pushRemappableOop(retOop);
+ oop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), (calloutState->structReturnSize));
+ if (returnStructInRegisters((calloutState->structReturnSize))) {
+ memcpy(interpreterProxy->firstIndexableField(oop), (&intRet), (calloutState->structReturnSize));
+ }
+ else {
+ memcpy(interpreterProxy->firstIndexableField(oop), (calloutState->limit), (calloutState->structReturnSize));
+ }
+ retOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop, oop);
+ return interpreterProxy->methodReturnValue(retOop);
+ }
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ return interpreterProxy->methodReturnValue(interpreterProxy->floatObjectOf(floatRet));
+ }
+ return interpreterProxy->methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
}
@@ -1092,18 +1271,43 @@
sqInt argSpec;
sqInt argType;
sqInt argTypeArray;
+ sqInt argTypes;
+ sqInt argTypes1;
+ sqInt atomicType;
+ sqInt atomicType1;
CalloutState *calloutState;
+ sqInt classOop;
+ char *cString;
sqInt err;
+ sqInt ffiRetType;
sqInt flags;
+ double floatRet;
sqInt functionName;
sqInt i;
+ sqInt i1;
+ usqLong intRet;
sqInt oop;
+ sqInt oop1;
+ sqInt oop2;
+ void *pointer;
int *ptr;
+ sqInt *ptr1;
sqInt requiredStackSize;
sqInt result;
+ sqInt retClass;
+ sqInt retClass1;
+ sqInt retOop;
+ sqInt retOop1;
+ sqInt retType;
+ sqInt specLiteral;
+ sqInt specLiteral1;
sqInt stackSize;
+ sqInt strLen;
+ sqInt strOop;
+ char *strPtr;
CalloutState theCalloutState;
- sqInt value;
+ sqInt typeSpec;
+ sqInt typeSpec1;
if (!(interpreterProxy->isKindOfClass(externalFunction, interpreterProxy->classExternalFunction()))) {
return ffiFail(FFIErrorNotFunction);
@@ -1132,21 +1336,21 @@
/* begin ffiContentsOfHandle:errCode: */
if ((addressPtr & 1)) {
address1 = ffiFail(FFIErrorBadAddress);
- goto l2;
+ goto l3;
}
if (!(interpreterProxy->isBytes(addressPtr))) {
address1 = ffiFail(FFIErrorBadAddress);
- goto l2;
+ goto l3;
}
if (!((interpreterProxy->byteSizeOf(addressPtr)) == 4)) {
address1 = ffiFail(FFIErrorBadAddress);
- goto l2;
+ goto l3;
}
address1 = interpreterProxy->fetchPointerofObject(0, addressPtr);
-l2: /* end ffiContentsOfHandle:errCode: */;
+l3: /* end ffiContentsOfHandle:errCode: */;
if (interpreterProxy->failed()) {
address = 0;
- goto l3;
+ goto l4;
}
if (address1 == 0) {
if (externalFunctionInstSize > ExternalFunctionStackSizeIndex) {
@@ -1154,18 +1358,18 @@
}
if ((interpreterProxy->slotSizeOf(externalFunction)) < 5) {
address = ffiFail(FFIErrorNoModule);
- goto l3;
+ goto l4;
}
address1 = ffiLoadCalloutAddressFrom(externalFunction);
if (interpreterProxy->failed()) {
address = 0;
- goto l3;
+ goto l4;
}
ptr = interpreterProxy->firstIndexableField(addressPtr);
ptr[0] = address1;
}
address = address1;
-l3: /* end ffiLoadCalloutAddress: */;
+l4: /* end ffiLoadCalloutAddress: */;
if (interpreterProxy->failed()) {
return 0;
}
@@ -1205,8 +1409,13 @@
&& (1
&& (!(returnStructInRegisters((calloutState->structReturnSize)))))) {
/* begin ffiPushPointer:in: */
- value = (calloutState->limit);
- error("shouldBeImplemented");
+ pointer = (calloutState->limit);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ goto l1;
+ }
+ longAtput((calloutState->currentArg), pointer);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
+ l1: /* end ffiPushPointer:in: */;
}
for (i = 1; i <= nArgs; i += 1) {
argType = interpreterProxy->fetchPointerofObject(i, argTypeArray);
@@ -1221,9 +1430,6 @@
while (((calloutState->stringArgIndex)) > 0) {
free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
}
- if (err == (-PrimErrObjectMayMove)) {
- return PrimErrObjectMayMove;
- }
return ffiFail(err);
}
}
@@ -1232,18 +1438,138 @@
if (ffiLogEnabled) {
functionName = interpreterProxy->fetchPointerofObject(externalFunctionInstSize, externalFunction);
if (!(interpreterProxy->isBytes(functionName))) {
- goto l1;
+ goto l2;
}
ffiLogCallOfLength(interpreterProxy->firstIndexableField(functionName), interpreterProxy->byteSizeOf(functionName));
}
-l1: /* end ffiLogCallout: */;
+l2: /* end ffiLogCallout: */;
if ((requiredStackSize < 0)
&& (externalFunctionInstSize > ExternalFunctionStackSizeIndex)) {
stackSize = ((calloutState->currentArg)) - ((calloutState->argVector));
interpreterProxy->storeIntegerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, stackSize);
}
/* begin ffiCalloutTo:SpecOnStack:in: */
- subclassResponsibility();
+ if ((0 + (cStackAlignment())) > 0) {
+ setsp((calloutState->argVector));
+ }
+ /* begin atomicTypeOf: */
+ typeSpec = (calloutState->ffiRetHeader);
+ atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ floatRet = dispatchFunctionPointer(((double (*)()) address));
+ }
+ else {
+ intRet = dispatchFunctionPointer(((usqLong (*)()) address));
+ }
+ if (isCalleePopsConvention((calloutState->callFlags))) {
+ setsp((calloutState->argVector));
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
+ /* begin ffiReturnPointer:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral1 = (argArrayOrNil != null
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes1 = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
+ retType = interpreterProxy->fetchPointerofObject(0, argTypes1);
+ retClass1 = interpreterProxy->fetchPointerofObject(1, retType);
+ if (retClass1 == (interpreterProxy->nilObject())) {
+ /* begin atomicTypeOf: */
+ typeSpec1 = (calloutState->ffiRetHeader);
+ atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+ /* begin ffiReturnCStringFrom: */
+ if ((((usqInt) intRet)) == null) {
+ result = interpreterProxy->methodReturnValue(interpreterProxy->nilObject());
+ goto l5;
+ }
+ cString = ((char *) (((usqInt) intRet)));
+ strLen = 0;
+ while (!((cString[strLen]) == 0)) {
+ strLen += 1;
+ }
+ strOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strLen);
+ strPtr = interpreterProxy->firstIndexableField(strOop);
+ for (i1 = 0; i1 <= (strLen - 1); i1 += 1) {
+ strPtr[i1] = (cString[i1]);
+ }
+ result = interpreterProxy->methodReturnValue(strOop);
+ goto l5;
+ }
+ interpreterProxy->pushRemappableOop(retType);
+ oop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalAddress(), 4);
+ ptr1 = interpreterProxy->firstIndexableField(oop1);
+ ptr1[0] = (((sqInt) intRet));
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalData(), 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+
+ /* return type */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(1, retOop1, oop1);
+ result = interpreterProxy->methodReturnValue(retOop1);
+ goto l5;
+ }
+ interpreterProxy->pushRemappableOop(retClass1);
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ classOop = interpreterProxy->classByteArray();
+ }
+ else {
+ classOop = interpreterProxy->classExternalAddress();
+ }
+ oop1 = interpreterProxy->instantiateClassindexableSize(classOop, 4);
+ ptr1 = interpreterProxy->firstIndexableField(oop1);
+ ptr1[0] = (((sqInt) intRet));
+
+ /* return class */
+
+ retClass1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(retClass1, 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+ result = interpreterProxy->methodReturnValue(retOop1);
+ goto l5;
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ /* begin ffiReturnStruct:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral = (argArrayOrNil != null
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
+ ffiRetType = interpreterProxy->fetchPointerofObject(0, argTypes);
+ retClass = interpreterProxy->fetchPointerofObject(1, ffiRetType);
+ retOop = interpreterProxy->instantiateClassindexableSize(retClass, 0);
+ interpreterProxy->pushRemappableOop(retOop);
+ oop2 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), (calloutState->structReturnSize));
+ if (returnStructInRegisters((calloutState->structReturnSize))) {
+ memcpy(interpreterProxy->firstIndexableField(oop2), (&intRet), (calloutState->structReturnSize));
+ }
+ else {
+ memcpy(interpreterProxy->firstIndexableField(oop2), (calloutState->limit), (calloutState->structReturnSize));
+ }
+ retOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop, oop2);
+ result = interpreterProxy->methodReturnValue(retOop);
+ goto l5;
+ }
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ result = interpreterProxy->methodReturnValue(interpreterProxy->floatObjectOf(floatRet));
+ goto l5;
+ }
+ result = interpreterProxy->methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
+l5: /* end ffiCalloutTo:SpecOnStack:in: */;
/* begin cleanupCalloutState: */
while (((calloutState->stringArgIndex)) > 0) {
free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
@@ -1700,9 +2026,13 @@
}
static sqInt
-ffiPushDoubleFloatin(sqInt value, sqInt calloutState)
+ffiPushDoubleFloatin(double value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ storeFloatAtPointerfrom((calloutState->currentArg), value);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
@@ -1725,60 +2055,80 @@
return FFIErrorInvalidPointer;
}
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ptrAddress);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (ptrClass == (interpreterProxy->classByteArray())) {
- if ((((calloutState->callFlags)) & FFICallFlagThreaded)
- && (interpreterProxy->isYoung(oop))) {
- return -PrimErrObjectMayMove;
- }
ptrAddress = ((int) (interpreterProxy->firstIndexableField(oop)));
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ptrAddress);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
if (interpreterProxy->includesBehaviorThatOf(ptrClass, interpreterProxy->classAlien())) {
- if ((((calloutState->callFlags)) & FFICallFlagThreaded)
- && ((isDirectAlien(oop))
- && (interpreterProxy->isYoung(oop)))) {
- return -PrimErrObjectMayMove;
- }
ptrAddress = ((longAt(oop + BaseHeaderSize)) > 0
? (oop + BaseHeaderSize) + BytesPerOop
: longAt((oop + BaseHeaderSize) + BytesPerOop));
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ptrAddress);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
return FFIErrorBadArg;
}
static sqInt
-ffiPushPointerin(sqInt value, CalloutState *calloutState)
+ffiPushPointerin(void *pointer, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), pointer);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
static sqInt
ffiPushSignedBytein(sqInt value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((signed char) value));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
static sqInt
ffiPushSignedCharin(sqInt value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((signed char) value));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
static sqInt
ffiPushSignedIntin(sqInt value, CalloutState *calloutState)
{
- subclassResponsibility();
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), value);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
+ return 0;
}
@@ -1806,28 +2156,46 @@
}
}
/* begin ffiPushSignedLongLong:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((usqInt) value));
+ longAtput(((calloutState->currentArg)) + 4, ((usqInt) (((unsigned sqLong )value) >> 32)));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
static sqInt
-ffiPushSignedLongLongin(sqLong value, CalloutState *calloutState)
+ffiPushSignedLongLongin(usqLong value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((usqInt) value));
+ longAtput(((calloutState->currentArg)) + 4, ((usqInt) (value >> 32)));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
static sqInt
ffiPushSignedShortin(sqInt value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((signed short) value));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
static sqInt
-ffiPushSingleFloatin(sqInt value, CalloutState *calloutState)
+ffiPushSingleFloatin(float value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ storeSingleFloatAtPointerfrom((calloutState->currentArg), value);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
@@ -1848,7 +2216,11 @@
((calloutState->stringArgs))[(calloutState->stringArgIndex)] = copy;
(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) + 1);
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), copy);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
@@ -1864,6 +2236,8 @@
sqInt argSpecSize1;
sqInt ptrAddress;
sqInt ptrClass;
+ sqInt roundedSize;
+ sqInt roundedSize1;
sqInt structSize;
sqInt structSize1;
@@ -1882,8 +2256,13 @@
structSize = ((calloutState->ffiArgHeader)) & FFIStructSizeMask;
argSpec = (calloutState->ffiArgSpec);
argSpecSize = (calloutState->ffiArgSpecSize);
- subclassResponsibility();
- return null;
+ roundedSize = (structSize + 3) & (~3);
+ if ((((calloutState->currentArg)) + roundedSize) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ memcpy((calloutState->currentArg), ((void *) ptrAddress), structSize);
+ (calloutState->currentArg = ((calloutState->currentArg)) + roundedSize);
+ return 0;
}
if (ptrClass == (interpreterProxy->classByteArray())) {
if (!((interpreterProxy->byteSizeOf(oop)) == (((calloutState->ffiArgHeader)) & FFIStructSizeMask))) {
@@ -1891,16 +2270,17 @@
}
ptrAddress = ((int) (interpreterProxy->firstIndexableField(oop)));
if (!(((calloutState->ffiArgHeader)) & FFIFlagPointer)) {
- if ((((calloutState->callFlags)) & FFICallFlagThreaded)
- && (interpreterProxy->isYoung(oop))) {
- return -PrimErrObjectMayMove;
- }
/* begin ffiPushStructure:ofSize:typeSpec:ofLength:in: */
structSize1 = ((calloutState->ffiArgHeader)) & FFIStructSizeMask;
argSpec1 = (calloutState->ffiArgSpec);
argSpecSize1 = (calloutState->ffiArgSpecSize);
- subclassResponsibility();
- return null;
+ roundedSize1 = (structSize1 + 3) & (~3);
+ if ((((calloutState->currentArg)) + roundedSize1) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ memcpy((calloutState->currentArg), ((void *) ptrAddress), structSize1);
+ (calloutState->currentArg = ((calloutState->currentArg)) + roundedSize1);
+ return 0;
}
if (!((((calloutState->ffiArgHeader)) & FFIStructSizeMask) == 4)) {
return FFIErrorStructSize;
@@ -1910,7 +2290,11 @@
return FFIErrorInvalidPointer;
}
/* begin ffiPushPointer:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ptrAddress);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
return FFIErrorBadArg;
@@ -1919,27 +2303,48 @@
static sqInt
ffiPushStructureofSizetypeSpecofLengthin(void *pointer, sqInt structSize, sqInt *argSpec, sqInt argSpecSize, CalloutState *calloutState)
{
- subclassResponsibility();
+ sqInt roundedSize;
+
+ roundedSize = (structSize + 3) & (~3);
+ if ((((calloutState->currentArg)) + roundedSize) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ memcpy((calloutState->currentArg), pointer, structSize);
+ (calloutState->currentArg = ((calloutState->currentArg)) + roundedSize);
+ return 0;
}
static sqInt
ffiPushUnsignedBytein(sqInt value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((unsigned char) value));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
static sqInt
ffiPushUnsignedCharin(sqInt value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((unsigned char) value));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
static sqInt
ffiPushUnsignedIntin(sqInt value, CalloutState *calloutState)
{
- subclassResponsibility();
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), value);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
+ return 0;
}
@@ -1967,28 +2372,35 @@
}
}
/* begin ffiPushUnsignedLongLong:in: */
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((usqInt) value));
+ longAtput(((calloutState->currentArg)) + 4, ((usqInt) (value >> 32)));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
static sqInt
ffiPushUnsignedLongLongin(usqLong value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 8) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((usqInt) value));
+ longAtput(((calloutState->currentArg)) + 4, ((usqInt) (value >> 32)));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 8);
return 0;
}
static sqInt
-ffiPushUnsignedLongin(sqInt value, CalloutState *calloutState)
-{
- error("shouldBeImplemented");
- return 0;
-}
-
-static sqInt
ffiPushUnsignedShortin(sqInt value, CalloutState *calloutState)
{
- error("shouldBeImplemented");
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ return FFIErrorCallFrameTooBig;
+ }
+ longAtput((calloutState->currentArg), ((unsigned short) value));
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
return 0;
}
@@ -2122,9 +2534,25 @@
alloca'ed space pointed to by the calloutState. */
static sqInt
-ffiReturnStructofTypein(usqLong longLongRet, sqInt ffiRetClass, CalloutState *calloutState)
+ffiReturnStructofTypein(usqLong longLongRet, sqInt ffiRetType, CalloutState *calloutState)
{
- subclassResponsibility();
+ sqInt oop;
+ sqInt retClass;
+ sqInt retOop;
+
+ retClass = interpreterProxy->fetchPointerofObject(1, ffiRetType);
+ retOop = interpreterProxy->instantiateClassindexableSize(retClass, 0);
+ interpreterProxy->pushRemappableOop(retOop);
+ oop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), (calloutState->structReturnSize));
+ if (returnStructInRegisters((calloutState->structReturnSize))) {
+ memcpy(interpreterProxy->firstIndexableField(oop), (&longLongRet), (calloutState->structReturnSize));
+ }
+ else {
+ memcpy(interpreterProxy->firstIndexableField(oop), (calloutState->limit), (calloutState->structReturnSize));
+ }
+ retOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop, oop);
+ return interpreterProxy->methodReturnValue(retOop);
}
@@ -2255,16 +2683,6 @@
return 1;
}
-static void
-initialize(CalloutState * self_in_initialize)
-{
- (self_in_initialize->stringArgs) = on(CArrayAccessor, new(Array, maxNumArgs(ThreadedFFIPlugin)));
- (self_in_initialize->stringArgIndex) = 0;
- (self_in_initialize->structReturnSize) = 0;
- (self_in_initialize->regIndex) = 0;
- (self_in_initialize->integerRegisters) = on(CArrayAccessor, new(Array, numRegArgs(ThreadedARMFFIPlugin)));
-}
-
static sqInt
isAlien(sqInt anOop)
{
@@ -2312,22 +2730,335 @@
EXPORT(void)
primitiveCallout(void)
{
+ sqInt address;
+ sqInt address1;
+ sqInt addressPtr;
+ char *allocation;
+ sqInt argClass;
+ sqInt argSpec;
+ sqInt argType;
+ sqInt argTypeArray;
+ sqInt argTypes;
+ sqInt argTypes1;
+ sqInt atomicType;
+ sqInt atomicType1;
+ CalloutState *calloutState;
+ sqInt classOop;
+ char *cString;
+ sqInt err;
sqInt externalFunction;
+ sqInt ffiRetType;
+ sqInt flags;
+ double floatRet;
+ sqInt functionName;
+ sqInt i;
+ sqInt i1;
+ usqLong intRet;
sqInt meth;
sqInt nArgs;
- sqInt retryCount;
+ sqInt oop;
+ sqInt oop1;
+ sqInt oop2;
+ void *pointer;
+ int *ptr;
+ sqInt *ptr1;
+ sqInt requiredStackSize;
+ sqInt result;
+ sqInt retClass;
+ sqInt retClass1;
+ sqInt retOop;
+ sqInt retOop1;
+ sqInt retType;
+ sqInt specLiteral;
+ sqInt specLiteral1;
+ sqInt stackSize;
+ sqInt strLen;
+ sqInt strOop;
+ char *strPtr;
+ CalloutState theCalloutState;
+ sqInt typeSpec;
+ sqInt typeSpec1;
meth = interpreterProxy->primitiveMethod();
if (!((interpreterProxy->literalCountOf(meth)) > 0)) {
interpreterProxy->primitiveFailFor(PrimErrBadMethod); return;
}
externalFunction = interpreterProxy->literalofMethod(0, meth);
+ /* begin ffiCall:ArgArrayOrNil:NumArgs: */
nArgs = interpreterProxy->methodArgumentCount();
- retryCount = 0;
- while (((ffiCallArgArrayOrNilNumArgs(externalFunction, null, nArgs)) == PrimErrObjectMayMove)
- && (((retryCount += 1)) <= nArgs)) {
- interpreterProxy->tenuringIncrementalGC();
+ if (!(interpreterProxy->isKindOfClass(externalFunction, interpreterProxy->classExternalFunction()))) {
+ ffiFail(FFIErrorNotFunction);
+ goto l3;
}
+ flags = interpreterProxy->fetchIntegerofObject(ExternalFunctionFlagsIndex, externalFunction);
+ if (interpreterProxy->failed()) {
+ ffiFail(FFIErrorBadArgs);
+ goto l3;
+ }
+
+ /* must be array of arg types */
+
+ argTypeArray = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, externalFunction);
+ if (!((interpreterProxy->isArray(argTypeArray))
+ && ((interpreterProxy->slotSizeOf(argTypeArray)) == (nArgs + 1)))) {
+ ffiFail(FFIErrorBadArgs);
+ goto l3;
+ }
+ if (!(1)) {
+ ffiFail(FFIErrorCallType);
+ goto l3;
+ }
+ /* begin ffiLoadCalloutAddress: */
+
+ /* Lookup the address */
+ /* Make sure it's an external handle */
+
+ addressPtr = interpreterProxy->fetchPointerofObject(0, externalFunction);
+ /* begin ffiContentsOfHandle:errCode: */
+ if ((addressPtr & 1)) {
+ address1 = ffiFail(FFIErrorBadAddress);
+ goto l4;
+ }
+ if (!(interpreterProxy->isBytes(addressPtr))) {
+ address1 = ffiFail(FFIErrorBadAddress);
+ goto l4;
+ }
+ if (!((interpreterProxy->byteSizeOf(addressPtr)) == 4)) {
+ address1 = ffiFail(FFIErrorBadAddress);
+ goto l4;
+ }
+ address1 = interpreterProxy->fetchPointerofObject(0, addressPtr);
+l4: /* end ffiContentsOfHandle:errCode: */;
+ if (interpreterProxy->failed()) {
+ address = 0;
+ goto l5;
+ }
+ if (address1 == 0) {
+ if (externalFunctionInstSize > ExternalFunctionStackSizeIndex) {
+ interpreterProxy->storePointerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, ((-1 << 1) | 1));
+ }
+ if ((interpreterProxy->slotSizeOf(externalFunction)) < 5) {
+ address = ffiFail(FFIErrorNoModule);
+ goto l5;
+ }
+ address1 = ffiLoadCalloutAddressFrom(externalFunction);
+ if (interpreterProxy->failed()) {
+ address = 0;
+ goto l5;
+ }
+ ptr = interpreterProxy->firstIndexableField(addressPtr);
+ ptr[0] = address1;
+ }
+ address = address1;
+l5: /* end ffiLoadCalloutAddress: */;
+ if (interpreterProxy->failed()) {
+ goto l3;
+ }
+ requiredStackSize = (externalFunctionInstSize > ExternalFunctionStackSizeIndex
+ ? interpreterProxy->fetchIntegerofObject(ExternalFunctionStackSizeIndex, externalFunction)
+ : -1);
+ if (interpreterProxy->failed()) {
+ interpreterProxy->primitiveFailFor((null == null
+ ? PrimErrBadMethod
+ : PrimErrBadReceiver));
+ goto l3;
+ }
+ stackSize = (requiredStackSize < 0
+ ? DefaultMaxStackSize
+ : requiredStackSize);
+ null;
+ calloutState = (&theCalloutState);
+ memset(calloutState, 0, sizeof(CalloutState));
+;
+ (calloutState->callFlags = flags);
+ argType = interpreterProxy->fetchPointerofObject(0, argTypeArray);
+ argSpec = interpreterProxy->fetchPointerofObject(0, argType);
+ argClass = interpreterProxy->fetchPointerofObject(1, argType);
+ if (((err = ffiCheckReturnWithin(argSpec, argClass, calloutState))) != 0) {
+ ffiFail(err);
+ goto l3;
+ }
+ allocation = alloca(((stackSize + ((calloutState->structReturnSize))) + 0) + (cStackAlignment()));
+ if (allocaLiesSoUseGetsp()) {
+ allocation = getsp();
+ }
+ if ((cStackAlignment()) != 0) {
+ allocation = ((char *) ((((usqInt)allocation)) & (~((cStackAlignment()) - 1))));
+ }
+ (calloutState->argVector = allocation);
+ (calloutState->currentArg = allocation + 0);
+ (calloutState->limit = (allocation + stackSize) + 0);
+ if ((((calloutState->structReturnSize)) > 0)
+ && (1
+ && (!(returnStructInRegisters((calloutState->structReturnSize)))))) {
+ /* begin ffiPushPointer:in: */
+ pointer = (calloutState->limit);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ goto l1;
+ }
+ longAtput((calloutState->currentArg), pointer);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
+ l1: /* end ffiPushPointer:in: */;
+ }
+ for (i = 1; i <= nArgs; i += 1) {
+ argType = interpreterProxy->fetchPointerofObject(i, argTypeArray);
+ argSpec = interpreterProxy->fetchPointerofObject(0, argType);
+ argClass = interpreterProxy->fetchPointerofObject(1, argType);
+ oop = (null == null
+ ? interpreterProxy->stackValue(nArgs - i)
+ : interpreterProxy->fetchPointerofObject(i - 1, null));
+ err = ffiArgumentSpecClassin(oop, argSpec, argClass, calloutState);
+ if (err != 0) {
+ /* begin cleanupCalloutState: */
+ while (((calloutState->stringArgIndex)) > 0) {
+ free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
+ }
+ ffiFail(err);
+ goto l3;
+ }
+ }
+ assert(!(interpreterProxy->failed()));
+ /* begin ffiLogCallout: */
+ if (ffiLogEnabled) {
+ functionName = interpreterProxy->fetchPointerofObject(externalFunctionInstSize, externalFunction);
+ if (!(interpreterProxy->isBytes(functionName))) {
+ goto l2;
+ }
+ ffiLogCallOfLength(interpreterProxy->firstIndexableField(functionName), interpreterProxy->byteSizeOf(functionName));
+ }
+l2: /* end ffiLogCallout: */;
+ if ((requiredStackSize < 0)
+ && (externalFunctionInstSize > ExternalFunctionStackSizeIndex)) {
+ stackSize = ((calloutState->currentArg)) - ((calloutState->argVector));
+ interpreterProxy->storeIntegerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, stackSize);
+ }
+ /* begin ffiCalloutTo:SpecOnStack:in: */
+ if ((0 + (cStackAlignment())) > 0) {
+ setsp((calloutState->argVector));
+ }
+ /* begin atomicTypeOf: */
+ typeSpec = (calloutState->ffiRetHeader);
+ atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ floatRet = dispatchFunctionPointer(((double (*)()) address));
+ }
+ else {
+ intRet = dispatchFunctionPointer(((usqLong (*)()) address));
+ }
+ if (isCalleePopsConvention((calloutState->callFlags))) {
+ setsp((calloutState->argVector));
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
+ /* begin ffiReturnPointer:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral1 = (null != null
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes1 = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
+ retType = interpreterProxy->fetchPointerofObject(0, argTypes1);
+ retClass1 = interpreterProxy->fetchPointerofObject(1, retType);
+ if (retClass1 == (interpreterProxy->nilObject())) {
+ /* begin atomicTypeOf: */
+ typeSpec1 = (calloutState->ffiRetHeader);
+ atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+ /* begin ffiReturnCStringFrom: */
+ if ((((usqInt) intRet)) == null) {
+ result = interpreterProxy->methodReturnValue(interpreterProxy->nilObject());
+ goto l6;
+ }
+ cString = ((char *) (((usqInt) intRet)));
+ strLen = 0;
+ while (!((cString[strLen]) == 0)) {
+ strLen += 1;
+ }
+ strOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strLen);
+ strPtr = interpreterProxy->firstIndexableField(strOop);
+ for (i1 = 0; i1 <= (strLen - 1); i1 += 1) {
+ strPtr[i1] = (cString[i1]);
+ }
+ result = interpreterProxy->methodReturnValue(strOop);
+ goto l6;
+ }
+ interpreterProxy->pushRemappableOop(retType);
+ oop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalAddress(), 4);
+ ptr1 = interpreterProxy->firstIndexableField(oop1);
+ ptr1[0] = (((sqInt) intRet));
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalData(), 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+
+ /* return type */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(1, retOop1, oop1);
+ result = interpreterProxy->methodReturnValue(retOop1);
+ goto l6;
+ }
+ interpreterProxy->pushRemappableOop(retClass1);
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ classOop = interpreterProxy->classByteArray();
+ }
+ else {
+ classOop = interpreterProxy->classExternalAddress();
+ }
+ oop1 = interpreterProxy->instantiateClassindexableSize(classOop, 4);
+ ptr1 = interpreterProxy->firstIndexableField(oop1);
+ ptr1[0] = (((sqInt) intRet));
+
+ /* return class */
+
+ retClass1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(retClass1, 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+ result = interpreterProxy->methodReturnValue(retOop1);
+ goto l6;
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ /* begin ffiReturnStruct:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral = (null != null
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
+ ffiRetType = interpreterProxy->fetchPointerofObject(0, argTypes);
+ retClass = interpreterProxy->fetchPointerofObject(1, ffiRetType);
+ retOop = interpreterProxy->instantiateClassindexableSize(retClass, 0);
+ interpreterProxy->pushRemappableOop(retOop);
+ oop2 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), (calloutState->structReturnSize));
+ if (returnStructInRegisters((calloutState->structReturnSize))) {
+ memcpy(interpreterProxy->firstIndexableField(oop2), (&intRet), (calloutState->structReturnSize));
+ }
+ else {
+ memcpy(interpreterProxy->firstIndexableField(oop2), (calloutState->limit), (calloutState->structReturnSize));
+ }
+ retOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop, oop2);
+ result = interpreterProxy->methodReturnValue(retOop);
+ goto l6;
+ }
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ result = interpreterProxy->methodReturnValue(interpreterProxy->floatObjectOf(floatRet));
+ goto l6;
+ }
+ result = interpreterProxy->methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
+l6: /* end ffiCalloutTo:SpecOnStack:in: */;
+ /* begin cleanupCalloutState: */
+ while (((calloutState->stringArgIndex)) > 0) {
+ free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
+ }
+l3: /* end ffiCall:ArgArrayOrNil:NumArgs: */;
return;
}
@@ -2338,26 +3069,338 @@
EXPORT(void)
primitiveCalloutWithArgs(void)
{
+ sqInt address;
+ sqInt address1;
+ sqInt addressPtr;
+ char *allocation;
sqInt argArray;
+ sqInt argClass;
+ sqInt argSpec;
+ sqInt argType;
+ sqInt argTypeArray;
+ sqInt argTypes;
+ sqInt argTypes1;
+ sqInt atomicType;
+ sqInt atomicType1;
+ CalloutState *calloutState;
+ sqInt classOop;
+ char *cString;
+ sqInt err;
sqInt externalFunction;
+ sqInt ffiRetType;
+ sqInt flags;
+ double floatRet;
+ sqInt functionName;
+ sqInt i;
+ sqInt i1;
+ usqLong intRet;
sqInt nArgs;
- sqInt retryCount;
+ sqInt oop;
+ sqInt oop1;
+ sqInt oop2;
+ void *pointer;
+ int *ptr;
+ sqInt *ptr1;
+ sqInt requiredStackSize;
+ sqInt result;
+ sqInt retClass;
+ sqInt retClass1;
+ sqInt retOop;
+ sqInt retOop1;
+ sqInt retType;
+ sqInt specLiteral;
+ sqInt specLiteral1;
+ sqInt stackSize;
+ sqInt strLen;
+ sqInt strOop;
+ char *strPtr;
+ CalloutState theCalloutState;
+ sqInt typeSpec;
+ sqInt typeSpec1;
if (!((interpreterProxy->methodArgumentCount()) == 1)) {
interpreterProxy->primitiveFailFor(PrimErrBadNumArgs); return;
}
- retryCount = 0;
- while (1) {
- externalFunction = interpreterProxy->stackValue(1);
- argArray = interpreterProxy->stackValue(0);
- if (!(interpreterProxy->isArray(argArray))) {
- interpreterProxy->primitiveFailFor(PrimErrBadArgument); return;
+ externalFunction = interpreterProxy->stackValue(1);
+ argArray = interpreterProxy->stackValue(0);
+ if (!(interpreterProxy->isArray(argArray))) {
+ interpreterProxy->primitiveFailFor(PrimErrBadArgument); return;
+ }
+ nArgs = interpreterProxy->slotSizeOf(argArray);
+ /* begin ffiCall:ArgArrayOrNil:NumArgs: */
+ if (!(interpreterProxy->isKindOfClass(externalFunction, interpreterProxy->classExternalFunction()))) {
+ ffiFail(FFIErrorNotFunction);
+ goto l3;
+ }
+ flags = interpreterProxy->fetchIntegerofObject(ExternalFunctionFlagsIndex, externalFunction);
+ if (interpreterProxy->failed()) {
+ ffiFail(FFIErrorBadArgs);
+ goto l3;
+ }
+
+ /* must be array of arg types */
+
+ argTypeArray = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, externalFunction);
+ if (!((interpreterProxy->isArray(argTypeArray))
+ && ((interpreterProxy->slotSizeOf(argTypeArray)) == (nArgs + 1)))) {
+ ffiFail(FFIErrorBadArgs);
+ goto l3;
+ }
+ if (!(1)) {
+ ffiFail(FFIErrorCallType);
+ goto l3;
+ }
+ /* begin ffiLoadCalloutAddress: */
+
+ /* Lookup the address */
+ /* Make sure it's an external handle */
+
+ addressPtr = interpreterProxy->fetchPointerofObject(0, externalFunction);
+ /* begin ffiContentsOfHandle:errCode: */
+ if ((addressPtr & 1)) {
+ address1 = ffiFail(FFIErrorBadAddress);
+ goto l4;
+ }
+ if (!(interpreterProxy->isBytes(addressPtr))) {
+ address1 = ffiFail(FFIErrorBadAddress);
+ goto l4;
+ }
+ if (!((interpreterProxy->byteSizeOf(addressPtr)) == 4)) {
+ address1 = ffiFail(FFIErrorBadAddress);
+ goto l4;
+ }
+ address1 = interpreterProxy->fetchPointerofObject(0, addressPtr);
+l4: /* end ffiContentsOfHandle:errCode: */;
+ if (interpreterProxy->failed()) {
+ address = 0;
+ goto l5;
+ }
+ if (address1 == 0) {
+ if (externalFunctionInstSize > ExternalFunctionStackSizeIndex) {
+ interpreterProxy->storePointerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, ((-1 << 1) | 1));
}
- nArgs = interpreterProxy->slotSizeOf(argArray);
- if (!(((ffiCallArgArrayOrNilNumArgs(externalFunction, argArray, nArgs)) == PrimErrObjectMayMove)
- && (((retryCount += 1)) <= nArgs))) break;
- interpreterProxy->tenuringIncrementalGC();
+ if ((interpreterProxy->slotSizeOf(externalFunction)) < 5) {
+ address = ffiFail(FFIErrorNoModule);
+ goto l5;
+ }
+ address1 = ffiLoadCalloutAddressFrom(externalFunction);
+ if (interpreterProxy->failed()) {
+ address = 0;
+ goto l5;
+ }
+ ptr = interpreterProxy->firstIndexableField(addressPtr);
+ ptr[0] = address1;
}
+ address = address1;
+l5: /* end ffiLoadCalloutAddress: */;
+ if (interpreterProxy->failed()) {
+ goto l3;
+ }
+ requiredStackSize = (externalFunctionInstSize > ExternalFunctionStackSizeIndex
+ ? interpreterProxy->fetchIntegerofObject(ExternalFunctionStackSizeIndex, externalFunction)
+ : -1);
+ if (interpreterProxy->failed()) {
+ interpreterProxy->primitiveFailFor((argArray == null
+ ? PrimErrBadMethod
+ : PrimErrBadReceiver));
+ goto l3;
+ }
+ stackSize = (requiredStackSize < 0
+ ? DefaultMaxStackSize
+ : requiredStackSize);
+ null;
+ calloutState = (&theCalloutState);
+ memset(calloutState, 0, sizeof(CalloutState));
+;
+ (calloutState->callFlags = flags);
+ argType = interpreterProxy->fetchPointerofObject(0, argTypeArray);
+ argSpec = interpreterProxy->fetchPointerofObject(0, argType);
+ argClass = interpreterProxy->fetchPointerofObject(1, argType);
+ if (((err = ffiCheckReturnWithin(argSpec, argClass, calloutState))) != 0) {
+ ffiFail(err);
+ goto l3;
+ }
+ allocation = alloca(((stackSize + ((calloutState->structReturnSize))) + 0) + (cStackAlignment()));
+ if (allocaLiesSoUseGetsp()) {
+ allocation = getsp();
+ }
+ if ((cStackAlignment()) != 0) {
+ allocation = ((char *) ((((usqInt)allocation)) & (~((cStackAlignment()) - 1))));
+ }
+ (calloutState->argVector = allocation);
+ (calloutState->currentArg = allocation + 0);
+ (calloutState->limit = (allocation + stackSize) + 0);
+ if ((((calloutState->structReturnSize)) > 0)
+ && (1
+ && (!(returnStructInRegisters((calloutState->structReturnSize)))))) {
+ /* begin ffiPushPointer:in: */
+ pointer = (calloutState->limit);
+ if ((((calloutState->currentArg)) + 4) > ((calloutState->limit))) {
+ goto l1;
+ }
+ longAtput((calloutState->currentArg), pointer);
+ (calloutState->currentArg = ((calloutState->currentArg)) + 4);
+ l1: /* end ffiPushPointer:in: */;
+ }
+ for (i = 1; i <= nArgs; i += 1) {
+ argType = interpreterProxy->fetchPointerofObject(i, argTypeArray);
+ argSpec = interpreterProxy->fetchPointerofObject(0, argType);
+ argClass = interpreterProxy->fetchPointerofObject(1, argType);
+ oop = (argArray == null
+ ? interpreterProxy->stackValue(nArgs - i)
+ : interpreterProxy->fetchPointerofObject(i - 1, argArray));
+ err = ffiArgumentSpecClassin(oop, argSpec, argClass, calloutState);
+ if (err != 0) {
+ /* begin cleanupCalloutState: */
+ while (((calloutState->stringArgIndex)) > 0) {
+ free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
+ }
+ ffiFail(err);
+ goto l3;
+ }
+ }
+ assert(!(interpreterProxy->failed()));
+ /* begin ffiLogCallout: */
+ if (ffiLogEnabled) {
+ functionName = interpreterProxy->fetchPointerofObject(externalFunctionInstSize, externalFunction);
+ if (!(interpreterProxy->isBytes(functionName))) {
+ goto l2;
+ }
+ ffiLogCallOfLength(interpreterProxy->firstIndexableField(functionName), interpreterProxy->byteSizeOf(functionName));
+ }
+l2: /* end ffiLogCallout: */;
+ if ((requiredStackSize < 0)
+ && (externalFunctionInstSize > ExternalFunctionStackSizeIndex)) {
+ stackSize = ((calloutState->currentArg)) - ((calloutState->argVector));
+ interpreterProxy->storeIntegerofObjectwithValue(ExternalFunctionStackSizeIndex, externalFunction, stackSize);
+ }
+ /* begin ffiCalloutTo:SpecOnStack:in: */
+ if ((0 + (cStackAlignment())) > 0) {
+ setsp((calloutState->argVector));
+ }
+ /* begin atomicTypeOf: */
+ typeSpec = (calloutState->ffiRetHeader);
+ atomicType = ((usqInt) (typeSpec & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ floatRet = dispatchFunctionPointer(((double (*)()) address));
+ }
+ else {
+ intRet = dispatchFunctionPointer(((usqLong (*)()) address));
+ }
+ if (isCalleePopsConvention((calloutState->callFlags))) {
+ setsp((calloutState->argVector));
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagPointer) {
+ /* begin ffiReturnPointer:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral1 = (argArray != null
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes1 = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral1);
+ retType = interpreterProxy->fetchPointerofObject(0, argTypes1);
+ retClass1 = interpreterProxy->fetchPointerofObject(1, retType);
+ if (retClass1 == (interpreterProxy->nilObject())) {
+ /* begin atomicTypeOf: */
+ typeSpec1 = (calloutState->ffiRetHeader);
+ atomicType1 = ((usqInt) (typeSpec1 & FFIAtomicTypeMask)) >> FFIAtomicTypeShift;
+ if ((((usqInt) atomicType1) >> 1) == (((usqInt) FFITypeSignedChar) >> 1)) {
+ /* begin ffiReturnCStringFrom: */
+ if ((((usqInt) intRet)) == null) {
+ result = interpreterProxy->methodReturnValue(interpreterProxy->nilObject());
+ goto l6;
+ }
+ cString = ((char *) (((usqInt) intRet)));
+ strLen = 0;
+ while (!((cString[strLen]) == 0)) {
+ strLen += 1;
+ }
+ strOop = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classString(), strLen);
+ strPtr = interpreterProxy->firstIndexableField(strOop);
+ for (i1 = 0; i1 <= (strLen - 1); i1 += 1) {
+ strPtr[i1] = (cString[i1]);
+ }
+ result = interpreterProxy->methodReturnValue(strOop);
+ goto l6;
+ }
+ interpreterProxy->pushRemappableOop(retType);
+ oop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalAddress(), 4);
+ ptr1 = interpreterProxy->firstIndexableField(oop1);
+ ptr1[0] = (((sqInt) intRet));
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classExternalData(), 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+
+ /* return type */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(1, retOop1, oop1);
+ result = interpreterProxy->methodReturnValue(retOop1);
+ goto l6;
+ }
+ interpreterProxy->pushRemappableOop(retClass1);
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ classOop = interpreterProxy->classByteArray();
+ }
+ else {
+ classOop = interpreterProxy->classExternalAddress();
+ }
+ oop1 = interpreterProxy->instantiateClassindexableSize(classOop, 4);
+ ptr1 = interpreterProxy->firstIndexableField(oop1);
+ ptr1[0] = (((sqInt) intRet));
+
+ /* return class */
+
+ retClass1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->pushRemappableOop(oop1);
+ retOop1 = interpreterProxy->instantiateClassindexableSize(retClass1, 0);
+
+ /* external address */
+
+ oop1 = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop1, oop1);
+ result = interpreterProxy->methodReturnValue(retOop1);
+ goto l6;
+ }
+ if (((calloutState->ffiRetHeader)) & FFIFlagStructure) {
+ /* begin ffiReturnStruct:ofType:in: */
+ /* begin ffiReturnType: */
+ specLiteral = (argArray != null
+ ? interpreterProxy->stackValue(1)
+ : interpreterProxy->literalofMethod(0, interpreterProxy->primitiveMethod()));
+ argTypes = interpreterProxy->fetchPointerofObject(ExternalFunctionArgTypesIndex, specLiteral);
+ ffiRetType = interpreterProxy->fetchPointerofObject(0, argTypes);
+ retClass = interpreterProxy->fetchPointerofObject(1, ffiRetType);
+ retOop = interpreterProxy->instantiateClassindexableSize(retClass, 0);
+ interpreterProxy->pushRemappableOop(retOop);
+ oop2 = interpreterProxy->instantiateClassindexableSize(interpreterProxy->classByteArray(), (calloutState->structReturnSize));
+ if (returnStructInRegisters((calloutState->structReturnSize))) {
+ memcpy(interpreterProxy->firstIndexableField(oop2), (&intRet), (calloutState->structReturnSize));
+ }
+ else {
+ memcpy(interpreterProxy->firstIndexableField(oop2), (calloutState->limit), (calloutState->structReturnSize));
+ }
+ retOop = interpreterProxy->popRemappableOop();
+ interpreterProxy->storePointerofObjectwithValue(0, retOop, oop2);
+ result = interpreterProxy->methodReturnValue(retOop);
+ goto l6;
+ }
+ if ((atomicType == FFITypeSingleFloat)
+ || (atomicType == FFITypeDoubleFloat)) {
+ result = interpreterProxy->methodReturnValue(interpreterProxy->floatObjectOf(floatRet));
+ goto l6;
+ }
+ result = interpreterProxy->methodReturnValue(ffiCreateIntegralResultOopofAtomicTypein(intRet, atomicType, calloutState));
+l6: /* end ffiCalloutTo:SpecOnStack:in: */;
+ /* begin cleanupCalloutState: */
+ while (((calloutState->stringArgIndex)) > 0) {
+ free(((calloutState->stringArgs))[(calloutState->stringArgIndex = ((calloutState->stringArgIndex)) - 1)]);
+ }
+l3: /* end ffiCall:ArgArrayOrNil:NumArgs: */;
return;
}
@@ -2870,8 +3913,7 @@
/* Answer any space needed to prevent the alloca'ed outgoing arguments
marshalling area from
being overwritten by any register arguments during calls during
- marshalling. On ARM we
- believe this is zero. */
+ marshalling. On x86 this is 0 */
static sqInt
registerArgsSlop(void)
@@ -2880,15 +3922,6 @@
}
-/* Answer if a struct result of a given size is returned in memory or not. */
-
-static sqInt
-returnStructInRegisters(sqInt returnStructSize)
-{
- return subclassResponsibility();
-}
-
-
/* Note: This is coded so that is can be run from Squeak. */
EXPORT(sqInt)
More information about the Vm-dev
mailing list