SimpleExternalLibraryFunction.st
author Claus Gittinger <cg@exept.de>
Wed, 06 Apr 2016 15:08:21 +0200
changeset 19551 1cec0dc778a4
child 20307 678da26adf03
permissions -rw-r--r--
initial checkin
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:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    40
        aReceiverOrNil isNil ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    41
            "/ must have a c++ object instance
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    42
            self primitiveFailed.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    43
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    44
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    45
        "/ and it must be a kind of ExternalStructure !!
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    46
        (aReceiverOrNil isExternalStructure) ifFalse:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    47
            self primitiveFailed.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    48
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    49
        virtual ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    50
            vtOffset := name.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    51
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    52
    ] ifFalse:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    53
        objectiveC ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    54
            aReceiverOrNil isNil ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    55
                "/ must have an objective-c object instance
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    56
                self primitiveFailed.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    57
            ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    58
            (aReceiverOrNil isObjectiveCObject) ifFalse:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    59
                self primitiveFailed
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    60
            ]
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    61
        ] ifFalse:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    62
            aReceiverOrNil notNil ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    63
                "/ must NOT have a c++/objectiveC object instance
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    64
                self primitiveFailed.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    65
            ]
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    66
        ].
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;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    80
    INTFUNC codeAddress = (VOIDFUNC)__INST(code_);
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
    { \
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    85
        failureCode = fcode; failureArgNr = __mkSmallInteger(i+1); goto getOutOfHere; \
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) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    89
        __numArgs = 0;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    90
    } else if (__isArray(argumentsOrNil)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    91
        __numArgs = __arraySize(argumentsOrNil);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    92
    } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    93
        __FAIL__(@symbol(BadArgumentVector))
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) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    96
        __FAIL__(@symbol(ArgumentCountMismatch))
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) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
    99
        __FAIL__(@symbol(TooManyArguments))
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) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   106
        struct cPlusPlusInstance {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   107
            void **vTable;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   108
        };
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   109
        struct cPlusPlusInstance *inst;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   110
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   111
        if (__isExternalAddressLike(aReceiverOrNil)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   112
            inst = (void *)(__externalAddressVal(aReceiverOrNil));
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   113
        } else if (__isExternalBytesLike(aReceiverOrNil)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   114
            inst = (void *)(__externalBytesVal(aReceiverOrNil));
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   115
        } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   116
            __FAIL__(@symbol(InvalidInstance))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   117
        }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   118
        __args[0] = (INT)inst;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   119
        __numArgsIncludingThis = __numArgs + 1;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   120
        argIdx = 1;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   121
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   122
        if (virtual == true) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   123
            if (! __isSmallInteger(vtOffset)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   124
                __FAIL__(@symbol(InvalidVTableIndex))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   125
            }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   126
            codeAddress = inst->vTable[__intVal(vtOffset)];
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   127
# ifdef VERBOSE
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   128
            if (@global(Verbose) == true) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   129
                printf("virtual %d codeAddress: %"_lx_"\n", __intVal(vtOffset), (INT)codeAddress);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   130
            }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   131
# endif
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   132
        }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   133
    } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   134
        __numArgsIncludingThis = __numArgs;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   135
# ifdef VERBOSE
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   136
        if (@global(Verbose) == true) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   137
            printf("codeAddress: %"_lx_"\n", (INT)codeAddress);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   138
        }
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++) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   146
        OBJ arg;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   147
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   148
        failureInfo = __mkSmallInteger(i+1);   /* in case there is one */
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   149
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   150
        arg = __ArrayInstPtr(argumentsOrNil)->a_element[i];
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   151
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   152
        if (__isSmallInteger(arg)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   153
            __args[argIdx] = __intVal(arg);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   154
        } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   155
           INT iv = __signedLongIntVal(arg);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   156
           if (iv != 0) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   157
                __args[argIdx]  = iv;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   158
            } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   159
                unsigned INT iv = __unsignedLongIntVal(arg);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   160
                if (iv != 0) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   161
                    __args[argIdx] = iv;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   162
                } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   163
                    if (__isStringLike(arg)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   164
                        __args[argIdx] = (INT)(__stringVal(arg));
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   165
                    } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   166
                        if (__isBytes(arg)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   167
                            __args[argIdx] = (INT)(__byteArrayVal(arg));
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   168
                            if (arg == NULL) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   169
                                __args[argIdx] = (INT)0;
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   170
                            } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   171
                                if (__isExternalAddressLike(arg)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   172
                                    __args[argIdx] = (INT)(__externalAddressVal(arg));
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   173
                                } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   174
                                    if (__isExternalBytesLike(arg)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   175
                                        __args[argIdx] = (INT)(__externalBytesVal(arg));
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   176
                                    } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   177
                                        __FAIL__(@symbol(InvalidArgument))
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   178
                                    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   179
                                }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   180
                            }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   181
                        }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   182
                    }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   183
                }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   184
            }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   185
        }
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],
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   190
                            __args[7], __args[8], __args[9], __args[10]);
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) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   194
        printf("retval is %"_ld_" (0x%"_lx_")\n", retVal, retVal);
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
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   204
        if (@global(Verbose) == true) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   205
            printf("return int: %x\n", retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   206
        }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   207
