* src/vmcore/linker.c (build_display): Removed superfluous recursion; return
[cacao.git] / src / vm / jit / python.c
1 /* src/vm/jit/python.c - Python pass
2
3    Copyright (C) 2007, 2008
4    CACAOVM - Verein zu Foerderung der freien virtuellen Machine CACAO
5
6    This file is part of CACAO.
7
8    This program is free software; you can redistribute it and/or
9    modify it under the terms of the GNU General Public License as
10    published by the Free Software Foundation; either version 2, or (at
11    your option) any later version.
12
13    This program is distributed in the hope that it will be useful, but
14    WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16    General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21    02110-1301, USA.
22
23    Note: this code is currently alpha and needs to be documented.
24
25    This code wraps the jitdata structure into a python object and
26    makes it possible to implement a compiler pass as python function.
27
28    The wrapping of cacao types to python objects is meant to be easy and
29    straight-forward.
30  
31    Cacao structs a wrapped into a python ``wrapper'' object, the state of 
32    which consists of:
33
34     * A void pointer.
35         * A pointer to a class function (see class_func), which implements the
36           object's behaviour.
37
38    Arrays and collection-like data structures are wrapped into a python
39    ``iterator'' object, the state of wich consists of:
40
41     * A void pointer.
42         * Another void pointer that is the cursor.
43         * A pointer to a iterator function (see iterator_func) which implements
44           the iterator's behaviour.
45
46    Because in python field names are identified as strings, to avoid a lot
47    of string comparisons, we translate the field as early as possible into 
48    an integer constant. This is achieved using the field_map array.
49
50    We could have used a wrapper generator like swig, but we don't want to 
51    wrap the rather low level C api to python 1:1. When wrapping stuff, try
52    to do it rather high level and in a pythonic way. Examples:
53
54     * Bad: instruction.flags and cacao.FLAG_UNRESOLVED == 0
55         * Good: instruction.is_unresolved
56         * Bad: for i in range(0, bb.icount): instr = bb.instructions[i]
57         * Good: for instr in bb.instructions
58
59   Adding instructions or variables is currently problematic, because it 
60   requires to resize fixed sized arrays. Reallocating an array means that
61   all elements are possibly moved, their addresses are changed and the 
62   associated python object become invalid. Further, usually there is the 
63   need to add several instructions, which possibly results in several 
64   reallocations of the array. A good solution would be:
65
66    * Copy-on-write the array (ex. bptr->instructions) into a python list,
67      and put that list into the dictionnary of the parent object.
68    * When the python parent object is destroyed, recreate the array from the
69      list.
70    * From python, bptr.instructions will return either the wrapped array, or
71      the list from the dictionnary.
72
73 */
74
75 #include <Python.h>
76 #include <structmember.h>
77
78 #include "vm/global.h"
79 #include "vm/jit/python.h"
80 #include "vm/jit/show.h"
81 #if defined(ENABLE_THREADS)
82 # include "threads/lock-common.h"
83 #endif
84
85 #if defined(ENABLE_THREADS)
86 static java_object_t *python_global_lock;
87 #endif
88
89 /*
90  * Defs
91  */
92
93 typedef struct root_state root_state;
94
95 struct root_state {
96         jitdata *jd;
97         PyObject *object_cache;
98 };
99
100 typedef struct class_state class_state;
101
102 struct class_state {
103         root_state *root;
104         void *vp;
105 };
106
107 union class_arg {
108         struct {
109                 int is_method;
110                 int field;
111                 PyObject **result;
112         } get;
113         struct {
114                 int field;
115                 PyObject *value;
116         } set;
117         struct {
118                 PyObject *args;
119                 PyObject **result;
120         } call;
121         struct {
122                 int method;
123                 PyObject *args;
124                 PyObject **result;
125         } method_call;
126         struct {
127                 PyObject **result;
128         } str;
129         void *key;
130 };
131
132 typedef union class_arg class_arg;
133
134 enum class_op {
135         CLASS_SET_FIELD,
136         CLASS_GET_FIELD,
137         CLASS_CALL,
138         CLASS_STR,
139         CLASS_METHOD_CALL
140 };
141
142 typedef enum class_op class_op;
143
144 typedef int(*class_func)(class_op, class_state *, class_arg *);
145 #define CLASS_FUNC(name) int name(class_op op, class_state *state, class_arg *arg)
146 #define CLASS_FUNC_CALL(name) name(op, state, arg)
147
148 struct iterator_state {
149         root_state *root;
150         void *data;
151         void *pos;
152 };
153
154 union iterator_arg {
155         struct {
156                 PyObject **result;
157         } get;
158         struct {
159                 unsigned int index;
160                 PyObject **result;
161         } subscript;
162         int length;
163         struct {
164                 unsigned int index;
165                 PyObject *value;
166         } setitem;
167 };
168
169 typedef union iterator_arg iterator_arg;
170
171 typedef struct iterator_state iterator_state;
172
173 enum iterator_op {
174         ITERATOR_INIT,
175         ITERATOR_GET,
176         ITERATOR_FORWARD,
177         ITERATOR_END,
178         ITERATOR_SUBSCRIPT,
179         ITERATOR_LENGTH,
180         ITERATOR_SETITEM
181 };
182
183 typedef enum iterator_op iterator_op;
184
185 typedef int(*iterator_func)(iterator_op op, iterator_state *state, iterator_arg *arg);
186 #define ITERATOR_FUNC(name) int name (iterator_op op, iterator_state *state, iterator_arg *arg)
187 #define ITERATOR_SUBSCRIPT_CHECK(end) if (arg->subscript.index >= (end)) return -1
188 #define ITERATOR_SETITEM_CHECK(end) if (arg->setitem.index >= (end)) return -1
189
190 typedef struct method_state method_state;
191
192 struct method_state {
193         int method;
194         class_state *cstate;
195 };
196
197 struct field_map_entry {
198         const char *name;
199         int tag;
200 };
201
202 typedef struct field_map_entry field_map_entry;
203
204 enum field {
205         F_BASIC_BLOCKS,
206         F_CALL_RETURN_TYPE,
207         F_CALL_ARGS,
208         F_CLASSREF,
209         F_CONTROL_FLOW,
210         F_CONTROL_FLOW_EX,
211         F_DATA_FLOW,
212         F_DATA_FLOW_EX,
213         F_DESCRIPTOR,
214         F_DOM_SUCCESSORS,
215         F_DOMINANCE_FRONTIER,
216         F_DST,
217         F_END,
218         F_EXCEPTION_HANDLER,
219         F_EXCEPTION_TABLE,
220         F_FIELD,
221         F_FIELD_TYPE,
222         F_HANDLER,
223         F_HAS_CALL_ARGS,
224         F_HAS_DST,
225         F_IDOM,
226         F_INDEX,
227         F_INSTRUCTIONS,
228         F_INTERFACE_MAP,
229         F_IN_VARS,
230         F_IS_CLASS_CONSTANT,
231         F_IS_IN_MEMORY,
232         F_IS_INOUT,
233         F_IS_LOCAL,
234         F_IS_PREALLOCATED,
235         F_IS_SAVED,
236         F_IS_TEMPORARY,
237         F_IS_UNRESOLVED,
238         F_LOCAL_METHODINFO,
239         F_KLASS,
240         F_LINE,
241         F_LOCAL_MAP,
242         F_METHOD,
243         F_NAME,
244         F_NAME_EX,
245         F_NR,
246         F_OFFSET,
247         F_OPCODE,
248         F_OPCODE_EX,
249         F_OUT_VARS,
250         F_PARAMS,
251         F_PARAM_TYPES,
252         F_PEI,
253         F_PEI_EX,
254         F_PREDECESSORS,
255         F_REACHED,
256         F_REGISTER_OFFSET,
257         F_RETURN_TYPE,
258         F_S,
259         F_SHOW,
260         F_SUCCESSORS,
261         F_START,
262         F_TYPE,
263         F_UNRESOLVED_FIELD,
264         F_UNUSED,
265         F_VARS
266 };
267
268 /* Keep it soreted alphabetically, so we can support binary search in future. */
269 struct field_map_entry field_map[] = {
270         { "basic_blocks", F_BASIC_BLOCKS },
271         { "call_return_type", F_CALL_RETURN_TYPE },
272         { "call_args", F_CALL_ARGS },
273         { "classref", F_CLASSREF },
274         { "control_flow", F_CONTROL_FLOW },
275         { "control_flow_ex", F_CONTROL_FLOW_EX },
276         { "data_flow", F_DATA_FLOW },
277         { "data_flow_ex", F_DATA_FLOW_EX },
278         { "descriptor", F_DESCRIPTOR },
279         { "dom_successors", F_DOM_SUCCESSORS },
280         { "dominance_frontier", F_DOMINANCE_FRONTIER },
281         { "dst", F_DST },
282         { "end", F_END },
283         { "exception_handler", F_EXCEPTION_HANDLER },
284         { "exception_table", F_EXCEPTION_TABLE },
285         { "field", F_FIELD },
286         { "field_type", F_FIELD_TYPE },
287         { "handler", F_HANDLER },
288         { "has_call_args", F_HAS_CALL_ARGS },
289         { "has_dst", F_HAS_DST },
290         { "idom", F_IDOM, },
291         { "index", F_INDEX },
292         { "instructions", F_INSTRUCTIONS },
293         { "interface_map", F_INTERFACE_MAP },
294         { "in_vars", F_IN_VARS },
295         { "is_class_constant", F_IS_CLASS_CONSTANT },
296         { "is_inout", F_IS_INOUT },
297         { "is_in_memory", F_IS_IN_MEMORY },
298         { "is_local", F_IS_LOCAL },
299         { "is_preallocated", F_IS_PREALLOCATED },
300         { "is_saved", F_IS_SAVED },
301         { "is_temporary", F_IS_TEMPORARY },
302         { "is_unresolved", F_IS_UNRESOLVED },
303         { "klass", F_KLASS },
304         { "line", F_LINE },
305         { "local_map", F_LOCAL_MAP },
306         { "local_methodinfo", F_LOCAL_METHODINFO },
307         { "method", F_METHOD },
308         { "name", F_NAME },
309         { "name_ex", F_NAME_EX },
310         { "nr", F_NR },
311         { "offset", F_OFFSET },
312         { "opcode", F_OPCODE },
313         { "opcode_ex", F_OPCODE_EX },
314         { "out_vars", F_OUT_VARS },
315         { "params", F_PARAMS },
316         { "param_types", F_PARAM_TYPES },
317         { "pei", F_PEI },
318         { "pei_ex", F_PEI_EX },
319         { "predecessors", F_PREDECESSORS },
320         { "reached", F_REACHED },
321         { "register_offset", F_REGISTER_OFFSET },
322         { "return_type", F_RETURN_TYPE },
323         { "s", F_S },
324         { "show", F_SHOW },
325         { "start", F_START },
326         { "successors", F_SUCCESSORS },
327         { "type", F_TYPE },
328         { "unresolved_field", F_UNRESOLVED_FIELD },
329         { "unused", F_UNUSED },
330         { "vars", F_VARS },
331         { NULL, 0 }
332 };
333
334 int field_find(const char *key) {
335         field_map_entry *it;
336
337         for (it = field_map; it->name; ++it) {
338                 if (strcmp(it->name, key) == 0) {
339                         return it->tag;
340                 }
341         }
342
343         return -1;
344 }
345
346 /*
347  * Python
348  */
349
350 typedef struct method method;
351
352 struct method {
353         PyObject_HEAD;
354         class_func func;
355         method_state state;
356 };
357
358 PyObject *method_call(method *m, PyObject *args, PyObject *kw) {
359         class_arg arg;
360         PyObject *result = NULL;
361
362         arg.method_call.method = m->state.method;
363         arg.method_call.args = args;
364         arg.method_call.result = &result;
365
366         if (m->func(CLASS_METHOD_CALL, m->state.cstate, &arg) == -1) {
367                 return NULL;
368         }
369
370         if (result == NULL) {
371                 Py_INCREF(Py_None);
372                 result = Py_None;
373         }
374
375         return result;
376 }
377
378 PyTypeObject method_type = {
379         PyObject_HEAD_INIT(NULL)
380         0, /* ob_size */
381         "method", /* tp_name */
382         sizeof(method), /* tp_basicsize */
383         0, /* tp_itemsize */
384         0, /* tp_dealloc */
385         0, /* tp_print */
386         0, /* tp_getattr */
387         0, /* tp_setattr */
388         0, /* tp_compare */
389         0, /* tp_repr */
390         0, /* tp_as_number */
391         0, /* tp_as_sequence */
392         0, /* tp_as_mapping */
393         0, /* tp_hash */
394         method_call, /* tp_call */
395         0, /* tp_str */
396         0, /* tp_getattro */
397         0, /* tp_setattro */
398         0, /* tp_as_buffer */
399         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
400         0, /* tp_doc */
401         0, /* tp_traverse */
402         0, /* tp_clear */
403         0, /* tp_richcompare */
404         0, /* tp_weaklistoffset */
405         0, /* tp_iter */
406         0, /* tp_iternext */
407         0, /* tp_methods */
408         0, /* tp_members */
409         0, /* tp_getset */
410         0, /* tp_base */
411         0, /* tp_dict */
412         0, /* tp_descr_get */
413         0, /* tp_descr_set */
414         0, /* tp_dictoffset */
415         0, /* tp_init */
416         0, /* tp_alloc */
417         PyType_GenericNew, /* tp_new */
418 };
419
420 struct wrapper {
421         PyObject_HEAD
422         class_state state;
423         class_func func;
424         PyObject *dict;
425 };
426
427 typedef struct wrapper wrapper;
428
429 PyObject *wrapper_getattr(wrapper *w, PyObject *fld) {
430         class_arg arg;
431         PyObject *result;
432
433         /* First, try generic getattr */
434
435         result = PyObject_GenericGetAttr(w, fld);
436
437         if (result != NULL) {
438                 return result;
439         }
440
441         /* Exception is set here */
442
443         arg.get.field = field_find(PyString_AsString(fld));
444         if (arg.get.field == -1) {
445                 goto failout;
446         }
447
448         arg.get.is_method = 0;
449         arg.get.result = &result;
450
451         if (w->func(CLASS_GET_FIELD, &w->state, &arg) == -1) {
452                 goto failout;
453         }
454
455         if (arg.get.is_method) {
456                 result = PyObject_CallObject((PyObject *)&method_type, NULL);
457                 method *m = (method *)result;
458                 m->func = w->func;
459                 m->state.method = arg.get.field;
460                 m->state.cstate = &w->state;
461         }
462
463         PyErr_Clear();
464
465         return result;
466
467 failout:
468
469         return NULL;
470 }
471
472 int wrapper_setattr(wrapper *w, PyObject *fld, PyObject *value) {
473         class_arg arg;
474
475         arg.set.field = field_find(PyString_AsString(fld));
476         if (arg.set.field == -1) {
477                 goto failout;
478         }
479         arg.set.value = value;
480
481         if (w->func(CLASS_SET_FIELD, &w->state, &arg) == -1) {
482                 goto failout;
483         }
484
485         return 0;
486
487 failout:
488
489         return PyObject_GenericSetAttr(w, fld, value);
490 }
491
492 extern PyTypeObject wrapper_type;
493
494 inline void *wrapper_key(wrapper *w) {
495         return w->state.vp;
496 }
497
498 int wrapper_compare(wrapper *a, wrapper *b) {
499         void *keya, *keyb;
500         if (PyObject_TypeCheck(b, &wrapper_type)) {
501                 keya = wrapper_key(a);
502                 keyb = wrapper_key(b);
503                 if (keya < keyb) {
504                         return -1;
505                 } else if (keya > keyb) {
506                         return 1;
507                 } else {
508                         return 0;
509                 }
510         } else {
511                 /* If classes differ, compare classes */
512                 return PyObject_Compare(a->ob_type, b->ob_type);
513         }
514 }
515
516 long wrapper_hash(wrapper *a) {
517         return (long)wrapper_key(a);
518 }
519
520 PyObject *wrapper_call(wrapper *w, PyObject *args, PyObject *kw) {
521         class_arg arg;
522         PyObject *result;
523
524         arg.call.args = args;
525         arg.call.result = &result;
526
527         if (w->func(CLASS_CALL, &w->state, &arg) == -1) {
528                 return NULL;
529         }
530
531         return result;
532 }
533
534 PyObject *wrapper_str(wrapper *w) {
535         class_arg arg;
536         PyObject *result;
537         arg.str.result = &result;
538         if (w->func(CLASS_STR, &w->state, &arg) == -1) {
539                 return PyString_FromFormat("Wrapper(0x%p)", w->state.vp);
540         } else {
541                 return result;
542         }
543 }
544
545 PyTypeObject wrapper_type = {
546         PyObject_HEAD_INIT(NULL)
547         0, /* ob_size */
548         "wrapper", /* tp_name */
549         sizeof(wrapper), /* tp_basicsize */
550         0, /* tp_itemsize */
551         0, /* tp_dealloc */
552         0, /* tp_print */
553         0, /* tp_getattr */
554         0, /* tp_setattr */
555         wrapper_compare, /* tp_compare */
556         wrapper_str, /* tp_repr */
557         0, /* tp_as_number */
558         0, /* tp_as_sequence */
559         0, /* tp_as_mapping */
560         wrapper_hash, /* tp_hash */
561         wrapper_call, /* tp_call */
562         wrapper_str, /* tp_str */
563         wrapper_getattr, /* tp_getattro */
564         wrapper_setattr, /* tp_setattro */
565         0, /* tp_as_buffer */
566         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
567         0, /* tp_doc */
568         0, /* tp_traverse */
569         0, /* tp_clear */
570         0, /* tp_richcompare */
571         0, /* tp_weaklistoffset */
572         0, /* tp_iter */
573         0, /* tp_iternext */
574         0, /* tp_methods */
575         0, /* tp_members */
576         0, /* tp_getset */
577         0, /* tp_base */
578         0, /* tp_dict */
579         0, /* tp_descr_get */
580         0, /* tp_descr_set */
581         offsetof(wrapper, dict), /* tp_dictoffset */
582         0, /* tp_init */
583         0, /* tp_alloc */
584         PyType_GenericNew, /* tp_new */
585 };
586
587 struct iterator {
588         PyObject_HEAD
589         iterator_func func;
590         iterator_state state;
591 };
592
593 typedef struct iterator iterator;
594
595 PyObject *iterator_iter(struct iterator *it) {
596         Py_INCREF(it);
597         return (PyObject *)it;
598 }
599
600 PyObject *iterator_iternext(struct iterator *it) {
601         PyObject *ret;
602         iterator_arg arg;
603
604         if (it->func(ITERATOR_END, &it->state, NULL)) {
605                 return NULL;
606         } else {
607                 arg.get.result = &ret;
608                 it->func(ITERATOR_GET, &it->state, &arg);
609                 it->func(ITERATOR_FORWARD, &it->state, NULL);
610                 return ret;
611         }
612 }
613
614 PyObject *iterator_getitem(struct iterator *it, PyObject* item) {
615         iterator_arg arg;
616         PyObject *ret;
617
618         if (PyInt_Check(item)) {
619                 arg.subscript.index = PyInt_AS_LONG(item);
620                 arg.subscript.result = &ret;
621                 if (index < 0) { 
622                         return NULL;
623                 } else if (it->func(ITERATOR_SUBSCRIPT, &it->state, &arg) != -1) {
624                         return ret;
625                 } else {
626                         return NULL;
627                 }
628         } else {
629                 return NULL;
630         }
631 }
632
633 int iterator_setitem(struct iterator *it, PyObject *item, PyObject *value) {
634         iterator_arg arg;
635         if (PyInt_Check(item)) {
636                 arg.setitem.index = PyInt_AS_LONG(item);
637                 arg.setitem.value = value;
638                 if (it->func(ITERATOR_SETITEM, &it->state, &arg) != -1) {
639                         return 0;
640                 } else {
641                         return -1;
642                 }
643         } else {
644                 return -1;
645         }
646 }
647
648 int iterator_length(struct iterator *it) {
649         iterator_arg arg;
650         if (it->func(ITERATOR_LENGTH, &it->state, &arg) == -1) {
651                 return -1;
652         } else {
653                 return arg.length;
654         }
655 }
656
657 PyMappingMethods iterator_mapping = {
658         iterator_length,
659         iterator_getitem,
660         iterator_setitem
661 };
662
663 PyTypeObject iterator_type = {
664         PyObject_HEAD_INIT(NULL)
665         0, /* ob_size */
666         "iterator", /* tp_name */
667         sizeof(iterator), /* tp_basicsize */
668         0, /* tp_itemsize */
669         0, /* tp_dealloc */
670         0, /* tp_print */
671         0, /* tp_getattr */
672         0, /* tp_setattr */
673         0, /* tp_compare */
674         0, /* tp_repr */
675         0, /* tp_as_number */
676         0, /* tp_as_sequence */
677         &iterator_mapping, /* tp_as_mapping */
678         0, /* tp_hash */
679         0, /* tp_call */
680         0, /* tp_str */
681         0, /* tp_getattro */
682         0, /* tp_setattro */
683         0, /* tp_as_buffer */
684         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
685         0, /* tp_doc */
686         0, /* tp_traverse */
687         0, /* tp_clear */
688         0, /* tp_richcompare */
689         0, /* tp_weaklistoffset */
690         iterator_iter, /* tp_iter */
691         iterator_iternext, /* tp_iternext */
692         0, /* tp_methods */
693         0, /* tp_members */
694         0, /* tp_getset */
695         0, /* tp_base */
696         0, /* tp_dict */
697         0, /* tp_descr_get */
698         0, /* tp_descr_set */
699         0, /* tp_dictoffset */
700         0, /* tp_init */
701         0, /* tp_alloc */
702         PyType_GenericNew, /* tp_new */
703 };
704
705 /*
706  * Utils
707  */
708
709 int set_s4(s4 *p, PyObject *o) {
710         if (PyInt_Check(o)) {
711                 *p = PyInt_AsLong(o);   
712                 return 0;
713         } else {
714                 return -1;
715         }
716 }
717
718 int set_s4_flag(s4 *p, s4 flag, PyObject *o) {
719         if (o == Py_True) {
720                 *p |= flag;
721                 return 0;
722         } else if (o == Py_False) {
723                 *p &= ~flag;
724                 return 0;
725         } else {
726                 return -1;
727         }
728 }
729
730 int get_int(PyObject **o, int p) {
731         *o = PyInt_FromLong(p);
732         return 0;
733 }
734
735 int get_string(PyObject **o, const char *str) {
736         *o = PyString_FromString(str);
737         return 0;
738 }
739
740 int get_obj(PyObject **res, class_func f, root_state *root, void *p) {
741         if (p == NULL) {
742                 return get_none(res);
743         } else {
744                 PyObject *key = PyInt_FromLong((long)p);
745                 PyObject *o = PyDict_GetItem(root->object_cache, key);
746                 if (o == NULL) {
747                         o = PyObject_CallObject((PyObject *)&wrapper_type, NULL);
748                         struct wrapper * w = (struct wrapper *)o;
749                         w->func = f;
750                         w->state.root = root;
751                         w->state.vp = p;
752                         PyDict_SetItem(root->object_cache, key, o);
753                 } else {
754                         Py_INCREF(o);
755                 }
756                 *res = o;
757                 return 0;
758         }
759 }
760
761 int get_true(PyObject **res) {
762         Py_INCREF(Py_True);
763         *res = Py_True;
764         return 0;
765 }
766
767 int get_false(PyObject **res) {
768         Py_INCREF(Py_False);
769         *res = Py_False;
770         return 0;
771 }
772
773 int get_none(PyObject **res) {
774         Py_INCREF(Py_None);
775         *res = Py_None;
776         return 0;
777 }
778
779 int get_bool(PyObject **res, int cond) {
780         return cond ? get_true(res) : get_false(res);
781 }
782         
783 int get_iter(PyObject **res, iterator_func f, root_state *root, void *p) {
784         PyObject *o = PyObject_CallObject((PyObject *)&iterator_type, NULL);
785         struct iterator * it = (struct iterator *)o;
786         it->func = f;
787         it->state.root = root;
788         it->state.data = p;
789         f(ITERATOR_INIT, &it->state, NULL);
790         *res = o;
791         return 0;
792 }
793
794 int add_const(PyObject *module, const char *name, int value) {
795         PyObject *pyvalue = PyInt_FromLong(value);
796         if (pyvalue != NULL) {
797                 PyModule_AddObject(module, name, pyvalue);
798         }
799 }
800
801 void *get_vp(PyObject *o, class_func func) {
802         if (o->ob_type == &wrapper_type) {
803                 if (((wrapper *)o)->func == func) {
804                         return ((wrapper *)o)->state.vp;
805                 }
806         }
807         return NULL;
808 }
809
810 /*
811  * Implemnetation
812  */
813
814 CLASS_FUNC(basicblock_func);
815 CLASS_FUNC(classinfo_func);
816 CLASS_FUNC(constant_classref_func);
817 CLASS_FUNC(methodinfo_func);
818 CLASS_FUNC(varinfo_func);
819
820 int get_varinfo(PyObject **res, root_state *root, s4 index) {
821         return get_obj(res, varinfo_func, root, root->jd->var + index);
822 }
823
824 static inline int instruction_opcode_ex(instruction *iptr) {
825         if (iptr->opc == ICMD_BUILTIN) {
826                 return iptr->sx.s23.s3.bte->opcode;
827         } else {
828                 return iptr->opc;
829         }
830 }
831
832 ITERATOR_FUNC(call_args_iter_func) {
833         instruction *iptr = (instruction *)state->data;
834         switch (op) {
835                 case ITERATOR_INIT:
836                         state->pos = iptr->sx.s23.s2.args;
837                         return 0;
838                 case ITERATOR_LENGTH:
839                         arg->length = iptr->s1.argcount;
840                         return 0;
841                 case ITERATOR_GET:
842                         /* return get_int(arg->get.result, *(int *)state->pos);*/
843                         return get_varinfo(arg->get.result, state->root, *(int *)state->pos);
844                 case ITERATOR_END:
845                         return state->pos == iptr->sx.s23.s2.args + iptr->s1.argcount;
846                 case ITERATOR_FORWARD:
847                         state->pos = ((int *)state->pos) + 1;
848                         return 0;
849                 case ITERATOR_SUBSCRIPT:
850                         ITERATOR_SUBSCRIPT_CHECK(iptr->s1.argcount);
851                         return get_int(arg->subscript.result, iptr->sx.s23.s2.args[arg->subscript.index]);
852                 case ITERATOR_SETITEM:
853                         ITERATOR_SETITEM_CHECK(iptr->s1.argcount);
854                         return set_s4(iptr->sx.s23.s2.args + arg->setitem.index, arg->setitem.value);
855         }
856         return -1;
857 }
858
859 CLASS_FUNC(fieldinfo_func) {
860         fieldinfo *fi = (fieldinfo *)state->vp;
861
862         switch (op) {
863                 case CLASS_GET_FIELD:
864                         switch (arg->get.field) {
865                                 case F_TYPE:
866                                         return get_int(arg->get.result, fi->type);
867                                 case F_OFFSET:
868                                         return get_int(arg->get.result, fi->offset);
869                                 case F_NAME:
870                                         return get_string(arg->get.result, fi->name->text);
871                                 case F_KLASS:
872                                         return get_obj(arg->get.result, classinfo_func, state->root, fi->clazz);
873                         }
874         }
875
876         return -1;
877 }
878
879 CLASS_FUNC(unresolved_field_func) {
880         unresolved_field *uf = (unresolved_field *)state->vp;
881         switch (op) {
882                 case CLASS_GET_FIELD:
883                         switch (arg->get.field) {
884                                 case F_NAME:
885                                         return get_string(arg->get.result, uf->fieldref->name->text);
886                                 case F_CLASSREF:
887                                         if (IS_FMIREF_RESOLVED(uf->fieldref)) {
888                                                 return get_none(arg->get.result);
889                                         } else {
890                                                 return get_obj(arg->get.result, constant_classref_func, state->root, uf->fieldref->p.classref);
891                                         }
892                                 case F_DESCRIPTOR:
893                                         return get_string(arg->get.result, uf->fieldref->descriptor->text);
894                                 case F_FIELD:
895                                         if (IS_FMIREF_RESOLVED(uf->fieldref)) {
896                                                 return get_obj(arg->get.result, fieldinfo_func, state->root, uf->fieldref->p.field);
897                                         } else {
898                                                 return get_none(arg->get.result);
899                                         }
900                                 case F_IS_UNRESOLVED:
901                                         return get_bool(arg->get.result, !IS_FMIREF_RESOLVED(uf->fieldref));
902                         }
903         }
904         return -1;
905 }
906
907 static inline int instruction_num_s(instruction *iptr) {
908         switch (icmd_table[iptr->opc].dataflow) {
909                 case DF_1_TO_0:
910                 case DF_1_TO_1:
911                 case DF_COPY:
912                 case DF_MOVE:
913                         return 1;
914                 case DF_2_TO_0:
915                 case DF_2_TO_1:
916                         return 2;
917                 case DF_3_TO_0:
918                 case DF_3_TO_1:
919                         return 3;
920                 default:
921                         return 0;
922         }
923 }
924
925 static inline s4 *instruction_get_s(instruction *iptr, int s) {
926         switch (s) {
927                 case 0:
928                         return &(iptr->s1.varindex);
929                 case 1:
930                         return &(iptr->sx.s23.s2.varindex);
931                 case 2:
932                         return &(iptr->sx.s23.s3.varindex);
933         }
934 }
935
936 ITERATOR_FUNC(s_iter_func) {
937         instruction *iptr = (instruction *)state->data;
938         uintptr_t pos = (uintptr_t)state->pos;
939
940         switch (op) {
941                 case ITERATOR_INIT:
942                         state->pos = (void *)0;
943                         return 0;
944                 case ITERATOR_LENGTH:
945                         arg->length = instruction_num_s(iptr);
946                         return 0;
947                 case ITERATOR_GET:
948                         return get_varinfo(arg->get.result, state->root, 
949                                 *instruction_get_s(iptr, pos));
950                 case ITERATOR_END:
951                         return pos == instruction_num_s(iptr);
952                 case ITERATOR_FORWARD:
953                         state->pos = (void *)(pos + 1);
954                         return 0;
955                 case ITERATOR_SUBSCRIPT:
956                         ITERATOR_SUBSCRIPT_CHECK(3);
957                         return get_varinfo(arg->subscript.result, state->root, 
958                                 *instruction_get_s(iptr, arg->subscript.index));
959                 case ITERATOR_SETITEM:
960                         ITERATOR_SETITEM_CHECK(3);
961                         return set_s4(instruction_get_s(iptr, arg->setitem.index), 
962                                 arg->setitem.value);
963         }
964         return -1;
965 }
966
967 CLASS_FUNC(instruction_func) {
968
969         instruction *iptr = (instruction *)state->vp;
970
971         switch (op) {
972                 case CLASS_GET_FIELD:
973                         switch (arg->get.field) {
974                                 case F_OPCODE:
975                                         return get_int(arg->get.result, iptr->opc);
976                                 case F_OPCODE_EX:
977                                         return get_int(arg->get.result, instruction_opcode_ex(iptr));
978                                 case F_NAME:
979                                         return get_string(arg->get.result, icmd_table[iptr->opc].name);
980                                 case F_NAME_EX:
981                                         return get_string(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].name);
982                                 case F_S:
983                                         return get_iter(arg->get.result, s_iter_func, state->root, iptr);       
984                                 case F_DST:
985                                         return get_varinfo(arg->get.result, state->root, 
986                                                 iptr->dst.varindex);
987                                 case F_HAS_DST:
988                                         if (
989                                                 (icmd_table[iptr->opc].dataflow == DF_INVOKE) ||
990                                                 (icmd_table[iptr->opc].dataflow == DF_BUILTIN)
991                                         ) {
992                                                 return get_bool(
993                                                         arg->get.result,
994                                                         instruction_call_site(iptr)->returntype.type != TYPE_VOID
995                                                 );
996                                         }
997                                         return get_bool(arg->get.result, icmd_table[iptr->opc].dataflow >= DF_DST_BASE);
998                                 case F_CALL_RETURN_TYPE:
999                                         return get_int(arg->get.result, instruction_call_site(iptr)->returntype.type);
1000                                 case F_CALL_ARGS:
1001                                         return get_iter(arg->get.result, call_args_iter_func, state->root, iptr);       
1002                                 case F_HAS_CALL_ARGS:
1003                                         return get_bool(arg->get.result,
1004                                                 icmd_table[iptr->opc].dataflow == DF_INVOKE ||
1005                                                 icmd_table[iptr->opc].dataflow == DF_BUILTIN ||
1006                                                 icmd_table[iptr->opc].dataflow == DF_N_TO_1
1007                                         );
1008                                 case F_IS_UNRESOLVED:
1009                                         return get_bool(arg->get.result, iptr->flags.bits & INS_FLAG_UNRESOLVED);
1010                                 case F_IS_CLASS_CONSTANT:
1011                                         return get_bool(arg->get.result, iptr->flags.bits & INS_FLAG_CLASS);
1012                                 case F_KLASS:
1013                                         return get_obj(arg->get.result, classinfo_func, state->root, iptr->sx.val.c.cls);
1014                                 case F_CLASSREF:
1015                                         return get_obj(arg->get.result, constant_classref_func, state->root, iptr->sx.val.c.ref);
1016                                 case F_LOCAL_METHODINFO:
1017                                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1018                                                 return get_none(arg->get.result);
1019                                         } else {        
1020                                                 return get_obj(arg->get.result, methodinfo_func, 
1021                                                         state->root, iptr->sx.s23.s3.fmiref->p.method);
1022                                         }
1023                                 case F_FIELD_TYPE:
1024                                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1025                                                 return get_int(arg->get.result,
1026                                                         iptr->sx.s23.s3.uf->fieldref->parseddesc.fd->type);
1027                                         } else {
1028                                                 return get_int(arg->get.result,
1029                                                         iptr->sx.s23.s3.fmiref->p.field->type);
1030                                         }
1031                                 case F_FIELD:
1032                                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1033                                                 return get_none(arg->get.result);
1034                                         } else {
1035                                                 return get_obj(arg->get.result, fieldinfo_func, state->root, iptr->sx.s23.s3.fmiref->p.field);
1036                                         }
1037                                         break;
1038                                 case F_UNRESOLVED_FIELD:
1039                                         if (INSTRUCTION_IS_UNRESOLVED(iptr)) {
1040                                                 return get_obj(arg->get.result, unresolved_field_func, state->root, iptr->sx.s23.s3.uf);
1041                                         } else {
1042                                                 return get_none(arg->get.result);
1043                                         }
1044                                         break;
1045                                 case F_LINE:
1046                                         return get_int(arg->get.result, iptr->line);
1047                                 case F_PEI:
1048                                         return get_bool(arg->get.result, icmd_table[iptr->opc].flags & ICMDTABLE_PEI);
1049                                 case F_PEI_EX:
1050                                         return get_bool(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].flags & ICMDTABLE_PEI);
1051                                 case F_DATA_FLOW:
1052                                         return get_int(arg->get.result, icmd_table[iptr->opc].dataflow);
1053                                 case F_DATA_FLOW_EX:
1054                                         return get_int(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].dataflow);
1055                                 case F_CONTROL_FLOW:
1056                                         return get_int(arg->get.result, icmd_table[iptr->opc].controlflow);
1057                                 case F_CONTROL_FLOW_EX:
1058                                         return get_int(arg->get.result, icmd_table[instruction_opcode_ex(iptr)].controlflow);
1059                                 case F_SHOW:
1060                                         arg->get.is_method = 1;
1061                                         return 0;
1062                         }
1063                 case CLASS_SET_FIELD:
1064                         switch (arg->set.field) {
1065                                 case F_DST:
1066                                         return set_s4(&(iptr->dst.varindex), arg->set.value);
1067                                 case F_OPCODE:
1068                                         return set_s4(&(iptr->opc), arg->set.value);
1069                         }
1070                 case CLASS_METHOD_CALL:
1071                         switch (arg->method_call.method) {
1072                                 case F_SHOW:
1073                                         show_icmd(state->root->jd, iptr, 1, SHOW_CFG);
1074                                         return 0;
1075                         }
1076         }
1077
1078         return -1;
1079 }
1080
1081 ITERATOR_FUNC(predecessors_iter_func) {
1082         basicblock *bptr = (basicblock *)state->data;
1083
1084         switch (op) {
1085                 case ITERATOR_INIT:
1086                         state->pos = bptr->predecessors;
1087                         return 0;
1088                 case ITERATOR_GET:
1089                         return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
1090                 case ITERATOR_SUBSCRIPT:
1091                         ITERATOR_SUBSCRIPT_CHECK(bptr->predecessorcount);
1092                         return get_obj(arg->subscript.result, basicblock_func, state->root, 
1093                                 bptr->predecessors[arg->subscript.index]);
1094                 case ITERATOR_END:
1095                         return 
1096                                 (state->pos == (bptr->predecessors + bptr->predecessorcount)) ||
1097                                 (bptr->predecessorcount < 0);
1098                 case ITERATOR_FORWARD:
1099                         state->pos = ((basicblock **)state->pos) + 1;
1100                         return 0;
1101                 case ITERATOR_LENGTH:
1102                         arg->length = bptr->predecessorcount;
1103                         return 0;
1104         }
1105
1106         return -1;
1107 }
1108
1109 ITERATOR_FUNC(successors_iter_func) {
1110         basicblock *bptr = (basicblock *)state->data;
1111
1112         switch (op) {
1113                 case ITERATOR_INIT:
1114                         state->pos = bptr->successors;
1115                         return 0;
1116                 case ITERATOR_GET:
1117                         return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
1118                 case ITERATOR_SUBSCRIPT:
1119                         ITERATOR_SUBSCRIPT_CHECK(bptr->successorcount);
1120                         return get_obj(arg->subscript.result, basicblock_func, state->root, 
1121                                 bptr->successors[arg->subscript.index]);
1122                 case ITERATOR_END:
1123                         return 
1124                                 (state->pos == (bptr->successors + bptr->successorcount)) || 
1125                                 (bptr->successorcount < 0);
1126                 case ITERATOR_FORWARD:
1127                         state->pos = ((basicblock **)state->pos) + 1;
1128                         return 0;
1129                 case ITERATOR_LENGTH:
1130                         arg->length = bptr->successorcount;
1131                         return 0;
1132         }
1133
1134         return  -1;
1135 }
1136
1137 ITERATOR_FUNC(dom_successors_iter_func) {
1138         basicblock *bptr = (basicblock *)state->data;
1139
1140         switch (op) {
1141                 case ITERATOR_INIT:
1142                         state->pos = bptr->domsuccessors;
1143                         return 0;
1144                 case ITERATOR_GET:
1145                         return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
1146                 case ITERATOR_END:
1147                         return (state->pos == (bptr->domsuccessors + bptr->domsuccessorcount));
1148                 case ITERATOR_FORWARD:
1149                         state->pos = ((basicblock **)state->pos) + 1;
1150                         return 0;
1151                 case ITERATOR_LENGTH:
1152                         arg->length = bptr->domsuccessorcount;
1153                         return 0;
1154         }
1155
1156         return  -1;
1157 }
1158
1159 ITERATOR_FUNC(dominance_frontier_iter_func) {
1160         basicblock *bptr = (basicblock *)state->data;
1161
1162         switch (op) {
1163                 case ITERATOR_INIT:
1164                         state->pos = bptr->domfrontier;
1165                         return 0;
1166                 case ITERATOR_GET:
1167                         return get_obj(arg->get.result, basicblock_func, state->root, *(basicblock **)state->pos);
1168                 case ITERATOR_END:
1169                         return (state->pos == (bptr->domfrontier + bptr->domfrontiercount));
1170                 case ITERATOR_FORWARD:
1171                         state->pos = ((basicblock **)state->pos) + 1;
1172                         return 0;
1173         }
1174
1175         return  -1;
1176 }
1177
1178 ITERATOR_FUNC(instruction_iter_func) {
1179         basicblock *bptr = (basicblock *)state->data;
1180
1181         switch (op) {
1182                 case ITERATOR_INIT:
1183                         state->pos = bptr->iinstr;
1184                         return 0;
1185                 case ITERATOR_GET:
1186                         return get_obj(arg->get.result, instruction_func, state->root, state->pos);
1187                 case ITERATOR_FORWARD:
1188                         state->pos = ((instruction *)state->pos) + 1;
1189                         return 0;
1190                 case ITERATOR_END:
1191                         return state->pos == (bptr->iinstr + bptr->icount);
1192                 case ITERATOR_SUBSCRIPT:
1193                         ITERATOR_SUBSCRIPT_CHECK(bptr->icount);
1194                         return get_obj(arg->subscript.result, instruction_func, state->root, bptr->iinstr + arg->subscript.index);
1195                 case ITERATOR_LENGTH:
1196                         arg->length = bptr->icount;
1197                         return 0;
1198         }
1199         return -1;
1200 }
1201
1202 ITERATOR_FUNC(in_vars_iter_func) {
1203         basicblock *bptr = (basicblock *)state->data;
1204         switch (op) {
1205                 case ITERATOR_INIT:
1206                         state->pos = bptr->invars;
1207                         return 0;
1208                 case ITERATOR_GET:
1209                         return get_varinfo(arg->get.result, state->root, *(s4 *)(state->pos));
1210                 case ITERATOR_FORWARD:
1211                         state->pos = ((s4 *)state->pos) + 1;
1212                         return 0;
1213                 case ITERATOR_END:
1214                         return state->pos == (bptr->invars + bptr->indepth);
1215                 case ITERATOR_SUBSCRIPT:
1216                         ITERATOR_SUBSCRIPT_CHECK(bptr->icount);
1217                         return get_varinfo(arg->subscript.result, state->root, bptr->invars[arg->subscript.index]);
1218                 case ITERATOR_LENGTH:
1219                         arg->length = bptr->indepth;
1220                         return 0;
1221         }
1222 }
1223
1224 ITERATOR_FUNC(out_vars_iter_func) {
1225         basicblock *bptr = (basicblock *)state->data;
1226         switch (op) {
1227                 case ITERATOR_INIT:
1228                         state->pos = bptr->outvars;
1229                         return 0;
1230                 case ITERATOR_GET:
1231                         return get_varinfo(arg->get.result, state->root, *(s4 *)(state->pos));
1232                 case ITERATOR_FORWARD:
1233                         state->pos = ((s4 *)state->pos) + 1;
1234                         return 0;
1235                 case ITERATOR_END:
1236                         return state->pos == (bptr->outvars + bptr->outdepth);
1237                 case ITERATOR_SUBSCRIPT:
1238                         ITERATOR_SUBSCRIPT_CHECK(bptr->icount);
1239                         return get_varinfo(arg->subscript.result, state->root, bptr->outvars[arg->subscript.index]);
1240                 case ITERATOR_LENGTH:
1241                         arg->length = bptr->outdepth;
1242                         return 0;
1243         }
1244 }
1245
1246 CLASS_FUNC(basicblock_func) {
1247         basicblock *bptr = (basicblock *)state->vp;
1248
1249         switch (op) {
1250                 case CLASS_GET_FIELD:
1251                         switch (arg->get.field) {
1252                                 case F_INSTRUCTIONS:
1253                                         return get_iter(arg->get.result, instruction_iter_func, state->root, bptr);
1254                                 case F_NR:
1255                                         return get_int(arg->get.result, bptr->nr);
1256                                 case F_PREDECESSORS:
1257                                         return get_iter(arg->get.result, predecessors_iter_func, state->root, bptr);
1258                                 case F_SUCCESSORS:
1259                                         return get_iter(arg->get.result, successors_iter_func, state->root, bptr);
1260                                 case F_REACHED:
1261                                         return get_bool(arg->get.result, bptr->flags >= BBREACHED);
1262                                 case F_EXCEPTION_HANDLER:
1263                                         return get_bool(arg->get.result, bptr->type == BBTYPE_EXH);
1264                                 case F_IDOM:
1265                                         return get_obj(arg->get.result, basicblock_func, state->root, bptr->idom);
1266                                 case F_DOM_SUCCESSORS:
1267                                         return get_iter(arg->get.result, dom_successors_iter_func, state->root, bptr);
1268                                 case F_DOMINANCE_FRONTIER:
1269                                         return get_iter(arg->get.result, dominance_frontier_iter_func, state->root, bptr);
1270                                 case F_IN_VARS:
1271                                         return get_iter(arg->get.result, in_vars_iter_func, state->root, bptr);
1272                                 case F_OUT_VARS:
1273                                         return get_iter(arg->get.result, in_vars_iter_func, state->root, bptr);
1274                                 case F_SHOW:
1275                                         arg->get.is_method = 1;
1276                                         return 0;
1277                         }
1278                 case CLASS_STR:
1279                         *arg->str.result = PyString_FromFormat("BB_%d", bptr->nr);
1280                         return 0;
1281                 case CLASS_METHOD_CALL:
1282                         switch (arg->method_call.method) {      
1283                                 case F_SHOW:
1284                                         show_basicblock(state->root->jd, bptr, SHOW_CFG);
1285                                         return 0;
1286                         }
1287         }
1288
1289         return -1;
1290 }
1291
1292 ITERATOR_FUNC(basicblocks_iter_func) {
1293         jitdata *jd = (jitdata *)state->data;
1294         basicblock *bb;
1295
1296         switch (op) {
1297                 case ITERATOR_INIT:
1298                         state->pos = jd->basicblocks;
1299                         return 0;       
1300                 case ITERATOR_GET:
1301                         return get_obj(arg->get.result, basicblock_func, state->root, state->pos);
1302                 case ITERATOR_FORWARD:
1303                         state->pos = ((basicblock *)(state->pos))->next;
1304                         return 0;
1305                 case ITERATOR_END:
1306                         return (state->pos == NULL);
1307                 case ITERATOR_SUBSCRIPT:
1308                         for (bb = jd->basicblocks; bb != NULL; bb = bb->next) {
1309                                 if (bb->nr == arg->subscript.index) {
1310                                         return get_obj(arg->subscript.result, basicblock_func, state->root, bb);
1311                                 }
1312                         }
1313                         return -1;
1314         }
1315
1316         return -1;
1317 }
1318
1319 CLASS_FUNC(classinfo_func) {
1320         classinfo *c = (classinfo *)state->vp;
1321         switch (op) {
1322                 case CLASS_GET_FIELD:
1323                         switch (arg->get.field) {
1324                                 case F_NAME:
1325                                         return get_string(arg->get.result, c->name->text);
1326                         }
1327         }
1328         return -1;
1329 }
1330
1331 CLASS_FUNC(constant_classref_func) {
1332         constant_classref *cr = (constant_classref *)state->vp;
1333         switch (op) {
1334                 case CLASS_GET_FIELD:
1335                         switch (arg->get.field) {
1336                                 case F_NAME:
1337                                         return get_string(arg->get.result, cr->name->text);
1338                         }
1339         }
1340         return -1;
1341 }
1342
1343 ITERATOR_FUNC(param_types_iter_func) {
1344         methodinfo *m = (methodinfo *)state->data;
1345
1346         switch (op) {
1347                 case ITERATOR_INIT:
1348                         state->pos = m->parseddesc->paramtypes;
1349                         return 0;
1350                 case ITERATOR_END:
1351                         return state->pos == (m->parseddesc->paramtypes + m->parseddesc->paramcount);
1352                 case ITERATOR_FORWARD:
1353                         state->pos = ((typedesc *)state->pos) + 1;
1354                         return 0;
1355                 case ITERATOR_GET:
1356                         return get_int(arg->get.result, ((typedesc *)state->pos)->type);
1357                 case ITERATOR_LENGTH:
1358                         arg->length = m->parseddesc->paramcount;
1359                         return 0;
1360                 case ITERATOR_SUBSCRIPT:
1361                         ITERATOR_SUBSCRIPT_CHECK(m->parseddesc->paramcount);
1362                         return get_int(arg->subscript.result, m->parseddesc->paramtypes[arg->subscript.index].type);
1363         }
1364
1365         return -1;
1366 }
1367
1368 ITERATOR_FUNC(params_iter_func) {
1369
1370         methodinfo *m = (methodinfo *)state->data;
1371         /* param counter */
1372         uint16_t p = (uintptr_t)(state->pos) & 0xFFFF;
1373         /* local counter */
1374         uint16_t l = ((uintptr_t)(state->pos) >> 16) & 0xFFFF;
1375
1376         int varnum;
1377
1378         switch (op) {
1379                 case ITERATOR_INIT:
1380                         state->pos = (void *)0;
1381                         return 0;
1382                 case ITERATOR_END:
1383                         return p == m->parseddesc->paramcount;
1384                 case ITERATOR_FORWARD:
1385                         l += (IS_2_WORD_TYPE(m->parseddesc->paramtypes[p].type) ? 2 : 1);
1386                         p += 1;
1387                         state->pos = (void *)(uintptr_t)((l << 16) | p);
1388                         return 0;
1389                 case ITERATOR_GET:
1390                         varnum = state->root->jd->local_map[(5 * l) + m->parseddesc->paramtypes[p].type];
1391                         return get_varinfo(arg->get.result, state->root, varnum);
1392         }
1393                 
1394         return -1;
1395 }
1396
1397 CLASS_FUNC(methodinfo_func) {
1398         methodinfo *m = (methodinfo *)state->vp;
1399         switch (op) {
1400                 case CLASS_GET_FIELD:
1401                         switch (arg->get.field) {
1402                                 case F_NAME:
1403                                         return get_string(arg->get.result, m->name->text);
1404                                 case F_KLASS:
1405                                         return get_obj(arg->get.result, classinfo_func, state->root, m->clazz);
1406                                 case F_PARAM_TYPES:
1407                                         return get_iter(arg->get.result, param_types_iter_func, state->root, m);
1408                                 case F_PARAMS:
1409                                         if (m == state->root->jd->m) {
1410                                                 return get_iter(arg->get.result, params_iter_func, state->root, m);
1411                                         } else {
1412                                                 return get_none(arg->get.result);
1413                                         }
1414                                 case F_RETURN_TYPE:
1415                                         return get_int(arg->get.result, m->parseddesc->returntype.type);
1416                                 case F_SHOW:
1417                                         if (m == state->root->jd->m) {
1418                                                 arg->get.is_method = 1;
1419                                                 return 0;
1420                                         }
1421                         }
1422                 case CLASS_METHOD_CALL:
1423                         switch (arg->method_call.method) {
1424                                 case F_SHOW:
1425                                         show_method(state->root->jd, SHOW_CFG);
1426                                         return 0;
1427                         }
1428         }
1429         return -1;
1430 }
1431
1432 static inline PyObject *varinfo_str(jitdata *jd, int index, varinfo *v) {
1433         char type = '?';
1434         char kind = '?';
1435
1436         switch (v->type) {
1437                 case TYPE_INT: type = 'i'; break;
1438                 case TYPE_LNG: type = 'l'; break;
1439                 case TYPE_FLT: type = 'f'; break;
1440                 case TYPE_DBL: type = 'd'; break;
1441                 case TYPE_ADR: type = 'a'; break;
1442                 case TYPE_RET: type = 'r'; break;
1443                 default:       type = '?';
1444         }
1445
1446         if (index < jd->localcount) {
1447                 kind = 'L';
1448         }
1449         else {
1450                 if (v->flags & PREALLOC) {
1451                         kind = 'A';
1452                         if (v->flags & INOUT) {
1453                                 /* PREALLOC is used to avoid allocation of TYPE_RET */
1454                                 if (v->type == TYPE_RET)
1455                                         kind = 'i';
1456                         }
1457                 }
1458                 else if (v->flags & INOUT)
1459                         kind = 'I';
1460                 else
1461                         kind = 'T';
1462         }
1463
1464         if (index == -1) {
1465                 return PyString_FromString("UNUSED");
1466         } else {
1467                 return PyString_FromFormat("%c%c%d", kind, type, index);
1468         }
1469 }
1470
1471
1472 CLASS_FUNC(varinfo_func) {
1473         jitdata *jd = state->root->jd;
1474         varinfo *var = (varinfo *)state->vp;
1475         int index = var - jd->var;
1476
1477         switch (op) {
1478                 case CLASS_GET_FIELD:
1479                         switch (arg->get.field) {
1480                                 case F_TYPE:
1481                                         return get_int(arg->get.result, var->type);
1482                                 case F_IS_LOCAL:
1483                                         return get_bool(arg->get.result, index < jd->localcount);
1484                                 case F_IS_PREALLOCATED:
1485                                         return get_bool(
1486                                                 arg->get.result, 
1487                                                 (index >= jd->localcount) && (var->flags & PREALLOC)
1488                                         );
1489                                 case F_IS_INOUT:
1490                                         return get_bool(
1491                                                 arg->get.result, 
1492                                                 (index >= jd->localcount) && !(var->flags & PREALLOC) && (var->flags & INOUT)
1493                                         );
1494                                 case F_IS_TEMPORARY:
1495                                         return get_bool(
1496                                                 arg->get.result, 
1497                                                 (index >= jd->localcount) && !(var->flags & PREALLOC) && !(var->flags & INOUT)
1498                                         );
1499                                 case F_IS_SAVED:
1500                                         return get_bool(arg->get.result, var->flags & SAVEDVAR);
1501                                 case F_INDEX:
1502                                         return get_int(arg->get.result, index);
1503                                 case F_UNUSED:
1504                                         return get_bool(arg->get.result, index == UNUSED);
1505                                 case F_REGISTER_OFFSET:
1506                                         return get_int(arg->get.result, var->vv.regoff);
1507                                 case F_IS_IN_MEMORY:
1508                                         return get_bool(arg->get.result, var->flags & INMEMORY);
1509                         }
1510                 case CLASS_SET_FIELD:
1511                         switch (arg->set.field) {
1512                                 case F_TYPE:
1513                                         return set_s4(&(var->type), arg->set.value);
1514                                 case F_IS_LOCAL:
1515                                         if (PyBool_Check(arg->set.value)) {
1516                                                 if (arg->set.value == Py_True) {
1517                                                         if (jd->localcount < (index + 1)) {
1518                                                                 jd->localcount = (index + 1);
1519                                                         }
1520                                                 } else {
1521                                                         if (jd->localcount > (index)) {
1522                                                                 jd->localcount = index;
1523                                                         }
1524                                                 }
1525                                                 return 0;
1526                                         }
1527                                         break;
1528                                 case F_IS_SAVED:
1529                                         if (PyBool_Check(arg->set.value)) {
1530                                                 if (arg->set.value == Py_True) {
1531                                                         var->flags |= SAVEDVAR;
1532                                                 } else {
1533                                                         var->flags &= ~SAVEDVAR;
1534                                                 }
1535                                                 return 0;
1536                                         }
1537                                         break;
1538                                 case F_IS_PREALLOCATED:
1539                                         if (arg->set.value == Py_True) {
1540                                                 var->flags |= PREALLOC;
1541                                                 return 0;
1542                                         }
1543                                         break;
1544                                 case F_IS_INOUT:
1545                                         if (arg->set.value == Py_True) {
1546                                                 var->flags &= ~PREALLOC;
1547                                                 var->flags |= INOUT;
1548                                                 return 0;
1549                                         }
1550                                         break;
1551                                 case F_IS_TEMPORARY:
1552                                         if (arg->set.value == Py_True) {
1553                                                 var->flags &= ~PREALLOC;
1554                                                 var->flags &= ~INOUT;
1555                                                 return 0;
1556                                         }
1557                                         break;
1558                                 case F_REGISTER_OFFSET:
1559                                         return set_s4(&(var->vv.regoff), arg->set.value);
1560                                 case F_IS_IN_MEMORY:
1561                                         return set_s4_flags(&(var->flags), INMEMORY, arg->set.value);
1562                         }
1563                 case CLASS_STR:
1564                         *arg->str.result = varinfo_str(jd, index, var);
1565                         return 0;
1566
1567         }
1568         return -1;
1569 }
1570
1571 int vars_grow(jitdata *jd, unsigned size) {
1572         int newcount;
1573         if (size > 16 * 1024) {
1574                 return 0;
1575         }
1576         if (size >= jd->varcount) {
1577                 newcount = 2 * jd->varcount;
1578                 if (size > newcount) {
1579                         newcount = size;
1580                 }
1581                 jd->var = DMREALLOC(jd->var, varinfo, jd->varcount, newcount);
1582                 MZERO(jd->var + jd->varcount, varinfo, (newcount - jd->varcount));
1583                 jd->varcount = newcount;
1584         }
1585         return 1;
1586 }
1587
1588 ITERATOR_FUNC(vars_iter_func) {
1589         jitdata *jd = (jitdata *)state->data;
1590         void *vp;
1591         switch (op) {
1592                 case ITERATOR_INIT:
1593                         state->pos = jd->var;
1594                         return 0;
1595                 case ITERATOR_FORWARD:
1596                         state->pos = ((varinfo *)state->pos) + 1;
1597                         return 0;
1598                 case ITERATOR_END:
1599                         return state->pos == (jd->var + jd->vartop);
1600                 case ITERATOR_GET:
1601                         return get_obj(arg->get.result, varinfo_func, state->root, state->pos);
1602                 case ITERATOR_LENGTH:
1603                         arg->length = jd->vartop;
1604                         return 0;
1605                 case ITERATOR_SUBSCRIPT:
1606                         ITERATOR_SUBSCRIPT_CHECK(jd->vartop);
1607                         return get_obj(arg->subscript.result, varinfo_func, 
1608                                 state->root, jd->var + arg->subscript.index);
1609                 case ITERATOR_SETITEM:
1610                         ITERATOR_SETITEM_CHECK(jd->vartop);
1611                         vp = get_vp(arg->setitem.value, varinfo_func);
1612                         if (vp) {
1613                                 jd->var[arg->setitem.index] = *(varinfo *)vp;
1614                                 return 0;
1615                         }
1616
1617         }
1618         return -1;
1619 }
1620
1621 ITERATOR_FUNC(map_2_iter_func) {
1622         int *arr = (int *)state->data;
1623         switch (op) {
1624                 case ITERATOR_SUBSCRIPT:
1625                         ITERATOR_SUBSCRIPT_CHECK(5);
1626                         return get_int(arg->subscript.result, arr[arg->subscript.index]);
1627                 case ITERATOR_LENGTH:
1628                         arg->length = 5;
1629                         return 0;
1630                 case ITERATOR_SETITEM:
1631                         ITERATOR_SETITEM_CHECK(5);
1632                         return set_s4(arr + arg->subscript.index, arg->setitem.value);
1633         }
1634         return -1;
1635 }
1636
1637 ITERATOR_FUNC(local_map_iter_func) {
1638         jitdata *jd = (jitdata *)state->data;
1639         switch (op) {
1640                 case ITERATOR_SUBSCRIPT:
1641                         ITERATOR_SUBSCRIPT_CHECK(jd->maxlocals);
1642                         return get_iter(arg->subscript.result, map_2_iter_func, state->root,
1643                                 jd->local_map + (5 * arg->subscript.index));
1644         }
1645         return -1;
1646 }
1647
1648 ITERATOR_FUNC(interface_map_iter_func) {
1649         jitdata *jd = (jitdata *)state->data;
1650         switch (op) {
1651                 case ITERATOR_SUBSCRIPT:
1652                         ITERATOR_SUBSCRIPT_CHECK(jd->maxinterfaces);
1653                         return get_iter(arg->subscript.result, map_2_iter_func, state->root,
1654                                 jd->interface_map + (5 * arg->subscript.index));
1655         }
1656         return -1;
1657 }
1658
1659 ITERATOR_FUNC(exception_entry_basic_blocks_iter_func) {
1660         exception_entry *ee = (exception_entry *)state->data;
1661         switch (op) {
1662                 case ITERATOR_INIT:
1663                         state->pos = ee->start;
1664                         return 0;
1665                 case ITERATOR_FORWARD:
1666                         state->pos = ((basicblock *)state->pos)->next;
1667                         return 0;
1668                 case ITERATOR_END:
1669                         return state->pos == ee->end;
1670                 case ITERATOR_GET:
1671                         return get_obj(arg->get.result, basicblock_func, state->root, state->pos);
1672         }
1673         return -1;
1674 }
1675
1676 CLASS_FUNC(exception_entry_func) {
1677         exception_entry *ee = (exception_entry *)state->vp;
1678         switch (op) {
1679                 case CLASS_GET_FIELD:
1680                         switch (arg->get.field) {
1681                                 case F_START:
1682                                         return get_obj(arg->get.result, basicblock_func, state->root, ee->start);
1683                                 case F_END:
1684                                         return get_obj(arg->get.result, basicblock_func, state->root, ee->end);
1685                                 case F_HANDLER:
1686                                         return get_obj(arg->get.result, basicblock_func, state->root, ee->handler);
1687                                 case F_BASIC_BLOCKS:
1688                                         return get_iter(arg->get.result, exception_entry_basic_blocks_iter_func, state->root, ee);
1689                         }
1690                         break;
1691         }
1692         return -1;
1693 }
1694
1695 ITERATOR_FUNC(exception_table_iter_func) {
1696         jitdata *jd = (jitdata *)state->data;
1697         switch (op) {
1698                 case ITERATOR_INIT:
1699                         state->pos = jd->exceptiontable;
1700                         return 0;
1701                 case ITERATOR_FORWARD:
1702                         state->pos = ((exception_entry *)state->pos)->down;
1703                         return 0;
1704                 case ITERATOR_END:
1705                         return state->pos == NULL;
1706                 case ITERATOR_GET:
1707                         return get_obj(arg->get.result, exception_entry_func, state->root, state->pos);
1708         }
1709         return -1;
1710 }
1711
1712 CLASS_FUNC(jd_func) {
1713         jitdata *jd = (jitdata *)state->vp;
1714
1715         switch (op) {
1716                 case CLASS_GET_FIELD:
1717                         switch (arg->get.field) {
1718                                 case F_BASIC_BLOCKS:
1719                                         return get_iter(arg->get.result, basicblocks_iter_func, state->root, jd);
1720                                 case F_METHOD:
1721                                         return get_obj(arg->get.result, methodinfo_func, state->root, jd->m);
1722                                 case F_VARS:
1723                                         return get_iter(arg->get.result, vars_iter_func, state->root, jd);
1724                                 case F_LOCAL_MAP:
1725                                         return get_iter(arg->get.result, local_map_iter_func, state->root, jd);
1726                                 case F_INTERFACE_MAP:
1727                                         return get_iter(arg->get.result, interface_map_iter_func, state->root, jd);
1728                                 case F_EXCEPTION_TABLE:
1729                                         return get_iter(arg->get.result, exception_table_iter_func, state->root, jd);
1730                         }
1731         }
1732
1733         return -1;
1734 }
1735
1736 void constants(PyObject *m) {
1737         char buf[32];
1738         char *pos;
1739         int i;
1740
1741         /* icmds */
1742
1743         for (i = 0; i < sizeof(icmd_table) / sizeof(icmd_table[0]); ++i) {
1744                 snprintf(buf, sizeof(buf), "ICMD_%s", icmd_table[i].name);
1745                 pos = strchr(buf, ' ');
1746                 if (pos != NULL) {
1747                         *pos = '\0';
1748                 }
1749                 add_const(m, buf, i);
1750         }
1751
1752 #       define c(x) add_const(m, #x, x)
1753
1754         /* types */
1755
1756         c(TYPE_INT);
1757         c(TYPE_LNG);
1758         c(TYPE_ADR);
1759         c(TYPE_FLT);
1760         c(TYPE_DBL);
1761         c(TYPE_VOID);
1762         c(UNUSED);
1763
1764         /* data flow */
1765
1766         c(DF_0_TO_0);
1767         c(DF_1_TO_0);
1768         c(DF_2_TO_0);
1769         c(DF_3_TO_0);
1770         c(DF_DST_BASE);
1771         c(DF_0_TO_1);
1772         c(DF_1_TO_1);
1773         c(DF_2_TO_1);
1774         c(DF_3_TO_1);
1775         c(DF_N_TO_1);
1776         c(DF_INVOKE);
1777         c(DF_BUILTIN);
1778         c(DF_COPY);
1779         c(DF_MOVE);
1780         c(DF_DUP);
1781         c(DF_DUP_X1);
1782         c(DF_DUP_X2);
1783         c(DF_DUP2);
1784         c(DF_DUP2_X1);
1785         c(DF_DUP2_X2);
1786         c(DF_SWAP);
1787         c(DF_LOAD);
1788         c(DF_STORE);
1789         c(DF_IINC);
1790         c(DF_POP);
1791         c(DF_POP2);
1792
1793         /* control flow */
1794
1795         c(CF_NORMAL);
1796         c(CF_IF);
1797         c(CF_END_BASE);
1798         c(CF_END);
1799         c(CF_GOTO);
1800         c(CF_TABLE);
1801         c(CF_LOOKUP);
1802         c(CF_JSR);
1803         c(CF_RET);
1804
1805 #       undef c
1806 }
1807
1808 /*
1809  * Pythonpass
1810  */
1811
1812 void pythonpass_init() {
1813         PyObject *m;
1814         
1815         Py_Initialize();
1816         PyEval_InitThreads();
1817
1818         if (PyType_Ready(&wrapper_type) < 0) return;
1819         if (PyType_Ready(&iterator_type) < 0) return;
1820         if (PyType_Ready(&method_type) < 0) return;
1821
1822         m = Py_InitModule3("cacao", NULL, NULL);
1823         if (m != NULL) {
1824                 constants(m);
1825         }
1826
1827 #if defined(ENABLE_THREADS)
1828         python_global_lock = NEW(java_object_t);
1829         LOCK_INIT_OBJECT_LOCK(python_global_lock);
1830 #endif
1831
1832 }
1833
1834 void pythonpass_cleanup() {
1835         Py_Finalize();
1836 }
1837
1838 int pythonpass_run(jitdata *jd, const char *module, const char *function) {
1839         PyObject *pymodname = NULL;
1840         PyObject *pymod = NULL;
1841         PyObject *pydict = NULL;
1842         PyObject *pyfunc = NULL;
1843         PyObject *pyargs = NULL;
1844         PyObject *pyret = NULL;
1845         PyObject *pyarg = NULL;
1846         PyObject *objcache = NULL;
1847         int success = 0;
1848         root_state root;
1849
1850         LOCK_MONITOR_ENTER(python_global_lock);
1851
1852         pymodname = PyString_FromString(module);
1853         pymod = PyImport_Import(pymodname);
1854
1855         root.jd = jd;
1856         root.object_cache = objcache = PyDict_New();
1857
1858         if (pymod != NULL) {
1859                 pydict = PyModule_GetDict(pymod);
1860                 pyfunc = PyDict_GetItemString(pydict, function);
1861                 if (pyfunc != NULL && PyCallable_Check(pyfunc)) {
1862                         pyargs = PyTuple_New(1);
1863
1864                         if (get_obj(&pyarg, jd_func, &root, jd) != -1) {
1865                         }
1866
1867                         /* */
1868
1869                         PyTuple_SetItem(pyargs, 0, pyarg);
1870
1871                         pyret = PyObject_CallObject(pyfunc, pyargs);
1872                         if (pyret == NULL) {
1873                 PyErr_Print();
1874                         } else {
1875                                 success = 1;
1876                         }
1877                 } else {
1878                         if (PyErr_Occurred())
1879                                 PyErr_Print();
1880                 }
1881         } else {
1882                 PyErr_Print();
1883         }
1884
1885         Py_XDECREF(pymodname);
1886         Py_XDECREF(pymod);
1887         Py_XDECREF(pyargs);
1888         Py_XDECREF(pyret);
1889         Py_XDECREF(objcache);
1890
1891         LOCK_MONITOR_EXIT(python_global_lock);
1892
1893         return (success == 1 ? 1 : 0);
1894 }
1895
1896 /*
1897  * These are local overrides for various environment variables in Emacs.
1898  * Please do not remove this and leave it at the end of the file, where
1899  * Emacs will automagically detect them.
1900  * ---------------------------------------------------------------------
1901  * Local variables:
1902  * mode: c
1903  * indent-tabs-mode: t
1904  * c-basic-offset: 4
1905  * tab-width: 4
1906  * End:
1907  * vim:noexpandtab:sw=4:ts=4:
1908  */