diff -r b758351d191f -r cc9b7e14412b web/lib/arch/osx/jcc/sources/functions.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/web/lib/arch/osx/jcc/sources/functions.cpp Tue May 25 02:43:45 2010 +0200 @@ -0,0 +1,1272 @@ +/* + * 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 +#include + +#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 *array = va_arg(list, JArray *); + +#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) NULL); + else if (PyObject_TypeCheck(arg, JArrayObject$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayBool$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(arg); + + if (PyErr_Occurred()) + return -1; + } + else + { + jboolean *b = va_arg(list, jboolean *); + *b = arg == Py_True; + } + break; + } + + case 'B': /* byte */ + { + if (array) + { + JArray *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayByte$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayChar$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayInt$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayShort$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayDouble$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayFloat$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayLong$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else if (PyObject_TypeCheck(arg, JArrayString$$Type)) + *array = ((t_jarray *) arg)->array; + else + *array = JArray(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 *array = va_arg(list, JArray *); + + if (arg == Py_None) + *array = JArray((jobject) NULL); + else + *array = JArray(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