/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <jni.h>
#include <stdarg.h>
#include "java/lang/Object.h"
#include "java/lang/Class.h"
#include "java/lang/String.h"
#include "java/lang/Throwable.h"
#include "java/lang/Boolean.h"
#include "java/lang/Integer.h"
#include "java/lang/Long.h"
#include "java/lang/Double.h"
#include "java/util/Iterator.h"
#include "JArray.h"
#include "functions.h"
#include "macros.h"
using namespace java::lang;
using namespace java::util;
PyObject *PyExc_JavaError = PyExc_ValueError;
PyObject *PyExc_InvalidArgsError = PyExc_ValueError;
PyObject *_set_exception_types(PyObject *self, PyObject *args)
{
if (!PyArg_ParseTuple(args, "OO",
&PyExc_JavaError, &PyExc_InvalidArgsError))
return NULL;
Py_RETURN_NONE;
}
PyObject *_set_function_self(PyObject *self, PyObject *args)
{
PyObject *object, *module;
if (!PyArg_ParseTuple(args, "OO", &object, &module))
return NULL;
if (!PyCFunction_Check(object))
{
PyErr_SetObject(PyExc_TypeError, object);
return NULL;
}
PyCFunctionObject *cfn = (PyCFunctionObject *) object;
Py_INCREF(module);
Py_XDECREF(cfn->m_self);
cfn->m_self = module;
Py_RETURN_NONE;
}
PyObject *findClass(PyObject *self, PyObject *args)
{
char *className;
if (!PyArg_ParseTuple(args, "s", &className))
return NULL;
try {
jclass cls = env->findClass(className);
if (cls)
return t_Class::wrap_Object(Class(cls));
} catch (JCCEnv::pythonError e) {
return NULL;
} catch (JCCEnv::exception e) {
PyErr_SetJavaError(e.throwable);
return NULL;
}
Py_RETURN_NONE;
}
#if defined(_MSC_VER) || defined(__SUNPRO_CC)
int __parseArgs(PyObject *args, char *types, ...)
{
int count = ((PyTupleObject *)(args))->ob_size;
va_list list, check;
va_start(list, types);
va_start(check, types);
return _parseArgs(((PyTupleObject *)(args))->ob_item, count, types,
list, check);
}
int __parseArg(PyObject *arg, char *types, ...)
{
va_list list, check;
va_start(list, types);
va_start(check, types);
return _parseArgs(&arg, 1, types, list, check);
}
int _parseArgs(PyObject **args, unsigned int count, char *types,
va_list list, va_list check)
{
unsigned int typeCount = strlen(types);
if (count > typeCount)
return -1;
#else
int _parseArgs(PyObject **args, unsigned int count, char *types, ...)
{
unsigned int typeCount = strlen(types);
va_list list, check;
if (count > typeCount)
return -1;
va_start(list, types);
va_start(check, types);
#endif
if (!env->vm)
{
PyErr_SetString(PyExc_RuntimeError, "initVM() must be called first");
return -1;
}
JNIEnv *vm_env = env->get_vm_env();
if (!vm_env)
{
PyErr_SetString(PyExc_RuntimeError, "attachCurrentThread() must be called first");
return -1;
}
unsigned int pos = 0;
int array = 0;
for (unsigned int a = 0; a < count; a++, pos++) {
PyObject *arg = args[a];
switch (types[pos]) {
case '[':
{
if (++array > 1)
return -1;
a -= 1;
break;
}
case 'j': /* Java object, with class$ */
case 'k': /* Java object, with initializeClass */
case 'K': /* Java object, with initializeClass and params */
{
jclass cls = NULL;
switch (types[pos]) {
case 'j':
cls = (jclass) va_arg(list, Class *)->this$;
break;
case 'k':
case 'K':
try {
getclassfn initializeClass = va_arg(list, getclassfn);
cls = (*initializeClass)();
} catch (JCCEnv::pythonError e) {
return -1;
} catch (JCCEnv::exception e) {
PyErr_SetJavaError(e.throwable);
return -1;
}
break;
}
if (arg == Py_None)
break;
/* ensure that class Class is initialized (which may not be the
* case because of earlier recursion avoidance (JObject(cls)).
*/
if (!Class::class$)
Class::initializeClass();
if (array)
{
if (PyObject_TypeCheck(arg, JArrayObject$$Type))
break;
if (PySequence_Check(arg) &&
!PyString_Check(arg) && !PyUnicode_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = 0;
if (obj == Py_None)
ok = 1;
else if (PyObject_TypeCheck(obj, &Object$$Type) &&
vm_env->IsInstanceOf(((t_Object *) obj)->object.this$, cls))
ok = 1;
else if (PyObject_TypeCheck(obj, &FinalizerProxy$$Type))
{
PyObject *o = ((t_fp *) obj)->object;
if (PyObject_TypeCheck(o, &Object$$Type) &&
vm_env->IsInstanceOf(((t_Object *) o)->object.this$, cls))
ok = 1;
}
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (PyObject_TypeCheck(arg, &Object$$Type) &&
vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
break;
else if (PyObject_TypeCheck(arg, &FinalizerProxy$$Type))
{
arg = ((t_fp *) arg)->object;
if (PyObject_TypeCheck(arg, &Object$$Type) &&
vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
break;
}
return -1;
}
case 'Z': /* boolean, strict */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayBool$$Type))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = obj == Py_True || obj == Py_False;
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (arg == Py_True || arg == Py_False)
break;
return -1;
}
case 'B': /* byte */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayByte$$Type))
break;
}
else if (PyString_Check(arg) && (PyString_Size(arg) == 1))
break;
else if (PyInt_CheckExact(arg))
break;
return -1;
}
case 'C': /* char */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayChar$$Type))
break;
}
else if (PyUnicode_Check(arg) && PyUnicode_GET_SIZE(arg) == 1)
break;
return -1;
}
case 'I': /* int */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayInt$$Type))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyInt_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (PyInt_CheckExact(arg))
break;
return -1;
}
case 'S': /* short */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayShort$$Type))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyInt_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (PyInt_CheckExact(arg))
break;
return -1;
}
case 'D': /* double */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayDouble$$Type))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyFloat_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (PyFloat_CheckExact(arg))
break;
return -1;
}
case 'F': /* float */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayFloat$$Type))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyFloat_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (PyFloat_CheckExact(arg))
break;
return -1;
}
case 'J': /* long long */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayLong$$Type))
break;
if (PySequence_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok = PyLong_CheckExact(obj);
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (PyLong_CheckExact(arg))
break;
return -1;
}
case 's': /* string */
{
if (array)
{
if (arg == Py_None)
break;
if (PyObject_TypeCheck(arg, JArrayString$$Type))
break;
if (PySequence_Check(arg) &&
!PyString_Check(arg) && !PyUnicode_Check(arg))
{
if (PySequence_Length(arg) > 0)
{
PyObject *obj = PySequence_GetItem(arg, 0);
int ok =
(obj == Py_None ||
PyString_Check(obj) || PyUnicode_Check(obj));
Py_DECREF(obj);
if (ok)
break;
}
else
break;
}
}
else if (arg == Py_None ||
PyString_Check(arg) || PyUnicode_Check(arg))
break;
return -1;
}
case 'o': /* java.lang.Object */
break;
default:
return -1;
}
if (types[pos] != '[')
array = 0;
}
if (array)
return -1;
pos = 0;
for (unsigned int a = 0; a < count; a++, pos++) {
PyObject *arg = args[a];
switch (types[pos]) {
case '[':
{
if (++array > 1)
return -1;
a -= 1;
break;
}
case 'j': /* Java object except String and Object */
case 'k': /* Java object, with initializeClass */
case 'K': /* Java object, with initializeClass and params */
{
jclass cls = NULL;
switch (types[pos]) {
case 'j':
cls = (jclass) va_arg(check, Class *)->this$;
break;
case 'k':
case 'K':
getclassfn initializeClass = va_arg(check, getclassfn);
cls = (*initializeClass)();
}
if (array)
{
JArray<jobject> *array = va_arg(list, JArray<jobject> *);
#ifdef _java_generics
if (types[pos] == 'K')
{
PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
va_arg(list, getparametersfn);
*tp = NULL;
}
#endif
if (arg == Py_None)
*array = JArray<jobject>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayObject$$Type))
*array = ((t_jarray<jobject> *) arg)->array;
else
*array = JArray<jobject>(cls, arg);
if (PyErr_Occurred())
return -1;
}
else
{
Object *obj = va_arg(list, Object *);
if (PyObject_TypeCheck(arg, &FinalizerProxy$$Type))
arg = ((t_fp *) arg)->object;
#ifdef _java_generics
if (types[pos] == 'K')
{
PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
PyTypeObject **(*parameters_)(void *) =
va_arg(list, getparametersfn);
if (arg == Py_None)
*tp = NULL;
else
*tp = (*parameters_)(arg);
}
#endif
*obj = arg == Py_None
? Object(NULL)
: ((t_Object *) arg)->object;
}
break;
}
case 'Z': /* boolean, strict */
{
if (array)
{
JArray<jboolean> *array = va_arg(list, JArray<jboolean> *);
if (arg == Py_None)
*array = JArray<jboolean>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayBool$$Type))
*array = ((t_jarray<jboolean> *) arg)->array;
else
*array = JArray<jboolean>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jboolean *b = va_arg(list, jboolean *);
*b = arg == Py_True;
}
break;
}
case 'B': /* byte */
{
if (array)
{
JArray<jbyte> *array = va_arg(list, JArray<jbyte> *);
if (arg == Py_None)
*array = JArray<jbyte>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayByte$$Type))
*array = ((t_jarray<jbyte> *) arg)->array;
else
*array = JArray<jbyte>(arg);
if (PyErr_Occurred())
return -1;
}
else if (PyString_Check(arg))
{
jbyte *a = va_arg(list, jbyte *);
*a = (jbyte) PyString_AS_STRING(arg)[0];
}
else
{
jbyte *a = va_arg(list, jbyte *);
*a = (jbyte) PyInt_AsLong(arg);
}
break;
}
case 'C': /* char */
{
if (array)
{
JArray<jchar> *array = va_arg(list, JArray<jchar> *);
if (arg == Py_None)
*array = JArray<jchar>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayChar$$Type))
*array = ((t_jarray<jchar> *) arg)->array;
else
*array = JArray<jchar>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jchar *c = va_arg(list, jchar *);
*c = (jchar) PyUnicode_AS_UNICODE(arg)[0];
}
break;
}
case 'I': /* int */
{
if (array)
{
JArray<jint> *array = va_arg(list, JArray<jint> *);
if (arg == Py_None)
*array = JArray<jint>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayInt$$Type))
*array = ((t_jarray<jint> *) arg)->array;
else
*array = JArray<jint>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jint *n = va_arg(list, jint *);
*n = (jint) PyInt_AsLong(arg);
}
break;
}
case 'S': /* short */
{
if (array)
{
JArray<jshort> *array = va_arg(list, JArray<jshort> *);
if (arg == Py_None)
*array = JArray<jshort>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayShort$$Type))
*array = ((t_jarray<jshort> *) arg)->array;
else
*array = JArray<jshort>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jshort *n = va_arg(list, jshort *);
*n = (jshort) PyInt_AsLong(arg);
}
break;
}
case 'D': /* double */
{
if (array)
{
JArray<jdouble> *array = va_arg(list, JArray<jdouble> *);
if (arg == Py_None)
*array = JArray<jdouble>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayDouble$$Type))
*array = ((t_jarray<jdouble> *) arg)->array;
else
*array = JArray<jdouble>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jdouble *d = va_arg(list, jdouble *);
*d = (jdouble) PyFloat_AsDouble(arg);
}
break;
}
case 'F': /* float */
{
if (array)
{
JArray<jfloat> *array = va_arg(list, JArray<jfloat> *);
if (arg == Py_None)
*array = JArray<jfloat>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayFloat$$Type))
*array = ((t_jarray<jfloat> *) arg)->array;
else
*array = JArray<jfloat>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jfloat *d = va_arg(list, jfloat *);
*d = (jfloat) (float) PyFloat_AsDouble(arg);
}
break;
}
case 'J': /* long long */
{
if (array)
{
JArray<jlong> *array = va_arg(list, JArray<jlong> *);
if (arg == Py_None)
*array = JArray<jlong>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayLong$$Type))
*array = ((t_jarray<jlong> *) arg)->array;
else
*array = JArray<jlong>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
jlong *l = va_arg(list, jlong *);
*l = (jlong) PyLong_AsLongLong(arg);
}
break;
}
case 's': /* string */
{
if (array)
{
JArray<jstring> *array = va_arg(list, JArray<jstring> *);
if (arg == Py_None)
*array = JArray<jstring>((jobject) NULL);
else if (PyObject_TypeCheck(arg, JArrayString$$Type))
*array = ((t_jarray<jstring> *) arg)->array;
else
*array = JArray<jstring>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
String *str = va_arg(list, String *);
if (arg == Py_None)
*str = String(NULL);
else
{
*str = p2j(arg);
if (PyErr_Occurred())
return -1;
}
}
break;
}
case 'o': /* java.lang.Object */
{
if (array)
{
JArray<Object> *array = va_arg(list, JArray<Object> *);
if (arg == Py_None)
*array = JArray<Object>((jobject) NULL);
else
*array = JArray<Object>(arg);
if (PyErr_Occurred())
return -1;
}
else
{
Object *obj = va_arg(list, Object *);
if (arg == Py_None)
*obj = Object(NULL);
else if (PyObject_TypeCheck(arg, &Object$$Type))
*obj = ((t_Object *) arg)->object;
else if (PyObject_TypeCheck(arg, &FinalizerProxy$$Type))
{
arg = ((t_fp *) arg)->object;
if (PyObject_TypeCheck(arg, &Object$$Type))
*obj = ((t_Object *) arg)->object;
else
return -1;
}
else if (PyString_Check(arg) || PyUnicode_Check(arg))
{
*obj = p2j(arg);
if (PyErr_Occurred())
return -1;
}
else if (arg == Py_True)
*obj = *Boolean::TRUE;
else if (arg == Py_False)
*obj = *Boolean::FALSE;
else if (PyInt_Check(arg))
{
long ln = PyInt_AS_LONG(arg);
int n = (int) ln;
if (ln != (long) n)
*obj = Long((jlong) ln);
else
*obj = Integer((jint) n);
}
else if (PyLong_Check(arg))
*obj = Long((jlong) PyLong_AsLongLong(arg));
else if (PyFloat_Check(arg))
*obj = Double((jdouble) PyFloat_AS_DOUBLE(arg));
else
return -1;
}
break;
}
default:
return -1;
}
if (types[pos] != '[')
array = 0;
}
if (pos == typeCount)
return 0;
return -1;
}
String p2j(PyObject *object)
{
return String(env->fromPyString(object));
}
PyObject *j2p(const String& js)
{
return env->fromJString((jstring) js.this$, 0);
}
PyObject *PyErr_SetArgsError(char *name, PyObject *args)
{
if (!PyErr_Occurred())
{
PyObject *err = Py_BuildValue("(sO)", name, args);
PyErr_SetObject(PyExc_InvalidArgsError, err);
Py_DECREF(err);
}
return NULL;
}
PyObject *PyErr_SetArgsError(PyObject *self, char *name, PyObject *args)
{
if (!PyErr_Occurred())
{
PyObject *type = (PyObject *) self->ob_type;
PyObject *err = Py_BuildValue("(OsO)", type, name, args);
PyErr_SetObject(PyExc_InvalidArgsError, err);
Py_DECREF(err);
}
return NULL;
}
PyObject *PyErr_SetArgsError(PyTypeObject *type, char *name, PyObject *args)
{
if (!PyErr_Occurred())
{
PyObject *err = Py_BuildValue("(OsO)", type, name, args);
PyErr_SetObject(PyExc_InvalidArgsError, err);
Py_DECREF(err);
}
return NULL;
}
PyObject *PyErr_SetJavaError(jthrowable throwable)
{
PyObject *err = t_Throwable::wrap_Object(Throwable(throwable));
PyErr_SetObject(PyExc_JavaError, err);
Py_DECREF(err);
return NULL;
}
void throwPythonError(void)
{
PyObject *exc = PyErr_Occurred();
if (exc && PyErr_GivenExceptionMatches(exc, PyExc_JavaError))
{
PyObject *value, *traceback;
PyErr_Fetch(&exc, &value, &traceback);
if (value)
{
PyObject *je = PyObject_CallMethod(value, "getJavaException", "");
if (!je)
PyErr_Restore(exc, value, traceback);
else
{
Py_DECREF(exc);
Py_DECREF(value);
Py_XDECREF(traceback);
exc = je;
if (exc && PyObject_TypeCheck(exc, &Throwable$$Type))
{
jobject jobj = ((t_Throwable *) exc)->object.this$;
env->get_vm_env()->Throw((jthrowable) jobj);
Py_DECREF(exc);
return;
}
}
}
else
{
Py_DECREF(exc);
Py_XDECREF(traceback);
}
}
else if (exc && PyErr_GivenExceptionMatches(exc, PyExc_StopIteration))
{
PyErr_Clear();
return;
}
if (exc)
{
PyObject *name = PyObject_GetAttrString(exc, "__name__");
env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
PyString_AS_STRING(name));
Py_DECREF(name);
}
else
env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
"python error");
}
void throwTypeError(const char *name, PyObject *object)
{
PyObject *tuple = Py_BuildValue("(ssO)", "while calling", name, object);
PyErr_SetObject(PyExc_TypeError, tuple);
Py_DECREF(tuple);
env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(), "type error");
}
int abstract_init(PyObject *self, PyObject *args, PyObject *kwds)
{
PyObject *err =
Py_BuildValue("(sO)", "instantiating java class", self->ob_type);
PyErr_SetObject(PyExc_NotImplementedError, err);
Py_DECREF(err);
return -1;
}
PyObject *callSuper(PyTypeObject *type, const char *name, PyObject *args,
int cardinality)
{
PyObject *super = (PyObject *) type->tp_base;
PyObject *method =
PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
PyObject *value;
if (!method)
return NULL;
if (cardinality > 1)
value = PyObject_Call(method, args, NULL);
else
{
#if PY_VERSION_HEX < 0x02040000
PyObject *tuple = Py_BuildValue("(O)", args);
#else
PyObject *tuple = PyTuple_Pack(1, args);
#endif
value = PyObject_Call(method, tuple, NULL);
Py_DECREF(tuple);
}
Py_DECREF(method);
return value;
}
PyObject *callSuper(PyTypeObject *type, PyObject *self,
const char *name, PyObject *args, int cardinality)
{
#if PY_VERSION_HEX < 0x02040000
PyObject *tuple = Py_BuildValue("(OO)", type, self);
#else
PyObject *tuple = PyTuple_Pack(2, type, self);
#endif
PyObject *super = PyObject_Call((PyObject *) &PySuper_Type, tuple, NULL);
PyObject *method, *value;
Py_DECREF(tuple);
if (!super)
return NULL;
method = PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
Py_DECREF(super);
if (!method)
return NULL;
if (cardinality > 1)
value = PyObject_Call(method, args, NULL);
else
{
#if PY_VERSION_HEX < 0x02040000
tuple = Py_BuildValue("(O)", args);
#else
tuple = PyTuple_Pack(1, args);
#endif
value = PyObject_Call(method, tuple, NULL);
Py_DECREF(tuple);
}
Py_DECREF(method);
return value;
}
PyObject *castCheck(PyObject *obj, getclassfn initializeClass,
int reportError)
{
if (PyObject_TypeCheck(obj, &FinalizerProxy$$Type))
obj = ((t_fp *) obj)->object;
if (!PyObject_TypeCheck(obj, &Object$$Type))
{
if (reportError)
PyErr_SetObject(PyExc_TypeError, obj);
return NULL;
}
jobject jobj = ((t_Object *) obj)->object.this$;
if (jobj)
{
jclass cls;
try {
cls = (*initializeClass)();
} catch (JCCEnv::pythonError e) {
return NULL;
} catch (JCCEnv::exception e) {
PyErr_SetJavaError(e.throwable);
return NULL;
}
if (!env->get_vm_env()->IsInstanceOf(jobj, cls))
{
if (reportError)
PyErr_SetObject(PyExc_TypeError, obj);
return NULL;
}
}
return obj;
}
PyObject *get_extension_iterator(PyObject *self)
{
return PyObject_CallMethod(self, "iterator", "");
}
PyObject *get_extension_next(PyObject *self)
{
return PyObject_CallMethod(self, "next", "");
}
PyObject *get_extension_nextElement(PyObject *self)
{
return PyObject_CallMethod(self, "nextElement", "");
}
jobjectArray fromPySequence(jclass cls, PyObject *sequence)
{
if (sequence == Py_None)
return NULL;
if (!PySequence_Check(sequence))
{
PyErr_SetObject(PyExc_TypeError, sequence);
return NULL;
}
int length = PySequence_Length(sequence);
jobjectArray array;
try {
array = env->newObjectArray(cls, length);
} catch (JCCEnv::pythonError) {
return NULL;
} catch (JCCEnv::exception e) {
PyErr_SetJavaError(e.throwable);
return NULL;
}
JNIEnv *vm_env = env->get_vm_env();
for (int i = 0; i < length; i++) {
PyObject *obj = PySequence_GetItem(sequence, i);
int fromString = 0;
jobject jobj;
if (!obj)
break;
else if (obj == Py_None)
jobj = NULL;
else if (PyString_Check(obj) || PyUnicode_Check(obj))
{
jobj = env->fromPyString(obj);
fromString = 1;
}
else if (PyObject_TypeCheck(obj, &JObject$$Type))
jobj = ((t_JObject *) obj)->object.this$;
else if (PyObject_TypeCheck(obj, &FinalizerProxy$$Type))
jobj = ((t_JObject *) ((t_fp *) obj)->object)->object.this$;
else /* todo: add auto-boxing of primitive types */
{
PyErr_SetObject(PyExc_TypeError, obj);
Py_DECREF(obj);
return NULL;
}
Py_DECREF(obj);
try {
env->setObjectArrayElement(array, i, jobj);
if (fromString)
vm_env->DeleteLocalRef(jobj);
} catch (JCCEnv::exception e) {
PyErr_SetJavaError(e.throwable);
return NULL;
}
}
return array;
}
void installType(PyTypeObject *type, PyObject *module, char *name,
int isExtension)
{
if (PyType_Ready(type) == 0)
{
Py_INCREF(type);
if (isExtension)
{
type->ob_type = &FinalizerClass$$Type;
Py_INCREF(&FinalizerClass$$Type);
}
PyModule_AddObject(module, name, (PyObject *) type);
}
}
PyObject *wrapType(PyTypeObject *type, const jobject& obj)
{
PyObject *cobj = PyObject_GetAttrString((PyObject *) type, "wrapfn_");
PyObject *(*wrapfn)(const jobject&);
if (cobj == NULL)
return NULL;
wrapfn = (PyObject *(*)(const jobject &)) PyCObject_AsVoidPtr(cobj);
Py_DECREF(cobj);
return wrapfn(obj);
}
#ifdef _java_generics
PyObject *typeParameters(PyTypeObject *types[], size_t size)
{
size_t count = size / sizeof(PyTypeObject *);
PyObject *tuple = PyTuple_New(count);
for (size_t i = 0; i < count; i++) {
PyObject *type = (PyObject *) types[i];
if (type == NULL)
type = Py_None;
PyTuple_SET_ITEM(tuple, i, type);
Py_INCREF(type);
}
return tuple;
}
#endif