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) |
Free forum by Nabble | Edit this page |