web/lib/arch/osx/jcc/sources/functions.cpp
changeset 29 cc9b7e14412b
equal deleted inserted replaced
28:b758351d191f 29:cc9b7e14412b
       
     1 /*
       
     2  *   Licensed under the Apache License, Version 2.0 (the "License");
       
     3  *   you may not use this file except in compliance with the License.
       
     4  *   You may obtain a copy of the License at
       
     5  *
       
     6  *       http://www.apache.org/licenses/LICENSE-2.0
       
     7  *
       
     8  *   Unless required by applicable law or agreed to in writing, software
       
     9  *   distributed under the License is distributed on an "AS IS" BASIS,
       
    10  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    11  *   See the License for the specific language governing permissions and
       
    12  *   limitations under the License.
       
    13  */
       
    14 
       
    15 #include <jni.h>
       
    16 #include <stdarg.h>
       
    17 
       
    18 #include "java/lang/Object.h"
       
    19 #include "java/lang/Class.h"
       
    20 #include "java/lang/String.h"
       
    21 #include "java/lang/Throwable.h"
       
    22 #include "java/lang/Boolean.h"
       
    23 #include "java/lang/Integer.h"
       
    24 #include "java/lang/Long.h"
       
    25 #include "java/lang/Double.h"
       
    26 #include "java/util/Iterator.h"
       
    27 #include "JArray.h"
       
    28 #include "functions.h"
       
    29 #include "macros.h"
       
    30 
       
    31 using namespace java::lang;
       
    32 using namespace java::util;
       
    33 
       
    34 PyObject *PyExc_JavaError = PyExc_ValueError;
       
    35 PyObject *PyExc_InvalidArgsError = PyExc_ValueError;
       
    36 
       
    37 PyObject *_set_exception_types(PyObject *self, PyObject *args)
       
    38 {
       
    39     if (!PyArg_ParseTuple(args, "OO",
       
    40                           &PyExc_JavaError, &PyExc_InvalidArgsError))
       
    41         return NULL;
       
    42 
       
    43     Py_RETURN_NONE;
       
    44 }
       
    45 
       
    46 PyObject *_set_function_self(PyObject *self, PyObject *args)
       
    47 {
       
    48     PyObject *object, *module;
       
    49 
       
    50     if (!PyArg_ParseTuple(args, "OO", &object, &module))
       
    51         return NULL;
       
    52 
       
    53     if (!PyCFunction_Check(object))
       
    54     {
       
    55         PyErr_SetObject(PyExc_TypeError, object);
       
    56         return NULL;
       
    57     }
       
    58 
       
    59     PyCFunctionObject *cfn = (PyCFunctionObject *) object;
       
    60 
       
    61     Py_INCREF(module);
       
    62     Py_XDECREF(cfn->m_self);
       
    63     cfn->m_self = module;
       
    64 
       
    65     Py_RETURN_NONE;
       
    66 }
       
    67 
       
    68 PyObject *findClass(PyObject *self, PyObject *args)
       
    69 {
       
    70     char *className;
       
    71 
       
    72     if (!PyArg_ParseTuple(args, "s", &className))
       
    73         return NULL;
       
    74 
       
    75     try {
       
    76         jclass cls = env->findClass(className);
       
    77 
       
    78         if (cls)
       
    79             return t_Class::wrap_Object(Class(cls));
       
    80     } catch (JCCEnv::pythonError e) {
       
    81         return NULL;
       
    82     } catch (JCCEnv::exception e) {
       
    83         PyErr_SetJavaError(e.throwable);
       
    84         return NULL;
       
    85     }
       
    86 
       
    87     Py_RETURN_NONE;
       
    88 }
       
    89 
       
    90 
       
    91 #if defined(_MSC_VER) || defined(__SUNPRO_CC)
       
    92 int __parseArgs(PyObject *args, char *types, ...)
       
    93 {
       
    94     int count = ((PyTupleObject *)(args))->ob_size;
       
    95     va_list list, check;
       
    96 
       
    97     va_start(list, types);
       
    98     va_start(check, types);
       
    99 
       
   100     return _parseArgs(((PyTupleObject *)(args))->ob_item, count, types,
       
   101 		      list, check);
       
   102 }
       
   103 
       
   104 int __parseArg(PyObject *arg, char *types, ...)
       
   105 {
       
   106     va_list list, check;
       
   107 
       
   108     va_start(list, types);
       
   109     va_start(check, types);
       
   110 
       
   111     return _parseArgs(&arg, 1, types, list, check);
       
   112 }
       
   113 
       
   114 int _parseArgs(PyObject **args, unsigned int count, char *types,
       
   115 	       va_list list, va_list check)
       
   116 {
       
   117     unsigned int typeCount = strlen(types);
       
   118 
       
   119     if (count > typeCount)
       
   120         return -1;
       
   121 #else
       
   122 
       
   123 int _parseArgs(PyObject **args, unsigned int count, char *types, ...)
       
   124 {
       
   125     unsigned int typeCount = strlen(types);
       
   126     va_list list, check;
       
   127 
       
   128     if (count > typeCount)
       
   129         return -1;
       
   130 
       
   131     va_start(list, types);
       
   132     va_start(check, types);
       
   133 #endif
       
   134 
       
   135     if (!env->vm)
       
   136     {
       
   137         PyErr_SetString(PyExc_RuntimeError, "initVM() must be called first");
       
   138         return -1;
       
   139     }
       
   140 
       
   141     JNIEnv *vm_env = env->get_vm_env();
       
   142 
       
   143     if (!vm_env)
       
   144     {
       
   145         PyErr_SetString(PyExc_RuntimeError, "attachCurrentThread() must be called first");
       
   146         return -1;
       
   147     }
       
   148 
       
   149     unsigned int pos = 0;
       
   150     int array = 0;
       
   151 
       
   152     for (unsigned int a = 0; a < count; a++, pos++) {
       
   153         PyObject *arg = args[a];
       
   154 
       
   155         switch (types[pos]) {
       
   156           case '[':
       
   157           {
       
   158               if (++array > 1)
       
   159                   return -1;
       
   160 
       
   161               a -= 1;
       
   162               break;
       
   163           }
       
   164 
       
   165           case 'j':           /* Java object, with class$    */
       
   166           case 'k':           /* Java object, with initializeClass */
       
   167           case 'K':           /* Java object, with initializeClass and params */
       
   168           {
       
   169               jclass cls = NULL;
       
   170 
       
   171               switch (types[pos]) {
       
   172                 case 'j':
       
   173                   cls = (jclass) va_arg(list, Class *)->this$;
       
   174                   break;
       
   175                 case 'k':
       
   176                 case 'K':
       
   177                   try {
       
   178                       getclassfn initializeClass = va_arg(list, getclassfn);
       
   179                       cls = (*initializeClass)();
       
   180                   } catch (JCCEnv::pythonError e) {
       
   181                       return -1;
       
   182                   } catch (JCCEnv::exception e) {
       
   183                       PyErr_SetJavaError(e.throwable);
       
   184                       return -1;
       
   185                   }
       
   186                   break;
       
   187               }
       
   188 
       
   189               if (arg == Py_None)
       
   190                   break;
       
   191 
       
   192               /* ensure that class Class is initialized (which may not be the
       
   193                * case because of earlier recursion avoidance (JObject(cls)).
       
   194                */
       
   195               if (!Class::class$)
       
   196                   Class::initializeClass();
       
   197 
       
   198               if (array)
       
   199               {
       
   200                   if (PyObject_TypeCheck(arg, JArrayObject$$Type))
       
   201                       break;
       
   202 
       
   203                   if (PySequence_Check(arg) &&
       
   204                       !PyString_Check(arg) && !PyUnicode_Check(arg))
       
   205                   {
       
   206                       if (PySequence_Length(arg) > 0)
       
   207                       {
       
   208                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   209                           int ok = 0;
       
   210 
       
   211                           if (obj == Py_None)
       
   212                               ok = 1;
       
   213                           else if (PyObject_TypeCheck(obj, &Object$$Type) &&
       
   214                                    vm_env->IsInstanceOf(((t_Object *) obj)->object.this$, cls))
       
   215                               ok = 1;
       
   216                           else if (PyObject_TypeCheck(obj, &FinalizerProxy$$Type))
       
   217                           {
       
   218                               PyObject *o = ((t_fp *) obj)->object;
       
   219 
       
   220                               if (PyObject_TypeCheck(o, &Object$$Type) &&
       
   221                                   vm_env->IsInstanceOf(((t_Object *) o)->object.this$, cls))
       
   222                                   ok = 1;
       
   223                           }
       
   224 
       
   225                           Py_DECREF(obj);
       
   226                           if (ok)
       
   227                               break;
       
   228                       }
       
   229                       else
       
   230                           break;
       
   231                   }
       
   232               }
       
   233               else if (PyObject_TypeCheck(arg, &Object$$Type) &&
       
   234                        vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
       
   235                   break;
       
   236               else if (PyObject_TypeCheck(arg, &FinalizerProxy$$Type))
       
   237               {
       
   238                   arg = ((t_fp *) arg)->object;
       
   239                   if (PyObject_TypeCheck(arg, &Object$$Type) &&
       
   240                       vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
       
   241                       break;
       
   242               }
       
   243 
       
   244               return -1;
       
   245           }
       
   246 
       
   247           case 'Z':           /* boolean, strict */
       
   248           {
       
   249               if (array)
       
   250               {
       
   251                   if (arg == Py_None)
       
   252                       break;
       
   253 
       
   254                   if (PyObject_TypeCheck(arg, JArrayBool$$Type))
       
   255                       break;
       
   256 
       
   257                   if (PySequence_Check(arg))
       
   258                   {
       
   259                       if (PySequence_Length(arg) > 0)
       
   260                       {
       
   261                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   262                           int ok = obj == Py_True || obj == Py_False;
       
   263 
       
   264                           Py_DECREF(obj);
       
   265                           if (ok)
       
   266                               break;
       
   267                       }
       
   268                       else
       
   269                           break;
       
   270                   }
       
   271               }
       
   272               else if (arg == Py_True || arg == Py_False)
       
   273                   break;
       
   274 
       
   275               return -1;
       
   276           }
       
   277 
       
   278           case 'B':           /* byte */
       
   279           {
       
   280               if (array)
       
   281               {
       
   282                   if (arg == Py_None)
       
   283                       break;
       
   284                   if (PyObject_TypeCheck(arg, JArrayByte$$Type))
       
   285                       break;
       
   286               }
       
   287               else if (PyString_Check(arg) && (PyString_Size(arg) == 1))
       
   288                   break;
       
   289               else if (PyInt_CheckExact(arg))
       
   290                   break;
       
   291 
       
   292               return -1;
       
   293           }
       
   294 
       
   295           case 'C':           /* char */
       
   296           {
       
   297               if (array)
       
   298               {
       
   299                   if (arg == Py_None)
       
   300                       break;
       
   301                   if (PyObject_TypeCheck(arg, JArrayChar$$Type))
       
   302                       break;
       
   303               }
       
   304               else if (PyUnicode_Check(arg) && PyUnicode_GET_SIZE(arg) == 1)
       
   305                   break;
       
   306               return -1;
       
   307           }
       
   308 
       
   309           case 'I':           /* int */
       
   310           {
       
   311               if (array)
       
   312               {
       
   313                   if (arg == Py_None)
       
   314                       break;
       
   315 
       
   316                   if (PyObject_TypeCheck(arg, JArrayInt$$Type))
       
   317                       break;
       
   318 
       
   319                   if (PySequence_Check(arg))
       
   320                   {
       
   321                       if (PySequence_Length(arg) > 0)
       
   322                       {
       
   323                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   324                           int ok = PyInt_CheckExact(obj);
       
   325 
       
   326                           Py_DECREF(obj);
       
   327                           if (ok)
       
   328                               break;
       
   329                       }
       
   330                       else
       
   331                           break;
       
   332                   }
       
   333               }
       
   334               else if (PyInt_CheckExact(arg))
       
   335                   break;
       
   336 
       
   337               return -1;
       
   338           }
       
   339 
       
   340           case 'S':           /* short */
       
   341           {
       
   342               if (array)
       
   343               {
       
   344                   if (arg == Py_None)
       
   345                       break;
       
   346 
       
   347                   if (PyObject_TypeCheck(arg, JArrayShort$$Type))
       
   348                       break;
       
   349 
       
   350                   if (PySequence_Check(arg))
       
   351                   {
       
   352                       if (PySequence_Length(arg) > 0)
       
   353                       {
       
   354                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   355                           int ok = PyInt_CheckExact(obj);
       
   356 
       
   357                           Py_DECREF(obj);
       
   358                           if (ok)
       
   359                               break;
       
   360                       }
       
   361                       else
       
   362                           break;
       
   363                   }
       
   364               }
       
   365               else if (PyInt_CheckExact(arg))
       
   366                   break;
       
   367 
       
   368               return -1;
       
   369           }
       
   370 
       
   371           case 'D':           /* double */
       
   372           {
       
   373               if (array)
       
   374               {
       
   375                   if (arg == Py_None)
       
   376                       break;
       
   377 
       
   378                   if (PyObject_TypeCheck(arg, JArrayDouble$$Type))
       
   379                       break;
       
   380 
       
   381                   if (PySequence_Check(arg))
       
   382                   {
       
   383                       if (PySequence_Length(arg) > 0)
       
   384                       {
       
   385                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   386                           int ok = PyFloat_CheckExact(obj);
       
   387 
       
   388                           Py_DECREF(obj);
       
   389                           if (ok)
       
   390                               break;
       
   391                       }
       
   392                       else
       
   393                           break;
       
   394                   }
       
   395               }
       
   396               else if (PyFloat_CheckExact(arg))
       
   397                   break;
       
   398 
       
   399               return -1;
       
   400           }
       
   401 
       
   402           case 'F':           /* float */
       
   403           {
       
   404               if (array)
       
   405               {
       
   406                   if (arg == Py_None)
       
   407                       break;
       
   408 
       
   409                   if (PyObject_TypeCheck(arg, JArrayFloat$$Type))
       
   410                       break;
       
   411 
       
   412                   if (PySequence_Check(arg))
       
   413                   {
       
   414                       if (PySequence_Length(arg) > 0)
       
   415                       {
       
   416                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   417                           int ok = PyFloat_CheckExact(obj);
       
   418 
       
   419                           Py_DECREF(obj);
       
   420                           if (ok)
       
   421                               break;
       
   422                       }
       
   423                       else
       
   424                           break;
       
   425                   }
       
   426               }
       
   427               else if (PyFloat_CheckExact(arg))
       
   428                   break;
       
   429 
       
   430               return -1;
       
   431           }
       
   432 
       
   433           case 'J':           /* long long */
       
   434           {
       
   435               if (array)
       
   436               {
       
   437                   if (arg == Py_None)
       
   438                       break;
       
   439 
       
   440                   if (PyObject_TypeCheck(arg, JArrayLong$$Type))
       
   441                       break;
       
   442 
       
   443                   if (PySequence_Check(arg))
       
   444                   {
       
   445                       if (PySequence_Length(arg) > 0)
       
   446                       {
       
   447                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   448                           int ok = PyLong_CheckExact(obj);
       
   449 
       
   450                           Py_DECREF(obj);
       
   451                           if (ok)
       
   452                               break;
       
   453                       }
       
   454                       else
       
   455                           break;
       
   456                   }
       
   457               }
       
   458               else if (PyLong_CheckExact(arg))
       
   459                   break;
       
   460 
       
   461               return -1;
       
   462           }
       
   463 
       
   464           case 's':           /* string  */
       
   465           {
       
   466               if (array)
       
   467               {
       
   468                   if (arg == Py_None)
       
   469                       break;
       
   470 
       
   471                   if (PyObject_TypeCheck(arg, JArrayString$$Type))
       
   472                       break;
       
   473 
       
   474                   if (PySequence_Check(arg) && 
       
   475                       !PyString_Check(arg) && !PyUnicode_Check(arg))
       
   476                   {
       
   477                       if (PySequence_Length(arg) > 0)
       
   478                       {
       
   479                           PyObject *obj = PySequence_GetItem(arg, 0);
       
   480                           int ok =
       
   481                               (obj == Py_None ||
       
   482                                PyString_Check(obj) || PyUnicode_Check(obj));
       
   483 
       
   484                           Py_DECREF(obj);
       
   485                           if (ok)
       
   486                               break;
       
   487                       }
       
   488                       else
       
   489                           break;
       
   490                   }
       
   491               }
       
   492               else if (arg == Py_None ||
       
   493                        PyString_Check(arg) || PyUnicode_Check(arg))
       
   494                   break;
       
   495 
       
   496               return -1;
       
   497           }
       
   498 
       
   499           case 'o':         /* java.lang.Object */
       
   500             break;
       
   501 
       
   502           default:
       
   503             return -1;
       
   504         }
       
   505 
       
   506         if (types[pos] != '[')
       
   507             array = 0;
       
   508     }
       
   509 
       
   510     if (array)
       
   511         return -1;
       
   512 
       
   513     pos = 0;
       
   514 
       
   515     for (unsigned int a = 0; a < count; a++, pos++) {
       
   516         PyObject *arg = args[a];
       
   517         
       
   518         switch (types[pos]) {
       
   519           case '[':
       
   520           {
       
   521               if (++array > 1)
       
   522                   return -1;
       
   523 
       
   524               a -= 1;
       
   525               break;
       
   526           }
       
   527 
       
   528           case 'j':           /* Java object except String and Object */
       
   529           case 'k':           /* Java object, with initializeClass    */
       
   530           case 'K':           /* Java object, with initializeClass and params */
       
   531           {
       
   532               jclass cls = NULL;
       
   533 
       
   534               switch (types[pos]) {
       
   535                 case 'j':
       
   536                   cls = (jclass) va_arg(check, Class *)->this$;
       
   537                   break;
       
   538                 case 'k':
       
   539                 case 'K':
       
   540                   getclassfn initializeClass = va_arg(check, getclassfn);
       
   541                   cls = (*initializeClass)();
       
   542               }
       
   543 
       
   544               if (array)
       
   545               {
       
   546                   JArray<jobject> *array = va_arg(list, JArray<jobject> *);
       
   547 
       
   548 #ifdef _java_generics
       
   549                   if (types[pos] == 'K')
       
   550                   {
       
   551                       PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
       
   552 
       
   553                       va_arg(list, getparametersfn);
       
   554                       *tp = NULL;
       
   555                   }
       
   556 #endif
       
   557                   if (arg == Py_None)
       
   558                       *array = JArray<jobject>((jobject) NULL);
       
   559                   else if (PyObject_TypeCheck(arg, JArrayObject$$Type))
       
   560                       *array = ((t_jarray<jobject> *) arg)->array;
       
   561                   else 
       
   562                       *array = JArray<jobject>(cls, arg);
       
   563 
       
   564                   if (PyErr_Occurred())
       
   565                       return -1;
       
   566               }
       
   567               else
       
   568               {
       
   569                   Object *obj = va_arg(list, Object *);
       
   570 
       
   571                   if (PyObject_TypeCheck(arg, &FinalizerProxy$$Type))
       
   572                       arg = ((t_fp *) arg)->object;
       
   573 
       
   574 #ifdef _java_generics
       
   575                   if (types[pos] == 'K')
       
   576                   {
       
   577                       PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
       
   578                       PyTypeObject **(*parameters_)(void *) = 
       
   579                           va_arg(list, getparametersfn);
       
   580 
       
   581                       if (arg == Py_None)
       
   582                           *tp = NULL;
       
   583                       else
       
   584                           *tp = (*parameters_)(arg);
       
   585                   }
       
   586 #endif
       
   587 
       
   588                   *obj = arg == Py_None
       
   589                       ? Object(NULL)
       
   590                       : ((t_Object *) arg)->object;
       
   591               }
       
   592               break;
       
   593           }
       
   594 
       
   595           case 'Z':           /* boolean, strict */
       
   596           {
       
   597               if (array)
       
   598               {
       
   599                   JArray<jboolean> *array = va_arg(list, JArray<jboolean> *);
       
   600 
       
   601                   if (arg == Py_None)
       
   602                       *array = JArray<jboolean>((jobject) NULL);
       
   603                   else if (PyObject_TypeCheck(arg, JArrayBool$$Type))
       
   604                       *array = ((t_jarray<jboolean> *) arg)->array;
       
   605                   else
       
   606                       *array = JArray<jboolean>(arg);
       
   607 
       
   608                   if (PyErr_Occurred())
       
   609                       return -1;
       
   610               }
       
   611               else
       
   612               {
       
   613                   jboolean *b = va_arg(list, jboolean *);
       
   614                   *b = arg == Py_True;
       
   615               }
       
   616               break;
       
   617           }
       
   618 
       
   619           case 'B':           /* byte */
       
   620           {
       
   621               if (array)
       
   622               {
       
   623                   JArray<jbyte> *array = va_arg(list, JArray<jbyte> *);
       
   624 
       
   625                   if (arg == Py_None)
       
   626                       *array = JArray<jbyte>((jobject) NULL);
       
   627                   else if (PyObject_TypeCheck(arg, JArrayByte$$Type))
       
   628                       *array = ((t_jarray<jbyte> *) arg)->array;
       
   629                   else 
       
   630                       *array = JArray<jbyte>(arg);
       
   631 
       
   632                   if (PyErr_Occurred())
       
   633                       return -1;
       
   634               }
       
   635               else if (PyString_Check(arg))
       
   636               {
       
   637                   jbyte *a = va_arg(list, jbyte *);
       
   638                   *a = (jbyte) PyString_AS_STRING(arg)[0];
       
   639               }
       
   640               else
       
   641               {
       
   642                   jbyte *a = va_arg(list, jbyte *);
       
   643                   *a = (jbyte) PyInt_AsLong(arg);
       
   644               }
       
   645               break;
       
   646           }
       
   647 
       
   648           case 'C':           /* char */
       
   649           {
       
   650               if (array)
       
   651               {
       
   652                   JArray<jchar> *array = va_arg(list, JArray<jchar> *);
       
   653 
       
   654                   if (arg == Py_None)
       
   655                       *array = JArray<jchar>((jobject) NULL);
       
   656                   else if (PyObject_TypeCheck(arg, JArrayChar$$Type))
       
   657                       *array = ((t_jarray<jchar> *) arg)->array;
       
   658                   else 
       
   659                       *array = JArray<jchar>(arg);
       
   660 
       
   661                   if (PyErr_Occurred())
       
   662                       return -1;
       
   663               }
       
   664               else
       
   665               {
       
   666                   jchar *c = va_arg(list, jchar *);
       
   667                   *c = (jchar) PyUnicode_AS_UNICODE(arg)[0];
       
   668               }
       
   669               break;
       
   670           }
       
   671 
       
   672           case 'I':           /* int */
       
   673           {
       
   674               if (array)
       
   675               {
       
   676                   JArray<jint> *array = va_arg(list, JArray<jint> *);
       
   677 
       
   678                   if (arg == Py_None)
       
   679                       *array = JArray<jint>((jobject) NULL);
       
   680                   else if (PyObject_TypeCheck(arg, JArrayInt$$Type))
       
   681                       *array = ((t_jarray<jint> *) arg)->array;
       
   682                   else 
       
   683                       *array = JArray<jint>(arg);
       
   684 
       
   685                   if (PyErr_Occurred())
       
   686                       return -1;
       
   687               }
       
   688               else
       
   689               {
       
   690                   jint *n = va_arg(list, jint *);
       
   691                   *n = (jint) PyInt_AsLong(arg);
       
   692               }
       
   693               break;
       
   694           }
       
   695 
       
   696           case 'S':           /* short */
       
   697           {
       
   698               if (array)
       
   699               {
       
   700                   JArray<jshort> *array = va_arg(list, JArray<jshort> *);
       
   701 
       
   702                   if (arg == Py_None)
       
   703                       *array = JArray<jshort>((jobject) NULL);
       
   704                   else if (PyObject_TypeCheck(arg, JArrayShort$$Type))
       
   705                       *array = ((t_jarray<jshort> *) arg)->array;
       
   706                   else 
       
   707                       *array = JArray<jshort>(arg);
       
   708 
       
   709                   if (PyErr_Occurred())
       
   710                       return -1;
       
   711               }
       
   712               else
       
   713               {
       
   714                   jshort *n = va_arg(list, jshort *);
       
   715                   *n = (jshort) PyInt_AsLong(arg);
       
   716               }
       
   717               break;
       
   718           }
       
   719 
       
   720           case 'D':           /* double */
       
   721           {
       
   722               if (array)
       
   723               {
       
   724                   JArray<jdouble> *array = va_arg(list, JArray<jdouble> *);
       
   725 
       
   726                   if (arg == Py_None)
       
   727                       *array = JArray<jdouble>((jobject) NULL);
       
   728                   else if (PyObject_TypeCheck(arg, JArrayDouble$$Type))
       
   729                       *array = ((t_jarray<jdouble> *) arg)->array;
       
   730                   else 
       
   731                       *array = JArray<jdouble>(arg);
       
   732 
       
   733                   if (PyErr_Occurred())
       
   734                       return -1;
       
   735               }
       
   736               else
       
   737               {
       
   738                   jdouble *d = va_arg(list, jdouble *);
       
   739                   *d = (jdouble) PyFloat_AsDouble(arg);
       
   740               }
       
   741               break;
       
   742           }
       
   743 
       
   744           case 'F':           /* float */
       
   745           {
       
   746               if (array)
       
   747               {
       
   748                   JArray<jfloat> *array = va_arg(list, JArray<jfloat> *);
       
   749 
       
   750                   if (arg == Py_None)
       
   751                       *array = JArray<jfloat>((jobject) NULL);
       
   752                   else if (PyObject_TypeCheck(arg, JArrayFloat$$Type))
       
   753                       *array = ((t_jarray<jfloat> *) arg)->array;
       
   754                   else 
       
   755                       *array = JArray<jfloat>(arg);
       
   756 
       
   757                   if (PyErr_Occurred())
       
   758                       return -1;
       
   759               }
       
   760               else
       
   761               {
       
   762                   jfloat *d = va_arg(list, jfloat *);
       
   763                   *d = (jfloat) (float) PyFloat_AsDouble(arg);
       
   764               }
       
   765               break;
       
   766           }
       
   767 
       
   768           case 'J':           /* long long */
       
   769           {
       
   770               if (array)
       
   771               {
       
   772                   JArray<jlong> *array = va_arg(list, JArray<jlong> *);
       
   773 
       
   774                   if (arg == Py_None)
       
   775                       *array = JArray<jlong>((jobject) NULL);
       
   776                   else if (PyObject_TypeCheck(arg, JArrayLong$$Type))
       
   777                       *array = ((t_jarray<jlong> *) arg)->array;
       
   778                   else 
       
   779                       *array = JArray<jlong>(arg);
       
   780 
       
   781                   if (PyErr_Occurred())
       
   782                       return -1;
       
   783               }
       
   784               else
       
   785               {
       
   786                   jlong *l = va_arg(list, jlong *);
       
   787                   *l = (jlong) PyLong_AsLongLong(arg);
       
   788               }
       
   789               break;
       
   790           }
       
   791 
       
   792           case 's':           /* string  */
       
   793           {
       
   794               if (array)
       
   795               {
       
   796                   JArray<jstring> *array = va_arg(list, JArray<jstring> *);
       
   797 
       
   798                   if (arg == Py_None)
       
   799                       *array = JArray<jstring>((jobject) NULL);
       
   800                   else if (PyObject_TypeCheck(arg, JArrayString$$Type))
       
   801                       *array = ((t_jarray<jstring> *) arg)->array;
       
   802                   else 
       
   803                       *array = JArray<jstring>(arg);
       
   804 
       
   805                   if (PyErr_Occurred())
       
   806                       return -1;
       
   807               }
       
   808               else
       
   809               {
       
   810                   String *str = va_arg(list, String *);
       
   811 
       
   812                   if (arg == Py_None)
       
   813                       *str = String(NULL);
       
   814                   else
       
   815                   {
       
   816                       *str = p2j(arg);
       
   817                       if (PyErr_Occurred())
       
   818                           return -1;
       
   819                   }
       
   820               }
       
   821               break;
       
   822           }
       
   823 
       
   824           case 'o':           /* java.lang.Object  */
       
   825           {
       
   826               if (array)
       
   827               {
       
   828                   JArray<Object> *array = va_arg(list, JArray<Object> *);
       
   829 
       
   830                   if (arg == Py_None)
       
   831                       *array = JArray<Object>((jobject) NULL);
       
   832                   else 
       
   833                       *array = JArray<Object>(arg);
       
   834 
       
   835                   if (PyErr_Occurred())
       
   836                       return -1;
       
   837               }
       
   838               else
       
   839               {
       
   840                   Object *obj = va_arg(list, Object *);
       
   841 
       
   842                   if (arg == Py_None)
       
   843                       *obj = Object(NULL);
       
   844                   else if (PyObject_TypeCheck(arg, &Object$$Type))
       
   845                       *obj = ((t_Object *) arg)->object;
       
   846                   else if (PyObject_TypeCheck(arg, &FinalizerProxy$$Type))
       
   847                   {
       
   848                       arg = ((t_fp *) arg)->object;
       
   849                       if (PyObject_TypeCheck(arg, &Object$$Type))
       
   850                           *obj = ((t_Object *) arg)->object;
       
   851                       else
       
   852                           return -1;
       
   853                   }
       
   854                   else if (PyString_Check(arg) || PyUnicode_Check(arg))
       
   855                   {
       
   856                       *obj = p2j(arg);
       
   857                       if (PyErr_Occurred())
       
   858                           return -1;
       
   859                   }
       
   860                   else if (arg == Py_True)
       
   861                       *obj = *Boolean::TRUE;
       
   862                   else if (arg == Py_False)
       
   863                       *obj = *Boolean::FALSE;
       
   864                   else if (PyInt_Check(arg))
       
   865                   {
       
   866                       long ln = PyInt_AS_LONG(arg);
       
   867                       int n = (int) ln;
       
   868 
       
   869                       if (ln != (long) n)
       
   870                           *obj = Long((jlong) ln);
       
   871                       else
       
   872                           *obj = Integer((jint) n);
       
   873                   }
       
   874                   else if (PyLong_Check(arg))
       
   875                       *obj = Long((jlong) PyLong_AsLongLong(arg));
       
   876                   else if (PyFloat_Check(arg))
       
   877                       *obj = Double((jdouble) PyFloat_AS_DOUBLE(arg));
       
   878                   else
       
   879                       return -1;
       
   880               }
       
   881               break;
       
   882           }
       
   883 
       
   884           default:
       
   885             return -1;
       
   886         }
       
   887 
       
   888         if (types[pos] != '[')
       
   889             array = 0;
       
   890     }
       
   891 
       
   892     if (pos == typeCount)
       
   893         return 0;
       
   894 
       
   895     return -1;
       
   896 }
       
   897 
       
   898 
       
   899 String p2j(PyObject *object)
       
   900 {
       
   901     return String(env->fromPyString(object));
       
   902 }
       
   903 
       
   904 PyObject *j2p(const String& js)
       
   905 {
       
   906     return env->fromJString((jstring) js.this$, 0);
       
   907 }
       
   908 
       
   909 PyObject *PyErr_SetArgsError(char *name, PyObject *args)
       
   910 {
       
   911     if (!PyErr_Occurred())
       
   912     {
       
   913         PyObject *err = Py_BuildValue("(sO)", name, args);
       
   914 
       
   915         PyErr_SetObject(PyExc_InvalidArgsError, err);
       
   916         Py_DECREF(err);
       
   917     }
       
   918 
       
   919     return NULL;
       
   920 }
       
   921 
       
   922 PyObject *PyErr_SetArgsError(PyObject *self, char *name, PyObject *args)
       
   923 {
       
   924     if (!PyErr_Occurred())
       
   925     {
       
   926         PyObject *type = (PyObject *) self->ob_type;
       
   927         PyObject *err = Py_BuildValue("(OsO)", type, name, args);
       
   928 
       
   929         PyErr_SetObject(PyExc_InvalidArgsError, err);
       
   930         Py_DECREF(err);
       
   931     }
       
   932 
       
   933     return NULL;
       
   934 }
       
   935 
       
   936 PyObject *PyErr_SetArgsError(PyTypeObject *type, char *name, PyObject *args)
       
   937 {
       
   938     if (!PyErr_Occurred())
       
   939     {
       
   940         PyObject *err = Py_BuildValue("(OsO)", type, name, args);
       
   941 
       
   942         PyErr_SetObject(PyExc_InvalidArgsError, err);
       
   943         Py_DECREF(err);
       
   944     }
       
   945 
       
   946     return NULL;
       
   947 }
       
   948 
       
   949 PyObject *PyErr_SetJavaError(jthrowable throwable)
       
   950 {
       
   951     PyObject *err = t_Throwable::wrap_Object(Throwable(throwable));
       
   952 
       
   953     PyErr_SetObject(PyExc_JavaError, err);
       
   954     Py_DECREF(err);
       
   955 
       
   956     return NULL;
       
   957 }
       
   958 
       
   959 void throwPythonError(void)
       
   960 {
       
   961     PyObject *exc = PyErr_Occurred();
       
   962 
       
   963     if (exc && PyErr_GivenExceptionMatches(exc, PyExc_JavaError))
       
   964     {
       
   965         PyObject *value, *traceback;
       
   966 
       
   967         PyErr_Fetch(&exc, &value, &traceback);
       
   968         if (value)
       
   969         {
       
   970             PyObject *je = PyObject_CallMethod(value, "getJavaException", "");
       
   971 
       
   972             if (!je)
       
   973                 PyErr_Restore(exc, value, traceback);
       
   974             else
       
   975             {
       
   976                 Py_DECREF(exc);
       
   977                 Py_DECREF(value);
       
   978                 Py_XDECREF(traceback);
       
   979                 exc = je;
       
   980 
       
   981                 if (exc && PyObject_TypeCheck(exc, &Throwable$$Type))
       
   982                 {
       
   983                     jobject jobj = ((t_Throwable *) exc)->object.this$;
       
   984 
       
   985                     env->get_vm_env()->Throw((jthrowable) jobj);
       
   986                     Py_DECREF(exc);
       
   987 
       
   988                     return;
       
   989                 }
       
   990             }
       
   991         }
       
   992         else
       
   993         {
       
   994             Py_DECREF(exc);
       
   995             Py_XDECREF(traceback);
       
   996         }
       
   997     }
       
   998     else if (exc && PyErr_GivenExceptionMatches(exc, PyExc_StopIteration))
       
   999     {
       
  1000         PyErr_Clear();
       
  1001         return;
       
  1002     }
       
  1003 
       
  1004     if (exc)
       
  1005     {
       
  1006         PyObject *name = PyObject_GetAttrString(exc, "__name__");
       
  1007 
       
  1008         env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
       
  1009                                     PyString_AS_STRING(name));
       
  1010         Py_DECREF(name);
       
  1011     }
       
  1012     else
       
  1013         env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
       
  1014                                     "python error");
       
  1015 }
       
  1016 
       
  1017 void throwTypeError(const char *name, PyObject *object)
       
  1018 {
       
  1019     PyObject *tuple = Py_BuildValue("(ssO)", "while calling", name, object);
       
  1020 
       
  1021     PyErr_SetObject(PyExc_TypeError, tuple);
       
  1022     Py_DECREF(tuple);
       
  1023 
       
  1024     env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(), "type error");
       
  1025 }
       
  1026 
       
  1027 int abstract_init(PyObject *self, PyObject *args, PyObject *kwds)
       
  1028 {
       
  1029     PyObject *err =
       
  1030         Py_BuildValue("(sO)", "instantiating java class", self->ob_type);
       
  1031 
       
  1032     PyErr_SetObject(PyExc_NotImplementedError, err);
       
  1033     Py_DECREF(err);
       
  1034 
       
  1035     return -1;
       
  1036 }
       
  1037 
       
  1038 PyObject *callSuper(PyTypeObject *type, const char *name, PyObject *args,
       
  1039                     int cardinality)
       
  1040 {
       
  1041     PyObject *super = (PyObject *) type->tp_base;
       
  1042     PyObject *method =
       
  1043         PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
       
  1044     PyObject *value;
       
  1045 
       
  1046     if (!method)
       
  1047         return NULL;
       
  1048 
       
  1049     if (cardinality > 1)
       
  1050         value = PyObject_Call(method, args, NULL);
       
  1051     else
       
  1052     {
       
  1053 #if PY_VERSION_HEX < 0x02040000
       
  1054         PyObject *tuple = Py_BuildValue("(O)", args);
       
  1055 #else
       
  1056         PyObject *tuple = PyTuple_Pack(1, args);
       
  1057 #endif   
       
  1058         value = PyObject_Call(method, tuple, NULL);
       
  1059         Py_DECREF(tuple);
       
  1060     }
       
  1061 
       
  1062     Py_DECREF(method);
       
  1063 
       
  1064     return value;
       
  1065 }
       
  1066 
       
  1067 PyObject *callSuper(PyTypeObject *type, PyObject *self,
       
  1068                     const char *name, PyObject *args, int cardinality)
       
  1069 {
       
  1070 #if PY_VERSION_HEX < 0x02040000
       
  1071     PyObject *tuple = Py_BuildValue("(OO)", type, self);
       
  1072 #else
       
  1073     PyObject *tuple = PyTuple_Pack(2, type, self);
       
  1074 #endif
       
  1075     PyObject *super = PyObject_Call((PyObject *) &PySuper_Type, tuple, NULL);
       
  1076     PyObject *method, *value;
       
  1077 
       
  1078     Py_DECREF(tuple);
       
  1079     if (!super)
       
  1080         return NULL;
       
  1081 
       
  1082     method = PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
       
  1083     Py_DECREF(super);
       
  1084     if (!method)
       
  1085         return NULL;
       
  1086 
       
  1087     if (cardinality > 1)
       
  1088         value = PyObject_Call(method, args, NULL);
       
  1089     else
       
  1090     {
       
  1091 #if PY_VERSION_HEX < 0x02040000
       
  1092         tuple = Py_BuildValue("(O)", args);
       
  1093 #else
       
  1094         tuple = PyTuple_Pack(1, args);
       
  1095 #endif
       
  1096         value = PyObject_Call(method, tuple, NULL);
       
  1097         Py_DECREF(tuple);
       
  1098     }
       
  1099 
       
  1100     Py_DECREF(method);
       
  1101 
       
  1102     return value;
       
  1103 }
       
  1104 
       
  1105 PyObject *castCheck(PyObject *obj, getclassfn initializeClass,
       
  1106                     int reportError)
       
  1107 {
       
  1108     if (PyObject_TypeCheck(obj, &FinalizerProxy$$Type))
       
  1109         obj = ((t_fp *) obj)->object;
       
  1110 
       
  1111     if (!PyObject_TypeCheck(obj, &Object$$Type))
       
  1112     {
       
  1113         if (reportError)
       
  1114             PyErr_SetObject(PyExc_TypeError, obj);
       
  1115         return NULL;
       
  1116     }
       
  1117 
       
  1118     jobject jobj = ((t_Object *) obj)->object.this$;
       
  1119 
       
  1120     if (jobj)
       
  1121     {
       
  1122         jclass cls;
       
  1123 
       
  1124         try {
       
  1125             cls = (*initializeClass)();
       
  1126         } catch (JCCEnv::pythonError e) {
       
  1127             return NULL;
       
  1128         } catch (JCCEnv::exception e) {
       
  1129             PyErr_SetJavaError(e.throwable);
       
  1130             return NULL;
       
  1131         }
       
  1132 
       
  1133         if (!env->get_vm_env()->IsInstanceOf(jobj, cls))
       
  1134         {
       
  1135             if (reportError)
       
  1136                 PyErr_SetObject(PyExc_TypeError, obj);
       
  1137 
       
  1138             return NULL;
       
  1139         }
       
  1140     }
       
  1141 
       
  1142     return obj;
       
  1143 }
       
  1144 
       
  1145 PyObject *get_extension_iterator(PyObject *self)
       
  1146 {
       
  1147     return PyObject_CallMethod(self, "iterator", "");
       
  1148 }
       
  1149 
       
  1150 PyObject *get_extension_next(PyObject *self)
       
  1151 {
       
  1152     return PyObject_CallMethod(self, "next", "");
       
  1153 }
       
  1154 
       
  1155 PyObject *get_extension_nextElement(PyObject *self)
       
  1156 {
       
  1157     return PyObject_CallMethod(self, "nextElement", "");
       
  1158 }
       
  1159 
       
  1160 jobjectArray fromPySequence(jclass cls, PyObject *sequence)
       
  1161 {
       
  1162     if (sequence == Py_None)
       
  1163         return NULL;
       
  1164 
       
  1165     if (!PySequence_Check(sequence))
       
  1166     {
       
  1167         PyErr_SetObject(PyExc_TypeError, sequence);
       
  1168         return NULL;
       
  1169     }
       
  1170 
       
  1171     int length = PySequence_Length(sequence);
       
  1172     jobjectArray array;
       
  1173 
       
  1174     try {
       
  1175         array = env->newObjectArray(cls, length);
       
  1176     } catch (JCCEnv::pythonError) {
       
  1177         return NULL;
       
  1178     } catch (JCCEnv::exception e) {
       
  1179         PyErr_SetJavaError(e.throwable);
       
  1180         return NULL;
       
  1181     }
       
  1182 
       
  1183     JNIEnv *vm_env = env->get_vm_env();
       
  1184 
       
  1185     for (int i = 0; i < length; i++) {
       
  1186         PyObject *obj = PySequence_GetItem(sequence, i);
       
  1187         int fromString = 0;
       
  1188         jobject jobj;
       
  1189 
       
  1190         if (!obj)
       
  1191             break;
       
  1192         else if (obj == Py_None)
       
  1193             jobj = NULL;
       
  1194         else if (PyString_Check(obj) || PyUnicode_Check(obj))
       
  1195         {
       
  1196             jobj = env->fromPyString(obj);
       
  1197             fromString = 1;
       
  1198         }
       
  1199         else if (PyObject_TypeCheck(obj, &JObject$$Type))
       
  1200             jobj = ((t_JObject *) obj)->object.this$;
       
  1201         else if (PyObject_TypeCheck(obj, &FinalizerProxy$$Type))
       
  1202             jobj = ((t_JObject *) ((t_fp *) obj)->object)->object.this$;
       
  1203         else /* todo: add auto-boxing of primitive types */
       
  1204         {
       
  1205             PyErr_SetObject(PyExc_TypeError, obj);
       
  1206             Py_DECREF(obj);
       
  1207             return NULL;
       
  1208         }
       
  1209 
       
  1210         Py_DECREF(obj);
       
  1211 
       
  1212         try {
       
  1213             env->setObjectArrayElement(array, i, jobj);
       
  1214             if (fromString)
       
  1215                 vm_env->DeleteLocalRef(jobj);
       
  1216         } catch (JCCEnv::exception e) {
       
  1217             PyErr_SetJavaError(e.throwable);
       
  1218             return NULL;
       
  1219         }
       
  1220     }
       
  1221 
       
  1222     return array;
       
  1223 }
       
  1224 
       
  1225 void installType(PyTypeObject *type, PyObject *module, char *name,
       
  1226                  int isExtension)
       
  1227 {
       
  1228     if (PyType_Ready(type) == 0)
       
  1229     {
       
  1230         Py_INCREF(type);
       
  1231         if (isExtension)
       
  1232         {
       
  1233             type->ob_type = &FinalizerClass$$Type;
       
  1234             Py_INCREF(&FinalizerClass$$Type);
       
  1235         }
       
  1236         PyModule_AddObject(module, name, (PyObject *) type);
       
  1237     }
       
  1238 }
       
  1239 
       
  1240 PyObject *wrapType(PyTypeObject *type, const jobject& obj)
       
  1241 {
       
  1242     PyObject *cobj = PyObject_GetAttrString((PyObject *) type, "wrapfn_");
       
  1243     PyObject *(*wrapfn)(const jobject&);
       
  1244     
       
  1245     if (cobj == NULL)
       
  1246         return NULL;
       
  1247 
       
  1248     wrapfn = (PyObject *(*)(const jobject &)) PyCObject_AsVoidPtr(cobj);
       
  1249     Py_DECREF(cobj);
       
  1250 
       
  1251     return wrapfn(obj);
       
  1252 }
       
  1253 
       
  1254 #ifdef _java_generics
       
  1255 PyObject *typeParameters(PyTypeObject *types[], size_t size)
       
  1256 {
       
  1257     size_t count = size / sizeof(PyTypeObject *);
       
  1258     PyObject *tuple = PyTuple_New(count);
       
  1259 
       
  1260     for (size_t i = 0; i < count; i++) {
       
  1261         PyObject *type = (PyObject *) types[i];
       
  1262         
       
  1263         if (type == NULL)
       
  1264             type = Py_None;
       
  1265 
       
  1266         PyTuple_SET_ITEM(tuple, i, type);
       
  1267         Py_INCREF(type);
       
  1268     }
       
  1269 
       
  1270     return tuple;
       
  1271 }
       
  1272 #endif