pylucene 3.5.0-3
[pylucene.git] / jcc / jcc / sources / functions.cpp
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/Byte.h"
24 #include "java/lang/Character.h"
25 #include "java/lang/Double.h"
26 #include "java/lang/Float.h"
27 #include "java/lang/Integer.h"
28 #include "java/lang/Long.h"
29 #include "java/lang/Short.h"
30 #include "java/util/Iterator.h"
31 #include "JArray.h"
32 #include "functions.h"
33 #include "macros.h"
34
35 using namespace java::lang;
36 using namespace java::util;
37
38 PyObject *PyExc_JavaError = PyExc_ValueError;
39 PyObject *PyExc_InvalidArgsError = PyExc_ValueError;
40
41 PyObject *_set_exception_types(PyObject *self, PyObject *args)
42 {
43     if (!PyArg_ParseTuple(args, "OO",
44                           &PyExc_JavaError, &PyExc_InvalidArgsError))
45         return NULL;
46
47     Py_RETURN_NONE;
48 }
49
50 PyObject *_set_function_self(PyObject *self, PyObject *args)
51 {
52     PyObject *object, *module;
53
54     if (!PyArg_ParseTuple(args, "OO", &object, &module))
55         return NULL;
56
57     if (!PyCFunction_Check(object))
58     {
59         PyErr_SetObject(PyExc_TypeError, object);
60         return NULL;
61     }
62
63     PyCFunctionObject *cfn = (PyCFunctionObject *) object;
64
65     Py_INCREF(module);
66     Py_XDECREF(cfn->m_self);
67     cfn->m_self = module;
68
69     Py_RETURN_NONE;
70 }
71
72 PyObject *findClass(PyObject *self, PyObject *args)
73 {
74     char *className;
75
76     if (!PyArg_ParseTuple(args, "s", &className))
77         return NULL;
78
79     try {
80         jclass cls = env->findClass(className);
81
82         if (cls)
83             return t_Class::wrap_Object(Class(cls));
84     } catch (int e) {
85         switch (e) {
86           case _EXC_PYTHON:
87             return NULL;
88           case _EXC_JAVA:
89             return PyErr_SetJavaError();
90           default:
91             throw;
92         }
93     }
94
95     Py_RETURN_NONE;
96 }
97
98 static boxfn get_boxfn(PyTypeObject *type)
99 {
100     static PyObject *boxfn_ = PyString_FromString("boxfn_");
101     PyObject *cobj = PyObject_GetAttr((PyObject *) type, boxfn_);
102     boxfn fn;
103     
104     if (cobj == NULL)
105         return NULL;
106
107     fn = (boxfn) PyCObject_AsVoidPtr(cobj);
108     Py_DECREF(cobj);
109
110     return fn;
111 }
112
113 static int is_instance_of(PyObject *arg, PyTypeObject *type)
114 {
115     static PyObject *class_ = PyString_FromString("class_");
116     PyObject *clsObj = PyObject_GetAttr((PyObject *) type, class_);
117     int result;
118
119     if (clsObj == NULL)
120         return -1;
121
122     result = env->get_vm_env()->
123         IsInstanceOf(((t_Object *) arg)->object.this$,
124                      (jclass) ((t_Object *) clsObj)->object.this$);
125     Py_DECREF(clsObj);
126
127     return result;
128 }
129
130
131 #if defined(_MSC_VER) || defined(__SUNPRO_CC)
132 int __parseArgs(PyObject *args, char *types, ...)
133 {
134     int count = ((PyTupleObject *)(args))->ob_size;
135     va_list list, check;
136
137     va_start(list, types);
138     va_start(check, types);
139
140     return _parseArgs(((PyTupleObject *)(args))->ob_item, count, types,
141                       list, check);
142 }
143
144 int __parseArg(PyObject *arg, char *types, ...)
145 {
146     va_list list, check;
147
148     va_start(list, types);
149     va_start(check, types);
150
151     return _parseArgs(&arg, 1, types, list, check);
152 }
153
154 int _parseArgs(PyObject **args, unsigned int count, char *types,
155                va_list list, va_list check)
156 {
157     unsigned int typeCount = strlen(types);
158
159     if (count > typeCount)
160         return -1;
161 #else
162
163 int _parseArgs(PyObject **args, unsigned int count, char *types, ...)
164 {
165     unsigned int typeCount = strlen(types);
166     va_list list, check;
167
168     if (count > typeCount)
169         return -1;
170
171     va_start(list, types);
172     va_start(check, types);
173 #endif
174
175     if (!env->vm)
176     {
177         PyErr_SetString(PyExc_RuntimeError, "initVM() must be called first");
178         return -1;
179     }
180
181     JNIEnv *vm_env = env->get_vm_env();
182
183     if (!vm_env)
184     {
185         PyErr_SetString(PyExc_RuntimeError, "attachCurrentThread() must be called first");
186         return -1;
187     }
188
189     unsigned int pos = 0;
190     int array = 0;
191
192     for (unsigned int a = 0; a < count; a++, pos++) {
193         PyObject *arg = args[a];
194
195         switch (types[pos]) {
196           case '[':
197           {
198               if (++array > 1)
199                   return -1;
200
201               a -= 1;
202               break;
203           }
204
205           case 'j':           /* Java object, with class$    */
206           case 'k':           /* Java object, with initializeClass */
207           case 'K':           /* Java object, with initializeClass and params */
208           {
209               jclass cls = NULL;
210
211               switch (types[pos]) {
212                 case 'j':
213                   cls = (jclass) va_arg(list, Class *)->this$;
214                   break;
215                 case 'k':
216                 case 'K':
217                   try {
218                       getclassfn initializeClass = va_arg(list, getclassfn);
219                       cls = (*initializeClass)();
220                   } catch (int e) {
221                       switch (e) {
222                         case _EXC_PYTHON:
223                           return -1;
224                         case _EXC_JAVA:
225                           PyErr_SetJavaError();
226                           return -1;
227                         default:
228                           throw;
229                       }
230                   }
231                   break;
232               }
233
234               if (arg == Py_None)
235                   break;
236
237               /* ensure that class Class is initialized (which may not be the
238                * case because of earlier recursion avoidance (JObject(cls)).
239                */
240               if (!Class::class$)
241                   Class::initializeClass();
242
243               if (array)
244               {
245                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayObject)))
246                       break;
247
248                   if (PySequence_Check(arg) &&
249                       !PyString_Check(arg) && !PyUnicode_Check(arg))
250                   {
251                       if (PySequence_Length(arg) > 0)
252                       {
253                           PyObject *obj = PySequence_GetItem(arg, 0);
254                           int ok = 0;
255
256                           if (obj == Py_None)
257                               ok = 1;
258                           else if (PyObject_TypeCheck(obj, &PY_TYPE(Object)) &&
259                                    vm_env->IsInstanceOf(((t_Object *) obj)->object.this$, cls))
260                               ok = 1;
261                           else if (PyObject_TypeCheck(obj, &PY_TYPE(FinalizerProxy)))
262                           {
263                               PyObject *o = ((t_fp *) obj)->object;
264
265                               if (PyObject_TypeCheck(o, &PY_TYPE(Object)) &&
266                                   vm_env->IsInstanceOf(((t_Object *) o)->object.this$, cls))
267                                   ok = 1;
268                           }
269
270                           Py_DECREF(obj);
271                           if (ok)
272                               break;
273                       }
274                       else
275                           break;
276                   }
277               }
278               else if (PyObject_TypeCheck(arg, &PY_TYPE(Object)) &&
279                        vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
280                   break;
281               else if (PyObject_TypeCheck(arg, &PY_TYPE(FinalizerProxy)))
282               {
283                   arg = ((t_fp *) arg)->object;
284                   if (PyObject_TypeCheck(arg, &PY_TYPE(Object)) &&
285                       vm_env->IsInstanceOf(((t_Object *) arg)->object.this$, cls))
286                       break;
287               }
288
289               return -1;
290           }
291
292           case 'Z':           /* boolean, strict */
293           {
294               if (array)
295               {
296                   if (arg == Py_None)
297                       break;
298
299                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayBool)))
300                       break;
301
302                   if (PySequence_Check(arg))
303                   {
304                       if (PySequence_Length(arg) > 0)
305                       {
306                           PyObject *obj = PySequence_GetItem(arg, 0);
307                           int ok = obj == Py_True || obj == Py_False;
308
309                           Py_DECREF(obj);
310                           if (ok)
311                               break;
312                       }
313                       else
314                           break;
315                   }
316               }
317               else if (arg == Py_True || arg == Py_False)
318                   break;
319
320               return -1;
321           }
322
323           case 'B':           /* byte */
324           {
325               if (array)
326               {
327                   if (arg == Py_None)
328                       break;
329                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayByte)))
330                       break;
331               }
332               else if (PyString_Check(arg) && (PyString_Size(arg) == 1))
333                   break;
334               else if (PyInt_CheckExact(arg))
335                   break;
336
337               return -1;
338           }
339
340           case 'C':           /* char */
341           {
342               if (array)
343               {
344                   if (arg == Py_None)
345                       break;
346                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayChar)))
347                       break;
348               }
349               else if (PyUnicode_Check(arg) && PyUnicode_GET_SIZE(arg) == 1)
350                   break;
351               return -1;
352           }
353
354           case 'I':           /* int */
355           {
356               if (array)
357               {
358                   if (arg == Py_None)
359                       break;
360
361                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayInt)))
362                       break;
363
364                   if (PySequence_Check(arg))
365                   {
366                       if (PySequence_Length(arg) > 0)
367                       {
368                           PyObject *obj = PySequence_GetItem(arg, 0);
369                           int ok = PyInt_CheckExact(obj);
370
371                           Py_DECREF(obj);
372                           if (ok)
373                               break;
374                       }
375                       else
376                           break;
377                   }
378               }
379               else if (PyInt_CheckExact(arg))
380                   break;
381
382               return -1;
383           }
384
385           case 'S':           /* short */
386           {
387               if (array)
388               {
389                   if (arg == Py_None)
390                       break;
391
392                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayShort)))
393                       break;
394
395                   if (PySequence_Check(arg))
396                   {
397                       if (PySequence_Length(arg) > 0)
398                       {
399                           PyObject *obj = PySequence_GetItem(arg, 0);
400                           int ok = PyInt_CheckExact(obj);
401
402                           Py_DECREF(obj);
403                           if (ok)
404                               break;
405                       }
406                       else
407                           break;
408                   }
409               }
410               else if (PyInt_CheckExact(arg))
411                   break;
412
413               return -1;
414           }
415
416           case 'D':           /* double */
417           {
418               if (array)
419               {
420                   if (arg == Py_None)
421                       break;
422
423                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayDouble)))
424                       break;
425
426                   if (PySequence_Check(arg))
427                   {
428                       if (PySequence_Length(arg) > 0)
429                       {
430                           PyObject *obj = PySequence_GetItem(arg, 0);
431                           int ok = PyFloat_CheckExact(obj);
432
433                           Py_DECREF(obj);
434                           if (ok)
435                               break;
436                       }
437                       else
438                           break;
439                   }
440               }
441               else if (PyFloat_CheckExact(arg))
442                   break;
443
444               return -1;
445           }
446
447           case 'F':           /* float */
448           {
449               if (array)
450               {
451                   if (arg == Py_None)
452                       break;
453
454                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayFloat)))
455                       break;
456
457                   if (PySequence_Check(arg))
458                   {
459                       if (PySequence_Length(arg) > 0)
460                       {
461                           PyObject *obj = PySequence_GetItem(arg, 0);
462                           int ok = PyFloat_CheckExact(obj);
463
464                           Py_DECREF(obj);
465                           if (ok)
466                               break;
467                       }
468                       else
469                           break;
470                   }
471               }
472               else if (PyFloat_CheckExact(arg))
473                   break;
474
475               return -1;
476           }
477
478           case 'J':           /* long long */
479           {
480               if (array)
481               {
482                   if (arg == Py_None)
483                       break;
484
485                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayLong)))
486                       break;
487
488                   if (PySequence_Check(arg))
489                   {
490                       if (PySequence_Length(arg) > 0)
491                       {
492                           PyObject *obj = PySequence_GetItem(arg, 0);
493                           int ok = PyLong_CheckExact(obj);
494
495                           Py_DECREF(obj);
496                           if (ok)
497                               break;
498                       }
499                       else
500                           break;
501                   }
502               }
503               else if (PyLong_CheckExact(arg))
504                   break;
505
506               return -1;
507           }
508
509           case 's':           /* string  */
510           {
511               if (array)
512               {
513                   if (arg == Py_None)
514                       break;
515
516                   if (PyObject_TypeCheck(arg, PY_TYPE(JArrayString)))
517                       break;
518
519                   if (PySequence_Check(arg) && 
520                       !PyString_Check(arg) && !PyUnicode_Check(arg))
521                   {
522                       if (PySequence_Length(arg) > 0)
523                       {
524                           PyObject *obj = PySequence_GetItem(arg, 0);
525                           int ok =
526                               (obj == Py_None ||
527                                PyString_Check(obj) || PyUnicode_Check(obj));
528
529                           Py_DECREF(obj);
530                           if (ok)
531                               break;
532                       }
533                       else
534                           break;
535                   }
536               }
537               else if (arg == Py_None ||
538                        PyString_Check(arg) || PyUnicode_Check(arg))
539                   break;
540
541               return -1;
542           }
543
544           case 'o':         /* java.lang.Object */
545             break;
546
547           case 'O':         /* java.lang.Object with type param */
548           {
549               PyTypeObject *type = va_arg(list, PyTypeObject *);
550
551               if (type != NULL)
552               {
553                   boxfn fn = get_boxfn(type);
554     
555                   if (fn == NULL || fn(type, arg, NULL) < 0)
556                       return -1;
557               }
558               break;
559           }
560
561           case 'T':         /* tuple of python types with wrapfn_ */
562           {
563               static PyObject *wrapfn_ = PyString_FromString("wrapfn_");
564               int len = va_arg(list, int);
565
566               if (PyTuple_Check(arg))
567               {
568                   if (PyTuple_GET_SIZE(arg) != len)
569                       return -1;
570
571                   for (int i = 0; i < len; i++) {
572                       PyObject *type = PyTuple_GET_ITEM(arg, i);
573
574                       if (!(type == Py_None ||
575                             (PyType_Check(type) &&
576                              PyObject_HasAttr(type, wrapfn_))))
577                           return -1;
578                   }
579                   break;
580               }
581               return -1;
582           }
583
584           default:
585             return -1;
586         }
587
588         if (types[pos] != '[')
589             array = 0;
590     }
591
592     if (array)
593         return -1;
594
595     if (pos != typeCount)
596       return -1;
597
598     pos = 0;
599
600     for (unsigned int a = 0; a < count; a++, pos++) {
601         PyObject *arg = args[a];
602         
603         switch (types[pos]) {
604           case '[':
605           {
606               if (++array > 1)
607                   return -1;
608
609               a -= 1;
610               break;
611           }
612
613           case 'j':           /* Java object except String and Object */
614           case 'k':           /* Java object, with initializeClass    */
615           case 'K':           /* Java object, with initializeClass and params */
616           {
617               jclass cls = NULL;
618
619               switch (types[pos]) {
620                 case 'j':
621                   cls = (jclass) va_arg(check, Class *)->this$;
622                   break;
623                 case 'k':
624                 case 'K':
625                   getclassfn initializeClass = va_arg(check, getclassfn);
626                   cls = (*initializeClass)();
627                   break;
628               }
629
630               if (array)
631               {
632                   JArray<jobject> *array = va_arg(list, JArray<jobject> *);
633
634 #ifdef _java_generics
635                   if (types[pos] == 'K')
636                   {
637                       PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
638
639                       va_arg(list, getparametersfn);
640                       *tp = NULL;
641                   }
642 #endif
643                   if (arg == Py_None)
644                       *array = JArray<jobject>((jobject) NULL);
645                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayObject)))
646                       *array = ((t_JArray<jobject> *) arg)->array;
647                   else 
648                       *array = JArray<jobject>(cls, arg);
649
650                   if (PyErr_Occurred())
651                       return -1;
652               }
653               else
654               {
655                   Object *obj = va_arg(list, Object *);
656
657                   if (PyObject_TypeCheck(arg, &PY_TYPE(FinalizerProxy)))
658                       arg = ((t_fp *) arg)->object;
659
660 #ifdef _java_generics
661                   if (types[pos] == 'K')
662                   {
663                       PyTypeObject ***tp = va_arg(list, PyTypeObject ***);
664                       PyTypeObject **(*parameters_)(void *) = 
665                           va_arg(list, getparametersfn);
666
667                       if (arg == Py_None)
668                           *tp = NULL;
669                       else
670                           *tp = (*parameters_)(arg);
671                   }
672 #endif
673
674                   *obj = arg == Py_None
675                       ? Object(NULL)
676                       : ((t_Object *) arg)->object;
677               }
678               break;
679           }
680
681           case 'Z':           /* boolean, strict */
682           {
683               if (array)
684               {
685                   JArray<jboolean> *array = va_arg(list, JArray<jboolean> *);
686
687                   if (arg == Py_None)
688                       *array = JArray<jboolean>((jobject) NULL);
689                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayBool)))
690                       *array = ((t_JArray<jboolean> *) arg)->array;
691                   else
692                       *array = JArray<jboolean>(arg);
693
694                   if (PyErr_Occurred())
695                       return -1;
696               }
697               else
698               {
699                   jboolean *b = va_arg(list, jboolean *);
700                   *b = arg == Py_True;
701               }
702               break;
703           }
704
705           case 'B':           /* byte */
706           {
707               if (array)
708               {
709                   JArray<jbyte> *array = va_arg(list, JArray<jbyte> *);
710
711                   if (arg == Py_None)
712                       *array = JArray<jbyte>((jobject) NULL);
713                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayByte)))
714                       *array = ((t_JArray<jbyte> *) arg)->array;
715                   else 
716                       *array = JArray<jbyte>(arg);
717
718                   if (PyErr_Occurred())
719                       return -1;
720               }
721               else if (PyString_Check(arg))
722               {
723                   jbyte *a = va_arg(list, jbyte *);
724                   *a = (jbyte) PyString_AS_STRING(arg)[0];
725               }
726               else
727               {
728                   jbyte *a = va_arg(list, jbyte *);
729                   *a = (jbyte) PyInt_AsLong(arg);
730               }
731               break;
732           }
733
734           case 'C':           /* char */
735           {
736               if (array)
737               {
738                   JArray<jchar> *array = va_arg(list, JArray<jchar> *);
739
740                   if (arg == Py_None)
741                       *array = JArray<jchar>((jobject) NULL);
742                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayChar)))
743                       *array = ((t_JArray<jchar> *) arg)->array;
744                   else 
745                       *array = JArray<jchar>(arg);
746
747                   if (PyErr_Occurred())
748                       return -1;
749               }
750               else
751               {
752                   jchar *c = va_arg(list, jchar *);
753                   *c = (jchar) PyUnicode_AS_UNICODE(arg)[0];
754               }
755               break;
756           }
757
758           case 'I':           /* int */
759           {
760               if (array)
761               {
762                   JArray<jint> *array = va_arg(list, JArray<jint> *);
763
764                   if (arg == Py_None)
765                       *array = JArray<jint>((jobject) NULL);
766                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayInt)))
767                       *array = ((t_JArray<jint> *) arg)->array;
768                   else 
769                       *array = JArray<jint>(arg);
770
771                   if (PyErr_Occurred())
772                       return -1;
773               }
774               else
775               {
776                   jint *n = va_arg(list, jint *);
777                   *n = (jint) PyInt_AsLong(arg);
778               }
779               break;
780           }
781
782           case 'S':           /* short */
783           {
784               if (array)
785               {
786                   JArray<jshort> *array = va_arg(list, JArray<jshort> *);
787
788                   if (arg == Py_None)
789                       *array = JArray<jshort>((jobject) NULL);
790                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayShort)))
791                       *array = ((t_JArray<jshort> *) arg)->array;
792                   else 
793                       *array = JArray<jshort>(arg);
794
795                   if (PyErr_Occurred())
796                       return -1;
797               }
798               else
799               {
800                   jshort *n = va_arg(list, jshort *);
801                   *n = (jshort) PyInt_AsLong(arg);
802               }
803               break;
804           }
805
806           case 'D':           /* double */
807           {
808               if (array)
809               {
810                   JArray<jdouble> *array = va_arg(list, JArray<jdouble> *);
811
812                   if (arg == Py_None)
813                       *array = JArray<jdouble>((jobject) NULL);
814                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayDouble)))
815                       *array = ((t_JArray<jdouble> *) arg)->array;
816                   else 
817                       *array = JArray<jdouble>(arg);
818
819                   if (PyErr_Occurred())
820                       return -1;
821               }
822               else
823               {
824                   jdouble *d = va_arg(list, jdouble *);
825                   *d = (jdouble) PyFloat_AsDouble(arg);
826               }
827               break;
828           }
829
830           case 'F':           /* float */
831           {
832               if (array)
833               {
834                   JArray<jfloat> *array = va_arg(list, JArray<jfloat> *);
835
836                   if (arg == Py_None)
837                       *array = JArray<jfloat>((jobject) NULL);
838                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayFloat)))
839                       *array = ((t_JArray<jfloat> *) arg)->array;
840                   else 
841                       *array = JArray<jfloat>(arg);
842
843                   if (PyErr_Occurred())
844                       return -1;
845               }
846               else
847               {
848                   jfloat *d = va_arg(list, jfloat *);
849                   *d = (jfloat) (float) PyFloat_AsDouble(arg);
850               }
851               break;
852           }
853
854           case 'J':           /* long long */
855           {
856               if (array)
857               {
858                   JArray<jlong> *array = va_arg(list, JArray<jlong> *);
859
860                   if (arg == Py_None)
861                       *array = JArray<jlong>((jobject) NULL);
862                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayLong)))
863                       *array = ((t_JArray<jlong> *) arg)->array;
864                   else 
865                       *array = JArray<jlong>(arg);
866
867                   if (PyErr_Occurred())
868                       return -1;
869               }
870               else
871               {
872                   jlong *l = va_arg(list, jlong *);
873                   *l = (jlong) PyLong_AsLongLong(arg);
874               }
875               break;
876           }
877
878           case 's':           /* string  */
879           {
880               if (array)
881               {
882                   JArray<jstring> *array = va_arg(list, JArray<jstring> *);
883
884                   if (arg == Py_None)
885                       *array = JArray<jstring>((jobject) NULL);
886                   else if (PyObject_TypeCheck(arg, PY_TYPE(JArrayString)))
887                       *array = ((t_JArray<jstring> *) arg)->array;
888                   else 
889                       *array = JArray<jstring>(arg);
890
891                   if (PyErr_Occurred())
892                       return -1;
893               }
894               else
895               {
896                   String *str = va_arg(list, String *);
897
898                   if (arg == Py_None)
899                       *str = String(NULL);
900                   else
901                   {
902                       *str = p2j(arg);
903                       if (PyErr_Occurred())
904                           return -1;
905                   }
906               }
907               break;
908           }
909
910           case 'o':           /* java.lang.Object  */
911           case 'O':           /* java.lang.Object with type param */
912           {
913               if (array)
914               {
915                   JArray<Object> *array = va_arg(list, JArray<Object> *);
916
917                   if (arg == Py_None)
918                       *array = JArray<Object>((jobject) NULL);
919                   else 
920                       *array = JArray<Object>(arg);
921
922                   if (PyErr_Occurred())
923                       return -1;
924               }
925               else
926               {
927                   Object *obj = va_arg(list, Object *);
928
929                   if (types[pos] == 'O')
930                   {
931                       PyTypeObject *type = va_arg(check, PyTypeObject *);
932
933                       if (type != NULL)
934                       {
935                           boxfn fn = get_boxfn(type);
936
937                           if (fn == NULL || fn(type, arg, obj) < 0)
938                               return -1;
939
940                           break;
941                       }
942                   }
943
944                   if (boxObject(NULL, arg, obj) < 0)
945                       return -1;
946               }
947               break;
948           }
949
950           case 'T':         /* tuple of python types with wrapfn_ */
951           {
952               int len = va_arg(check, int);
953               PyTypeObject **types = va_arg(list, PyTypeObject **);
954
955               for (int i = 0; i < len; i++) {
956                   PyObject *type = PyTuple_GET_ITEM(arg, i);
957
958                   if (type == Py_None)
959                       types[i] = NULL;
960                   else
961                       types[i] = (PyTypeObject *) type;
962               }
963               break;
964           }
965
966           default:
967             return -1;
968         }
969
970         if (types[pos] != '[')
971             array = 0;
972     }
973
974     if (pos == typeCount)
975         return 0;
976
977     return -1;
978 }
979
980
981 String p2j(PyObject *object)
982 {
983     return String(env->fromPyString(object));
984 }
985
986 PyObject *j2p(const String& js)
987 {
988     return env->fromJString((jstring) js.this$, 0);
989 }
990
991 PyObject *PyErr_SetArgsError(char *name, PyObject *args)
992 {
993     if (!PyErr_Occurred())
994     {
995         PyObject *err = Py_BuildValue("(sO)", name, args);
996
997         PyErr_SetObject(PyExc_InvalidArgsError, err);
998         Py_DECREF(err);
999     }
1000
1001     return NULL;
1002 }
1003
1004 PyObject *PyErr_SetArgsError(PyObject *self, char *name, PyObject *args)
1005 {
1006     if (!PyErr_Occurred())
1007     {
1008         PyObject *type = (PyObject *) self->ob_type;
1009         PyObject *err = Py_BuildValue("(OsO)", type, name, args);
1010
1011         PyErr_SetObject(PyExc_InvalidArgsError, err);
1012         Py_DECREF(err);
1013     }
1014
1015     return NULL;
1016 }
1017
1018 PyObject *PyErr_SetArgsError(PyTypeObject *type, char *name, PyObject *args)
1019 {
1020     if (!PyErr_Occurred())
1021     {
1022         PyObject *err = Py_BuildValue("(OsO)", type, name, args);
1023
1024         PyErr_SetObject(PyExc_InvalidArgsError, err);
1025         Py_DECREF(err);
1026     }
1027
1028     return NULL;
1029 }
1030
1031 PyObject *PyErr_SetJavaError()
1032 {
1033     JNIEnv *vm_env = env->get_vm_env();
1034     jthrowable throwable = vm_env->ExceptionOccurred();
1035     PyObject *err;
1036
1037     vm_env->ExceptionClear();
1038     err = t_Throwable::wrap_Object(Throwable(throwable));
1039
1040     PyErr_SetObject(PyExc_JavaError, err);
1041     Py_DECREF(err);
1042
1043     return NULL;
1044 }
1045
1046 void throwPythonError(void)
1047 {
1048     PyObject *exc = PyErr_Occurred();
1049
1050     if (exc && PyErr_GivenExceptionMatches(exc, PyExc_JavaError))
1051     {
1052         PyObject *value, *traceback;
1053
1054         PyErr_Fetch(&exc, &value, &traceback);
1055         if (value)
1056         {
1057             PyObject *je = PyObject_CallMethod(value, "getJavaException", "");
1058
1059             if (!je)
1060                 PyErr_Restore(exc, value, traceback);
1061             else
1062             {
1063                 Py_DECREF(exc);
1064                 Py_DECREF(value);
1065                 Py_XDECREF(traceback);
1066                 exc = je;
1067
1068                 if (exc && PyObject_TypeCheck(exc, &PY_TYPE(Throwable)))
1069                 {
1070                     jobject jobj = ((t_Throwable *) exc)->object.this$;
1071
1072                     env->get_vm_env()->Throw((jthrowable) jobj);
1073                     Py_DECREF(exc);
1074
1075                     return;
1076                 }
1077             }
1078         }
1079         else
1080         {
1081             Py_DECREF(exc);
1082             Py_XDECREF(traceback);
1083         }
1084     }
1085     else if (exc && PyErr_GivenExceptionMatches(exc, PyExc_StopIteration))
1086     {
1087         PyErr_Clear();
1088         return;
1089     }
1090
1091     if (exc)
1092     {
1093         PyObject *name = PyObject_GetAttrString(exc, "__name__");
1094
1095         env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
1096                                     PyString_AS_STRING(name));
1097         Py_DECREF(name);
1098     }
1099     else
1100         env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(),
1101                                     "python error");
1102 }
1103
1104 void throwTypeError(const char *name, PyObject *object)
1105 {
1106     PyObject *tuple = Py_BuildValue("(ssO)", "while calling", name, object);
1107
1108     PyErr_SetObject(PyExc_TypeError, tuple);
1109     Py_DECREF(tuple);
1110
1111     env->get_vm_env()->ThrowNew(env->getPythonExceptionClass(), "type error");
1112 }
1113
1114 int abstract_init(PyObject *self, PyObject *args, PyObject *kwds)
1115 {
1116     PyObject *err =
1117         Py_BuildValue("(sO)", "instantiating java class", self->ob_type);
1118
1119     PyErr_SetObject(PyExc_NotImplementedError, err);
1120     Py_DECREF(err);
1121
1122     return -1;
1123 }
1124
1125 PyObject *callSuper(PyTypeObject *type, const char *name, PyObject *args,
1126                     int cardinality)
1127 {
1128     PyObject *super = (PyObject *) type->tp_base;
1129     PyObject *method =
1130         PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
1131     PyObject *value;
1132
1133     if (!method)
1134         return NULL;
1135
1136     if (cardinality > 1)
1137         value = PyObject_Call(method, args, NULL);
1138     else
1139     {
1140 #if PY_VERSION_HEX < 0x02040000
1141         PyObject *tuple = Py_BuildValue("(O)", args);
1142 #else
1143         PyObject *tuple = PyTuple_Pack(1, args);
1144 #endif   
1145         value = PyObject_Call(method, tuple, NULL);
1146         Py_DECREF(tuple);
1147     }
1148
1149     Py_DECREF(method);
1150
1151     return value;
1152 }
1153
1154 PyObject *callSuper(PyTypeObject *type, PyObject *self,
1155                     const char *name, PyObject *args, int cardinality)
1156 {
1157 #if PY_VERSION_HEX < 0x02040000
1158     PyObject *tuple = Py_BuildValue("(OO)", type, self);
1159 #else
1160     PyObject *tuple = PyTuple_Pack(2, type, self);
1161 #endif
1162     PyObject *super = PyObject_Call((PyObject *) &PySuper_Type, tuple, NULL);
1163     PyObject *method, *value;
1164
1165     Py_DECREF(tuple);
1166     if (!super)
1167         return NULL;
1168
1169     method = PyObject_GetAttrString(super, (char *) name); // python 2.4 cast
1170     Py_DECREF(super);
1171     if (!method)
1172         return NULL;
1173
1174     if (cardinality > 1)
1175         value = PyObject_Call(method, args, NULL);
1176     else
1177     {
1178 #if PY_VERSION_HEX < 0x02040000
1179         tuple = Py_BuildValue("(O)", args);
1180 #else
1181         tuple = PyTuple_Pack(1, args);
1182 #endif
1183         value = PyObject_Call(method, tuple, NULL);
1184         Py_DECREF(tuple);
1185     }
1186
1187     Py_DECREF(method);
1188
1189     return value;
1190 }
1191
1192 PyObject *castCheck(PyObject *obj, getclassfn initializeClass,
1193                     int reportError)
1194 {
1195     if (PyObject_TypeCheck(obj, &PY_TYPE(FinalizerProxy)))
1196         obj = ((t_fp *) obj)->object;
1197
1198     if (!PyObject_TypeCheck(obj, &PY_TYPE(Object)))
1199     {
1200         if (reportError)
1201             PyErr_SetObject(PyExc_TypeError, obj);
1202         return NULL;
1203     }
1204
1205     jobject jobj = ((t_Object *) obj)->object.this$;
1206
1207     if (jobj && !env->isInstanceOf(jobj, initializeClass))
1208     {
1209         if (reportError)
1210             PyErr_SetObject(PyExc_TypeError, obj);
1211
1212         return NULL;
1213     }
1214
1215     return obj;
1216 }
1217
1218 PyObject *get_extension_iterator(PyObject *self)
1219 {
1220     return PyObject_CallMethod(self, "iterator", "");
1221 }
1222
1223 PyObject *get_extension_next(PyObject *self)
1224 {
1225     return PyObject_CallMethod(self, "next", "");
1226 }
1227
1228 PyObject *get_extension_nextElement(PyObject *self)
1229 {
1230     return PyObject_CallMethod(self, "nextElement", "");
1231 }
1232
1233 jobjectArray fromPySequence(jclass cls, PyObject *sequence)
1234 {
1235     if (sequence == Py_None)
1236         return NULL;
1237
1238     if (!PySequence_Check(sequence))
1239     {
1240         PyErr_SetObject(PyExc_TypeError, sequence);
1241         return NULL;
1242     }
1243
1244     int length = PySequence_Length(sequence);
1245     jobjectArray array;
1246
1247     try {
1248         array = env->newObjectArray(cls, length);
1249     } catch (int e) {
1250         switch (e) {
1251           case _EXC_PYTHON:
1252             return NULL;
1253           case _EXC_JAVA:
1254             PyErr_SetJavaError();
1255             return NULL;
1256           default:
1257             throw;
1258         }
1259     }
1260
1261     JNIEnv *vm_env = env->get_vm_env();
1262
1263     for (int i = 0; i < length; i++) {
1264         PyObject *obj = PySequence_GetItem(sequence, i);
1265         int fromString = 0;
1266         jobject jobj;
1267
1268         if (!obj)
1269             break;
1270         else if (obj == Py_None)
1271             jobj = NULL;
1272         else if (PyString_Check(obj) || PyUnicode_Check(obj))
1273         {
1274             jobj = env->fromPyString(obj);
1275             fromString = 1;
1276         }
1277         else if (PyObject_TypeCheck(obj, &PY_TYPE(JObject)))
1278             jobj = ((t_JObject *) obj)->object.this$;
1279         else if (PyObject_TypeCheck(obj, &PY_TYPE(FinalizerProxy)))
1280             jobj = ((t_JObject *) ((t_fp *) obj)->object)->object.this$;
1281         else /* todo: add auto-boxing of primitive types */
1282         {
1283             PyErr_SetObject(PyExc_TypeError, obj);
1284             Py_DECREF(obj);
1285             return NULL;
1286         }
1287
1288         Py_DECREF(obj);
1289
1290         try {
1291             env->setObjectArrayElement(array, i, jobj);
1292             if (fromString)
1293                 vm_env->DeleteLocalRef(jobj);
1294         } catch (int e) {
1295             switch (e) {
1296               case _EXC_JAVA:
1297                 PyErr_SetJavaError();
1298                 return NULL;
1299               default:
1300                 throw;
1301             }
1302         }
1303     }
1304
1305     return array;
1306 }
1307
1308 void installType(PyTypeObject *type, PyObject *module, char *name,
1309                  int isExtension)
1310 {
1311     if (PyType_Ready(type) == 0)
1312     {
1313         Py_INCREF(type);
1314         if (isExtension)
1315         {
1316             type->ob_type = &PY_TYPE(FinalizerClass);
1317             Py_INCREF(&PY_TYPE(FinalizerClass));
1318         }
1319         PyModule_AddObject(module, name, (PyObject *) type);
1320     }
1321 }
1322
1323 PyObject *wrapType(PyTypeObject *type, const jobject& obj)
1324 {
1325     static PyObject *wrapfn_ = PyString_FromString("wrapfn_");
1326     PyObject *cobj = PyObject_GetAttr((PyObject *) type, wrapfn_);
1327     PyObject *(*wrapfn)(const jobject&);
1328     
1329     if (cobj == NULL)
1330         return NULL;
1331
1332     wrapfn = (PyObject *(*)(const jobject &)) PyCObject_AsVoidPtr(cobj);
1333     Py_DECREF(cobj);
1334
1335     return wrapfn(obj);
1336 }
1337
1338 PyObject *unboxBoolean(const jobject& obj)
1339 {
1340     if (obj != NULL)
1341     {
1342         if (!env->isInstanceOf(obj, java::lang::Boolean::initializeClass))
1343         {
1344             PyErr_SetObject(PyExc_TypeError,
1345                             (PyObject *) &java::lang::PY_TYPE(Boolean));
1346             return NULL;
1347         }
1348         
1349         if (env->booleanValue(obj))
1350             Py_RETURN_TRUE;
1351
1352         Py_RETURN_FALSE;
1353     }
1354
1355     Py_RETURN_NONE;
1356 }
1357
1358 PyObject *unboxByte(const jobject &obj)
1359 {
1360     if (obj != NULL)
1361     {
1362         if (!env->isInstanceOf(obj, java::lang::Byte::initializeClass))
1363         {
1364             PyErr_SetObject(PyExc_TypeError,
1365                             (PyObject *) &java::lang::PY_TYPE(Byte));
1366             return NULL;
1367         }
1368         
1369         return PyInt_FromLong((long) env->byteValue(obj));
1370     }
1371
1372     Py_RETURN_NONE;
1373 }
1374
1375 PyObject *unboxCharacter(const jobject &obj)
1376 {
1377     if (obj != NULL)
1378     {
1379         if (!env->isInstanceOf(obj, java::lang::Character::initializeClass))
1380         {
1381             PyErr_SetObject(PyExc_TypeError,
1382                             (PyObject *) &java::lang::PY_TYPE(Character));
1383             return NULL;
1384         }
1385         
1386         jchar c = env->charValue(obj);
1387         return PyUnicode_FromUnicode((Py_UNICODE *) &c, 1);
1388     }
1389
1390     Py_RETURN_NONE;
1391 }
1392
1393 PyObject *unboxDouble(const jobject &obj)
1394 {
1395     if (obj != NULL)
1396     {
1397         if (!env->isInstanceOf(obj, java::lang::Double::initializeClass))
1398         {
1399             PyErr_SetObject(PyExc_TypeError,
1400                             (PyObject *) &java::lang::PY_TYPE(Double));
1401             return NULL;
1402         }
1403         
1404         return PyFloat_FromDouble((double) env->doubleValue(obj));
1405     }
1406
1407     Py_RETURN_NONE;
1408 }
1409
1410 PyObject *unboxFloat(const jobject &obj)
1411 {
1412     if (obj != NULL)
1413     {
1414         if (!env->isInstanceOf(obj, java::lang::Float::initializeClass))
1415         {
1416             PyErr_SetObject(PyExc_TypeError,
1417                             (PyObject *) &java::lang::PY_TYPE(Float));
1418             return NULL;
1419         }
1420         
1421         return PyFloat_FromDouble((double) env->floatValue(obj));
1422     }
1423
1424     Py_RETURN_NONE;
1425 }
1426
1427 PyObject *unboxInteger(const jobject &obj)
1428 {
1429     if (obj != NULL)
1430     {
1431         if (!env->isInstanceOf(obj, java::lang::Integer::initializeClass))
1432         {
1433             PyErr_SetObject(PyExc_TypeError,
1434                             (PyObject *) &java::lang::PY_TYPE(Integer));
1435             return NULL;
1436         }
1437         
1438         return PyInt_FromLong((long) env->intValue(obj));
1439     }
1440
1441     Py_RETURN_NONE;
1442 }
1443
1444 PyObject *unboxLong(const jobject &obj)
1445 {
1446     if (obj != NULL)
1447     {
1448         if (!env->isInstanceOf(obj, java::lang::Long::initializeClass))
1449         {
1450             PyErr_SetObject(PyExc_TypeError,
1451                             (PyObject *) &java::lang::PY_TYPE(Long));
1452             return NULL;
1453         }
1454         
1455         return PyLong_FromLongLong((PY_LONG_LONG) env->longValue(obj));
1456     }
1457
1458     Py_RETURN_NONE;
1459 }
1460
1461 PyObject *unboxShort(const jobject &obj)
1462 {
1463     if (obj != NULL)
1464     {
1465         if (!env->isInstanceOf(obj, java::lang::Short::initializeClass))
1466         {
1467             PyErr_SetObject(PyExc_TypeError,
1468                             (PyObject *) &java::lang::PY_TYPE(Short));
1469             return NULL;
1470         }
1471         
1472         return PyInt_FromLong((long) env->shortValue(obj));
1473     }
1474
1475     Py_RETURN_NONE;
1476 }
1477
1478 PyObject *unboxString(const jobject &obj)
1479 {
1480     if (obj != NULL)
1481     {
1482         if (!env->isInstanceOf(obj, java::lang::String::initializeClass))
1483         {
1484             PyErr_SetObject(PyExc_TypeError,
1485                             (PyObject *) &java::lang::PY_TYPE(String));
1486             return NULL;
1487         }
1488         
1489         return env->fromJString((jstring) obj, 0);
1490     }
1491
1492     Py_RETURN_NONE;
1493 }
1494
1495 static int boxJObject(PyTypeObject *type, PyObject *arg,
1496                       java::lang::Object *obj)
1497 {
1498     if (arg == Py_None)
1499     {
1500         if (obj != NULL)
1501             *obj = Object(NULL);
1502     }
1503     else if (PyObject_TypeCheck(arg, &PY_TYPE(Object)))
1504     {
1505         if (type != NULL && !is_instance_of(arg, type))
1506             return -1;
1507
1508         if (obj != NULL)
1509             *obj = ((t_Object *) arg)->object;
1510     }
1511     else if (PyObject_TypeCheck(arg, &PY_TYPE(FinalizerProxy)))
1512     {
1513         arg = ((t_fp *) arg)->object;
1514         if (PyObject_TypeCheck(arg, &PY_TYPE(Object)))
1515         {
1516             if (type != NULL && !is_instance_of(arg, type))
1517                 return -1;
1518
1519             if (obj != NULL)
1520                 *obj = ((t_Object *) arg)->object;
1521         }
1522         else
1523             return -1;
1524     }
1525     else
1526         return 1;
1527
1528     return 0;
1529 }
1530
1531 int boxBoolean(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1532 {
1533     int result = boxJObject(type, arg, obj);
1534
1535     if (result <= 0)
1536         return result;
1537
1538     if (arg == Py_True)
1539     {
1540         if (obj != NULL)
1541             *obj = *Boolean::TRUE;
1542     }
1543     else if (arg == Py_False)
1544     {
1545         if (obj != NULL)
1546             *obj = *Boolean::FALSE;
1547     }
1548     else
1549         return -1;
1550
1551     return 0;
1552 }
1553
1554 int boxByte(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1555 {
1556     int result = boxJObject(type, arg, obj);
1557
1558     if (result <= 0)
1559         return result;
1560
1561     if (PyInt_Check(arg))
1562     {
1563         int n = PyInt_AS_LONG(arg);
1564         jbyte b = (jbyte) n;
1565
1566         if (b == n)
1567         {
1568             if (obj != NULL)
1569                 *obj = Byte(b);
1570         }
1571         else
1572             return -1;
1573     }
1574     else if (PyLong_Check(arg))
1575     {
1576         PY_LONG_LONG ln = PyLong_AsLongLong(arg);
1577         jbyte b = (jbyte) ln;
1578
1579         if (b == ln)
1580         {
1581             if (obj != NULL)
1582                 *obj = Byte(b);
1583         }
1584         else
1585             return -1;
1586     }
1587     else if (PyFloat_Check(arg))
1588     {
1589         double d = PyFloat_AS_DOUBLE(arg);
1590         jbyte b = (jbyte) d;
1591
1592         if (b == d)
1593         {
1594             if (obj != NULL)
1595                 *obj = Byte(b);
1596         }
1597         else
1598             return -1;
1599     }
1600     else
1601         return -1;
1602
1603     return 0;
1604 }
1605
1606 int boxCharacter(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1607 {
1608     int result = boxJObject(type, arg, obj);
1609
1610     if (result <= 0)
1611         return result;
1612
1613     if (PyString_Check(arg))
1614     {
1615         char *c;
1616         Py_ssize_t len;
1617
1618         if (PyString_AsStringAndSize(arg, &c, &len) < 0 || len != 1)
1619             return -1;
1620
1621         if (obj != NULL)
1622             *obj = Character((jchar) c[0]);
1623     }
1624     else if (PyUnicode_Check(arg))
1625     {
1626         Py_ssize_t len = PyUnicode_GetSize(arg);
1627
1628         if (len != 1)
1629             return -1;
1630
1631         if (obj != NULL)
1632             *obj = Character((jchar) PyUnicode_AsUnicode(arg)[0]);
1633     }
1634     else
1635         return -1;
1636
1637     return 0;
1638 }
1639
1640 int boxCharSequence(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1641 {
1642     int result = boxJObject(type, arg, obj);
1643
1644     if (result <= 0)
1645         return result;
1646
1647     if (PyString_Check(arg) || PyUnicode_Check(arg))
1648     {
1649         if (obj != NULL)
1650         {
1651             *obj = p2j(arg);
1652             if (PyErr_Occurred())
1653                 return -1;
1654         }
1655     }
1656     else
1657         return -1;
1658     
1659     return 0;
1660 }
1661
1662 int boxDouble(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1663 {
1664     int result = boxJObject(type, arg, obj);
1665
1666     if (result <= 0)
1667         return result;
1668
1669     if (PyInt_Check(arg))
1670     {
1671         if (obj != NULL)
1672             *obj = Double((jdouble) PyInt_AS_LONG(arg));
1673     }
1674     else if (PyLong_Check(arg))
1675     {
1676         if (obj != NULL)
1677             *obj = Double((jdouble) PyLong_AsLongLong(arg));
1678     }
1679     else if (PyFloat_Check(arg))
1680     {
1681         if (obj != NULL)
1682             *obj = Double(PyFloat_AS_DOUBLE(arg));
1683     }
1684     else
1685         return -1;
1686
1687     return 0;
1688 }
1689
1690 int boxFloat(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1691 {
1692     int result = boxJObject(type, arg, obj);
1693
1694     if (result <= 0)
1695         return result;
1696
1697     if (PyInt_Check(arg))
1698     {
1699         if (obj != NULL)
1700             *obj = Float((jfloat) PyInt_AS_LONG(arg));
1701     }
1702     else if (PyLong_Check(arg))
1703     {
1704         PY_LONG_LONG ln = PyLong_AsLongLong(arg);
1705         float f = (float) ln;
1706
1707         if ((PY_LONG_LONG) f == ln)
1708         {
1709             if (obj != NULL)
1710                 *obj = Float(f);
1711         }
1712         else
1713             return -1;
1714     }
1715     else if (PyFloat_Check(arg))
1716     {
1717         double d = PyFloat_AS_DOUBLE(arg);
1718         float f = (float) d;
1719
1720         if ((double) f == d)
1721         {
1722             if (obj != NULL)
1723                 *obj = Float(f);
1724         }
1725         else
1726             return -1;
1727     }
1728     else
1729         return -1;
1730
1731     return 0;
1732 }
1733
1734 int boxInteger(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1735 {
1736     int result = boxJObject(type, arg, obj);
1737
1738     if (result <= 0)
1739         return result;
1740
1741     if (PyInt_Check(arg))
1742     {
1743         if (obj != NULL)
1744             *obj = Integer((jint) PyInt_AS_LONG(arg));
1745     }
1746     else if (PyLong_Check(arg))
1747     {
1748         PY_LONG_LONG ln = PyLong_AsLongLong(arg);
1749         int n = (int) ln;
1750
1751         if (n == ln)
1752         {
1753             if (obj != NULL)
1754                 *obj = Integer(n);
1755         }
1756         else
1757             return -1;
1758     }
1759     else if (PyFloat_Check(arg))
1760     {
1761         double d = PyFloat_AS_DOUBLE(arg);
1762         int n = (int) d;
1763
1764         if ((double) n == d)
1765         {
1766             if (obj != NULL)
1767                 *obj = Integer(n);
1768         }
1769         else
1770             return -1;
1771     }
1772     else
1773         return -1;
1774
1775     return 0;
1776 }
1777
1778 int boxLong(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1779 {
1780     int result = boxJObject(type, arg, obj);
1781
1782     if (result <= 0)
1783         return result;
1784
1785     if (PyInt_Check(arg))
1786     {
1787         if (obj != NULL)
1788             *obj = Long((jlong) PyInt_AS_LONG(arg));
1789     }
1790     else if (PyLong_Check(arg))
1791     {
1792         if (obj != NULL)
1793             *obj = Long((jlong) PyLong_AsLongLong(arg));
1794     }
1795     else if (PyFloat_Check(arg))
1796     {
1797         double d = PyFloat_AS_DOUBLE(arg);
1798         PY_LONG_LONG n = (PY_LONG_LONG) d;
1799
1800         if ((double) n == d)
1801         {
1802             if (obj != NULL)
1803                 *obj = Long((jlong) n);
1804         }
1805         else
1806             return -1;
1807     }
1808     else
1809         return -1;
1810
1811     return 0;
1812 }
1813
1814 int boxNumber(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1815 {
1816     int result = boxJObject(type, arg, obj);
1817
1818     if (result <= 0)
1819         return result;
1820
1821     if (PyInt_Check(arg))
1822     {
1823         if (obj != NULL)
1824             *obj = Integer((jint) PyInt_AS_LONG(arg));
1825     }
1826     else if (PyLong_Check(arg))
1827     {
1828         if (obj != NULL)
1829             *obj = Long((jlong) PyLong_AsLongLong(arg));
1830     }
1831     else if (PyFloat_Check(arg))
1832     {
1833         if (obj != NULL)
1834             *obj = Double((jdouble) PyFloat_AS_DOUBLE(arg));
1835     }
1836     else
1837         return -1;
1838
1839     return 0;
1840 }
1841
1842 int boxShort(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1843 {
1844     int result = boxJObject(type, arg, obj);
1845
1846     if (result <= 0)
1847         return result;
1848
1849     if (PyInt_Check(arg))
1850     {
1851         int n = (int) PyInt_AS_LONG(arg);
1852         short sn = (short) n;
1853
1854         if (sn == n)
1855         {
1856             if (obj != NULL)
1857                 *obj = Short((jshort) sn);
1858         }
1859         else
1860             return -1;
1861     }
1862     else if (PyLong_Check(arg))
1863     {
1864         PY_LONG_LONG ln = PyLong_AsLongLong(arg);
1865         short sn = (short) ln;
1866
1867         if (sn == ln)
1868         {
1869             if (obj != NULL)
1870                 *obj = Short((jshort) sn);
1871         }
1872         else
1873             return -1;
1874     }
1875     else if (PyFloat_Check(arg))
1876     {
1877         double d = PyFloat_AS_DOUBLE(arg);
1878         short sn = (short) (int) d;
1879
1880         if ((double) sn == d)
1881         {
1882             if (obj != NULL)
1883                 *obj = Short((jshort) sn);
1884         }
1885         else
1886             return -1;
1887     }
1888     else
1889         return -1;
1890
1891     return 0;
1892 }
1893
1894 int boxString(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1895 {
1896     int result = boxJObject(type, arg, obj);
1897
1898     if (result <= 0)
1899         return result;
1900
1901     if (PyString_Check(arg) || PyUnicode_Check(arg))
1902     {
1903         if (obj != NULL)
1904         {
1905             *obj = p2j(arg);
1906             if (PyErr_Occurred())
1907                 return -1;
1908         }
1909     }
1910     else
1911         return -1;
1912
1913     return 0;
1914 }
1915
1916 int boxObject(PyTypeObject *type, PyObject *arg, java::lang::Object *obj)
1917 {
1918     int result = boxJObject(type, arg, obj);
1919
1920     if (result <= 0)
1921         return result;
1922
1923     if (obj != NULL)
1924     {
1925         if (PyString_Check(arg) || PyUnicode_Check(arg))
1926         {
1927             *obj = p2j(arg);
1928             if (PyErr_Occurred())
1929                 return -1;
1930         }
1931         else if (arg == Py_True)
1932             *obj = *Boolean::TRUE;
1933         else if (arg == Py_False)
1934             *obj = *Boolean::FALSE;
1935         else if (PyInt_Check(arg))
1936         {
1937             long ln = PyInt_AS_LONG(arg);
1938             int n = (int) ln;
1939
1940             if (ln != (long) n)
1941                 *obj = Long((jlong) ln);
1942             else
1943                 *obj = Integer((jint) n);
1944         }
1945         else if (PyLong_Check(arg))
1946             *obj = Long((jlong) PyLong_AsLongLong(arg));
1947         else if (PyFloat_Check(arg))
1948             *obj = Double((jdouble) PyFloat_AS_DOUBLE(arg));
1949         else
1950             return -1;
1951     }
1952     else if (!(PyString_Check(arg) || PyUnicode_Check(arg) ||
1953                arg == Py_True || arg == Py_False ||
1954                PyInt_Check(arg) || PyLong_Check(arg) ||
1955                PyFloat_Check(arg)))
1956         return -1;
1957
1958     return 0;
1959 }
1960
1961
1962 #ifdef _java_generics
1963 PyObject *typeParameters(PyTypeObject *types[], size_t size)
1964 {
1965     size_t count = size / sizeof(PyTypeObject *);
1966     PyObject *tuple = PyTuple_New(count);
1967
1968     for (size_t i = 0; i < count; i++) {
1969         PyObject *type = (PyObject *) types[i];
1970         
1971         if (type == NULL)
1972             type = Py_None;
1973
1974         PyTuple_SET_ITEM(tuple, i, type);
1975         Py_INCREF(type);
1976     }
1977
1978     return tuple;
1979 }
1980 #endif