SimpleExternalLibraryFunction.st
author Claus Gittinger <cg@exept.de>
Tue, 09 Jul 2019 20:55:17 +0200
changeset 24417 03b083548da2
parent 21623 0fd2de531f9a
permissions -rw-r--r--
#REFACTORING by exept class: Smalltalk class changed: #recursiveInstallAutoloadedClassesFrom:rememberIn:maxLevels:noAutoload:packageTop:showSplashInLevels: Transcript showCR:(... bindWith:...) -> Transcript showCR:... with:...
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     1
"{ Package: 'stx:libbasic' }"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     2
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     3
"{ NameSpace: Smalltalk }"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     4
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     5
ExternalLibraryFunction subclass:#SimpleExternalLibraryFunction
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     6
	instanceVariableNames:''
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     7
	classVariableNames:''
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     8
	poolDictionaries:''
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
     9
	category:'System-Support'
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    10
!
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    11
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    12
!SimpleExternalLibraryFunction class methodsFor:'documentation'!
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    13
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    14
documentation
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    15
"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    16
    instances of me are used for very simple functions, with all integer or
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    17
    equivalent arguments.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    18
    These avoid the realively expensive ffi- arg setup, and jump directly to the
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    19
    target function.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    20
    Can be used for a subset of all external functions and only on some machines.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    21
    Only for tuning; the superclass must provide a fallback for all calls
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    22
"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    23
! !
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    24
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    25
!SimpleExternalLibraryFunction methodsFor:'private invoking'!
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    26
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    27
invokeFFIwithArguments:argumentsOrNil forCPPInstance:aReceiverOrNil
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    28
    "the caller must have already checked, if instances of me are appropriate.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    29
     May only be used for up to 10 args, with INT-sized non-float, non-struct arguments,
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    30
     and int-sized, non-float, non-struct return value.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    31
     Now, all I do is convert the arguments and transfer directly; without the expensive ffi..."
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    32
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    33
    |argTypeSymbols returnTypeSymbol failureCode failureArgNr failureInfo returnValue stClass vtOffset
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    34
     virtual objectiveC async unlimitedStack callTypeNumber returnValueClass argValueClass
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    35
     oldReturnType oldArgumentTypes|
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    36
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    37
    virtual := self isVirtualCPP.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    38
    objectiveC := self isObjectiveC.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    39
    (virtual "or:[self isNonVirtualCPP]") ifTrue:[
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    40
	aReceiverOrNil isNil ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    41
	    "/ must have a c++ object instance
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    42
	    self primitiveFailed.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    43
	].
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    44
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    45
	"/ and it must be a kind of ExternalStructure !!
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    46
	(aReceiverOrNil isExternalStructure) ifFalse:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    47
	    self primitiveFailed.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    48
	].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    49
	virtual ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    50
	    vtOffset := name.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    51
	].
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
    ] ifFalse:[
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    53
	objectiveC ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    54
	    aReceiverOrNil isNil ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    55
		"/ must have an objective-c object instance
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    56
		self primitiveFailed.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    57
	    ].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    58
	    (aReceiverOrNil isObjectiveCObject) ifFalse:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    59
		self primitiveFailed
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    60
	    ]
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    61
	] ifFalse:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    62
	    aReceiverOrNil notNil ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    63
		"/ must NOT have a c++/objectiveC object instance
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    64
		self primitiveFailed.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    65
	    ]
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    66
	].
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    67
    ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    68
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    69
%{  /* STACK: 100000 */
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    70
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    71
#define VERBOSE
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    72
#define MAX_ARGS 10
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    73
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    74
    int __numArgs, __numArgsIncludingThis;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    75
    static INT null = 0;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    76
    INT __args[MAX_ARGS+1];
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    77
    INT retVal;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    78
    int i = -1;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    79
    int argIdx = 0;
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    80
    INTLFUNC codeAddress = (voidFUNC)__INST(code_);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    81
    int __numArgsWanted;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    82
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    83
#   define __FAIL__(fcode) \
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    84
    { \
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    85
	failureCode = fcode; failureArgNr = __mkSmallInteger(i+1); goto getOutOfHere; \
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    86
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    87
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    88
    if (argumentsOrNil == nil) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    89
	__numArgs = 0;
21623
0fd2de531f9a *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 20307
diff changeset
    90
    } else if (__isArrayLike(argumentsOrNil)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    91
	__numArgs = __arraySize(argumentsOrNil);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
    } else {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    93
	__FAIL__(@symbol(BadArgumentVector))
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    94
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    95
    if (__numArgs != __numArgsWanted) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    96
	__FAIL__(@symbol(ArgumentCountMismatch))
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    97
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    98
    if (__numArgs > MAX_ARGS) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
    99
	__FAIL__(@symbol(TooManyArguments))
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   100
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   101
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   102
    /*
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   103
     * validate the c++ object
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   104
     */
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   105
    if (aReceiverOrNil != nil) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   106
	struct cPlusPlusInstance {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   107
	    void **vTable;
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   108
	};
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   109
	struct cPlusPlusInstance *inst;
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   111
	if (__isExternalAddressLike(aReceiverOrNil)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   112
	    inst = (void *)(__externalAddressVal(aReceiverOrNil));
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   113
	} else if (__isExternalBytesLike(aReceiverOrNil)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   114
	    inst = (void *)(__externalBytesVal(aReceiverOrNil));
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   115
	} else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   116
	    __FAIL__(@symbol(InvalidInstance))
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   117
	}
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   118
	__args[0] = (INT)inst;
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   119
	__numArgsIncludingThis = __numArgs + 1;
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   120
	argIdx = 1;
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   122
	if (virtual == true) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   123
	    if (! __isSmallInteger(vtOffset)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   124
		__FAIL__(@symbol(InvalidVTableIndex))
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   125
	    }
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   126
	    codeAddress = inst->vTable[__intVal(vtOffset)];
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
# ifdef VERBOSE
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   128
	    if (@global(Verbose) == true) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   129
		printf("virtual %d codeAddress: %"_lx_"\n", __intVal(vtOffset), (INT)codeAddress);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   130
	    }
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
# endif
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   132
	}
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
    } else {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   134
	__numArgsIncludingThis = __numArgs;
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
# ifdef VERBOSE
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   136
	if (@global(Verbose) == true) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   137
	    printf("codeAddress: %"_lx_"\n", (INT)codeAddress);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   138
	}
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   139
# endif
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   140
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   141
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   142
    /*
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   143
     * validate all arg types, map each to an ffi_type, and setup arg-buffers
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   144
     */
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   145
    for (i=0; i<__numArgs; i++, argIdx++) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   146
	OBJ arg;
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   148
	failureInfo = __mkSmallInteger(i+1);   /* in case there is one */
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   150
	arg = __ArrayInstPtr(argumentsOrNil)->a_element[i];
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   152
	if (__isSmallInteger(arg)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   153
	    __args[argIdx] = __intVal(arg);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   154
	} else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   155
	   INT iv = __signedLongIntVal(arg);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   156
	   if (iv != 0) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   157
		__args[argIdx]  = iv;
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   158
	    } else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   159
		unsigned INT iv = __unsignedLongIntVal(arg);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   160
		if (iv != 0) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   161
		    __args[argIdx] = iv;
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   162
		} else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   163
		    if (__isStringLike(arg)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   164
			__args[argIdx] = (INT)(__stringVal(arg));
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   165
		    } else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   166
			if (__isBytes(arg)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   167
			    __args[argIdx] = (INT)(__byteArrayVal(arg));
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   168
			    if (arg == NULL) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   169
				__args[argIdx] = (INT)0;
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   170
			    } else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   171
				if (__isExternalAddressLike(arg)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   172
				    __args[argIdx] = (INT)(__externalAddressVal(arg));
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   173
				} else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   174
				    if (__isExternalBytesLike(arg)) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   175
					__args[argIdx] = (INT)(__externalBytesVal(arg));
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   176
				    } else {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   177
					__FAIL__(@symbol(InvalidArgument))
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   178
				    }
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   179
				}
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   180
			    }
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   181
			}
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   182
		    }
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   183
		}
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   184
	    }
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   185
	}
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   186
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   187
    failureInfo = nil;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   188
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   189
    retVal = (*codeAddress)(__args[0], __args[1], __args[2], __args[3], __args[4], __args[5], __args[6],
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   190
			    __args[7], __args[8], __args[9], __args[10]);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   191
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   192
# ifdef VERBOSE
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   193
    if (@global(Verbose) == true) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   194
	printf("retval is %"_ld_" (0x%"_lx_")\n", retVal, retVal);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   195
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   196
# endif
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   197
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   198
    if ((returnTypeSymbol == @symbol(int))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   199
     || (returnTypeSymbol == @symbol(sint))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   200
     || (returnTypeSymbol == @symbol(sint8))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   201
     || (returnTypeSymbol == @symbol(sint16))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   202
     || (returnTypeSymbol == @symbol(sint32))) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   203
