ExternalLibraryFunction.st
changeset 10440 b643af58f8bf
parent 10279 60c42983fdd4
child 10481 b3526180579f
equal deleted inserted replaced
10439:6b69b2ecb04c 10440:b643af58f8bf
   322 
   322 
   323 !ExternalLibraryFunction methodsFor:'invoking'!
   323 !ExternalLibraryFunction methodsFor:'invoking'!
   324 
   324 
   325 invoke
   325 invoke
   326     self hasCode ifFalse:[
   326     self hasCode ifFalse:[
   327 	self prepareInvoke.
   327         self prepareInvoke.
   328     ].
   328     ].
   329     ^ self invokeFFIWithArguments:#()
   329     ^ self invokeFFIWithArguments:nil
   330 !
   330 !
   331 
   331 
   332 invokeCPPVirtualOn:anInstance
   332 invokeCPPVirtualOn:anInstance
   333     self hasCode ifFalse:[
   333     self hasCode ifFalse:[
   334 	self prepareInvoke.
   334         self prepareInvoke.
   335     ].
   335     ].
   336     ^ self invokeCPPVirtualFFIOn:anInstance withArguments:#()
   336     ^ self invokeCPPVirtualFFIOn:anInstance withArguments:nil
   337 !
   337 !
   338 
   338 
   339 invokeCPPVirtualOn:instance with:arg
   339 invokeCPPVirtualOn:instance with:arg
   340     self hasCode ifFalse:[
   340     self hasCode ifFalse:[
   341 	self prepareInvoke.
   341 	self prepareInvoke.
   587     ^ self invokeFFIwithArguments:arguments forCPPInstance:nil
   587     ^ self invokeFFIwithArguments:arguments forCPPInstance:nil
   588 
   588 
   589     "Modified: / 01-08-2006 / 13:55:35 / cg"
   589     "Modified: / 01-08-2006 / 13:55:35 / cg"
   590 !
   590 !
   591 
   591 
   592 invokeFFIwithArguments:arguments forCPPInstance:aCPlusPlusObjectOrNil
   592 invokeFFIwithArguments:argumentsOrNil forCPPInstance:aCPlusPlusObjectOrNil
   593     |argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset
   593     |argTypeSymbols returnTypeSymbol failureCode failureInfo returnValue stClass vtOffset
   594      virtual async unlimitedStack callTypeNumber returnValueClass argValueClass|
   594      virtual async unlimitedStack callTypeNumber returnValueClass argValueClass|
   595 
   595 
   596     argTypeSymbols := argumentTypes.
   596     argTypeSymbols := argumentTypes.
   597     returnTypeSymbol := returnType.
   597     returnTypeSymbol := returnType.
   598 
   598 
   599     virtual := self isVirtualCPP.
   599     virtual := self isVirtualCPP.
   600     (virtual "or:[self isNonVirtualCPP]") ifTrue:[
   600     (virtual "or:[self isNonVirtualCPP]") ifTrue:[
   601 	aCPlusPlusObjectOrNil isNil ifTrue:[
   601         aCPlusPlusObjectOrNil isNil ifTrue:[
   602 	    "/ must have a c++ object instance
   602             "/ must have a c++ object instance
   603 	    self primitiveFailed.
   603             self primitiveFailed.
   604 	].
   604         ].
   605 
   605 
   606 	"/ and it must be a kind of ExternalStructure !!
   606         "/ and it must be a kind of ExternalStructure !!
   607 	(aCPlusPlusObjectOrNil isKindOf:ExternalStructure) ifFalse:[
   607         (aCPlusPlusObjectOrNil isKindOf:ExternalStructure) ifFalse:[
   608 	    self primitiveFailed.
   608             self primitiveFailed.
   609 	].
   609         ].
   610 	virtual ifTrue:[
   610         virtual ifTrue:[
   611 	    vtOffset := name.
   611             vtOffset := name.
   612 	    (vtOffset between:0 and:10000) ifFalse:[
   612             (vtOffset between:0 and:10000) ifFalse:[
   613 		self primitiveFailed.
   613                 self primitiveFailed.
   614 	    ]
   614             ]
   615 	].
   615         ].
   616     ] ifFalse:[
   616     ] ifFalse:[
   617 	aCPlusPlusObjectOrNil notNil ifTrue:[
   617         aCPlusPlusObjectOrNil notNil ifTrue:[
   618 	    "/ must NOT have a c++ object instance
   618             "/ must NOT have a c++ object instance
   619 	    self primitiveFailed.
   619             self primitiveFailed.
   620 	].
   620         ].
   621     ].
   621     ].
   622     async := self isAsync.
   622     async := self isAsync.
   623     unlimitedStack := self isUnlimitedStack.
   623     unlimitedStack := self isUnlimitedStack.
   624     callTypeNumber := self callTypeNumber.
   624     callTypeNumber := self callTypeNumber.
   625 
   625 
   628     ffi_cif __cif;
   628     ffi_cif __cif;
   629     ffi_type *__argTypesIncludingThis[MAX_ARGS+1];
   629     ffi_type *__argTypesIncludingThis[MAX_ARGS+1];
   630     ffi_type **__argTypes = __argTypesIncludingThis;
   630     ffi_type **__argTypes = __argTypesIncludingThis;
   631     ffi_type *__returnType = NULL;
   631     ffi_type *__returnType = NULL;
   632     union u {
   632     union u {
   633 	int iVal;
   633         int iVal;
   634 	float fVal;
   634         float fVal;
   635 	double dVal;
   635         double dVal;
   636 	void *pointerVal;
   636         void *pointerVal;
   637     };
   637     };
   638     union u __argValuesIncludingThis[MAX_ARGS+1];
   638     union u __argValuesIncludingThis[MAX_ARGS+1];
   639     union u *__argValues = __argValuesIncludingThis;
   639     union u *__argValues = __argValuesIncludingThis;
   640     union u __returnValue;
   640     union u __returnValue;
   641     void *__argValuePointersIncludingThis[MAX_ARGS+1];
   641     void *__argValuePointersIncludingThis[MAX_ARGS+1];
   644     int __numArgs, __numArgsIncludingThis;
   644     int __numArgs, __numArgsIncludingThis;
   645     static int null = 0;
   645     static int null = 0;
   646     int i;
   646     int i;
   647     ffi_abi __callType = FFI_DEFAULT_ABI;
   647     ffi_abi __callType = FFI_DEFAULT_ABI;
   648     VOIDFUNC codeAddress = (VOIDFUNC)__INST(code_);
   648     VOIDFUNC codeAddress = (VOIDFUNC)__INST(code_);
   649 
   649     int __numArgsWanted;
   650     if (arguments == nil) {
   650 
   651 	__numArgs = 0;
   651     if (argumentsOrNil == nil) {
   652 	if (argTypeSymbols != nil) {
   652         __numArgs = 0;
   653 	    if (! __isArray(argTypeSymbols)
   653     } else if (__isArray(argumentsOrNil)) {
   654 	     || (__arraySize(argTypeSymbols) != __numArgs)) {
   654         __numArgs = __arraySize(argumentsOrNil);
   655 		failureCode = @symbol(ArgumentCountMismatch);
       
   656 		goto getOutOfHere;
       
   657 	    }
       
   658 	}
       
   659     } else {
   655     } else {
   660 	if (! __isArray(arguments)
   656         failureCode = @symbol(BadArgumentVector);
   661 	 || ! __isArray(argTypeSymbols)
   657         goto getOutOfHere;
   662 	 || (__arraySize(argTypeSymbols) != (__numArgs = __arraySize(arguments)))) {
   658     }
   663 	    failureCode = @symbol(ArgumentCountMismatch);
   659     if (argTypeSymbols == nil) {
   664 	    goto getOutOfHere;
   660         __numArgsWanted = 0;
   665 	}
   661     } else if (__isArray(argTypeSymbols)) {
       
   662         __numArgsWanted = __arraySize(argTypeSymbols);
       
   663     } else {
       
   664         failureCode = @symbol(BadArgumentTypeVector);
       
   665         goto getOutOfHere;
       
   666     }
       
   667 
       
   668     if (__numArgs != __numArgsWanted) {
       
   669         failureCode = @symbol(ArgumentCountMismatch);
       
   670         goto getOutOfHere;
   666     }
   671     }
   667     if (__numArgs > MAX_ARGS) {
   672     if (__numArgs > MAX_ARGS) {
   668 	failureCode = @symbol(TooManyArguments);
   673         failureCode = @symbol(TooManyArguments);
   669 	goto getOutOfHere;
   674         goto getOutOfHere;
   670     }
   675     }
   671 
   676 
   672     /*
   677     /*
   673      * validate the return type
   678      * validate the return type
   674      */
   679      */
   675     __returnValuePointer = &__returnValue;
   680     __returnValuePointer = &__returnValue;
   676 
   681 
   677     if (returnTypeSymbol == @symbol(voidPointer)) {
   682     if (returnTypeSymbol == @symbol(voidPointer)) {
   678 	returnTypeSymbol = @symbol(handle);
   683         returnTypeSymbol = @symbol(handle);
   679     }
   684     }
   680 
   685 
   681     if (returnTypeSymbol == @symbol(int)) {
   686     if (returnTypeSymbol == @symbol(int)) {
   682 	__returnType = __get_ffi_type_sint();
   687         __returnType = __get_ffi_type_sint();
   683     } else if (returnTypeSymbol == @symbol(uint)) {
   688     } else if (returnTypeSymbol == @symbol(uint)) {
   684 	__returnType = __get_ffi_type_uint();
   689         __returnType = __get_ffi_type_uint();
   685     } else if (returnTypeSymbol == @symbol(uint8)) {
   690     } else if (returnTypeSymbol == @symbol(uint8)) {
   686 	__returnType = __get_ffi_type_uint8();
   691         __returnType = __get_ffi_type_uint8();
   687     } else if (returnTypeSymbol == @symbol(uint16)) {
   692     } else if (returnTypeSymbol == @symbol(uint16)) {
   688 	__returnType = __get_ffi_type_uint16();
   693         __returnType = __get_ffi_type_uint16();
   689     } else if (returnTypeSymbol == @symbol(uint32)) {
   694     } else if (returnTypeSymbol == @symbol(uint32)) {
   690 	__returnType = __get_ffi_type_uint32();
   695         __returnType = __get_ffi_type_uint32();
   691     } else if (returnTypeSymbol == @symbol(uint64)) {
   696     } else if (returnTypeSymbol == @symbol(uint64)) {
   692 	__returnType = __get_ffi_type_uint64();
   697         __returnType = __get_ffi_type_uint64();
   693 
   698 
   694     } else if (returnTypeSymbol == @symbol(sint)) {
   699     } else if (returnTypeSymbol == @symbol(sint)) {
   695 	__returnType = __get_ffi_type_sint();
   700         __returnType = __get_ffi_type_sint();
   696     } else if (returnTypeSymbol == @symbol(sint8)) {
   701     } else if (returnTypeSymbol == @symbol(sint8)) {
   697 	__returnType = __get_ffi_type_sint8();
   702         __returnType = __get_ffi_type_sint8();
   698     } else if (returnTypeSymbol == @symbol(sint16)) {
   703     } else if (returnTypeSymbol == @symbol(sint16)) {
   699 	__returnType = __get_ffi_type_sint16();
   704         __returnType = __get_ffi_type_sint16();
   700     } else if (returnTypeSymbol == @symbol(sint32)) {
   705     } else if (returnTypeSymbol == @symbol(sint32)) {
   701 	__returnType = __get_ffi_type_sint32();
   706         __returnType = __get_ffi_type_sint32();
   702     } else if (returnTypeSymbol == @symbol(sint64)) {
   707     } else if (returnTypeSymbol == @symbol(sint64)) {
   703 	__returnType = __get_ffi_type_sint64();
   708         __returnType = __get_ffi_type_sint64();
   704 
   709 
   705     } else if (returnTypeSymbol == @symbol(long)) {
   710     } else if (returnTypeSymbol == @symbol(long)) {
   706 	if (sizeof(long) == 4) {
   711         if (sizeof(long) == 4) {
   707 	   returnTypeSymbol = @symbol(sint32);
   712            returnTypeSymbol = @symbol(sint32);
   708 	   __returnType = __get_ffi_type_sint32();
   713            __returnType = __get_ffi_type_sint32();
   709 	} else if (sizeof(long) == 8) {
   714         } else if (sizeof(long) == 8) {
   710 	   returnTypeSymbol = @symbol(sint64);
   715            returnTypeSymbol = @symbol(sint64);
   711 	   __returnType = __get_ffi_type_sint64();
   716            __returnType = __get_ffi_type_sint64();
   712 	} else {
   717         } else {
   713 	    failureCode = @symbol(UnknownReturnType);
   718             failureCode = @symbol(UnknownReturnType);
   714 	    goto getOutOfHere;
   719             goto getOutOfHere;
   715 	}
   720         }
   716 
   721 
   717     } else if (returnTypeSymbol == @symbol(ulong)) {
   722     } else if (returnTypeSymbol == @symbol(ulong)) {
   718 	if (sizeof(long) == 4) {
   723         if (sizeof(long) == 4) {
   719 	   returnTypeSymbol = @symbol(uint32);
   724            returnTypeSymbol = @symbol(uint32);
   720 	   __returnType = __get_ffi_type_uint32();
   725            __returnType = __get_ffi_type_uint32();
   721 	}else if (sizeof(long) == 8) {
   726         }else if (sizeof(long) == 8) {
   722 	   returnTypeSymbol = @symbol(uint64);
   727            returnTypeSymbol = @symbol(uint64);
   723 	   __returnType = __get_ffi_type_uint64();
   728            __returnType = __get_ffi_type_uint64();
   724 	} else {
   729         } else {
   725 	    failureCode = @symbol(UnknownReturnType);
   730             failureCode = @symbol(UnknownReturnType);
   726 	    goto getOutOfHere;
   731             goto getOutOfHere;
   727 	}
   732         }
   728 
   733 
   729     } else if (returnTypeSymbol == @symbol(bool)) {
   734     } else if (returnTypeSymbol == @symbol(bool)) {
   730 	__returnType = __get_ffi_type_uint();
   735         __returnType = __get_ffi_type_uint();
   731 
   736 
   732     } else if (returnTypeSymbol == @symbol(float)) {
   737     } else if (returnTypeSymbol == @symbol(float)) {
   733 	__returnType = __get_ffi_type_float();
   738         __returnType = __get_ffi_type_float();
   734     } else if (returnTypeSymbol == @symbol(double)) {
   739     } else if (returnTypeSymbol == @symbol(double)) {
   735 	__returnType = __get_ffi_type_double();
   740         __returnType = __get_ffi_type_double();
   736 
   741 
   737     } else if (returnTypeSymbol == @symbol(void)) {
   742     } else if (returnTypeSymbol == @symbol(void)) {
   738 	__returnType = __get_ffi_type_void();
   743         __returnType = __get_ffi_type_void();
   739 	__returnValuePointer = NULL;
   744         __returnValuePointer = NULL;
   740     } else if ((returnTypeSymbol == @symbol(pointer)) || (returnTypeSymbol == @symbol(handle))) {
   745     } else if ((returnTypeSymbol == @symbol(pointer)) || (returnTypeSymbol == @symbol(handle))) {
   741 	__returnType = __get_ffi_type_pointer();
   746         __returnType = __get_ffi_type_pointer();
   742     } else if (returnTypeSymbol == @symbol(charPointer)) {
   747     } else if (returnTypeSymbol == @symbol(charPointer)) {
   743 	__returnType = __get_ffi_type_pointer();
   748         __returnType = __get_ffi_type_pointer();
   744     } else if (returnTypeSymbol == @symbol(wcharPointer)) {
   749     } else if (returnTypeSymbol == @symbol(wcharPointer)) {
   745 	__returnType = __get_ffi_type_pointer();
   750         __returnType = __get_ffi_type_pointer();
   746     } else {
   751     } else {
   747 	if (__isSymbol(returnTypeSymbol)
   752         if (__isSymbol(returnTypeSymbol)
   748 	 && ((returnValueClass = __GLOBAL_GET(returnTypeSymbol)) != nil)) {
   753          && ((returnValueClass = __GLOBAL_GET(returnTypeSymbol)) != nil)) {
   749 	    if (! __isBehaviorLike(returnValueClass)) {
   754             if (! __isBehaviorLike(returnValueClass)) {
   750 		failureCode = @symbol(NonBehaviorReturnType);
   755                 failureCode = @symbol(NonBehaviorReturnType);
   751 		goto getOutOfHere;
   756                 goto getOutOfHere;
   752 	    }
   757             }
   753 	    if (! __qIsSubclassOfExternalAddress(returnValueClass)) {
   758             if (! __qIsSubclassOfExternalAddress(returnValueClass)) {
   754 		failureCode = @symbol(NonExternalAddressReturnType);
   759                 failureCode = @symbol(NonExternalAddressReturnType);
   755 		goto getOutOfHere;
   760                 goto getOutOfHere;
   756 	    }
   761             }
   757 	    __returnType = __get_ffi_type_pointer();
   762             __returnType = __get_ffi_type_pointer();
   758 	    returnTypeSymbol = @symbol(pointer);
   763             returnTypeSymbol = @symbol(pointer);
   759 	} else {
   764         } else {
   760 	    failureCode = @symbol(UnknownReturnType);
   765             failureCode = @symbol(UnknownReturnType);
   761 	    goto getOutOfHere;
   766             goto getOutOfHere;
   762 	}
   767         }
   763     }
   768     }
   764 
   769 
   765     /*
   770     /*
   766      * validate the c++ object
   771      * validate the c++ object
   767      */
   772      */
   768     if (aCPlusPlusObjectOrNil != nil) {
   773     if (aCPlusPlusObjectOrNil != nil) {
   769 	struct cPlusPlusInstance {
   774         struct cPlusPlusInstance {
   770 	    void **vTable;
   775             void **vTable;
   771 	};
   776         };
   772 	struct cPlusPlusInstance *inst;
   777         struct cPlusPlusInstance *inst;
   773 
   778 
   774 	if (__isExternalAddressLike(aCPlusPlusObjectOrNil)) {
   779         if (__isExternalAddressLike(aCPlusPlusObjectOrNil)) {
   775 	    inst = (void *)(__externalAddressVal(aCPlusPlusObjectOrNil));
   780             inst = (void *)(__externalAddressVal(aCPlusPlusObjectOrNil));
   776 	} else if (__isExternalBytesLike(aCPlusPlusObjectOrNil)) {
   781         } else if (__isExternalBytesLike(aCPlusPlusObjectOrNil)) {
   777 	    inst = (void *)(__externalBytesVal(aCPlusPlusObjectOrNil));
   782             inst = (void *)(__externalBytesVal(aCPlusPlusObjectOrNil));
   778 	} else {
   783         } else {
   779 	    failureCode = @symbol(InvalidInstance);
   784             failureCode = @symbol(InvalidInstance);
   780 	    goto getOutOfHere;
   785             goto getOutOfHere;
   781 	}
   786         }
   782 	__argValues[0].pointerVal = inst;
   787         __argValues[0].pointerVal = inst;
   783 	__argValuePointersIncludingThis[0] = &(__argValues[0]);
   788         __argValuePointersIncludingThis[0] = &(__argValues[0]);
   784 	__argTypes[0] = __get_ffi_type_pointer();
   789         __argTypes[0] = __get_ffi_type_pointer();
   785 
   790 
   786 	__argValuePointers = &__argValuePointersIncludingThis[1];
   791         __argValuePointers = &__argValuePointersIncludingThis[1];
   787 	__argTypes = &__argTypesIncludingThis[1];
   792         __argTypes = &__argTypesIncludingThis[1];
   788 	__argValues = &__argValuesIncludingThis[1];
   793         __argValues = &__argValuesIncludingThis[1];
   789 	__numArgsIncludingThis = __numArgs + 1;
   794         __numArgsIncludingThis = __numArgs + 1;
   790 
   795 
   791 	if (virtual == true) {
   796         if (virtual == true) {
   792 	    if (! __isSmallInteger(vtOffset)) {
   797             if (! __isSmallInteger(vtOffset)) {
   793 		failureCode = @symbol(InvalidVTableIndex);
   798                 failureCode = @symbol(InvalidVTableIndex);
   794 		goto getOutOfHere;
   799                 goto getOutOfHere;
   795 	    }
   800             }
   796 	    codeAddress = inst->vTable[__intVal(vtOffset)];
   801             codeAddress = inst->vTable[__intVal(vtOffset)];
   797 #ifdef VERBOSE
   802 #ifdef VERBOSE
   798 	    printf("virtual codeAddress: %x\n", codeAddress);
   803             printf("virtual codeAddress: %x\n", codeAddress);
   799 #endif
   804 #endif
   800 	}
   805         }
   801     } else {
   806     } else {
   802 	__numArgsIncludingThis = __numArgs;
   807         __numArgsIncludingThis = __numArgs;
   803 #ifdef VERBOSE
   808 #ifdef VERBOSE
   804 	printf("codeAddress: %x\n", codeAddress);
   809         printf("codeAddress: %x\n", codeAddress);
   805 #endif
   810 #endif
   806     }
   811     }
   807 
   812 
   808     /*
   813     /*
   809      * validate all arg types and setup arg-buffers
   814      * validate all arg types and setup arg-buffers
   810      */
   815      */
   811     for (i=0; i<__numArgs; i++) {
   816     for (i=0; i<__numArgs; i++) {
   812 	ffi_type *thisType;
   817         ffi_type *thisType;
   813 	void *argValuePtr;
   818         void *argValuePtr;
   814 	OBJ typeSymbol;
   819         OBJ typeSymbol;
   815 	OBJ arg;
   820         OBJ arg;
   816 
   821 
   817 	failureInfo = __mkSmallInteger(i+1);   /* in case there is one */
   822         failureInfo = __mkSmallInteger(i+1);   /* in case there is one */
   818 
   823 
   819 	typeSymbol = __ArrayInstPtr(argTypeSymbols)->a_element[i];
   824         typeSymbol = __ArrayInstPtr(argTypeSymbols)->a_element[i];
   820 	arg = __ArrayInstPtr(arguments)->a_element[i];
   825         arg = __ArrayInstPtr(argumentsOrNil)->a_element[i];
   821 
   826 
   822 	if (typeSymbol == @symbol(handle)) {
   827         if (typeSymbol == @symbol(handle)) {
   823 	    typeSymbol = @symbol(pointer);
   828             typeSymbol = @symbol(pointer);
   824 	} else if (typeSymbol == @symbol(voidPointer)) {
   829         } else if (typeSymbol == @symbol(voidPointer)) {
   825 	    typeSymbol = @symbol(pointer);
   830             typeSymbol = @symbol(pointer);
   826 	}
   831         }
   827 
   832 
   828 	if (typeSymbol == @symbol(long)) {
   833         if (typeSymbol == @symbol(long)) {
   829 	    if (sizeof(long) == sizeof(int)) {
   834             if (sizeof(long) == sizeof(int)) {
   830 		typeSymbol = @symbol(sint);
   835                 typeSymbol = @symbol(sint);
   831 	    } else {
   836             } else {
   832 		if (sizeof(long) == 4) {
   837                 if (sizeof(long) == 4) {
   833 		    typeSymbol = @symbol(sint32);
   838                     typeSymbol = @symbol(sint32);
   834 		} else if (sizeof(long) == 8) {
   839                 } else if (sizeof(long) == 8) {
   835 		    typeSymbol = @symbol(sint64);
   840                     typeSymbol = @symbol(sint64);
   836 		}
   841                 }
   837 	    }
   842             }
   838 	}
   843         }
   839 	if (typeSymbol == @symbol(ulong)) {
   844         if (typeSymbol == @symbol(ulong)) {
   840 	    if (sizeof(unsigned long) == sizeof(unsigned int)) {
   845             if (sizeof(unsigned long) == sizeof(unsigned int)) {
   841 		typeSymbol = @symbol(uint);
   846                 typeSymbol = @symbol(uint);
   842 	    } else {
   847             } else {
   843 		if (sizeof(long) == 4) {
   848                 if (sizeof(long) == 4) {
   844 		    typeSymbol = @symbol(uint32);
   849                     typeSymbol = @symbol(uint32);
   845 		} else if (sizeof(long) == 8) {
   850                 } else if (sizeof(long) == 8) {
   846 		    typeSymbol = @symbol(uint64);
   851                     typeSymbol = @symbol(uint64);
   847 		}
   852                 }
   848 	    }
   853             }
   849 	}
   854         }
   850 
   855 
   851 	if (typeSymbol == @symbol(int)) {
   856         if (typeSymbol == @symbol(int)) {
   852 	    thisType = __get_ffi_type_sint();
   857             thisType = __get_ffi_type_sint();
   853 	    if (__isSmallInteger(arg)) {
   858             if (__isSmallInteger(arg)) {
   854 		__argValues[i].iVal = __intVal(arg);
   859                 __argValues[i].iVal = __intVal(arg);
   855 	    } else {
   860             } else {
   856 		__argValues[i].iVal = __signedLongIntVal(arg);
   861                 __argValues[i].iVal = __signedLongIntVal(arg);
   857 		if (__argValues[i].iVal == 0) {
   862                 if (__argValues[i].iVal == 0) {
   858 		    failureCode = @symbol(InvalidArgument);
   863                     failureCode = @symbol(InvalidArgument);
   859 		    goto getOutOfHere;
   864                     goto getOutOfHere;
   860 		}
   865                 }
   861 	    }
   866             }
   862 	    argValuePtr = &(__argValues[i].iVal);
   867             argValuePtr = &(__argValues[i].iVal);
   863 
   868 
   864 	} else if (typeSymbol == @symbol(uint)) {
   869         } else if (typeSymbol == @symbol(uint)) {
   865 	    thisType = __get_ffi_type_uint();
   870             thisType = __get_ffi_type_uint();
   866 
   871 
   867 	    if (__isSmallInteger(arg)) {
   872             if (__isSmallInteger(arg)) {
   868 		__argValues[i].iVal = __intVal(arg);
   873                 __argValues[i].iVal = __intVal(arg);
   869 	    } else {
   874             } else {
   870 		__argValues[i].iVal = __unsignedLongIntVal(arg);
   875                 __argValues[i].iVal = __unsignedLongIntVal(arg);
   871 		if (__argValues[i].iVal == 0) {
   876                 if (__argValues[i].iVal == 0) {
   872 		    failureCode = @symbol(InvalidArgument);
   877                     failureCode = @symbol(InvalidArgument);
   873 		    goto getOutOfHere;
   878                     goto getOutOfHere;
   874 		}
   879                 }
   875 	    }
   880             }
   876 	    argValuePtr = &(__argValues[i].iVal);
   881             argValuePtr = &(__argValues[i].iVal);
   877 
   882 
   878 	} else if (typeSymbol == @symbol(uint8)) {
   883         } else if (typeSymbol == @symbol(uint8)) {
   879 	    thisType = __get_ffi_type_uint8();
   884             thisType = __get_ffi_type_uint8();
   880 	    if (! __isSmallInteger(arg)) {
   885             if (! __isSmallInteger(arg)) {
   881 		failureCode = @symbol(InvalidArgument);
   886                 failureCode = @symbol(InvalidArgument);
   882 		goto getOutOfHere;
   887                 goto getOutOfHere;
   883 	    }
   888             }
   884 	    __argValues[i].iVal = __intVal(arg);
   889             __argValues[i].iVal = __intVal(arg);
   885 	    if (((unsigned)(__argValues[i].iVal)) > 0xFF) {
   890             if (((unsigned)(__argValues[i].iVal)) > 0xFF) {
   886 		failureCode = @symbol(InvalidArgument);
   891                 failureCode = @symbol(InvalidArgument);
   887 		goto getOutOfHere;
   892                 goto getOutOfHere;
   888 	    }
   893             }
   889 	    argValuePtr = &(__argValues[i].iVal);
   894             argValuePtr = &(__argValues[i].iVal);
   890 
   895 
   891 	} else if (typeSymbol == @symbol(sint8)) {
   896         } else if (typeSymbol == @symbol(sint8)) {
   892 	    thisType = __get_ffi_type_sint8();
   897             thisType = __get_ffi_type_sint8();
   893 	    if (! __isSmallInteger(arg)) {
   898             if (! __isSmallInteger(arg)) {
   894 		failureCode = @symbol(InvalidArgument);
   899                 failureCode = @symbol(InvalidArgument);
   895 		goto getOutOfHere;
   900                 goto getOutOfHere;
   896 	    }
   901             }
   897 	    __argValues[i].iVal = __intVal(arg);
   902             __argValues[i].iVal = __intVal(arg);
   898 	    if (((__argValues[i].iVal) < -0x80) || ((__argValues[i].iVal) > 0x7F))  {
   903             if (((__argValues[i].iVal) < -0x80) || ((__argValues[i].iVal) > 0x7F))  {
   899 		failureCode = @symbol(InvalidArgument);
   904                 failureCode = @symbol(InvalidArgument);
   900 		goto getOutOfHere;
   905                 goto getOutOfHere;
   901 	    }
   906             }
   902 	    argValuePtr = &(__argValues[i].iVal);
   907             argValuePtr = &(__argValues[i].iVal);
   903 
   908 
   904 	} else if (typeSymbol == @symbol(uint16)) {
   909         } else if (typeSymbol == @symbol(uint16)) {
   905 	    thisType = __get_ffi_type_uint16();
   910             thisType = __get_ffi_type_uint16();
   906 	    if (! __isSmallInteger(arg)) {
   911             if (! __isSmallInteger(arg)) {
   907 		failureCode = @symbol(InvalidArgument);
   912                 failureCode = @symbol(InvalidArgument);
   908 		goto getOutOfHere;
   913                 goto getOutOfHere;
   909 	    }
   914             }
   910 	    __argValues[i].iVal = __intVal(arg);
   915             __argValues[i].iVal = __intVal(arg);
   911 	    if (((unsigned)(__argValues[i].iVal)) > 0xFFFF) {
   916             if (((unsigned)(__argValues[i].iVal)) > 0xFFFF) {
   912 		failureCode = @symbol(InvalidArgument);
   917                 failureCode = @symbol(InvalidArgument);
   913 		goto getOutOfHere;
   918                 goto getOutOfHere;
   914 	    }
   919             }
   915 	    argValuePtr = &(__argValues[i].iVal);
   920             argValuePtr = &(__argValues[i].iVal);
   916 
   921 
   917 	} else if (typeSymbol == @symbol(sint16)) {
   922         } else if (typeSymbol == @symbol(sint16)) {
   918 	    thisType = __get_ffi_type_sint16();
   923             thisType = __get_ffi_type_sint16();
   919 	    if (! __isSmallInteger(arg)) {
   924             if (! __isSmallInteger(arg)) {
   920 		failureCode = @symbol(InvalidArgument);
   925                 failureCode = @symbol(InvalidArgument);
   921 		goto getOutOfHere;
   926                 goto getOutOfHere;
   922 	    }
   927             }
   923 	    __argValues[i].iVal = __intVal(arg);
   928             __argValues[i].iVal = __intVal(arg);
   924 	    if (((__argValues[i].iVal) < -0x8000) || ((__argValues[i].iVal) > 0x7FFF))  {
   929             if (((__argValues[i].iVal) < -0x8000) || ((__argValues[i].iVal) > 0x7FFF))  {
   925 		failureCode = @symbol(InvalidArgument);
   930                 failureCode = @symbol(InvalidArgument);
   926 		goto getOutOfHere;
   931                 goto getOutOfHere;
   927 	    }
   932             }
   928 	    argValuePtr = &(__argValues[i].iVal);
   933             argValuePtr = &(__argValues[i].iVal);
   929 
   934 
   930 	} else if ((typeSymbol == @symbol(uint32)) || (typeSymbol == @symbol(sint32))) {
   935         } else if ((typeSymbol == @symbol(uint32)) || (typeSymbol == @symbol(sint32))) {
   931 	    thisType = __get_ffi_type_uint32();
   936             thisType = __get_ffi_type_uint32();
   932 	    if (__isSmallInteger(arg)) {
   937             if (__isSmallInteger(arg)) {
   933 		__argValues[i].iVal = __intVal(arg);
   938                 __argValues[i].iVal = __intVal(arg);
   934 	    } else {
   939             } else {
   935 		__argValues[i].iVal = __unsignedLongIntVal(arg);
   940                 __argValues[i].iVal = __unsignedLongIntVal(arg);
   936 		if (__argValues[i].iVal == 0) {
   941                 if (__argValues[i].iVal == 0) {
   937 		    failureCode = @symbol(InvalidArgument);
   942                     failureCode = @symbol(InvalidArgument);
   938 		    goto getOutOfHere;
   943                     goto getOutOfHere;
   939 		}
   944                 }
   940 	    }
   945             }
   941 	    argValuePtr = &(__argValues[i].iVal);
   946             argValuePtr = &(__argValues[i].iVal);
   942 
   947 
   943 	} else if (typeSymbol == @symbol(float)) {
   948         } else if (typeSymbol == @symbol(float)) {
   944 	    thisType = __get_ffi_type_float();
   949             thisType = __get_ffi_type_float();
   945 	    if (__isSmallInteger(arg)) {
   950             if (__isSmallInteger(arg)) {
   946 		__argValues[i].fVal = (float)(__intVal(arg));
   951                 __argValues[i].fVal = (float)(__intVal(arg));
   947 	    } else if (__isFloat(arg)) {
   952             } else if (__isFloat(arg)) {
   948 		__argValues[i].fVal = (float)(__floatVal(arg));
   953                 __argValues[i].fVal = (float)(__floatVal(arg));
   949 	    } else if (__isShortFloat(arg)) {
   954             } else if (__isShortFloat(arg)) {
   950 		__argValues[i].fVal = (float)(__shortFloatVal(arg));
   955                 __argValues[i].fVal = (float)(__shortFloatVal(arg));
   951 	    } else {
   956             } else {
   952 		failureCode = @symbol(InvalidArgument);
   957                 failureCode = @symbol(InvalidArgument);
   953 		goto getOutOfHere;
   958                 goto getOutOfHere;
   954 	    }
   959             }
   955 	    argValuePtr = &(__argValues[i].fVal);
   960             argValuePtr = &(__argValues[i].fVal);
   956 
   961 
   957 	} else if (typeSymbol == @symbol(double)) {
   962         } else if (typeSymbol == @symbol(double)) {
   958 	    thisType = __get_ffi_type_double();
   963             thisType = __get_ffi_type_double();
   959 	    if (__isSmallInteger(arg)) {
   964             if (__isSmallInteger(arg)) {
   960 		__argValues[i].dVal = (double)(__intVal(arg));
   965                 __argValues[i].dVal = (double)(__intVal(arg));
   961 	    } else if (__isFloat(arg)) {
   966             } else if (__isFloat(arg)) {
   962 		__argValues[i].dVal = (double)(__floatVal(arg));
   967                 __argValues[i].dVal = (double)(__floatVal(arg));
   963 	    } else if (__isShortFloat(arg)) {
   968             } else if (__isShortFloat(arg)) {
   964 		__argValues[i].dVal = (double)(__shortFloatVal(arg));
   969                 __argValues[i].dVal = (double)(__shortFloatVal(arg));
   965 	    } else {
   970             } else {
   966 		failureCode = @symbol(InvalidArgument);
   971                 failureCode = @symbol(InvalidArgument);
   967 		goto getOutOfHere;
   972                 goto getOutOfHere;
   968 	    }
   973             }
   969 	    argValuePtr = &(__argValues[i].dVal);
   974             argValuePtr = &(__argValues[i].dVal);
   970 
   975 
   971 	} else if (typeSymbol == @symbol(void)) {
   976         } else if (typeSymbol == @symbol(void)) {
   972 	    thisType = __get_ffi_type_void();
   977             thisType = __get_ffi_type_void();
   973 	    argValuePtr = &null;
   978             argValuePtr = &null;
   974 
   979 
   975 	} else if (typeSymbol == @symbol(charPointer)) {
   980         } else if (typeSymbol == @symbol(charPointer)) {
   976 	    thisType = __get_ffi_type_pointer();
   981             thisType = __get_ffi_type_pointer();
   977 	    if (__isString(arg) || __isSymbol(arg)) {
   982             if (__isString(arg) || __isSymbol(arg)) {
   978 		if (async == true) goto badArgForAsyncCall;
   983                 if (async == true) goto badArgForAsyncCall;
   979 		__argValues[i].pointerVal = (void *)(__stringVal(arg));
   984                 __argValues[i].pointerVal = (void *)(__stringVal(arg));
   980 	    } else {
   985             } else {
   981 		if (__isBytes(arg)) {
   986                 if (__isBytes(arg)) {
   982 		    if (async == true) goto badArgForAsyncCall;
   987                     if (async == true) goto badArgForAsyncCall;
   983 		    __argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
   988                     __argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
   984 		} else {
   989                 } else {
   985 		    if (arg == nil) {
   990                     if (arg == nil) {
   986 			__argValues[i].pointerVal = (void *)0;
   991                         __argValues[i].pointerVal = (void *)0;
   987 		    } else {
   992                     } else {
   988 			failureCode = @symbol(InvalidArgument);
   993                         failureCode = @symbol(InvalidArgument);
   989 			goto getOutOfHere;
   994                         goto getOutOfHere;
   990 		    }
   995                     }
   991 		}
   996                 }
   992 	    }
   997             }
   993 	    argValuePtr = &(__argValues[i].pointerVal);;
   998             argValuePtr = &(__argValues[i].pointerVal);;
   994 
   999 
   995 	} else if (typeSymbol == @symbol(pointer)) {
  1000         } else if (typeSymbol == @symbol(pointer)) {
   996 commonPointerTypeArg: ;
  1001 commonPointerTypeArg: ;
   997 	    thisType = __get_ffi_type_pointer();
  1002             thisType = __get_ffi_type_pointer();
   998 	    if (arg == nil) {
  1003             if (arg == nil) {
   999 		__argValues[i].pointerVal = NULL;
  1004                 __argValues[i].pointerVal = NULL;
  1000 	    } else if (__isExternalAddressLike(arg)) {
  1005             } else if (__isExternalAddressLike(arg)) {
  1001 		__argValues[i].pointerVal = (void *)(__externalAddressVal(arg));
  1006                 __argValues[i].pointerVal = (void *)(__externalAddressVal(arg));
  1002 	    } else if (__isExternalBytesLike(arg)) {
  1007             } else if (__isExternalBytesLike(arg)) {
  1003 		__argValues[i].pointerVal = (void *)(__externalBytesVal(arg));
  1008                 __argValues[i].pointerVal = (void *)(__externalBytesVal(arg));
  1004 	    } else if (__isByteArray(arg)) {
  1009             } else if (__isByteArray(arg)) {
  1005 		if (async == true) goto badArgForAsyncCall;
  1010                 if (async == true) goto badArgForAsyncCall;
  1006 		__argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
  1011                 __argValues[i].pointerVal = (void *)(__byteArrayVal(arg));
  1007 	    } else if (__isFloatArray(arg)) {
  1012             } else if (__isFloatArray(arg)) {
  1008 		if (async == true) goto badArgForAsyncCall;
  1013                 if (async == true) goto badArgForAsyncCall;
  1009 		__argValues[i].pointerVal = (void *)(__FloatArrayInstPtr(arg)->f_element);
  1014                 __argValues[i].pointerVal = (void *)(__FloatArrayInstPtr(arg)->f_element);
  1010 	    } else if (__isDoubleArray(arg)) {
  1015             } else if (__isDoubleArray(arg)) {
  1011 		if (async == true) goto badArgForAsyncCall;
  1016                 if (async == true) goto badArgForAsyncCall;
  1012 		__argValues[i].pointerVal = (void *)(__DoubleArrayInstPtr(arg)->d_element);
  1017                 __argValues[i].pointerVal = (void *)(__DoubleArrayInstPtr(arg)->d_element);
  1013 	    } else if (__isString(arg) || __isSymbol(arg)) {
  1018             } else if (__isString(arg) || __isSymbol(arg)) {
  1014 		if (async == true) {
  1019                 if (async == true) {
  1015 badArgForAsyncCall: ;
  1020 badArgForAsyncCall: ;
  1016 		    failureCode = @symbol(BadArgForAsyncCall);
  1021                     failureCode = @symbol(BadArgForAsyncCall);
  1017 		    goto getOutOfHere;
  1022                     goto getOutOfHere;
  1018 		}
  1023                 }
  1019 		__argValues[i].pointerVal = (void *)(__stringVal(arg));
  1024                 __argValues[i].pointerVal = (void *)(__stringVal(arg));
  1020 	    } else if (__isBytes(arg)) {
  1025             } else if (__isBytes(arg)) {
  1021 		char *p = (char *)(__byteArrayVal(arg));
  1026                 char *p = (char *)(__byteArrayVal(arg));
  1022 		int nInstBytes;
  1027                 int nInstBytes;
  1023 		OBJ cls;
  1028                 OBJ cls;
  1024 
  1029 
  1025 		cls = __qClass(arg);
  1030                 cls = __qClass(arg);
  1026 		nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1031                 nInstBytes = __OBJS2BYTES__(__intVal(__ClassInstPtr(cls)->c_ninstvars));
  1027 		__argValues[i].pointerVal = p + nInstBytes;
  1032                 __argValues[i].pointerVal = p + nInstBytes;
  1028 	    } else {
  1033             } else {
  1029 		failureCode = @symbol(InvalidArgument);
  1034                 failureCode = @symbol(InvalidArgument);
  1030 		goto getOutOfHere;
  1035                 goto getOutOfHere;
  1031 	    }
  1036             }
  1032 	    argValuePtr = &(__argValues[i].pointerVal);;
  1037             argValuePtr = &(__argValues[i].pointerVal);;
  1033 
  1038 
  1034 	} else if (typeSymbol == @symbol(bool)) {
  1039         } else if (typeSymbol == @symbol(bool)) {
  1035 	    thisType = __get_ffi_type_uint();
  1040             thisType = __get_ffi_type_uint();
  1036 
  1041 
  1037 	    if (arg == true) {
  1042             if (arg == true) {
  1038 		__argValues[i].iVal = 1;
  1043                 __argValues[i].iVal = 1;
  1039 	    } else if (arg == false) {
  1044             } else if (arg == false) {
  1040 		__argValues[i].iVal = 0;
  1045                 __argValues[i].iVal = 0;
  1041 	    } else if (__isSmallInteger(arg)) {
  1046             } else if (__isSmallInteger(arg)) {
  1042 		__argValues[i].iVal = __intVal(arg);
  1047                 __argValues[i].iVal = __intVal(arg);
  1043 	    } else {
  1048             } else {
  1044 		__argValues[i].iVal = __unsignedLongIntVal(arg);
  1049                 __argValues[i].iVal = __unsignedLongIntVal(arg);
  1045 		if (__argValues[i].iVal == 0) {
  1050                 if (__argValues[i].iVal == 0) {
  1046 		    failureCode = @symbol(InvalidArgument);
  1051                     failureCode = @symbol(InvalidArgument);
  1047 		    goto getOutOfHere;
  1052                     goto getOutOfHere;
  1048 		}
  1053                 }
  1049 	    }
  1054             }
  1050 	    argValuePtr = &(__argValues[i].iVal);
  1055             argValuePtr = &(__argValues[i].iVal);
  1051 	} else {
  1056         } else {
  1052 	    if (__isSymbol(typeSymbol)
  1057             if (__isSymbol(typeSymbol)
  1053 	     && ((argValueClass = __GLOBAL_GET(typeSymbol)) != nil)) {
  1058              && ((argValueClass = __GLOBAL_GET(typeSymbol)) != nil)) {
  1054 		if (! __isBehaviorLike(argValueClass)) {
  1059                 if (! __isBehaviorLike(argValueClass)) {
  1055 		    failureCode = @symbol(NonBehaviorArgumentType);
  1060                     failureCode = @symbol(NonBehaviorArgumentType);
  1056 		    goto getOutOfHere;
  1061                     goto getOutOfHere;
  1057 		}
  1062                 }
  1058 		if (! __qIsSubclassOfExternalAddress(argValueClass)) {
  1063                 if (! __qIsSubclassOfExternalAddress(argValueClass)) {
  1059 		    failureCode = @symbol(NonExternalAddressArgumentType);
  1064                     failureCode = @symbol(NonExternalAddressArgumentType);
  1060 		    goto getOutOfHere;
  1065                     goto getOutOfHere;
  1061 		}
  1066                 }
  1062 		goto commonPointerTypeArg; /* sorry */
  1067                 goto commonPointerTypeArg; /* sorry */
  1063 	    } else {
  1068             } else {
  1064 		failureCode = @symbol(UnknownArgumentType);
  1069                 failureCode = @symbol(UnknownArgumentType);
  1065 		goto getOutOfHere;
  1070                 goto getOutOfHere;
  1066 	    }
  1071             }
  1067 	}
  1072         }
  1068 
  1073 
  1069 	__argTypes[i] = thisType;
  1074         __argTypes[i] = thisType;
  1070 	__argValuePointers[i] = argValuePtr;
  1075         __argValuePointers[i] = argValuePtr;
  1071 
  1076 
  1072 #ifdef VERBOSE
  1077 #ifdef VERBOSE
  1073 	printf("arg%d: %x\n", i, __argValues[i].iVal);
  1078         printf("arg%d: %x\n", i, __argValues[i].iVal);
  1074 #endif
  1079 #endif
  1075     }
  1080     }
  1076     failureInfo = nil;
  1081     failureInfo = nil;
  1077 
  1082 
  1078     __callType = FFI_DEFAULT_ABI;
  1083     __callType = FFI_DEFAULT_ABI;
  1079 
  1084 
  1080 #ifdef CALLTYPE_FFI_STDCALL
  1085 #ifdef CALLTYPE_FFI_STDCALL
  1081     if (callTypeNumber == @global(CALLTYPE_API)) {
  1086     if (callTypeNumber == @global(CALLTYPE_API)) {
  1082 	__callType = CALLTYPE_FFI_STDCALL;
  1087         __callType = CALLTYPE_FFI_STDCALL;
  1083     }
  1088     }
  1084 #endif
  1089 #endif
  1085 #ifdef CALLTYPE_FFI_V8
  1090 #ifdef CALLTYPE_FFI_V8
  1086     if (callTypeNumber == @global(CALLTYPE_V8)) {
  1091     if (callTypeNumber == @global(CALLTYPE_V8)) {
  1087 	__callType = CALLTYPE_FFI_V8;
  1092         __callType = CALLTYPE_FFI_V8;
  1088     }
  1093     }
  1089 #endif
  1094 #endif
  1090 #ifdef CALLTYPE_FFI_V9
  1095 #ifdef CALLTYPE_FFI_V9
  1091     if (callTypeNumber == @global(CALLTYPE_V9)) {
  1096     if (callTypeNumber == @global(CALLTYPE_V9)) {
  1092 	__callType = CALLTYPE_FFI_V9;
  1097         __callType = CALLTYPE_FFI_V9;
  1093     }
  1098     }
  1094 #endif
  1099 #endif
  1095 #ifdef CALLTYPE_FFI_UNIX64
  1100 #ifdef CALLTYPE_FFI_UNIX64
  1096     if (callTypeNumber == @global(CALLTYPE_UNIX64)) {
  1101     if (callTypeNumber == @global(CALLTYPE_UNIX64)) {
  1097 	__callType = CALLTYPE_FFI_UNIX64;
  1102         __callType = CALLTYPE_FFI_UNIX64;
  1098     }
  1103     }
  1099 #endif
  1104 #endif
  1100 
  1105 
  1101     if (ffi_prep_cif(&__cif, __callType, __numArgsIncludingThis, __returnType, __argTypesIncludingThis) != FFI_OK) {
  1106     if (ffi_prep_cif(&__cif, __callType, __numArgsIncludingThis, __returnType, __argTypesIncludingThis) != FFI_OK) {
  1102 	failureCode = @symbol(FFIPrepareFailed);
  1107         failureCode = @symbol(FFIPrepareFailed);
  1103 	goto getOutOfHere;
  1108         goto getOutOfHere;
  1104     }
  1109     }
  1105     if (async == true) {
  1110     if (async == true) {
  1106 #ifdef VERBOSE
  1111 #ifdef VERBOSE
  1107 	printf("async call 0x%x\n", codeAddress);
  1112         printf("async call 0x%x\n", codeAddress);
  1108 #endif
  1113 #endif
  1109 #ifdef WIN32
  1114 #ifdef WIN32
  1110 	__STX_C_CALL4( "ffi_call", ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1115         __STX_C_CALL4( "ffi_call", ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1111 #else
  1116 #else
  1112 	__BEGIN_INTERRUPTABLE__
  1117         __BEGIN_INTERRUPTABLE__
  1113 	ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1118         ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1114 	__END_INTERRUPTABLE__
  1119         __END_INTERRUPTABLE__
  1115 #endif
  1120 #endif
  1116     } else {
  1121     } else {
  1117 	if (unlimitedStack == true) {
  1122         if (unlimitedStack == true) {
  1118 #ifdef VERBOSE
  1123 #ifdef VERBOSE
  1119 	    printf("UNLIMITEDSTACKCALL call 0x%x\n", codeAddress);
  1124             printf("UNLIMITEDSTACKCALL call 0x%x\n", codeAddress);
  1120 #endif
  1125 #endif
  1121 #if 0
  1126 #if 0
  1122 	    __UNLIMITEDSTACKCALL__(ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1127             __UNLIMITEDSTACKCALL__(ffi_call, &__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1123 #endif
  1128 #endif
  1124 	} else {
  1129         } else {
  1125 #ifdef VERBOSE
  1130 #ifdef VERBOSE
  1126 	    printf("call 0x%x\n", codeAddress);
  1131             printf("call 0x%x\n", codeAddress);
  1127 #endif
  1132 #endif
  1128 	    ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1133             ffi_call(&__cif, codeAddress, __returnValuePointer, __argValuePointersIncludingThis);
  1129 	}
  1134         }
  1130     }
  1135     }
  1131 #ifdef VERBOSE
  1136 #ifdef VERBOSE
  1132     printf("retval is %d (0x%x)\n", __returnValue.iVal, __returnValue.iVal);
  1137     printf("retval is %d (0x%x)\n", __returnValue.iVal, __returnValue.iVal);
  1133 #endif
  1138 #endif
  1134     if ((returnTypeSymbol == @symbol(sint))
  1139     if ((returnTypeSymbol == @symbol(sint))
  1135      || (returnTypeSymbol == @symbol(sint8))
  1140      || (returnTypeSymbol == @symbol(sint8))
  1136      || (returnTypeSymbol == @symbol(sint16))
  1141      || (returnTypeSymbol == @symbol(sint16))
  1137      || (returnTypeSymbol == @symbol(sint32))) {
  1142      || (returnTypeSymbol == @symbol(sint32))) {
  1138 	RETURN ( __MKINT(__returnValue.iVal) );
  1143         RETURN ( __MKINT(__returnValue.iVal) );
  1139     }
  1144     }
  1140     if ((returnTypeSymbol == @symbol(uint))
  1145     if ((returnTypeSymbol == @symbol(uint))
  1141      || (returnTypeSymbol == @symbol(uint8))
  1146      || (returnTypeSymbol == @symbol(uint8))
  1142      || (returnTypeSymbol == @symbol(uint16))
  1147      || (returnTypeSymbol == @symbol(uint16))
  1143      || (returnTypeSymbol == @symbol(uint32))) {
  1148      || (returnTypeSymbol == @symbol(uint32))) {
  1144 	RETURN ( __MKUINT(__returnValue.iVal) );
  1149         RETURN ( __MKUINT(__returnValue.iVal) );
  1145     }
  1150     }
  1146     if (returnTypeSymbol == @symbol(bool)) {
  1151     if (returnTypeSymbol == @symbol(bool)) {
  1147 	RETURN ( __returnValue.iVal ? true : false );
  1152         RETURN ( __returnValue.iVal ? true : false );
  1148     }
  1153     }
  1149     if (returnTypeSymbol == @symbol(float)) {
  1154     if (returnTypeSymbol == @symbol(float)) {
  1150 	RETURN ( __MKFLOAT(__returnValue.fVal ));
  1155         RETURN ( __MKFLOAT(__returnValue.fVal ));
  1151     }
  1156     }
  1152     if (returnTypeSymbol == @symbol(double)) {
  1157     if (returnTypeSymbol == @symbol(double)) {
  1153 	RETURN ( __MKFLOAT(__returnValue.dVal ));
  1158         RETURN ( __MKFLOAT(__returnValue.dVal ));
  1154     }
  1159     }
  1155     if (returnTypeSymbol == @symbol(void)) {
  1160     if (returnTypeSymbol == @symbol(void)) {
  1156 	RETURN ( nil );
  1161         RETURN ( nil );
  1157     }
  1162     }
  1158     if (returnTypeSymbol == @symbol(char)) {
  1163     if (returnTypeSymbol == @symbol(char)) {
  1159 	RETURN ( __MKCHARACTER(__returnValue.iVal & 0xFF) );
  1164         RETURN ( __MKCHARACTER(__returnValue.iVal & 0xFF) );
  1160     }
  1165     }
  1161     if (returnTypeSymbol == @symbol(wchar)) {
  1166     if (returnTypeSymbol == @symbol(wchar)) {
  1162 	RETURN ( __MKUCHARACTER(__returnValue.iVal & 0xFFFF) );
  1167         RETURN ( __MKUCHARACTER(__returnValue.iVal & 0xFFFF) );
  1163     }
  1168     }
  1164     if (returnTypeSymbol == @symbol(handle)) {
  1169     if (returnTypeSymbol == @symbol(handle)) {
  1165 	returnValue = __MKEXTERNALADDRESS(__returnValue.pointerVal);
  1170         returnValue = __MKEXTERNALADDRESS(__returnValue.pointerVal);
  1166     } else if (returnTypeSymbol == @symbol(pointer)) {
  1171     } else if (returnTypeSymbol == @symbol(pointer)) {
  1167 	returnValue = __MKEXTERNALBYTES(__returnValue.pointerVal);
  1172         returnValue = __MKEXTERNALBYTES(__returnValue.pointerVal);
  1168     } else if (returnTypeSymbol == @symbol(charPointer)) {
  1173     } else if (returnTypeSymbol == @symbol(charPointer)) {
  1169 	returnValue = __MKSTRING(__returnValue.pointerVal);
  1174         returnValue = __MKSTRING(__returnValue.pointerVal);
  1170     } else if (returnTypeSymbol == @symbol(wcharPointer)) {
  1175     } else if (returnTypeSymbol == @symbol(wcharPointer)) {
  1171 	returnValue = __MKU16STRING(__returnValue.pointerVal);
  1176         returnValue = __MKU16STRING(__returnValue.pointerVal);
  1172     } else {
  1177     } else {
  1173 	failureCode = @symbol(UnknownReturnType2);
  1178         failureCode = @symbol(UnknownReturnType2);
  1174     }
  1179     }
  1175 getOutOfHere: ;
  1180 getOutOfHere: ;
  1176 
  1181 
  1177 #else /* no FFI support */
  1182 #else /* no FFI support */
  1178     failureCode = @symbol(FFINotSupported);
  1183     failureCode = @symbol(FFINotSupported);
  1179 #endif /* HAVE_FFI */
  1184 #endif /* HAVE_FFI */
  1180 %}.
  1185 %}.
  1181     failureCode notNil ifTrue:[
  1186     failureCode notNil ifTrue:[
  1182 	self primitiveFailed.
  1187         self primitiveFailed.
  1183 	^ nil
  1188         ^ nil
  1184     ].
  1189     ].
  1185 
  1190 
  1186     returnType isSymbol ifTrue:[
  1191     returnType isSymbol ifTrue:[
  1187 	returnValueClass notNil ifTrue:[
  1192         returnValueClass notNil ifTrue:[
  1188 	    self isConstReturnValue ifTrue:[
  1193             self isConstReturnValue ifTrue:[
  1189 		returnValue changeClassTo:returnValueClass.
  1194                 returnValue changeClassTo:returnValueClass.
  1190 		^ returnValue
  1195                 ^ returnValue
  1191 	    ].
  1196             ].
  1192 	    ^ returnValueClass fromExternalAddress:returnValue.
  1197             ^ returnValueClass fromExternalAddress:returnValue.
  1193 	].
  1198         ].
  1194     ] ifFalse:[
  1199     ] ifFalse:[
  1195 	returnType isCPointer ifTrue:[
  1200         returnType isCPointer ifTrue:[
  1196 	    returnType baseType isCStruct ifTrue:[
  1201             returnType baseType isCStruct ifTrue:[
  1197 		stClass := Smalltalk classNamed:returnType baseType name.
  1202                 stClass := Smalltalk classNamed:returnType baseType name.
  1198 		stClass notNil ifTrue:[
  1203                 stClass notNil ifTrue:[
  1199 		    self isConstReturnValue ifTrue:[
  1204                     self isConstReturnValue ifTrue:[
  1200 			returnValue changeClassTo:returnValueClass.
  1205                         returnValue changeClassTo:returnValueClass.
  1201 			^ returnValue
  1206                         ^ returnValue
  1202 		    ].
  1207                     ].
  1203 		    ^ stClass fromExternalAddress:returnValue.
  1208                     ^ stClass fromExternalAddress:returnValue.
  1204 		].
  1209                 ].
  1205 	    ].
  1210             ].
  1206 	    returnType baseType isCChar ifTrue:[
  1211             returnType baseType isCChar ifTrue:[
  1207 		^ returnValue stringAt:1
  1212                 ^ returnValue stringAt:1
  1208 	    ].
  1213             ].
  1209 	].
  1214         ].
  1210     ].
  1215     ].
  1211 
  1216 
  1212     ^ returnValue
  1217     ^ returnValue
  1213 
  1218 
  1214     "Created: / 01-08-2006 / 13:56:23 / cg"
  1219     "Created: / 01-08-2006 / 13:56:23 / cg"
  1216 ! !
  1221 ! !
  1217 
  1222 
  1218 !ExternalLibraryFunction class methodsFor:'documentation'!
  1223 !ExternalLibraryFunction class methodsFor:'documentation'!
  1219 
  1224 
  1220 version
  1225 version
  1221     ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.48 2006-12-21 06:29:00 ca Exp $'
  1226     ^ '$Header: /cvs/stx/stx/libbasic/ExternalLibraryFunction.st,v 1.49 2007-03-07 16:19:25 fm Exp $'
  1222 ! !
  1227 ! !
  1223 
  1228 
  1224 ExternalLibraryFunction initialize!
  1229 ExternalLibraryFunction initialize!