static void dc_callvm_argBool_ppc64(DCCallVM* in_self, DCbool x) { /* promote to longlong */ dcArgLongLong(in_self, (DClonglong) x ); }
int invoke(char const* signature, void* t) { DCCallVM * p = (DCCallVM*) G_callvm; char const * sig = signature; char rtype; char atype; int pos = 0; int s = 0; clear_V(); rtype = *sig++; dcReset(p); while ( (atype = *sig++) != '\0') { pos++; switch(atype) { case 'c': dcArgChar (p,K_c[pos]); break; case 's': dcArgShort (p,K_s[pos]); break; case 'i': dcArgInt (p,K_i[pos]); break; case 'j': dcArgLong (p,K_j[pos]); break; case 'l': dcArgLongLong(p,K_l[pos]); break; case 'p': dcArgPointer (p,K_p[pos]); break; case 'f': dcArgFloat (p,K_f[pos]); break; case 'd': dcArgDouble (p,K_d[pos]); break; default: printf("unknown atype '%c' (1) ;", atype); return 0; } } switch(rtype) { case 'v': dcCallVoid(p,t); s=1; /*TODO:check that no return-arg was touched.*/ break; case 'c': s = (dcCallChar (p,t) == K_c[pos]) ; break; case 's': s = (dcCallShort (p,t) == K_s[pos]) ; break; case 'i': s = (dcCallInt (p,t) == K_i[pos]) ; break; case 'j': s = (dcCallLong (p,t) == K_j[pos]) ; break; case 'l': s = (dcCallLongLong(p,t) == K_l[pos]) ; break; case 'p': s = (dcCallPointer (p,t) == K_p[pos]) ; break; case 'f': s = (dcCallFloat (p,t) == K_f[pos]) ; break; case 'd': s = (dcCallDouble (p,t) == K_d[pos]) ; break; default: printf("unknown rtype '%c'", rtype); return 0; } if (!s) { printf("rval wrong;"); return 0; } /* test: */ sig = signature+1; pos = 1; while ( (atype = *sig++) != '\0') { switch(atype) { #if 0 #define X(CH,T,QCH) case QCH: s = (V_##CH[pos] == K_##CH[pos]); break; DEF_TYPES #undef X #endif case 'c': s = ( V_c[pos] == K_c[pos] ); if (!s) printf("'c':%d: %d != %d ; ", pos, V_c[pos], K_c[pos]); break; case 's': s = ( V_s[pos] == K_s[pos] ); if (!s) printf("'s':%d: %d != %d ; ", pos, V_s[pos], K_s[pos]); break; case 'i': s = ( V_i[pos] == K_i[pos] ); if (!s) printf("'i':%d: %d != %d ; ", pos, V_i[pos], K_i[pos]); break; case 'j': s = ( V_j[pos] == K_j[pos] ); if (!s) printf("'j':%d: %ld != %ld ; ", pos, V_j[pos], K_j[pos]); break; case 'l': s = ( V_l[pos] == K_l[pos] ); if (!s) printf("'l':%d: %lld != %lld ; ", pos, V_l[pos], K_l[pos]); break; case 'p': s = ( V_p[pos] == K_p[pos] ); if (!s) printf("'p':%d: %lld != %lld ; ", pos, (long long) V_p[pos], (long long) K_p[pos]); break; case 'f': s = ( V_f[pos] == K_f[pos] ); if (!s) printf("'f':%d: %f != %f ; ", pos, V_f[pos], K_f[pos]); break; case 'd': s = ( V_d[pos] == K_d[pos] ); if (!s) printf("'d':%d: %f != %f ; ", pos, V_d[pos], K_d[pos]); break; default: printf("unknown atype '%c' ; ", atype); return 0; } if (!s) { printf("arg mismatch at %d ; ", pos); return 0; } pos++; } return 1; }
static PyObject* pydc_call(PyObject* self, PyObject* in_args) { PyObject* pcobj_funcptr; const char* signature; PyObject* args; int l; const char* ptr; char ch; int pos; void* pfunc; if ( !PyArg_ParseTuple(in_args,"OsO", &pcobj_funcptr, &signature, &args) ) return PyErr_Format(PyExc_RuntimeError, "argument mismatch"); pfunc = PyCObject_AsVoidPtr(pcobj_funcptr); if ( !pfunc ) return PyErr_Format( PyExc_RuntimeError, "function pointer is NULL" ); l = PyTuple_Size(args); ptr = signature; pos = 0; dcReset(gpCall); while ( (ch = *ptr) != '\0' && ch != ')' ) { PyObject* po; int index = pos+1; if (pos > l) return PyErr_Format( PyExc_RuntimeError, "expecting more arguments" ); po = PyTuple_GetItem(args,pos); switch(ch) { case DC_SIGCHAR_BOOL: { DCbool b; if ( !PyBool_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a bool", index ); b = (Py_True == po) ? DC_TRUE : DC_FALSE; dcArgBool(gpCall, b); } break; case DC_SIGCHAR_CHAR: { DCchar c; if ( PyString_Check(po) ) { // Py_ssize_t l; size_t l; char* s; l = PyString_GET_SIZE(po); if (l != 1) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string with length of 1 (a char string)", index ); s = PyString_AsString(po); c = (DCchar) s[0]; } else if ( PyInt_Check(po) ) { long l; l = PyInt_AsLong(po); if ( (l > CHAR_MAX) || (l < CHAR_MIN)) return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a char code", index ); c = (DCchar) l; } else return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a char", index ); dcArgChar(gpCall, c); } break; case DC_SIGCHAR_SHORT: { DCshort s; long v; if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a short int", index ); v = PyInt_AS_LONG(po); if ( (v < SHRT_MIN) || (v > SHRT_MAX) ) return PyErr_Format( PyExc_RuntimeError, "value out of range at argument %d - expecting a short value", index ); s = (DCshort) v; dcArgShort(gpCall, s); } break; case DC_SIGCHAR_INT: { long v; if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); v = PyInt_AS_LONG(po); dcArgInt(gpCall, (DCint) v ); } break; case DC_SIGCHAR_LONG: { long v; if ( !PyInt_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting an int", index ); v = PyInt_AsLong(po); } break; case DC_SIGCHAR_LONGLONG: { PY_LONG_LONG pl; DClonglong dl; if ( !PyLong_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a long long", index ); pl = PyLong_AsLongLong(po); dl = (DClonglong) pl; dcArgLongLong(gpCall, dl ); } break; case DC_SIGCHAR_FLOAT: { DCfloat f; if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index ); f = (float) PyFloat_AsDouble(po); dcArgFloat(gpCall, f); } break; case DC_SIGCHAR_DOUBLE: { double d; if (!PyFloat_Check(po)) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expeecting a float", index ); d = PyFloat_AsDouble(po); dcArgDouble(gpCall, d); } break; case DC_SIGCHAR_POINTER: { DCpointer ptr; if ( PyString_Check(po) ) { ptr = (DCpointer) PyString_AsString(po); } else if ( PyLong_Check(po) ) { ptr = (DCpointer) ( (DCint) PyLong_AsLongLong(po) ); } else { return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a promoting pointer-type (int,string)", index ); } dcArgPointer(gpCall, ptr ); } break; case 'S': { char* p; if (!PyString_Check(po) ) return PyErr_Format( PyExc_RuntimeError, "argument mismatch at pos %d - expecting a string", index ); p = PyString_AsString(po); dcArgPointer(gpCall, (DCpointer) p ); } break; default: return PyErr_Format( PyExc_RuntimeError, "unknown signature character '%c'", ch); } ++pos; ++ptr; } if (pos != l) return PyErr_Format( PyExc_RuntimeError, "too many arguments"); if (ch == '\0') return PyErr_Format( PyExc_RuntimeError, "return value missing in signature"); ch = *++ptr; switch(ch) { case DC_SIGCHAR_VOID: dcCallVoid(gpCall, pfunc); Py_RETURN_NONE; case DC_SIGCHAR_BOOL: return Py_BuildValue("i", dcCallBool(gpCall, pfunc) ); case DC_SIGCHAR_INT: return Py_BuildValue("i", dcCallInt(gpCall, pfunc) ); case DC_SIGCHAR_LONGLONG: return Py_BuildValue("L", (unsigned long long) dcCallLongLong(gpCall, pfunc) ); case DC_SIGCHAR_FLOAT: return Py_BuildValue("f", dcCallFloat(gpCall, pfunc) ); case DC_SIGCHAR_DOUBLE: return Py_BuildValue("d", dcCallDouble(gpCall, pfunc) ); case 's': return Py_BuildValue("s", dcCallPointer(gpCall, pfunc) ); case DC_SIGCHAR_POINTER: return Py_BuildValue("p", dcCallPointer(gpCall, pfunc) ); default: return PyErr_Format( PyExc_RuntimeError, "invalid return type signature" ); } }
template<> void _push_fn_arg<long long>(long long value) { dcArgLongLong(vm, value); }
jboolean followArgs(CallTempStruct* call, DCArgs* args, int nTypes, ValueType* pTypes, CallFlags flags) { JNIEnv* env = call->env; int iParam; for (iParam = 0; iParam < nTypes; iParam++) { ValueType type = pTypes[iParam]; switch (type) { case eIntFlagSet: { jobject callIO = call && call->pCallIOs ? *(call->pCallIOs++) : NULL; if (flags & CALLING_JAVA) { int flags = dcbArgInt(args); jobject obj = createPointerFromIO(env, JLONG_TO_PTR ((jlong)flags), callIO); dcArgPointer(call->vm, obj); addTempCallLocalRef(call, obj); } else { jobject obj = (jobject)dcbArgPointer(args); int arg = (jint)getFlagValue(env, obj); (*env)->DeleteLocalRef(env, obj); if (flags & IS_VAR_ARGS) dcArgPointer(call->vm, (void*)(ptrdiff_t)arg); else dcArgInt(call->vm, arg); } } break; case eIntValue: { int arg = dcbArgInt(args); if (flags & IS_VAR_ARGS) dcArgPointer(call->vm, (void*)(ptrdiff_t)arg); else dcArgInt(call->vm, arg); } break; #define ARG_BOXED_INTEGRAL(type, capitalized) \ { \ if (flags & CALLING_JAVA) { \ type arg = (sizeof(type) == 4) ? (type)dcbArgInt(args) : (type)dcbArgLongLong(args); \ jobject boxed = Box ## capitalized(env, arg); \ dcArgPointer(call->vm, boxed); \ addTempCallLocalRef(call, boxed); \ } else { \ jobject parg = dcbArgPointer(args); \ jlong arg = Unbox ## capitalized(env, parg); \ (*env)->DeleteLocalRef(env, parg); \ if (flags & IS_VAR_ARGS) \ dcArgPointer(call->vm, (void*)(ptrdiff_t)arg); \ else if (sizeof(type) == 4) \ dcArgInt(call->vm, (jint)arg); \ else \ dcArgLongLong(call->vm, (jlong)arg); \ } \ } #define ARG_UNBOXED_INTEGRAL(type, capitalized) \ { \ if (flags & CALLING_JAVA) { \ type arg = (sizeof(type) == 4) ? (type)dcbArgInt(args) : (type)dcbArgLongLong(args); \ dcArgLongLong(call->vm, (jlong)arg); \ } else { \ jlong arg = dcbArgLongLong(args); \ if (flags & IS_VAR_ARGS) \ dcArgPointer(call->vm, (void*)(ptrdiff_t)arg); \ else if (sizeof(type) == 4) \ dcArgInt(call->vm, (jint)arg); \ else \ dcArgLongLong(call->vm, (jlong)arg); \ } \ } case eCLongValue: ARG_UNBOXED_INTEGRAL(long, CLong); break; case eSizeTValue: ARG_UNBOXED_INTEGRAL(size_t, SizeT); break; case eCLongObjectValue: ARG_BOXED_INTEGRAL(long, CLong); break; case eSizeTObjectValue: ARG_BOXED_INTEGRAL(size_t, SizeT); break; case eTimeTObjectValue: ARG_BOXED_INTEGRAL(time_t, TimeT); break; case eLongValue: dcArgLongLong(call->vm, dcbArgLongLong(args)); break; case eShortValue: { short arg = dcbArgShort(args); if (flags & IS_VAR_ARGS) dcArgPointer(call->vm, (void*)(ptrdiff_t)arg); else dcArgShort(call->vm, arg); } break; case eBooleanValue: case eByteValue: { char arg = dcbArgChar(args); if (flags & IS_VAR_ARGS) dcArgPointer(call->vm, (void*)(ptrdiff_t)arg); else dcArgChar(call->vm, arg); } break; case eFloatValue: { float arg = dcbArgFloat(args); if (flags & IS_VAR_ARGS) dcArgDouble(call->vm, arg); else dcArgFloat(call->vm, arg); } break; case eDoubleValue: dcArgDouble(call->vm, dcbArgDouble(args)); break; case ePointerValue: { void* ptr = dcbArgPointer(args); jobject callIO = call && call->pCallIOs ? *(call->pCallIOs++) : NULL; if (flags & CALLING_JAVA) { ptr = createPointerFromIO(env, ptr, callIO); addTempCallLocalRef(call, ptr); } else { ptr = ptr ? getPointerPeer(env, ptr) : NULL; } dcArgPointer(call->vm, ptr); } break; case eWCharValue: switch (sizeof(wchar_t)) { case 1: dcArgChar(call->vm, dcbArgChar(args)); break; case 2: dcArgShort(call->vm, dcbArgShort(args)); break; case 4: dcArgInt(call->vm, dcbArgInt(args)); break; default: throwException(env, "Invalid wchar_t size for argument !"); return JNI_FALSE; } break; case eNativeObjectValue: { jobject callIO = call && call->pCallIOs ? *(call->pCallIOs++) : NULL; DCstruct* s = getStructFromIO(env, callIO); void* pStruct = getNativeObjectPointerWithIO(env, dcbArgPointer(args), callIO); if (!s) { throwException(env, "Failed to get low-level struct representation !"); return JNI_FALSE; } if (!pStruct) { throwException(env, "Struct by value cannot be null !"); return JNI_FALSE; } dcArgStruct(call->vm, s, pStruct); break; } case eEllipsis: { if (flags & CALLING_JAVA) { throwException(env, "Calling Java ellipsis is not supported yet !"); return JNI_FALSE; } else { jobjectArray arr = (jobjectArray)dcbArgPointer(args); jsize n = (*env)->GetArrayLength(env, arr), i; for (i = 0; i < n; i++) { jobject arg = (*env)->GetObjectArrayElement(env, arr, i); #define TEST_INSTANCEOF(cl, st) \ if ((*env)->IsInstanceOf(env, arg, cl)) st; if (arg == NULL) dcArgPointer(call->vm, NULL);//getPointerPeer(env, (void*)NULL)); else // As per the C standard for varargs, all ints are promoted to ptrdiff_t and float is promoted to double : TEST_INSTANCEOF(gIntClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)UnboxInt(env, arg))) else TEST_INSTANCEOF(gLongClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)UnboxLong(env, arg))) else TEST_INSTANCEOF(gShortClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)UnboxShort(env, arg))) else TEST_INSTANCEOF(gByteClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)UnboxByte(env, arg))) else TEST_INSTANCEOF(gBooleanClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)(char)UnboxBoolean(env, arg))) else TEST_INSTANCEOF(gCharClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)(short)UnboxChar(env, arg))) else TEST_INSTANCEOF(gDoubleClass, dcArgDouble(call->vm, UnboxDouble(env, arg))) else TEST_INSTANCEOF(gFloatClass, dcArgDouble(call->vm, UnboxFloat(env, arg))) else TEST_INSTANCEOF(gCLongClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)(long)UnboxCLong(env, arg))) else TEST_INSTANCEOF(gSizeTClass, dcArgPointer(call->vm, (void*)(ptrdiff_t)UnboxSizeT(env, arg))) else TEST_INSTANCEOF(gPointerClass, dcArgPointer(call->vm, getPointerPeer(env, (void*)arg))) else { throwException(env, "Invalid value type in ellipsis"); (*env)->DeleteLocalRef(env, arg); (*env)->DeleteLocalRef(env, arr); return JNI_FALSE; } (*env)->DeleteLocalRef(env, arg); } (*env)->DeleteLocalRef(env, arr); } break; } default: throwException(env, "Invalid argument value type !"); return JNI_FALSE; } } if ((*env)->ExceptionCheck(env)) return JNI_FALSE; return JNI_TRUE; }