# endif
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   208
        RETURN ( __MKINT(retVal) );
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
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   215
        if (@global(Verbose) == true) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   216
            printf("return uint: %x\n", retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   217
        }
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   218
# endif
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   219
        RETURN ( __MKUINT(retVal) );
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)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   222
        RETURN ( retVal ? true : false );
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)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   225
        RETURN ( nil );
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)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   228
        RETURN ( __MKCHARACTER(retVal & 0xFF) );
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)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   231
        RETURN ( __MKUCHARACTER(retVal & 0xFFFF) );
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) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   236
        printf("return pointer: %"_lx_"\n", (INT)(retVal));
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)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   240
        returnValue = __MKEXTERNALADDRESS(retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   241
    } else if (returnTypeSymbol == @symbol(pointer)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   242
        returnValue = __MKEXTERNALBYTES(retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   243
    } else if (returnTypeSymbol == @symbol(bytePointer)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   244
        returnValue = __MKEXTERNALBYTES(retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   245
    } else if (returnTypeSymbol == @symbol(charPointer)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   246
        returnValue = __MKSTRING(retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   247
    } else if (returnTypeSymbol == @symbol(wcharPointer)) {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   248
        returnValue = __MKU16STRING(retVal);
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   249
    } else {
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   250
        __FAIL__(@symbol(UnknownReturnType2))
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:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   255
        (failureCode == #UnknownReturnType or:[ failureCode == #UnknownArgumentType ]) ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   256
            oldReturnType := returnType.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   257
            oldArgumentTypes := argumentTypes.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   258
            self adjustTypes.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   259
            ((oldReturnType ~= returnType) or:[oldArgumentTypes ~= argumentTypes]) ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   260
                thisContext restart
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   261
            ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   262
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   263
        (failureCode == #BadArgForAsyncCall) ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   264
            ^ self tryAgainWithAsyncSafeArguments:argumentsOrNil forCPPInstance:aReceiverOrNil
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   265
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   266
        (failureCode == #FFINotSupported) ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   267
            self primitiveFailed:'FFI support missing in this build'.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   268
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   269
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   270
        self primitiveFailed.   "see failureCode and failureInfo for details"
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   271
        ^ nil
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:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   275
        returnValueClass notNil ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   276
            self isConstReturnValue ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   277
                returnValue changeClassTo:returnValueClass.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   278
                ^ returnValue
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   279
            ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   280
            ^ returnValueClass fromExternalAddress:returnValue.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   281
        ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   282
    ] ifFalse:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   283
        returnType isCPointer ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   284
            returnType baseType isCStruct ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   285
                stClass := Smalltalk classNamed:returnType baseType name.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   286
                stClass notNil ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   287
                    self isConstReturnValue ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   288
                        returnValue changeClassTo:returnValueClass.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   289
                        ^ returnValue
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   290
                    ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   291
                    ^ stClass fromExternalAddress:returnValue.
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   292
                ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   293
            ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   294
            returnType baseType isCChar ifTrue:[
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   295
                ^ returnValue stringAt:1
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   296
            ].
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   297
        ].
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
! !
1cec0dc778a4 initial checkin
Claus Gittinger <cg@exept.de>
parents:
diff changeset
   315