00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00035 #include "Python.h"
00036 #include "structmember.h"
00037 #include "ctrump/ctrump.h"
00038
00039 #if PY_VERSION_HEX < 0x02050000
00040 typedef int Py_ssize_t;
00041 typedef inquiry lenfunc;
00042 typedef intargfunc ssizeargfunc;
00043 #define PyIndex_Check(obj) PyInt_Check(obj)
00044 #define PyNumber_AsSsize_t(obj, exc) PyInt_AsLong(obj)
00045 #endif
00046
00047 struct EnvObject;
00051 typedef struct abiObject {
00052 PyObject_HEAD
00053 struct ctrump_abi abi;
00054 }abiObject ;
00055 static PyTypeObject abiObject_Type;
00056 static PyObject *symbol_obj(struct EnvObject *env, const struct ctrump_symbol *tobj);
00057 static PyObject *texpr_obj(struct EnvObject *env, struct ctrump_texpr *tobj);
00058
00059 static void *
00060 alloc_table(int num_entry)
00061 {
00062 int table_size = sizeof(void*)*num_entry;
00063 void **ret;
00064 int i;
00065
00066 ret = malloc(table_size);
00067 for (i=0; i<num_entry; i++) {
00068 ret[i] = NULL;
00069 }
00070
00071 return ret;
00072 }
00073
00074 static void
00075 expand_table_size(int *current_size,
00076 PyObject ***table,
00077 int assert_size)
00078 {
00079 int old_size = *current_size;
00080 if (assert_size >= *current_size) {
00081 int next_size = assert_size*2;
00082 int i;
00083 PyObject **tbl;
00084 tbl = *table = realloc(*table, sizeof(PyObject*)*next_size);
00085 *current_size = next_size;
00086
00087 for (i=old_size; i<next_size; i++) {
00088 tbl[i] = NULL;
00089 }
00090 }
00091 }
00092
00093 static void
00094 expand_table_size_memtbl(int *current_size,
00095 PyObject ***id2tree_table,
00096 PyObject ****memobj_table,
00097 int assert_size)
00098 {
00099 int old_size = *current_size;
00100
00101 if (assert_size >= *current_size) {
00102 int next_size = assert_size*2;
00103 int i;
00104 PyObject ***mem_tbl;
00105 PyObject **tree_tbl;
00106
00107 tree_tbl = *id2tree_table = realloc(*id2tree_table, sizeof(PyObject*)*next_size);
00108 mem_tbl = *memobj_table = realloc(*memobj_table, sizeof(PyObject**)*next_size);
00109
00110 *current_size = next_size;
00111
00112 for (i=old_size; i<next_size; i++) {
00113 mem_tbl[i] = NULL;
00114 tree_tbl[i] = NULL;
00115 }
00116 }
00117 }
00118
00119
00120
00121 typedef struct
00122 {
00123 PyObject_HEAD
00124 const struct ctrump_symbol *tree;
00125 } symbolObject;
00126
00127 static PyObject *
00128 symbol_str(symbolObject *obj)
00129 {
00130 PyObject *res;
00131 res = PyString_FromStringAndSize(obj->tree->symstr, obj->tree->symlen);
00132 return res;
00133 }
00134
00135 static PyTypeObject symbolObject_Type = {
00136 PyObject_HEAD_INIT (NULL) 0,
00137 "ctrump.symbol",
00138 sizeof (symbolObject),
00139 0,
00140
00141 0,
00142 0,
00143 (getattrfunc) 0,
00144 0,
00145 0,
00146 0,
00147 0,
00148 0,
00149 0,
00150 0,
00151 0,
00152 (reprfunc)symbol_str,
00153 };
00154
00155
00156
00157
00158 typedef struct
00159 {
00160 PyObject_HEAD
00161 struct ctrump_record_type_field *tree;
00162 struct EnvObject *env;
00163 } recordFieldObject;
00164
00165 static PyObject *
00166 record_field_getattr(recordFieldObject *self, char *name)
00167 {
00168 struct ctrump_record_type_field *tree;
00169 struct EnvObject *env = self->env;
00170 tree = self->tree;
00171
00172 if (strcmp(name, "type") == 0) {
00173 return texpr_obj(env, tree->type);
00174 } else if (strcmp(name, "name") == 0) {
00175 return symbol_obj(env, tree->name);
00176 }
00177
00178 PyErr_SetString(PyExc_AttributeError, name);
00179 return NULL;
00180 }
00181
00182
00183 static PyTypeObject recordFieldObject_Type = {
00184 PyObject_HEAD_INIT (NULL)
00185 0,
00186 "ctrump.recordField",
00187 sizeof (recordFieldObject),
00188 0,
00189
00190 0,
00191 0,
00192 (getattrfunc)record_field_getattr,
00193 0,
00194 0,
00195 0,
00196 0,
00197 0,
00198 0,
00199 0,
00200 0,
00201 (reprfunc)0,
00202 0,
00203 0,
00204 0,
00205 Py_TPFLAGS_DEFAULT,
00206 "CTRUMP record Field Object",
00207 0,
00208 0,
00209 0,
00210 0,
00211 0,
00212 0,
00213 0,
00214 };
00215
00216 static PyObject *record_field_obj(struct EnvObject *env, struct ctrump_record_type_field *tree);
00217
00218
00219 typedef struct
00220 {
00221 PyObject_HEAD
00222 struct ctrump_texpr *tree;
00223 struct EnvObject *env;
00224 } texprObject;
00225
00226 static PyObject *
00227 texpr_getattr(texprObject *self, char *name)
00228 {
00229 struct ctrump_texpr *tree;
00230 tree = self->tree;
00231
00232 if (strcmp(name, "code") == 0) {
00233 return PyInt_FromLong(tree->code);
00234 }
00235
00236 switch (tree->code) {
00237 case CTRUMP_TYPE_BUILTIN:
00238 break;
00239
00240 case CTRUMP_TYPE_QUALIFIED:
00241 if (strcmp(name, "aligned")==0) {
00242 return PyInt_FromLong(tree->u.qualified.attr.aligned);
00243 }
00244 if (strcmp(name, "qual_flags")==0) {
00245 return PyInt_FromLong(tree->u.qualified.qual_flags);
00246 }
00247 if (strcmp(name, "unqualified_type")==0) {
00248 return texpr_obj(self->env, tree->u.qualified.unqualified_type);
00249 }
00250 if (strcmp(name, "flags") == 0) {
00251 return PyInt_FromLong(tree->u.qualified.attr.flags);
00252 }
00253 break;
00254 case CTRUMP_TYPE_POINTER:
00255 if (strcmp(name, "pointer_to") == 0) {
00256 return texpr_obj(self->env, tree->u.pointer_to);
00257 }
00258 break;
00259 case CTRUMP_TYPE_TYPEDEF_NAME:
00260 if (strcmp(name, "defined_to") == 0) {
00261 return texpr_obj(self->env, tree->u.typedef_name.defined_to);
00262 }
00263 if (strcmp(name, "def_name") == 0) {
00264 return symbol_obj(self->env, tree->u.typedef_name.def_name);
00265 }
00266 break;
00267 case CTRUMP_TYPE_ARRAY:
00268 if (strcmp(name, "array_of") == 0) {
00269 return texpr_obj(self->env, tree->u.array.array_of);
00270 }
00271 if (strcmp(name, "size") == 0) {
00272 return PyInt_FromLong(tree->u.array.size);
00273 }
00274 break;
00275
00276 case CTRUMP_TYPE_UNION:
00277 case CTRUMP_TYPE_STRUCT:
00278 if (strcmp(name, "name") == 0) {
00279 return symbol_obj(self->env, tree->u.struct_.name);
00280 } else if (strcmp(name, "is_completed") == 0) {
00281 return PyInt_FromLong(tree->u.struct_.is_completed);
00282 } else if (tree->u.struct_.is_completed) {
00283 if (strcmp(name, "fields") == 0) {
00284 int n = tree->u.struct_.nfield, i;
00285 PyObject *a = PyList_New(n);
00286 for (i=0; i<n; i++) {
00287 PyObject *f = record_field_obj(self->env, &tree->u.struct_.fields[i]);
00288 PyList_SetItem(a, i, f);
00289 }
00290 return a;
00291 } else if (strcmp(name, "aligned")==0) {
00292 return PyInt_FromLong(tree->u.struct_.attr.aligned);
00293 } else if (strcmp(name, "flags")==0) {
00294 return PyInt_FromLong(tree->u.struct_.attr.flags);
00295 }
00296 }
00297
00298 break;
00299
00300 case CTRUMP_TYPE_VARLEN_ARRAY:
00301 case CTRUMP_TYPE_ENUM:
00302 case CTRUMP_TYPE_FUNC:
00303 case CTRUMP_TYPE_INCOMPLETE_ARRAY:
00304 break;
00305 }
00306
00307 PyErr_SetString(PyExc_AttributeError, name);
00308 return NULL;
00309 }
00310
00311
00312 static PyTypeObject texprObject_Type;
00313
00314 static PyObject *
00315 texpr_str(texprObject *self)
00316 {
00317 PyObject *obj;
00318 char *buf;
00319 int len;
00320
00321 ctrump_print_texpr_as_internal(&buf, &len, self->tree);
00322 obj = PyString_FromStringAndSize(buf, len);
00323 free(buf);
00324
00325 return obj;
00326 }
00327
00328 static PyTypeObject texprObject_Type = {
00329 PyObject_HEAD_INIT (NULL)
00330 0,
00331 "ctrump.texpr",
00332 sizeof (texprObject),
00333 0,
00334
00335 0,
00336 0,
00337 (getattrfunc)texpr_getattr,
00338 0,
00339 0,
00340 0,
00341 0,
00342 0,
00343 0,
00344 0,
00345 0,
00346 (reprfunc)texpr_str,
00347 0,
00348 0,
00349 0,
00350 Py_TPFLAGS_DEFAULT,
00351 "CTRUMP Type expr Object",
00352 0,
00353 0,
00354 0,
00355 0,
00356 0,
00357 0,
00358 0,
00359 };
00360
00361
00362
00363
00367 typedef struct {
00368 PyObject_HEAD
00369 ctrump_bitmap_t bmp;
00370 int length;
00371 } bitmapObject;
00372
00373 static PyObject *
00374 bitmap_str(bitmapObject *self)
00375 {
00376 PyObject *ret;
00377 int len = self->length;
00378
00379 ret = PyString_FromStringAndSize((char*)NULL, len);
00380 if (ret) {
00381 ctrump_bitmap_t bmp = self->bmp;
00382 char *s = PyString_AS_STRING(ret);
00383 int i;
00384 for (i=0; i<len; i++) {
00385 if (ctrump_bitmap_p(bmp, i)) {
00386 s[i] = '1';
00387 } else {
00388 s[i] = '0';
00389 }
00390 }
00391 }
00392 return ret;
00393 }
00394
00395 static PyObject *indexerr = NULL;
00396
00397 static PyObject *
00398 bitmap_item(bitmapObject *self, Py_ssize_t i)
00399 {
00400 if (i < 0 || i>=self->length) {
00401 if (indexerr == NULL)
00402 indexerr = PyString_FromString(
00403 "bitmap index out of range");
00404 PyErr_SetObject(PyExc_IndexError, indexerr);
00405 return NULL;
00406 }
00407
00408 if (ctrump_bitmap_p(self->bmp, i)) {
00409 Py_RETURN_TRUE;
00410 } else {
00411 Py_RETURN_FALSE;
00412 }
00413 }
00414
00415 static Py_ssize_t
00416 bitmap_length(bitmapObject *self)
00417 {
00418 return self->length;
00419 }
00420
00421 static PyObject*
00422 bitmap_subscript(bitmapObject *self, PyObject *item)
00423 {
00424 if (PyIndex_Check(item)) {
00425 Py_ssize_t i;
00426 i = PyNumber_AsSsize_t(item, PyExc_IndexError);
00427 if (i == -1 && PyErr_Occurred())
00428 return NULL;
00429 return bitmap_item(self, i);
00430 } else {
00431 PyErr_SetString(PyExc_TypeError,
00432 "bitmap indices must be integers");
00433 return NULL;
00434 }
00435 }
00436
00437 static PyObject *
00438 bitmap_pop(bitmapObject *self)
00439 {
00440 return PyInt_FromLong(ctrump_bitmap_popcnt(self->bmp, self->length));
00441 }
00442
00443 static PyMethodDef bitmap_methods[] = {
00444 {"__getitem__", (PyCFunction)bitmap_subscript, METH_O|METH_COEXIST},
00445 {"popcount", (PyCFunction)bitmap_pop, METH_NOARGS},
00446 {NULL, (PyCFunction)NULL, 0, NULL},
00447 };
00448
00449 static PySequenceMethods bitmap_as_sequence = {
00450 (lenfunc)bitmap_length,
00451 (binaryfunc)NULL,
00452 NULL,
00453 (ssizeargfunc)bitmap_item,
00454 };
00455
00456 static PyTypeObject bitmapObject_Type = {
00457 PyObject_HEAD_INIT (NULL)
00458 0,
00459 "ctrump.bitmap",
00460 sizeof (bitmapObject),
00461 0,
00462
00463 0,
00464 0,
00465 (getattrfunc) 0,
00466 0,
00467 0,
00468 0,
00469 0,
00470 &bitmap_as_sequence,
00471 0,
00472 0,
00473 0,
00474 (reprfunc)bitmap_str,
00475 0,
00476 0,
00477 0,
00478 Py_TPFLAGS_DEFAULT,
00479 "CTRUMP bitmap Object",
00480 0,
00481 0,
00482 0,
00483 0,
00484 0,
00485 0,
00486 bitmap_methods,
00487 };
00488
00489
00490
00491
00492
00493 enum {
00494 ERROR_BUILD_CFG,
00495 ERROR_CFRONT_PARSE
00496 };
00500 typedef struct {
00501 PyObject_HEAD
00502 int error_code;
00503 union {
00504 struct ctrump_build_cfg_error build_cfg;
00505 struct ctrump_loginfo cfront;
00506 } u;
00507 } CompilationErrorObject;
00508
00509 static PyObject *
00510 error_get_error_token(CompilationErrorObject *self, PyObject *args)
00511 {
00512 char *str_buf;
00513 int len;
00514 const struct ctrump_stmt *s;
00515 PyObject *obj;
00516 struct ctrump_pprint_format fmt;
00517
00518 switch (self->error_code) {
00519 case ERROR_BUILD_CFG:
00520 s = self->u.build_cfg.stmt;
00521 fmt = ctrump_generate_pprint_format(NULL);
00522 ctrump_print_stmt_format(&str_buf, &len, 0, &fmt, s);
00523 obj = PyString_FromStringAndSize(str_buf, len);
00524 free(str_buf);
00525 return obj;
00526
00527 case ERROR_CFRONT_PARSE:
00528 obj = PyString_FromString(self->u.cfront.tokens[0]);
00529 return obj;
00530 }
00531
00532 return NULL;
00533 }
00534
00535 static PyObject *
00536 error_get_lineno(CompilationErrorObject *self)
00537 {
00538 struct ctrump_location loc;
00539 switch (self->error_code) {
00540
00541 case ERROR_CFRONT_PARSE:
00542 return PyInt_FromLong(self->u.cfront.line);
00543
00544 case ERROR_BUILD_CFG:
00545 loc = ctrump_get_stmt_loc(self->u.build_cfg.stmt);
00546 return PyInt_FromLong(loc.lineno);
00547 }
00548
00549 return NULL;
00550 }
00551
00552 static PyObject *
00553 error_get_reason(CompilationErrorObject *self)
00554 {
00555 switch (self->error_code) {
00556 case ERROR_CFRONT_PARSE:
00557 return PyInt_FromLong(self->u.cfront.code);
00558
00559 case ERROR_BUILD_CFG:
00560 return PyInt_FromLong(-1);
00561 }
00562
00563 return NULL;
00564 }
00565
00566 static PyObject *
00567 error_get_path(CompilationErrorObject *self)
00568 {
00569 struct ctrump_location loc;
00570 switch (self->error_code) {
00571 case ERROR_CFRONT_PARSE:
00572 return PyString_FromString(self->u.cfront.filename);
00573
00574 case ERROR_BUILD_CFG:
00575 loc = ctrump_get_stmt_loc(self->u.build_cfg.stmt);
00576 return PyString_FromString(loc.path);
00577 }
00578
00579 return NULL;
00580 }
00581
00582 static PyObject *
00583 error_get_message(CompilationErrorObject *self)
00584 {
00585 PyObject *ret;
00586 char *str;
00587 switch (self->error_code) {
00588 case ERROR_CFRONT_PARSE:
00589 str = ctrump_get_loginfo_message(&self->u.cfront);
00590 ret = PyString_FromString(str);
00591 free(str);
00592 return ret;
00593
00594 case ERROR_BUILD_CFG:
00595 return PyString_FromString("build cfg error");
00596 }
00597
00598 return NULL;
00599 }
00600
00601
00602 static struct PyMethodDef compile_error_methods[] = {
00603 {"get_error_token", (PyCFunction)error_get_error_token, METH_VARARGS, NULL},
00604 {"lineno", (PyCFunction)error_get_lineno, METH_NOARGS, NULL},
00605 {"path", (PyCFunction)error_get_path, METH_NOARGS, NULL},
00606 {"reason", (PyCFunction)error_get_reason, METH_NOARGS, NULL},
00607 {"message", (PyCFunction)error_get_message, METH_NOARGS, NULL},
00608 {NULL, (PyCFunction)NULL, 0, NULL}
00609 };
00610
00611 static PyTypeObject CompilationErrorObject_Type = {
00612 PyObject_HEAD_INIT(NULL)
00613 0,
00614 "ctrump.CompilationErrorObject",
00615 sizeof(CompilationErrorObject),
00616 0,
00617
00618 0,
00619 0,
00620 (getattrfunc)0,
00621 0,
00622 0,
00623 0,
00624 0,
00625 0,
00626 0,
00627 0,
00628 0,
00629 0,
00630 0,
00631 0,
00632 0,
00633 Py_TPFLAGS_DEFAULT,
00634 "CTRUMP Compilation Error Object",
00635 0,
00636 0,
00637 0,
00638 0,
00639 0,
00640 0,
00641 compile_error_methods,
00642 0,
00643 0,
00644 0,
00645 0,
00646 0,
00647 0,
00648 0,
00649 (initproc)0,
00650 0,
00651 0,
00652 };
00653
00654
00655 static CompilationErrorObject *
00656 build_cfg_error_New(struct ctrump_build_cfg_error *e)
00657 {
00658 CompilationErrorObject *o = PyObject_New(CompilationErrorObject, &CompilationErrorObject_Type);
00659 if (o == NULL)
00660 return NULL;
00661 o->u.build_cfg = *e;
00662 o->error_code = ERROR_BUILD_CFG;
00663 return o;
00664 }
00665
00666 static CompilationErrorObject *
00667 cfront_parse_error_New(struct ctrump_loginfo *loginfo)
00668 {
00669 CompilationErrorObject *o = PyObject_New(CompilationErrorObject, &CompilationErrorObject_Type);
00670 if (o == NULL)
00671 return NULL;
00672 o->u.cfront = *loginfo;
00673 o->error_code = ERROR_CFRONT_PARSE;
00674
00675 return o;
00676 }
00677
00678
00679
00683 typedef struct {
00684 PyObject_HEAD
00685 struct ctrump_type_env type_env;
00686 int id2texpr_obj_table_size;
00687 PyObject **id2texpr_obj_table;
00688
00689 #define DEFINE_BUILTIN_TYPE(str_name,code,sym) \
00690 texprObject *str_name;
00691 #include "ctrump/ast/builtin-types.def"
00692 #undef DEFINE_BUILTIN_TYPE
00693
00694 } TypeEnvObject;
00695
00696 static PyMethodDef typeenv_methods[] = {
00697 {NULL, (PyCFunction)NULL, 0, NULL},
00698 };
00699
00700 static int
00701 typeenv_Init(TypeEnvObject *self, struct EnvObject *env, PyObject *args, PyObject *kwds)
00702 {
00703 int num_texpr;
00704 texprObject *type_obj;
00705
00706 ctrump_type_env_init(&self->type_env, 1);
00707
00708 num_texpr = self->type_env.id;
00709
00710 self->id2texpr_obj_table = alloc_table(num_texpr);
00711 self->id2texpr_obj_table_size = num_texpr;
00712
00713 #define DEFINE_BUILTIN_TYPE(str_name,c,sym) \
00714 type_obj = PyObject_New(texprObject, &texprObject_Type); \
00715 type_obj->tree = &ctrump_builtin_##str_name; \
00716 type_obj->env = env; \
00717 self->id2texpr_obj_table[type_obj->tree->id] = (PyObject*)type_obj; \
00718 self->str_name = type_obj;
00719
00720 #include "ctrump/ast/builtin-types.def"
00721 #undef DEFINE_BUILTIN_TYPE
00722
00723 return 0;
00724 }
00725
00726 static void
00727 typeenv_dealloc(TypeEnvObject *o)
00728 {
00729 free(o->id2texpr_obj_table);
00730 ctrump_type_env_destroy(&o->type_env);
00731 PyObject_Del(o);
00732 }
00733
00734 static PyMemberDef typeenv_members[] = {
00735 #define DEFINE_BUILTIN_TYPE(str_name,c,sym) \
00736 {#str_name, T_OBJECT, offsetof(TypeEnvObject, str_name), READONLY},
00737 #include "ctrump/ast/builtin-types.def"
00738 #undef DEFINE_BUILTIN_TYPE
00739 {0},
00740 };
00741
00742
00743 static PyTypeObject TypeEnvObject_Type = {
00744 PyObject_HEAD_INIT (NULL)
00745 0,
00746 "ctrump.TypeEnv",
00747 sizeof (TypeEnvObject),
00748 0,
00749
00750 (destructor)typeenv_dealloc,
00751 0,
00752 (getattrfunc) 0,
00753 0,
00754 0,
00755 0,
00756 0,
00757 0,
00758 0,
00759 0,
00760 0,
00761 (reprfunc)0,
00762 0,
00763 0,
00764 0,
00765 Py_TPFLAGS_DEFAULT,
00766 "CTRUMP C Types",
00767 0,
00768 0,
00769 0,
00770 0,
00771 0,
00772 0,
00773 typeenv_methods,
00774 typeenv_members,
00775 };
00776
00777
00778
00779
00780 typedef struct EnvObject {
00781 PyObject_HEAD
00782 struct ctrump_mempool tree_pool;
00783 struct ctrump_mempool pyobj_pool;
00784 int num_object;
00785 int id2symbol_table_size;
00786 int id_table_size;
00787 PyObject **id2tree_obj_table;
00788 PyObject **id2symbol_table;
00789 PyObject ***member_obj_table;
00790 TypeEnvObject *type_env;
00791 } EnvObject;
00792
00793 static PyTypeObject EnvObject_Type;
00794
00795 static int
00796 env_Init(EnvObject *self, PyObject *args, PyObject *kwds)
00797 {
00798 int num_sym;
00799
00800 ctrump_mempool_init(&self->tree_pool, 1024);
00801 ctrump_mempool_init(&self->pyobj_pool, 1024);
00802
00803 num_sym = ctrump_get_current_symbol_num();
00804 if (num_sym < 16)
00805 num_sym = 16;
00806
00807 self->id2symbol_table = alloc_table(num_sym);
00808 self->id2symbol_table_size = num_sym;
00809 self->member_obj_table = alloc_table(16);
00810 self->id2tree_obj_table = alloc_table(16);
00811
00812 self->type_env = PyObject_New(TypeEnvObject, &TypeEnvObject_Type);
00813 self->id_table_size = 16;
00814 self->num_object = 0;
00815
00816 typeenv_Init(self->type_env, self, NULL, NULL);
00817
00818 return 0;
00819 }
00820
00821 static PyObject *
00822 texpr_obj(EnvObject *env, struct ctrump_texpr *tobj)
00823 {
00824 TypeEnvObject *tenv = env->type_env;
00825 PyObject **tbl;
00826 int id = tobj->id;
00827 PyObject *ret;
00828 texprObject *obj;
00829
00830 expand_table_size(&tenv->id2texpr_obj_table_size,
00831 &tenv->id2texpr_obj_table,
00832 id);
00833 tbl = tenv->id2texpr_obj_table;
00834 ret = tbl[id];
00835
00836 if (ret) {
00837 Py_INCREF(ret);
00838 return ret;
00839 }
00840
00841 obj = PyObject_New(texprObject, &texprObject_Type);
00842 obj->tree = tobj;
00843 obj->env = env;
00844
00845 tbl[id] = (PyObject*)obj;
00846 Py_INCREF(obj);
00847
00848 return (PyObject*)obj;
00849 }
00850
00851 static PyObject *
00852 symbol_obj(EnvObject *env, const struct ctrump_symbol *tobj)
00853 {
00854 PyObject **tbl;
00855 int id = tobj->id;
00856 PyObject *ret;
00857 symbolObject *obj;
00858
00859 expand_table_size(&env->id2symbol_table_size,
00860 &env->id2symbol_table,
00861 id);
00862 tbl = env->id2symbol_table;
00863
00864 ret = tbl[id];
00865
00866 if (ret) {
00867 Py_INCREF(ret);
00868 return ret;
00869 }
00870
00871 obj = PyObject_New(symbolObject, &symbolObject_Type);
00872 obj->tree = tobj;
00873
00874 tbl[id] = (PyObject*)obj;
00875 Py_INCREF(obj);
00876
00877 return (PyObject*)obj;
00878 }
00879
00880 static PyObject *
00881 member_obj(PyObject **mem_tbl, int index)
00882 {
00883 PyObject *obj = mem_tbl[index];
00884 Py_INCREF(obj);
00885 return obj;
00886 }
00887
00888 static PyObject *record_field_obj(struct EnvObject *env, struct ctrump_record_type_field *tree)
00889 {
00890 recordFieldObject *o = PyObject_New(recordFieldObject, &recordFieldObject_Type);
00891 o->env = env;
00892 Py_INCREF(env);
00893 o->tree = tree;
00894
00895 return (PyObject*)o;
00896 }
00897
00898
00899 typedef struct ParserOptionObject {
00900 PyObject_HEAD
00901 struct ctrump_parser_option tree;
00902 } ParserOptionObject;
00903
00904 static PyMemberDef parserOption_members[] = {
00905 {"is_vector_keyword", T_INT, offsetof(ParserOptionObject, tree.is_vector_keyword), 0, "whether `vector' is keyword or not"},
00906 {0},
00907 };
00908
00909 static int
00910 parserOption_Init(ParserOptionObject *self, PyObject *args, PyObject *kwds)
00911 {
00912 ctrump_get_default_parser_option(&self->tree);
00913 return 0;
00914 }
00915
00916 static PyTypeObject ParserOption_Type = {
00917 PyObject_HEAD_INIT(NULL)
00918 0,
00919 "ctrump.ParserOption",
00920 sizeof(ParserOptionObject),
00921 0,
00922
00923 0,
00924 0,
00925 0,
00926 0,
00927 0,
00928 0,
00929 0,
00930 0,
00931 0,
00932 0,
00933 0,
00934 0,
00935 0,
00936 0,
00937 0,
00938 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
00939 "CTRUMP Parser Option Object",
00940 0,
00941 0,
00942 0,
00943 0,
00944 0,
00945 0,
00946 0,
00947 parserOption_members,
00948 0,
00949 0,
00950 0,
00951 0,
00952 0,
00953 0,
00954 (initproc)parserOption_Init,
00955 0,
00956 0,
00957 };
00958
00959 static PyObject *
00960 fill_table_symbol(EnvObject *env, const struct ctrump_symbol *sym)
00961 {
00962 return NULL;
00963 }
00964
00965 static PyObject *
00966 fill_table_texpr(EnvObject *env, const struct ctrump_texpr *sym)
00967 {
00968 return NULL;
00969 }
00970
00971 #include "astobj.h"
00972
00973 static PyObject *
00974 cfront_parse(EnvObject *self, PyObject *args)
00975 {
00976 char *fname;
00977 char *original_fname;
00978 struct ctrump_loginfo *error;
00979 int num_error=0;
00980 struct ctrump_build_cfg_error build_cfg_error;
00981 struct ctrump_translation_unit *unit;
00982 int num_tree, i, next_id, start_id;
00983 PyObject *ret;
00984 PyObject *errors;
00985 PyObject *tree_obj;
00986 PyObject *option_obj;
00987 ParserOptionObject *option;
00988
00989 if (!PyArg_ParseTuple(args, "ssO", &fname, &original_fname, &option_obj))
00990 return NULL;
00991
00992 if (!PyObject_TypeCheck(option_obj, &ParserOption_Type)) {
00993 PyErr_SetString(PyExc_TypeError, "requires parser option");
00994 return NULL;
00995 }
00996
00997 option = (ParserOptionObject*)option_obj;
00998 ret = PyTuple_New(2);
00999
01000 unit = ctrump_mempool_alloc(&self->tree_pool, sizeof(*unit));
01001
01002 start_id = self->num_object;
01003 next_id = ctrump_parse(&error, &num_error, unit, fname, original_fname,
01004 &self->type_env->type_env, &ctrump_ppc32_abi,
01005 &option->tree, start_id, &self->tree_pool);
01006
01007 if (next_id < 0) {
01008 errors = PyList_New(num_error);
01009
01010 PyTuple_SetItem(ret, 0, Py_None);
01011 PyTuple_SetItem(ret, 1, errors);
01012
01013 for (i=0; i<num_error; i++) {
01014 PyObject *o = (PyObject*)cfront_parse_error_New(&error[i]);
01015 PyList_SetItem(errors, i, o);
01016 }
01017
01018 return ret;
01019 }
01020
01021 num_tree = next_id - start_id;
01022 next_id = ctrump_analyze(unit, &ctrump_ppc32_abi, &self->tree_pool, &build_cfg_error, num_tree, next_id);
01023
01024 if (next_id < 0) {
01025 int num_all_error = num_error + 1;
01026
01027 errors = PyList_New(num_all_error);
01028
01029 PyTuple_SetItem(ret, 0, Py_None);
01030 PyTuple_SetItem(ret, 1, errors);
01031
01032 for (i=0; i<num_error; i++) {
01033 PyObject *o = (PyObject*)cfront_parse_error_New(&error[i]);
01034 PyList_SetItem(errors, i, o);
01035 }
01036
01037 PyList_SetItem(errors, num_error, (PyObject*)build_cfg_error_New(&build_cfg_error));
01038 return ret;
01039 }
01040
01041 expand_table_size_memtbl(&self->id_table_size,
01042 &self->id2tree_obj_table,
01043 &self->member_obj_table,
01044 next_id);
01045
01046 self->num_object = next_id;
01047 self->id_table_size = next_id;
01048
01049 tree_obj = fill_table_translation_unit(self, unit);
01050
01051 PyTuple_SetItem(ret, 0, tree_obj);
01052 errors = PyList_New(num_error);
01053 PyTuple_SetItem(ret, 1, errors);
01054
01055 for (i=0; i<num_error; i++) {
01056 PyObject *o = (PyObject*)cfront_parse_error_New(&error[i]);
01057 PyList_SetItem(errors, i, o);
01058 }
01059
01060 return ret;
01061 }
01062
01063
01064
01065 static PyObject *
01066 pprint0(PyObject *args, int print_ssa)
01067 {
01068 PyObject *obj, *use_column = Py_None;
01069 translation_unitObject *tobj;
01070 char *buf;
01071 int len;
01072 int is_use_column = 0;
01073 struct ctrump_pprint_format fmt;
01074
01075 if (!PyArg_ParseTuple(args, "O|O",
01076 &obj, &use_column))
01077 return NULL;
01078 if (!PyObject_TypeCheck(obj, &translation_unitObject_Type)) {
01079 PyErr_SetString(PyExc_TypeError, "requires translation unit");
01080 return NULL;
01081 }
01082 tobj = (translation_unitObject*)obj;
01083
01084 if (use_column == Py_True) {
01085 is_use_column = 1;
01086 }
01087
01088 fmt = ctrump_generate_pprint_format(NULL);
01089 ctrump_print_translation_unit_format(&buf, &len, print_ssa, &fmt, tobj->tree);
01090 obj = PyString_FromStringAndSize(buf, len);
01091 free(buf);
01092
01093 return obj;
01094 }
01095
01096 static PyObject *
01097 pprint(EnvObject *self, PyObject *args)
01098 {
01099 return pprint0(args, 0);
01100 }
01101 static PyObject *
01102 pprint_ssa(EnvObject *self, PyObject *args)
01103 {
01104 return pprint0(args, 1);
01105 }
01106
01107
01108 static PyObject *
01109 pprint_stmt(PyObject *self, PyObject *args)
01110 {
01111 PyObject *obj;
01112 stmtObject *sobj;
01113 char *buf;
01114 int len;
01115 struct ctrump_pprint_format fmt;
01116
01117 if (!PyArg_ParseTuple(args, "O",
01118 &obj))
01119 return NULL;
01120 if (!PyObject_TypeCheck(obj, &stmtObject_Type)) {
01121 PyErr_SetString(PyExc_TypeError, "requires stmt");
01122 return NULL;
01123 }
01124 sobj = (stmtObject*)obj;
01125
01126 fmt = ctrump_generate_pprint_format(NULL);
01127 ctrump_print_stmt_format(&buf, &len, 0, &fmt, sobj->tree);
01128 obj = PyString_FromStringAndSize(buf, len);
01129 free(buf);
01130
01131 return obj;
01132 }
01133 static PyObject *
01134 pprint_expr0(PyObject *args, int print_ssa)
01135 {
01136 PyObject *obj;
01137 exprObject *eobj;
01138 char *buf;
01139 int len;
01140 struct ctrump_pprint_format fmt;
01141
01142 if (!PyArg_ParseTuple(args, "O",
01143 &obj))
01144 return NULL;
01145 if (!PyObject_TypeCheck(obj, &exprObject_Type)) {
01146 PyErr_SetString(PyExc_TypeError, "requires expr");
01147 return NULL;
01148 }
01149 eobj = (exprObject*)obj;
01150
01151 fmt = ctrump_generate_pprint_format(NULL);
01152 ctrump_print_expr_format(&buf, &len, print_ssa, &fmt, eobj->tree);
01153 obj = PyString_FromStringAndSize(buf, len);
01154 free(buf);
01155
01156 return obj;
01157 }
01158
01159 static PyObject*
01160 pprint_expr(PyObject *self, PyObject *args)
01161 {
01162 return pprint_expr0(args, 0);
01163 }
01164 static PyObject*
01165 pprint_ssa_expr(PyObject *self, PyObject *args)
01166 {
01167 return pprint_expr0(args, 1);
01168 }
01169
01170 static struct ctrump_loop_subscript *
01171 subscript_typecheck(PyObject *o)
01172 {
01173 if (PyObject_TypeCheck(o, &loop_subscriptObject_Type)) {
01174 return ((loop_subscriptObject*)o)->tree;
01175 }
01176 if (PyObject_TypeCheck(o, &loop_subscriptProxy_Type)) {
01177 return ((loop_subscriptProxyObject*)o)->tree;
01178 }
01179
01180 return NULL;
01181 }
01182
01183 static struct ctrump_loop_index *
01184 index_typecheck(PyObject *o)
01185 {
01186 if (PyObject_TypeCheck(o, &loop_indexObject_Type)) {
01187 return ((loop_indexObject*)o)->tree;
01188 }
01189 if (PyObject_TypeCheck(o, &loop_indexProxy_Type)) {
01190 return ((loop_indexProxyObject*)o)->tree;
01191 }
01192
01193 return NULL;
01194 }
01195
01196
01197
01198 static PyObject*
01199 loop_subscript_hash(PyObject *self, PyObject *args)
01200 {
01201 PyObject *sub;
01202 struct ctrump_loop_subscript *s;
01203
01204 if (!PyArg_ParseTuple(args, "O", &sub))
01205 return NULL;
01206
01207 if (!(s = subscript_typecheck(sub))) {
01208 PyErr_SetString(PyExc_TypeError, "requires loop_subscript");
01209 return NULL;
01210 }
01211
01212 return PyInt_FromLong(ctrump_loop_subscript_hash(s));
01213 }
01214
01215 static PyObject*
01216 loop_subscript_equal(PyObject *self, PyObject *args)
01217 {
01218 PyObject *sub1, *sub2;
01219 struct ctrump_loop_subscript *s1, *s2;
01220 int r;
01221
01222 if (!PyArg_ParseTuple(args, "OO", &sub1, &sub2))
01223 return NULL;
01224
01225 if (!(s1=subscript_typecheck(sub1))) {
01226 PyErr_SetString(PyExc_TypeError, "requires loop_subscript");
01227 return NULL;
01228 }
01229 if (!(s2=subscript_typecheck(sub2))) {
01230 PyErr_SetString(PyExc_TypeError, "requires loop_subscript");
01231 return NULL;
01232 }
01233
01234 r = ctrump_loop_subscript_equal(s1, s2);
01235
01236 return PyBool_FromLong(r);
01237 }
01238
01239 static PyObject*
01240 loop_index_equal(PyObject *self, PyObject *args)
01241 {
01242 PyObject *sub1, *sub2;
01243 struct ctrump_loop_index *i1, *i2;
01244 int r;
01245
01246 if (!PyArg_ParseTuple(args, "OO", &sub1, &sub2))
01247 return NULL;
01248
01249 if (!(i1=index_typecheck(sub1))) {
01250 PyErr_SetString(PyExc_TypeError, "requires loop_index");
01251 return NULL;
01252 }
01253 if (!(i2=index_typecheck(sub2))) {
01254 PyErr_SetString(PyExc_TypeError, "requires loop_index");
01255 return NULL;
01256 }
01257
01258 r = ctrump_loop_index_equal(i1, i2);
01259
01260 return PyBool_FromLong(r);
01261 }
01262
01263
01264
01265
01266 static texprObject *
01267 texpr_arg(PyObject *args)
01268 {
01269 PyObject *obj;
01270 if (!PyArg_ParseTuple(args, "O",
01271 &obj))
01272 return NULL;
01273 if (!PyObject_TypeCheck(obj, &texprObject_Type)) {
01274 PyErr_SetString(PyExc_TypeError, "requires texpr");
01275 return NULL;
01276 }
01277 return (texprObject*)obj;
01278 }
01279
01280 static PyObject *
01281 is_pointer_type(PyObject *self, PyObject *args)
01282 {
01283 texprObject *tobj;
01284
01285 tobj = texpr_arg(args);
01286 if (!tobj)
01287 return NULL;
01288
01289 if (ctrump_texpr_is_pointer(tobj->tree)) {
01290 Py_RETURN_TRUE;
01291 } else {
01292 Py_RETURN_FALSE;
01293 }
01294 }
01295
01296 static PyObject *
01297 type_apply_unary_pointer_conversion(PyObject *self, PyObject *args)
01298 {
01299 texprObject *tobj;
01300 EnvObject *env;
01301 struct ctrump_texpr *pointer_type;
01302 struct ctrump_type_env *tenv;
01303
01304 tobj = texpr_arg(args);
01305 if (!tobj)
01306 return NULL;
01307
01308 env = tobj->env;
01309 tenv = &env->type_env->type_env;
01310
01311 pointer_type = ctrump_texpr_apply_unary_pointer_conversion(tenv, tobj->tree);
01312
01313 if (pointer_type) {
01314 return texpr_obj(env, pointer_type);
01315 } else {
01316 Py_RETURN_NONE;
01317 }
01318 }
01319
01320
01321 static PyObject *
01322 fold_const(PyObject *self, PyObject *args)
01323 {
01324 PyObject *arg_obj;
01325 exprObject *expr_obj;
01326 int is_const;
01327 int val;
01328
01329 if (!PyArg_ParseTuple(args, "O",
01330 &arg_obj))
01331 return NULL;
01332
01333 if (! PyObject_TypeCheck(arg_obj, &exprObject_Type)) {
01334 PyErr_SetString(PyExc_TypeError, "requries expr");
01335 return NULL;
01336 }
01337
01338 expr_obj = (exprObject*)arg_obj;
01339 val = ctrump_ast_fold_const_sint(expr_obj->tree, &is_const);
01340
01341 if (is_const) {
01342 return PyInt_FromLong(val);
01343 } else {
01344 Py_RETURN_NONE;
01345 }
01346 }
01347
01348
01349
01350 static PyObject *
01351 calc_type_size(PyObject *self, PyObject *args)
01352 {
01353 PyObject *tobj;
01354 PyObject *abi_obj;
01355 size_t sz;
01356 size_t align;
01357 int r;
01358
01359 if (!PyArg_ParseTuple(args, "OO",
01360 &abi_obj, &tobj))
01361 return NULL;
01362 if (!PyObject_TypeCheck(tobj, &texprObject_Type)) {
01363 PyErr_SetString(PyExc_TypeError, "requires texpr");
01364 return NULL;
01365 }
01366 if (!PyObject_TypeCheck(abi_obj, &abiObject_Type)) {
01367 PyErr_SetString(PyExc_TypeError, "requires abi");
01368 return NULL;
01369 }
01370
01371 r = ctrump_texpr_size(&sz, &align,
01372 &((abiObject*)abi_obj)->abi,
01373 ((texprObject*)tobj)->tree);
01374
01375 if (r < 0) {
01376 PyErr_SetString(PyExc_TypeError, "unknown size");
01377 return NULL;
01378 }
01379
01380 return PyInt_FromLong(sz);
01381 }
01382
01383 static PyObject *
01384 struct_field_offset(PyObject *self, PyObject *args)
01385 {
01386 PyObject *tobj;
01387 PyObject *abi_obj;
01388 PyObject *sym_obj;
01389 int r;
01390 struct ctrump_texpr *record_type;
01391
01392 if (!PyArg_ParseTuple(args, "OOO",
01393 &abi_obj, &tobj, &sym_obj))
01394 return NULL;
01395 if (!PyObject_TypeCheck(tobj, &texprObject_Type)) {
01396 PyErr_SetString(PyExc_TypeError, "requires texpr");
01397 return NULL;
01398 }
01399 if (!PyObject_TypeCheck(abi_obj, &abiObject_Type)) {
01400 PyErr_SetString(PyExc_TypeError, "requires abi");
01401 return NULL;
01402 }
01403 if (!PyObject_TypeCheck(sym_obj, &symbolObject_Type)) {
01404 PyErr_SetString(PyExc_TypeError, "requires symbol");
01405 return NULL;
01406 }
01407
01408 record_type = ((texprObject*)tobj)->tree;
01409 record_type = ctrump_get_unqualified_type(record_type);
01410 if (record_type->code == CTRUMP_TYPE_UNION) {
01411 return PyInt_FromLong(0);
01412 }
01413
01414 record_type = ctrump_retrieve_typedef_name(record_type);
01415
01416 if (record_type->code != CTRUMP_TYPE_STRUCT) {
01417 PyErr_SetString(PyExc_TypeError, "requires struct type");
01418 return NULL;
01419 }
01420
01421 r = ctrump_struct_field_offset(&record_type->u.struct_,
01422 ((symbolObject*)sym_obj)->tree,
01423 &((abiObject*)abi_obj)->abi);
01424
01425 if (r < 0) {
01426 PyErr_SetString(PyExc_TypeError, "unknown size");
01427 return NULL;
01428 }
01429
01430 return PyInt_FromLong(r);
01431 }
01432
01433
01434
01435
01436 static PyObject *
01437 retrieve_pointer_type(PyObject *self, PyObject *args)
01438 {
01439 texprObject *tobj;
01440 struct ctrump_texpr *t;
01441
01442 tobj = texpr_arg(args);
01443 if (!tobj)
01444 return NULL;
01445
01446 t = ctrump_retrieve_pointer_type(tobj->tree);
01447
01448 if (!t) {
01449 PyErr_SetString(PyExc_TypeError, "require pointer type");
01450 return NULL;
01451 }
01452
01453 return texpr_obj(tobj->env, t);
01454 }
01455
01456 static PyObject *
01457 retrieve_address_type(PyObject *self, PyObject *args)
01458 {
01459 texprObject *tobj;
01460 struct ctrump_texpr *t;
01461
01462 tobj = texpr_arg(args);
01463 if (!tobj)
01464 return NULL;
01465
01466 t = ctrump_retrieve_address_type(tobj->tree);
01467
01468 if (!t) {
01469 PyErr_SetString(PyExc_TypeError, "require pointer or array type");
01470 return NULL;
01471 }
01472
01473 return texpr_obj(tobj->env, t);
01474 }
01475
01476
01477 static void
01478 EnvObject_dealloc(EnvObject *o)
01479 {
01480 ctrump_mempool_destroy(&o->tree_pool);
01481 ctrump_mempool_destroy(&o->pyobj_pool);
01482
01483 free(o->id2symbol_table);
01484 free(o->member_obj_table);
01485 free(o->id2tree_obj_table);
01486
01487 Py_DECREF(o->type_env);
01488
01489 PyObject_Del(o);
01490 }
01491
01492 #define NELEM(a) (sizeof(a)/sizeof(a[0]))
01493
01494 static PyObject *
01495 expr_prec(PyObject *self, PyObject *args)
01496 {
01497 int val;
01498 if (!PyArg_ParseTuple(args, "i", &val))
01499 return NULL;
01500
01501 if (val > CTRUMP_EXPR_EMPTY) {
01502 PyErr_SetString(PyExc_IndexError, "expr code error");
01503 return NULL;
01504 }
01505
01506 return PyInt_FromLong(ctrump_expr_prec_table[val]);
01507 }
01508
01509 static PyObject *
01510 get_stmt_loc(PyObject *self, PyObject *args)
01511 {
01512 PyObject *stmt_obj;
01513 PyObject *ret, *path, *lineno;
01514 struct ctrump_stmt *stmt;
01515 struct ctrump_location loc;
01516
01517 if (!PyArg_ParseTuple(args, "O", &stmt_obj))
01518 return NULL;
01519
01520 if (PyObject_TypeCheck(stmt_obj, &stmtObject_Type)) {
01521 stmt = ((stmtObject*)stmt_obj)->tree;
01522 } else if (PyObject_TypeCheck(stmt_obj, &stmtProxy_Type)) {
01523 stmt = ((stmtProxyObject*)stmt_obj)->tree;
01524 } else {
01525 PyErr_SetString(PyExc_TypeError, "require stmt");
01526 return NULL;
01527 }
01528
01529 ret = PyTuple_New(2);
01530 loc = ctrump_get_stmt_loc(stmt);
01531
01532 if (loc.path) {
01533 path = PyString_FromString(loc.path);
01534 } else {
01535 path = PyString_FromString("<unknown>");
01536 }
01537 lineno = PyInt_FromLong(loc.lineno);
01538
01539 PyTuple_SetItem(ret, 0, path);
01540 PyTuple_SetItem(ret, 1, lineno);
01541
01542 return ret;
01543 }
01544
01545
01546 static PyMethodDef env_methods[] = {
01547 {"parse", (PyCFunction)cfront_parse, METH_VARARGS},
01548 {"cfront_parse", (PyCFunction)cfront_parse, METH_VARARGS},
01549 {NULL, (PyCFunction)NULL, 0, NULL}
01550 };
01551
01552 static PyMemberDef env_members[] = {
01553 {"type_env", T_OBJECT, offsetof(EnvObject, type_env), READONLY},
01554 {0},
01555 };
01556
01557 static PyTypeObject EnvObject_Type = {
01558 PyObject_HEAD_INIT(NULL)
01559 0,
01560 "ctrump.EnvObject",
01561 sizeof(EnvObject),
01562 0,
01563
01564 (destructor)EnvObject_dealloc,
01565 0,
01566 0,
01567 0,
01568 0,
01569 0,
01570 0,
01571 0,
01572 0,
01573 0,
01574 0,
01575 0,
01576 0,
01577 0,
01578 0,
01579 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
01580 "CTRUMP Env Object",
01581 0,
01582 0,
01583 0,
01584 0,
01585 0,
01586 0,
01587 env_methods,
01588 env_members,
01589 0,
01590 0,
01591 0,
01592 0,
01593 0,
01594 0,
01595 (initproc)env_Init,
01596 0,
01597 0,
01598 };
01599
01600 #define EnvObject_Check(v) ((v)->ob_type == &EnvObject_Type)
01601
01602
01603
01604
01608 typedef struct {
01609 PyObject_HEAD
01610 EnvObject *env;
01611 } BuilderObject ;
01612
01613 #include "build-ast.h"
01614
01615 static void
01616 BuilderObject_dealloc(BuilderObject *self)
01617 {
01618 Py_XDECREF(self->env);
01619 PyObject_DEL(self);
01620 }
01621
01622 static int
01623 builder_Init(BuilderObject *self, PyObject *args)
01624 {
01625 PyObject *arg_obj;
01626 EnvObject *env_obj;
01627 if (!PyArg_ParseTuple(args, "O",
01628 &arg_obj))
01629 return -1;
01630
01631 if (!PyObject_TypeCheck(arg_obj, &EnvObject_Type)) {
01632 PyErr_SetString(PyExc_TypeError, "requires env");
01633 return -1;
01634 }
01635
01636 env_obj = (EnvObject*)arg_obj;
01637 self->env = env_obj;
01638
01639 Py_INCREF(self->env);
01640
01641 return 0;
01642 }
01643
01644 static PyObject *
01645 build_symbol(BuilderObject *self, PyObject *args)
01646 {
01647 char *sym_buf;
01648 int sym_len;
01649 const struct ctrump_symbol *sym;
01650 EnvObject *env = self->env;
01651
01652 if (!PyArg_ParseTuple(args, "t#", &sym_buf, &sym_len))
01653 return NULL;
01654
01655 sym = ctrump_intern(sym_buf, sym_len);
01656 return symbol_obj(env, sym);
01657 }
01658
01659 static PyObject *
01660 build_struct(BuilderObject *self, PyObject *args)
01661 {
01662 EnvObject *env = self->env;
01663 PyObject *name_obj, *decls_vec_obj;
01664 int i, n;
01665 int code;
01666 struct ctrump_texpr *record_type;
01667 struct ctrump_struct_decl *decls;
01668 struct ctrump_type_env *tenv = &env->type_env->type_env;
01669 struct ctrump_location loc;
01670 struct ctrump_gccext_attribute attr;
01671 const struct ctrump_symbol *name;
01672
01673 if (!PyArg_ParseTuple(args, "OOiii", &name_obj, &decls_vec_obj, &code, &attr.flags, &attr.aligned))
01674 return NULL;
01675
01676 if (!PyList_Check(decls_vec_obj)) {
01677 PyErr_SetString(PyExc_TypeError, "decls should be list.");
01678 return NULL;
01679 }
01680
01681 if (code != CTRUMP_TYPE_UNION &&
01682 code != CTRUMP_TYPE_STRUCT &&
01683 code != CTRUMP_TYPE_ENUM) {
01684 PyErr_SetString(PyExc_TypeError, "texpr code should be struct.");
01685 return NULL;
01686 }
01687
01688 if (name_obj == Py_None) {
01689 name = NULL;
01690 } else if (PyObject_TypeCheck(name_obj, &symbolObject_Type)) {
01691 name = ((symbolObject*)name_obj)->tree;
01692 } else {
01693 PyErr_SetString(PyExc_TypeError, "name requires symbol.");
01694 return NULL;
01695 }
01696
01697 LOCATION_GENERATED(loc);
01698
01699 n = PyList_Size(decls_vec_obj);
01700 record_type = ctrump_get_incomplete_struct_type(tenv, code, name);
01701 decls = ctrump_mempool_alloc(&env->tree_pool, sizeof(*decls)*n);
01702
01703 for (i=0; i<n; i++) {
01704 PyObject *o = PyList_GetItem(decls_vec_obj, i);
01705 struct ctrump_struct_decl *decl;
01706
01707 if (!PyObject_TypeCheck(o, &struct_declObject_Type)) {
01708 PyErr_SetString(PyExc_TypeError, "decls should be list of struct_decl");
01709 return NULL;
01710 }
01711
01712 decl = ((struct_declObject*)o)->tree;
01713 decls[i] = *decl;
01714 }
01715
01716 ctrump_env_handle_record_decls(&record_type->u.struct_, tenv, decls,
01717 n, n, &attr, &loc, &env->tree_pool);
01718
01719 return texpr_obj(env, record_type);
01720 }
01721
01722 static PyObject *
01723 build_incomplete_field_type(BuilderObject *self,
01724 PyObject *args)
01725 {
01726 EnvObject *env = self->env;
01727 int code;
01728 struct ctrump_location loc;
01729 struct ctrump_texpr *texpr;
01730 const struct ctrump_symbol *sym;
01731 PyObject *name_obj;
01732
01733 if (!PyArg_ParseTuple(args, "iO", &code, &name_obj)) {
01734 return NULL;
01735 }
01736
01737 if ((code != CTRUMP_TYPE_STRUCT) &&
01738 (code != CTRUMP_TYPE_UNION) &&
01739 (code != CTRUMP_TYPE_ENUM)) {
01740 PyErr_SetString(PyExc_TypeError, "texpr code should be struct.");
01741 return NULL;
01742 }
01743
01744 if (name_obj == Py_None) {
01745 sym = NULL;
01746 } else if (PyObject_TypeCheck(name_obj, &symbolObject_Type)) {
01747 sym = ((symbolObject*)name_obj)->tree;
01748 } else {
01749 PyErr_SetString(PyExc_TypeError, "name requires symbol type object.");
01750 return NULL;
01751 }
01752
01753 LOCATION_GENERATED(loc);
01754
01755 texpr = ctrump_get_incomplete_struct_type(&env->type_env->type_env, code, sym);
01756
01757 return texpr_obj(env, texpr);
01758 }
01759
01760 static PyObject *
01761 build_typedef_name(BuilderObject *self,
01762 PyObject *args)
01763 {
01764 EnvObject *env = self->env;
01765 PyObject *sym, *texpr;
01766 struct ctrump_texpr *new_tree;
01767
01768 if (!PyArg_ParseTuple(args, "OO", &texpr, &sym)) {
01769 return NULL;
01770 }
01771
01772 if (!PyObject_TypeCheck(sym, &symbolObject_Type)) {
01773 PyErr_SetString(PyExc_TypeError, "not symbol object");
01774 return NULL;
01775 }
01776 if (!PyObject_TypeCheck(texpr, &texprObject_Type)) {
01777 PyErr_SetString(PyExc_TypeError, "not texpr object");
01778 return NULL;
01779 }
01780
01781 new_tree = ctrump_get_typedef_name(&env->type_env->type_env,
01782 ((texprObject*)texpr)->tree,
01783 ((symbolObject*)sym)->tree);
01784
01785 return texpr_obj(env, new_tree);
01786 }
01787
01788 static PyObject *
01789 build_func_type(BuilderObject *self,
01790 PyObject *args)
01791 {
01792 PyObject *arg_types_obj, *ret_type_obj, *arg_type_obj;
01793 texprObject *ret_type, *arg_type;
01794 int has_unspec_arg;
01795 int i, n;
01796 struct ctrump_get_functype_iterator iter;
01797 EnvObject *env = self->env;
01798 struct ctrump_type_env *type_env;
01799 struct ctrump_texpr *func_type;
01800
01801 if (!PyArg_ParseTuple(args, "OOi", &ret_type_obj, &arg_types_obj, &has_unspec_arg)) {
01802 return NULL;
01803 }
01804
01805 if (!PyList_Check(arg_types_obj)) {
01806 PyErr_SetString(PyExc_TypeError, "require types.");
01807 return NULL;
01808 }
01809 if (!PyObject_TypeCheck(ret_type_obj, &texprObject_Type)) {
01810 PyErr_SetString(PyExc_TypeError, "return type is not texpr.");
01811 return NULL;
01812 }
01813
01814 ret_type = (texprObject*)ret_type_obj;
01815
01816 type_env = &env->type_env->type_env;
01817 n = PyList_Size(arg_types_obj);
01818
01819 ctrump_get_functype_begin(&iter, type_env, ret_type->tree, n);
01820 for (i=0; i<n; i++) {
01821 arg_type_obj = PyList_GetItem(arg_types_obj, i);
01822 if (!PyObject_TypeCheck(arg_type_obj, &texprObject_Type)) {
01823 PyErr_SetString(PyExc_TypeError, "arg type is not texpr.");
01824 ctrump_get_functype_cancel(&iter);
01825 return NULL;
01826 }
01827 arg_type = (texprObject*)arg_type_obj;
01828 ctrump_get_functype_next(type_env, &iter, arg_type->tree);
01829 }
01830
01831 func_type = ctrump_get_functype_end(type_env, &iter, has_unspec_arg);
01832
01833 return texpr_obj(env, func_type);
01834 }
01835
01836 static PyObject *
01837 build_array_type(BuilderObject *self,
01838 PyObject *args)
01839 {
01840 PyObject *array_of_obj;
01841 int size;
01842 struct ctrump_texpr *array_of, *array_type;
01843 struct ctrump_type_env *type_env = &self->env->type_env->type_env;
01844 if (!PyArg_ParseTuple(args, "Oi", &array_of_obj, &size)) {
01845 return NULL;
01846 }
01847
01848 if (!PyObject_TypeCheck(array_of_obj, &texprObject_Type)) {
01849 PyErr_SetString(PyExc_TypeError, "element type is not texpr.");
01850 return NULL;
01851 }
01852
01853 array_of = ((texprObject*)array_of_obj)->tree;
01854 array_type = ctrump_get_array_type(type_env, array_of, size);
01855
01856 return texpr_obj(self->env, array_type);
01857 }
01858
01859 static PyObject *
01860 build_pointer_type(BuilderObject *self,
01861 PyObject *args)
01862 {
01863 PyObject *pointer_to_obj;
01864 struct ctrump_texpr *pointer_type, *pointer_to_type;
01865 struct ctrump_type_env *type_env = &self->env->type_env->type_env;
01866 if (!PyArg_ParseTuple(args, "O", &pointer_to_obj)) {
01867 return NULL;
01868 }
01869
01870 if (!PyObject_TypeCheck(pointer_to_obj, &texprObject_Type)) {
01871 PyErr_SetString(PyExc_TypeError, "`pointer to' is not texpr.");
01872 return NULL;
01873 }
01874
01875 pointer_to_type = ((texprObject*)pointer_to_obj)->tree;
01876 pointer_type = ctrump_get_pointer_type(type_env, pointer_to_type);
01877
01878 return texpr_obj(self->env, pointer_type);
01879 }
01880
01881 static PyObject *
01882 build_qualified_type(BuilderObject *self,
01883 PyObject *args)
01884 {
01885 PyObject *type_obj;
01886 struct ctrump_texpr *t, *qt;
01887 struct ctrump_gccext_attribute attr;
01888 int flags;
01889 attr.aligned = CTRUMP_ALIGN_UNSPECIFIED;
01890 attr.flags = 0;
01891 if (!PyArg_ParseTuple(args, "Oi|ii", &type_obj, &flags, &attr.aligned, &attr.flags)) {
01892 return NULL;
01893 }
01894
01895 if (!PyObject_TypeCheck(type_obj, &texprObject_Type)) {
01896 PyErr_SetString(PyExc_TypeError, "qualified type is not texpr.");
01897 return NULL;
01898 }
01899
01900 t = ((texprObject*)type_obj)->tree;
01901 qt = ctrump_get_qualified_attr_type(&self->env->type_env->type_env, t, flags, &attr);
01902
01903 return texpr_obj(self->env, qt);
01904 }
01905
01906 static PyMethodDef builder_methods[] = {
01907 {"symbol", (PyCFunction)build_symbol, METH_VARARGS, NULL},
01908 {"decls_to_struct_texpr", (PyCFunction)build_struct, METH_VARARGS, NULL},
01909 {"incomplete_struct", (PyCFunction)build_incomplete_field_type,METH_VARARGS, NULL},
01910 {"array_type", (PyCFunction)build_array_type, METH_VARARGS, NULL},
01911 {"typedef_name", (PyCFunction)build_typedef_name, METH_VARARGS, NULL},
01912 {"func_type", (PyCFunction)build_func_type, METH_VARARGS, NULL},
01913 {"pointer_type", (PyCFunction)build_pointer_type, METH_VARARGS, NULL},
01914 {"qualified_type", (PyCFunction)build_qualified_type, METH_VARARGS, NULL},
01915 BUILDER_METHOD_TABLE
01916 {NULL, NULL, 0, NULL}
01917 };
01918
01919 static PyTypeObject BuilderObject_Type = {
01920 PyObject_HEAD_INIT(NULL)
01921 0,
01922 "ctrump.BuilderObject",
01923 sizeof(BuilderObject),
01924 0,
01925
01926 (destructor)BuilderObject_dealloc,
01927 0,
01928 0,
01929 0,
01930 0,
01931 0,
01932 0,
01933 0,
01934 0,
01935 0,
01936 0,
01937 0,
01938 0,
01939 0,
01940 0,
01941 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
01942 "CTRUMP C AST Builder",
01943 0,
01944 0,
01945 0,
01946 0,
01947 0,
01948 0,
01949 builder_methods,
01950 0,
01951 0,
01952 0,
01953 0,
01954 0,
01955 0,
01956 0,
01957 (initproc)builder_Init,
01958 0,
01959 0,
01960 };
01961
01962
01963 #define TranslationUnitObject_Check(v) ((v)->ob_type == &translation_unit_Type)
01964 #define CompilationErrorObject_Check(v) ((v)->ob_type == &CompilationErrorObject_Type)
01965
01966 static struct PyMethodDef ctrump_methods[] = {
01967 {"pprint", (PyCFunction)pprint, METH_VARARGS},
01968 {"pprint_ssa", (PyCFunction)pprint_ssa, METH_VARARGS},
01969 {"pprint_expr", (PyCFunction)pprint_expr, METH_VARARGS},
01970 {"pprint_ssa_expr", (PyCFunction)pprint_ssa_expr, METH_VARARGS},
01971 {"pprint_stmt", (PyCFunction)pprint_stmt, METH_VARARGS},
01972 {"fold_const", (PyCFunction)fold_const, METH_VARARGS},
01973 {"expr_prec", (PyCFunction)expr_prec, METH_VARARGS},
01974 {"is_pointer_type", (PyCFunction)is_pointer_type, METH_VARARGS},
01975 {"type_apply_unary_pointer_conversion", (PyCFunction)type_apply_unary_pointer_conversion, METH_VARARGS},
01976 {"calc_type_size", (PyCFunction)calc_type_size, METH_VARARGS},
01977 {"get_stmt_loc", (PyCFunction)get_stmt_loc, METH_VARARGS},
01978 {"retrieve_pointer_type", (PyCFunction)retrieve_pointer_type, METH_VARARGS},
01979 {"retrieve_address_type", (PyCFunction)retrieve_address_type, METH_VARARGS},
01980 {"struct_field_offset", (PyCFunction)struct_field_offset, METH_VARARGS},
01981 {"loop_index_equal", (PyCFunction)loop_index_equal, METH_VARARGS},
01982 {"loop_subscript_equal", (PyCFunction)loop_subscript_equal, METH_VARARGS},
01983 {"loop_subscript_hash", (PyCFunction)loop_subscript_hash, METH_VARARGS},
01984 {NULL, (PyCFunction)NULL, 0, NULL}
01985 };
01986
01987 PyDoc_STRVAR(module_doc,
01988 "Python interface for ctrump.");
01989
01990 static PyMemberDef abi_members[] = {
01991 {"sizeof_pointer", T_INT, offsetof(abiObject, abi.sizeof_pointer), READONLY},
01992 {"sizeof_long", T_INT, offsetof(abiObject, abi.sizeof_long), READONLY},
01993 {"sizeof_int", T_INT, offsetof(abiObject, abi.sizeof_int), READONLY},
01994 {"sizeof_short", T_INT, offsetof(abiObject, abi.sizeof_short), READONLY},
01995 {"sizeof_bool", T_INT, offsetof(abiObject, abi.sizeof_bool), READONLY},
01996 {"sizeof_longlong", T_INT, offsetof(abiObject, abi.sizeof_longlong), READONLY},
01997 {"sizeof_float", T_INT, offsetof(abiObject, abi.sizeof_float), READONLY},
01998 {"sizeof_double", T_INT, offsetof(abiObject, abi.sizeof_double), READONLY},
01999 {"sizeof_long_double", T_INT, offsetof(abiObject, abi.sizeof_long_double), READONLY},
02000 {"sizeof_enum", T_INT, offsetof(abiObject, abi.sizeof_enum), READONLY},
02001 {"sizeof_vector", T_INT, offsetof(abiObject, abi.sizeof_vector), READONLY},
02002
02003 {"alignof_pointer", T_INT, offsetof(abiObject,abi.alignof_pointer), READONLY},
02004 {"alignof_long", T_INT, offsetof(abiObject,abi.alignof_long), READONLY},
02005 {"alignof_int", T_INT, offsetof(abiObject,abi.alignof_int), READONLY},
02006 {"alignof_short", T_INT, offsetof(abiObject,abi.alignof_short), READONLY},
02007 {"alignof_bool", T_INT, offsetof(abiObject,abi.alignof_bool), READONLY},
02008 {"alignof_longlong", T_INT, offsetof(abiObject,abi.alignof_longlong), READONLY},
02009 {"alignof_float", T_INT, offsetof(abiObject,abi.alignof_float), READONLY},
02010 {"alignof_double", T_INT, offsetof(abiObject,abi.alignof_double), READONLY},
02011 {"alignof_long_double", T_INT, offsetof(abiObject,abi.alignof_long_double), READONLY},
02012 {"alignof_enum", T_INT, offsetof(abiObject,abi.alignof_enum), READONLY},
02013 {"alignof_vector", T_INT, offsetof(abiObject,abi.alignof_vector), READONLY},
02014
02015 {"is_char_signed", T_INT, offsetof(abiObject, abi.is_char_signed), READONLY},
02016 {0},
02017 };
02018
02019 static PyTypeObject abiObject_Type = {
02020 PyObject_HEAD_INIT(NULL)
02021 0,
02022 "ctrump.abi",
02023 sizeof(abiObject),
02024 0,
02025
02026 (destructor)NULL,
02027 0,
02028 0,
02029 0,
02030 0,
02031 0,
02032 0,
02033 0,
02034 0,
02035 0,
02036 0,
02037 0,
02038 0,
02039 0,
02040 0,
02041 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
02042 "CTRUMP ABI Object",
02043 0,
02044 0,
02045 0,
02046 0,
02047 0,
02048 0,
02049 0,
02050 abi_members,
02051 };
02052
02053 struct ctrump_abi_register_node {
02054 const char *name;
02055 const struct ctrump_abi *abi;
02056 };
02057 static struct ctrump_abi_register_node abis[] = {
02058 {"spu_abi", &ctrump_spu_abi},
02059 {"ppc32_abi", &ctrump_ppc32_abi},
02060 {"ppc64_abi", &ctrump_ppc64_abi}
02061 };
02062
02063 static void
02064 register_abis(PyObject *dict)
02065 {
02066 abiObject *obj;
02067 int n = sizeof(abis)/sizeof(abis[0]);
02068 int i;
02069
02070 for (i=0; i<n; i++) {
02071 struct ctrump_abi_register_node *node = &abis[i];
02072 obj = PyObject_New(abiObject, &abiObject_Type);
02073 obj->abi = *(node->abi);
02074 PyDict_SetItemString(dict, node->name,
02075 (PyObject*)obj);
02076 }
02077 }
02078
02079
02080 CTRUMP_EXTDEF PyMODINIT_FUNC
02081 init_ctrump(void)
02082 {
02083 PyObject *m, *d, *constant_arr;
02084 PyTypeObject *t;
02085
02086 EnvObject_Type.tp_new = PyType_GenericNew;
02087 BuilderObject_Type.tp_new = PyType_GenericNew;
02088 ParserOption_Type.tp_new = PyType_GenericNew;
02089
02090 ctrump_init_all();
02091 t = &EnvObject_Type;
02092
02093 if (PyType_Ready(t) < 0)
02094 return;
02095 if (PyType_Ready(&CompilationErrorObject_Type) < 0)
02096 return;
02097 if (PyType_Ready(&bitmapObject_Type) < 0)
02098 return;
02099 if (PyType_Ready(&BuilderObject_Type) < 0)
02100 return;
02101 if (PyType_Ready(&TypeEnvObject_Type) < 0)
02102 return;
02103 if (PyType_Ready(&texprObject_Type) < 0)
02104 return;
02105 if (PyType_Ready(&symbolObject_Type) < 0)
02106 return;
02107 if (PyType_Ready(&recordFieldObject_Type) < 0)
02108 return;
02109 if (PyType_Ready(&ParserOption_Type) < 0)
02110 return;
02111 if (PyType_Ready(&abiObject_Type) < 0)
02112 return;
02113
02114
02115
02116 m = Py_InitModule3("_ctrump",
02117 ctrump_methods,
02118 module_doc);
02119 if (m == NULL)
02120 return;
02121
02122 if (astobj_init() < 0)
02123 return;
02124
02125 d = PyModule_GetDict(m);
02126
02127
02128
02129 Py_INCREF(t);
02130 if (PyDict_SetItemString(d, "EnvType",
02131 (PyObject*)t) != 0)
02132 return;
02133 Py_INCREF(&CompilationErrorObject_Type);
02134 if (PyDict_SetItemString(d, "CompilationErrorType",
02135 (PyObject*)&CompilationErrorObject_Type) != 0)
02136 return;
02137 Py_INCREF(&BuilderObject_Type);
02138 if (PyDict_SetItemString(d, "BuilderType",
02139 (PyObject*)&BuilderObject_Type) != 0)
02140 return;
02141 Py_INCREF(&texprObject_Type);
02142 if (PyDict_SetItemString(d, "texprType",
02143 (PyObject*)&texprObject_Type) != 0)
02144 return;
02145 Py_INCREF(&symbolObject_Type);
02146 if (PyDict_SetItemString(d, "symbolType",
02147 (PyObject*)&symbolObject_Type) != 0)
02148 return;
02149 Py_INCREF(&ParserOption_Type);
02150 if (PyDict_SetItemString(d, "ParserOptionType",
02151 (PyObject*)&ParserOption_Type) != 0)
02152 return;
02153
02154 register_abis(d);
02155
02156 PyModule_AddStringConstant(m, "builtin_optimizer_dir", BUILTIN_OPTIMIZER_DIR);
02157 PyModule_AddStringConstant(m, "target_include_dir", TARGET_INCLUDE_DIR);
02158 PyModule_AddStringConstant(m, "cpp_comapt_macros_path", CPP_COMPAT_MACROS_H);
02159 PyModule_AddStringConstant(m, "version", CTRUMP_VERSION);
02160
02161 #include "constants.h"
02162
02163
02164 if (PyErr_Occurred())
02165 Py_FatalError("can't initialize module ctrump");
02166 }
02167
02168
02169
02170
02171
02172