# ifdef VERBOSE
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   204
	if (@global(Verbose) == true) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   205
	    printf("return int: %x\n", retVal);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   206
	}
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   207
# endif
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   208
	RETURN ( __MKINT(retVal) );
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   209
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   210
    if ((returnTypeSymbol == @symbol(uint))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   211
     || (returnTypeSymbol == @symbol(uint8))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   212
     || (returnTypeSymbol == @symbol(uint16))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   213
     || (returnTypeSymbol == @symbol(uint32))) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   214
# ifdef VERBOSE
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   215
	if (@global(Verbose) == true) {
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   216
	    printf("return uint: %x\n", retVal);
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   217
	}
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   218
# endif
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   219
	RETURN ( __MKUINT(retVal) );
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   220
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   221
    if (returnTypeSymbol == @symbol(bool)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   222
	RETURN ( retVal ? true : false );
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   223
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   224
    if (returnTypeSymbol == @symbol(void)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   225
	RETURN ( nil );
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   226
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   227
    if (returnTypeSymbol == @symbol(char)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   228
	RETURN ( __MKCHARACTER(retVal & 0xFF) );
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   229
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   230
    if (returnTypeSymbol == @symbol(wchar)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   231
	RETURN ( __MKUCHARACTER(retVal & 0xFFFF) );
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   232
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   233
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   234
# ifdef VERBOSE
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   235
    if (@global(Verbose) == true) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   236
	printf("return pointer: %"_lx_"\n", (INT)(retVal));
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   237
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   238
# endif
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   239
    if (returnTypeSymbol == @symbol(handle)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   240
	returnValue = __MKEXTERNALADDRESS(retVal);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   241
    } else if (returnTypeSymbol == @symbol(pointer)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   242
	returnValue = __MKEXTERNALBYTES(retVal);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   243
    } else if (returnTypeSymbol == @symbol(bytePointer)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   244
	returnValue = __MKEXTERNALBYTES(retVal);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   245
    } else if (returnTypeSymbol == @symbol(charPointer)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   246
	returnValue = __MKSTRING(retVal);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   247
    } else if (returnTypeSymbol == @symbol(wcharPointer)) {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   248
	returnValue = __MKU16STRING(retVal);
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   249
    } else {
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   250
	__FAIL__(@symbol(UnknownReturnType2))
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   251
    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   252
getOutOfHere: ;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   253
%}.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   254
    failureCode notNil ifTrue:[
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   255
	(failureCode == #UnknownReturnType or:[ failureCode == #UnknownArgumentType ]) ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   256
	    oldReturnType := returnType.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   257
	    oldArgumentTypes := argumentTypes.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   258
	    self adjustTypes.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   259
	    ((oldReturnType ~= returnType) or:[oldArgumentTypes ~= argumentTypes]) ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   260
		thisContext restart
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   261
	    ].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   262
	].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   263
	(failureCode == #BadArgForAsyncCall) ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   264
	    ^ self tryAgainWithAsyncSafeArguments:argumentsOrNil forCPPInstance:aReceiverOrNil
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   265
	].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   266
	(failureCode == #FFINotSupported) ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   267
	    self primitiveFailed:'FFI support missing in this build'.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   268
	].
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   269
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   270
	self primitiveFailed.   "see failureCode and failureInfo for details"
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   271
	^ nil
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   272
    ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   273
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   274
    returnType isSymbol ifTrue:[
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   275
	returnValueClass notNil ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   276
	    self isConstReturnValue ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   277
		returnValue changeClassTo:returnValueClass.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   278
		^ returnValue
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   279
	    ].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   280
	    ^ returnValueClass fromExternalAddress:returnValue.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   281
	].
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   282
    ] ifFalse:[
20307
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   283
	returnType isCPointer ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   284
	    returnType baseType isCStruct ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   285
		stClass := Smalltalk classNamed:returnType baseType name.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   286
		stClass notNil ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   287
		    self isConstReturnValue ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   288
			returnValue changeClassTo:returnValueClass.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   289
			^ returnValue
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   290
		    ].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   291
		    ^ stClass fromExternalAddress:returnValue.
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   292
		].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   293
	    ].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   294
	    returnType baseType isCChar ifTrue:[
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   295
		^ returnValue stringAt:1
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   296
	    ].
678da26adf03 *** empty log message ***
Claus Gittinger <cg@exept.de>
parents: 19551
diff changeset
   297
	].
19551
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   298
    ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   299
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   300
    ^ returnValue
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   301
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   302
    "Created: / 01-08-2006 / 13:56:23 / cg"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   303
    "Modified: / 31-03-2016 / 00:03:03 / cg"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   304
! !
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   305
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   306
!SimpleExternalLibraryFunction class methodsFor:'documentation'!
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   307
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   308
version
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   309
    ^ '$Header$'
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   310
!
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   311
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   312
version_CVS
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   313
    ^ '$Header$'
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   314
! !