Ticket #2655: trac_2655_cython_9612.patch

File trac_2655_cython_9612.patch, 20.9 KB (added by gfurnish, 2 years ago)
  • Compiler/Code.py

    # HG changeset patch
    # User Gary Furnish <gfurnish@gfurnish.net>
    # Date 1206288126 21600
    # Node ID 9611bac649351947262a8c6075d88bddbbb81735
    # Parent  eb2d12f543448f7aa24c449cd4053f92228c811e
    Circular cdef's
    
    diff -r eb2d12f54344 -r 9611bac64935 Compiler/Code.py
    a b  
    326326    def error_goto(self, pos): 
    327327        lbl = self.error_label 
    328328        self.use_label(lbl) 
    329         return "{%s = %s[%s]; %s = %s; goto %s;}" % ( 
     329        return "{%s = %s[%s]; %s = %s; %s = %s; goto %s;}" % ( 
    330330            Naming.filename_cname, 
    331331            Naming.filetable_cname, 
    332332            self.lookup_filename(pos[0]), 
    333333            Naming.lineno_cname, 
    334334            pos[1], 
     335            Naming.clineno_cname, 
     336            Naming.line_c_macro, 
    335337            lbl) 
    336338             
    337339    def error_goto_if(self, cond, pos): 
  • Compiler/Main.py

    diff -r eb2d12f54344 -r 9611bac64935 Compiler/Main.py
    a b  
    306306#------------------------------------------------------------------------ 
    307307 
    308308def main(command_line = 0): 
     309 
    309310    args = sys.argv[1:] 
    310311    any_failures = 0 
    311312    if command_line: 
  • Compiler/ModuleNode.py

    diff -r eb2d12f54344 -r 9611bac64935 Compiler/ModuleNode.py
    a b  
    1818from Errors import error 
    1919from PyrexTypes import py_object_type 
    2020from Cython.Utils import open_new_file, replace_suffix 
     21 
     22 
     23def recurse_vtab_check_inheritance(entry,b, dict): 
     24    base = entry 
     25    while base is not None: 
     26        if base.type.base_type is None or base.type.base_type.vtabstruct_cname is None: 
     27            return False 
     28        if base.type.base_type.vtabstruct_cname == b.type.vtabstruct_cname: 
     29            return True 
     30        base = dict[base.type.base_type.vtabstruct_cname] 
     31    return False 
     32     
     33def recurse_vtabslot_check_inheritance(entry,b, dict): 
     34    base = entry 
     35    while base is not None: 
     36        if base.type.base_type is None: 
     37            return False 
     38        if base.type.base_type.objstruct_cname == b.type.objstruct_cname: 
     39            return True 
     40        base = dict[base.type.base_type.objstruct_cname] 
     41    return False 
     42     
     43 
    2144 
    2245class ModuleNode(Nodes.Node, Nodes.BlockNode): 
    2346    #  doc       string or None 
     
    224247        self.generate_method_table(env, code) 
    225248        self.generate_filename_init_prototype(code) 
    226249        self.generate_module_init_func(modules[:-1], env, code) 
     250        self.generate_module_init2_func(modules[:-1], env, code) 
    227251        code.mark_pos(None) 
    228252        self.generate_module_cleanup_func(env, code) 
    229253        self.generate_filename_table(code) 
    230254        self.generate_utility_functions(env, code) 
    231255 
    232         for module in modules: 
    233             self.generate_declarations_for_module(module, code.h, 
    234                 definition = module is env) 
     256        self.generate_declarations_for_module(env, modules, code.h) 
    235257 
    236258        f = open_new_file(result.c_file) 
    237259        f.write(code.h.f.getvalue()) 
     
    242264        if Options.annotate: 
    243265            self.annotate(code) 
    244266            code.save_annotation(result.c_file[:-1] + "pyx") # change? 
     267     
     268     
     269     
    245270     
    246271    def find_referenced_modules(self, env, module_list, modules_seen): 
    247272        if env not in modules_seen: 
     
    290315        if Options.pre_import is not None: 
    291316            code.putln('static PyObject *%s;' % Naming.preimport_cname) 
    292317        code.putln('static int %s;' % Naming.lineno_cname) 
     318        code.putln('static int %s;' % Naming.clineno_cname) 
     319        code.putln('static char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro)) 
    293320        code.putln('static char *%s;' % Naming.filename_cname) 
    294321        code.putln('static char **%s;' % Naming.filetable_cname) 
    295322        if env.doc: 
     
    327354            code.putln("0") 
    328355        code.putln("};") 
    329356     
    330     def generate_declarations_for_module(self, env, code, definition): 
     357    def generate_vtab_dict(self, module_list): 
     358        vtab_dict = {} 
     359        for module in module_list: 
     360            for entry in module.c_class_entries: 
     361                if not entry.in_cinclude: 
     362                    type = entry.type 
     363                    scope = type.scope 
     364                    if type.vtabstruct_cname: 
     365                        vtab_dict[type.vtabstruct_cname]=entry 
     366        return vtab_dict 
     367    def generate_vtab_list(self, vtab_dict): 
     368        vtab_list = list() 
     369        for entry in vtab_dict.itervalues(): 
     370            vtab_list.append(entry) 
     371        for i in range(0,len(vtab_list)): 
     372            for j in range(0,len(vtab_list)): 
     373                if(recurse_vtab_check_inheritance(vtab_list[j],vtab_list[i], vtab_dict)==1): 
     374                    if i > j: 
     375                        vtab_list.insert(j,vtab_list[i]) 
     376                        if i > j: 
     377                            vtab_list.pop(i+1) 
     378                        else: 
     379                            vtab_list.pop(i) 
     380        #for entry in vtab_list: 
     381            #print entry.type.vtabstruct_cname 
     382        return vtab_list 
     383         
     384    def generate_vtabslot_dict(self, module_list, env): 
     385        vtab_dict={} 
     386        type_entries=[] 
     387        for module in module_list: 
     388            definition = module is env 
     389            if definition: 
     390                type_entries.extend( env.type_entries) 
     391            else: 
     392                for entry in module.type_entries: 
     393                    if entry.defined_in_pxd: 
     394                        type_entries.append(entry) 
     395        for entry in type_entries: 
     396            type = entry.type 
     397            if type.is_extension_type: 
     398                if not entry.in_cinclude: 
     399                    type = entry.type 
     400                    scope = type.scope 
     401                    vtab_dict[type.objstruct_cname]=entry 
     402        return vtab_dict 
     403    def generate_vtabslot_list(self, vtab_dict): 
     404        vtab_list = list() 
     405        for entry in vtab_dict.itervalues(): 
     406            vtab_list.append(entry) 
     407        for i in range(0,len(vtab_list)): 
     408            for j in range(0,len(vtab_list)): 
     409                if(recurse_vtabslot_check_inheritance(vtab_list[j],vtab_list[i], vtab_dict)==1): 
     410                    if i > j: 
     411                        vtab_list.insert(j,vtab_list[i]) 
     412                        if i > j: 
     413                            vtab_list.pop(i+1) 
     414                        else: 
     415                            vtab_list.pop(i) 
     416        #for entry in vtab_list: 
     417            #print entry.type.vtabstruct_cname 
     418        return vtab_list 
     419         
     420         
     421    def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code): 
     422        for module in modules: 
     423            definition = module is env 
     424            if definition: 
     425                type_entries = module.type_entries 
     426            else: 
     427                type_entries = [] 
     428                for entry in module.type_entries: 
     429                    if entry.defined_in_pxd: 
     430                        type_entries.append(entry) 
     431            self.generate_type_header_code(type_entries, code) 
     432        for entry in vtabslot_list: 
     433            self.generate_obj_struct_definition(entry.type, code) 
     434        for entry in vtab_list: 
     435            self.generate_typeobject_predeclaration(entry, code) 
     436            self.generate_exttype_vtable_struct(entry, code) 
     437            self.generate_exttype_vtabptr_declaration(entry, code) 
     438     
     439    def generate_declarations_for_module(self, env, modules, code): 
    331440        code.putln("") 
    332         code.putln("/* Declarations from %s */" % env.qualified_name) 
    333         self.generate_type_predeclarations(env, code) 
    334         self.generate_type_definitions(env, code, definition) 
    335         self.generate_global_declarations(env, code, definition) 
    336         self.generate_cfunction_predeclarations(env, code, definition) 
    337  
    338     def generate_type_predeclarations(self, env, code): 
    339         pass 
     441        code.putln("/* Declarations */") 
     442        vtab_dict = self.generate_vtab_dict(modules) 
     443        vtab_list = self.generate_vtab_list(vtab_dict) 
     444        vtabslot_dict = self.generate_vtabslot_dict(modules,env) 
     445        vtabslot_list = self.generate_vtabslot_list(vtabslot_dict) 
     446        self.generate_type_definitions(env, modules, vtab_list, vtabslot_list, code) 
     447        for module in modules: 
     448            definition = module is env 
     449            self.generate_global_declarations(module, code, definition) 
     450            self.generate_cfunction_predeclarations(module, code, definition) 
    340451     
    341452    def generate_type_header_code(self, type_entries, code): 
    342453        # Generate definitions of structs/unions/enums/typedefs/objstructs. 
     
    352463                    self.generate_struct_union_definition(entry, code) 
    353464                elif type.is_enum: 
    354465                    self.generate_enum_definition(entry, code) 
    355                 elif type.is_extension_type: 
    356                     self.generate_obj_struct_definition(type, code) 
    357      
    358     def generate_type_definitions(self, env, code, definition): 
    359         if definition: 
    360             type_entries = env.type_entries 
    361         else: 
    362             type_entries = [] 
    363             for entry in env.type_entries: 
    364                 if entry.defined_in_pxd: 
    365                     type_entries.append(entry) 
    366         self.generate_type_header_code(type_entries, code) 
    367         for entry in env.c_class_entries: 
    368             if not entry.in_cinclude: 
    369                 self.generate_typeobject_predeclaration(entry, code) 
    370                 self.generate_exttype_vtable_struct(entry, code) 
    371                 self.generate_exttype_vtabptr_declaration(entry, code) 
    372466     
    373467    def generate_gcc33_hack(self, env, code): 
    374468        # Workaround for spurious warning generation in gcc 3.3 
     
    12781372 
    12791373    def generate_module_init_func(self, imported_modules, env, code): 
    12801374        code.putln("") 
     1375        code.putln("PyMODINIT_FUNC init2%s(void);" % env.module_name) 
     1376        code.putln("") 
    12811377        header = "PyMODINIT_FUNC init%s(void)" % env.module_name 
    12821378        code.putln("%s; /*proto*/" % header) 
    12831379        code.putln("%s {" % header) 
     1380        code.putln("PyObject* __pyx_internal1;") 
     1381        code.putln("PyObject* __pyx_internal2;") 
    12841382        code.put_var_declarations(env.temp_entries) 
    12851383 
    12861384        code.putln("/*--- Libary function declarations ---*/") 
     
    13091407        code.putln("/*--- Function export code ---*/") 
    13101408        self.generate_c_function_export_code(env, code) 
    13111409 
     1410        env.use_utility_code(function_export_utility_code) 
     1411        #code.putln('printf("foo");') 
     1412        code.putln('if (__Pyx_ExportFunction("init2%s", (void*)init2%s, "int (void)") < 0) %s' % (env.module_name, env.module_name, code.error_goto((env.qualified_name,0,0) ) ) ) 
     1413        #code.putln('printf("foo2");') 
     1414        code.putln("/*--- Type init code ---*/") 
     1415        self.generate_type_init_code(env, code) 
     1416        #code.putln('printf("foo3");') 
     1417        code.putln("/*--- Type import code ---*/") 
     1418        for module in imported_modules: 
     1419            self.generate_type_import_code_for_module(module, env, code) 
     1420        #code.putln('printf("foo4");') 
    13121421        code.putln("/*--- Function import code ---*/") 
    13131422        for module in imported_modules: 
    13141423            self.generate_c_function_import_code_for_module(module, env, code) 
     1424        #code.putln('printf("foo5");') 
     1425        #code.putln("/*--- Execution code ---*/") 
     1426        #code.mark_pos(None) 
     1427        #self.body.generate_execution_code(code) 
     1428        env.use_utility_code(function_import_utility_code) 
     1429        code.putln('void (*__Pyx_internal4)(void);') 
     1430        code.putln('PyObject* __Pyx_internal5;') 
     1431        #code.putln('printf("foo6");') 
     1432        #for module in imported_modules: 
     1433            #module_abs = module.qualified_name 
     1434            #code.putln('if ( ( __Pyx_internal5 = __Pyx_ImportModule("%s") ) == 0) %s' % ( module_abs , code.error_goto((env.qualified_name,0,0) ) ) ) 
     1435            #code.putln('if ( ( __Pyx_ImportFunction(__Pyx_internal5,"init2%s", (void**)(&__Pyx_internal4), "int (void)" ) ) == 0 ) %s' % (module.name, code.error_goto((env.qualified_name,0,0) ) ) ) 
     1436            #code.putln('__Pyx_internal4();') 
     1437        #code.putln('printf("foo7");') 
     1438        code.putln('init2%s();' % env.module_name) 
     1439        #code.putln('printf("foo8");') 
     1440        if Options.generate_cleanup_code: 
     1441            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos)) 
     1442        code.putln("return;") 
     1443        code.put_label(code.error_label) 
     1444        code.put_var_xdecrefs(env.temp_entries) 
     1445        #code.putln('printf("fooError");') 
     1446        code.putln('__Pyx_AddTraceback("%s",%s,%s);' % (env.qualified_name,Naming.cfilenm_cname,Naming.clineno_cname)) 
     1447        env.use_utility_code(Nodes.traceback_utility_code) 
     1448        code.putln('}') 
    13151449 
    1316         code.putln("/*--- Type init code ---*/") 
    1317         self.generate_type_init_code(env, code) 
    1318  
    1319         code.putln("/*--- Type import code ---*/") 
    1320         for module in imported_modules: 
    1321             self.generate_type_import_code_for_module(module, env, code) 
    1322  
     1450    def generate_module_init2_func(self, imported_modules, env, code): 
     1451        code.putln("") 
     1452        header = "PyMODINIT_FUNC init2%s(void)" % env.module_name 
     1453        code.putln("%s; /*proto*/" % header) 
     1454        code.putln("%s {" % header) 
     1455        #code.putln('printf("gamma1");') 
     1456        code.putln("static int __Pyx_unique = 0;") 
     1457        code.putln("if (__Pyx_unique==1) return;") 
     1458        code.putln("__Pyx_unique = 1;") 
     1459        #code.putln('printf("gamma2");') 
     1460        code.put_var_declarations(env.temp_entries) 
     1461        #code.putln('printf("gamma3");') 
    13231462        code.putln("/*--- Execution code ---*/") 
    13241463        code.mark_pos(None) 
    13251464        self.body.generate_execution_code(code) 
    1326          
     1465        #code.putln('printf("gamma4");') 
    13271466        if Options.generate_cleanup_code: 
    13281467            code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos)) 
    1329          
     1468#        code.putln('printf("gamma5");') 
    13301469        code.putln("return;") 
    13311470        code.put_label(code.error_label) 
    13321471        code.put_var_xdecrefs(env.temp_entries) 
    1333         code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name)) 
     1472#        code.putln('printf("gammaError");') 
     1473        code.putln('__Pyx_AddTraceback("%s",%s,%s);' % (env.qualified_name,Naming.cfilenm_cname,Naming.clineno_cname)) 
    13341474        env.use_utility_code(Nodes.traceback_utility_code) 
    1335         code.putln('}') 
     1475        code.putln('}')         
    13361476             
    13371477    def generate_module_cleanup_func(self, env, code): 
    13381478        if not Options.generate_cleanup_code: 
     
    15171657                self.generate_exttype_vtable_init_code(entry, code) 
    15181658                self.generate_type_ready_code(env, entry, code) 
    15191659                self.generate_typeptr_assignment_code(entry, code) 
    1520      
     1660         
    15211661    def generate_base_type_import_code(self, env, entry, code): 
    15221662        base_type = entry.type.base_type 
    15231663        if base_type and base_type.module_name <> env.qualified_name: 
     
    16521792# 
    16531793#------------------------------------------------------------------------------------ 
    16541794 
     1795 
     1796call_module_function_code = [ 
     1797""" 
     1798static PyObject *__Pyx_CallModuleFunction(char* module, char *name); /*proto*/ 
     1799""",""" 
     1800static PyObject *__Pyx_CallModuleFunction(char* module, char *name) 
     1801{ 
     1802    PyObject* py_name = 0; 
     1803    PyObject* py_module_name = 0; 
     1804    PyObject* py_module = 0; 
     1805    PyObject* py_dict = 0; 
     1806    PyObject* py_func = 0; 
     1807    PyObject* py_tuple = PyTuple_New(0); 
     1808    PyObject* ret = 0; 
     1809    py_dict = PyImport_GetModuleDict(); 
     1810    if(py_dict == 0) 
     1811        goto bad; 
     1812    if(py_tuple == 0) 
     1813        goto bad; 
     1814    py_name = PyString_FromString(name); 
     1815    if(py_name == 0) 
     1816        goto bad; 
     1817    py_module_name = PyString_FromString(module); 
     1818    if(py_module_name == 0) 
     1819        goto bad; 
     1820    py_module = PyObject_GetItem(py_dict, py_module); 
     1821    if(py_module == 0) 
     1822        goto bad; 
     1823    if ( (py_func = PyObject_GetAttr(py_module, py_name) ) == 0) 
     1824        goto bad; 
     1825    if ( (ret = PyObject_Call(py_func, py_tuple,NULL) ) == 0) 
     1826        goto bad; 
     1827    return ret; 
     1828bad: 
     1829    Py_XDECREF(py_name); 
     1830    Py_XDECREF(py_module_name); 
     1831    Py_XDECREF(py_module); 
     1832    Py_XDECREF(py_dict);     
     1833    Py_XDECREF(py_func); 
     1834    return 0; 
     1835} 
     1836"""] 
     1837 
    16551838import_module_utility_code = [ 
    16561839""" 
    16571840static PyObject *__Pyx_ImportModule(char *name); /*proto*/ 
     
    16881871{ 
    16891872    PyObject *py_module = 0; 
    16901873    PyObject *result = 0; 
     1874    PyObject *py_name = 0; 
    16911875     
     1876    py_name = PyString_FromString(module_name); 
     1877    if (!py_name) 
     1878        goto bad; 
     1879         
    16921880    py_module = __Pyx_ImportModule(module_name); 
    16931881    if (!py_module) 
    16941882        goto bad; 
     
    17091897    } 
    17101898    return (PyTypeObject *)result; 
    17111899bad: 
     1900    Py_XDECREF(py_name); 
    17121901    Py_XDECREF(result); 
    17131902    return 0; 
    17141903} 
     
    17211910""" 
    17221911static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/ 
    17231912""",r""" 
    1724 static int __Pyx_ExportFunction(char *n, void *f, char *s) { 
     1913static int __Pyx_ExportFunction(char *name, void *f, char *sig) { 
    17251914    PyObject *d = 0; 
    17261915    PyObject *p = 0; 
    17271916    d = PyObject_GetAttrString(%(MODULE)s, "%(API)s"); 
     
    17341923        if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0) 
    17351924            goto bad; 
    17361925    } 
    1737     p = PyCObject_FromVoidPtrAndDesc(f, s, 0); 
     1926    p = PyCObject_FromVoidPtrAndDesc(f, sig, 0); 
    17381927    if (!p) 
    17391928        goto bad; 
    1740     if (PyDict_SetItemString(d, n, p) < 0) 
     1929    if (PyDict_SetItemString(d, name, p) < 0) 
    17411930        goto bad; 
    17421931    Py_DECREF(d); 
    17431932    return 0; 
  • Compiler/Naming.py

    diff -r eb2d12f54344 -r 9611bac64935 Compiler/Naming.py
    a b  
    4848intern_tab_cname = pyrex_prefix + "intern_tab" 
    4949kwds_cname       = pyrex_prefix + "kwds" 
    5050lineno_cname     = pyrex_prefix + "lineno" 
     51clineno_cname    = pyrex_prefix + "clineno" 
     52cfilenm_cname    = pyrex_prefix + "cfilenm" 
    5153module_cname     = pyrex_prefix + "m" 
    5254moddoc_cname     = pyrex_prefix + "mdoc" 
    5355methtable_cname  = pyrex_prefix + "methods" 
     
    6466optional_args_cname = pyrex_prefix + "optional_args" 
    6567no_opt_args      = pyrex_prefix + "no_opt_args" 
    6668 
     69line_c_macro = "__LINE__" 
     70 
     71file_c_macro = "__FILE__" 
    6772 
    6873extern_c_macro  = pyrex_prefix.upper() + "EXTERN_C" 
    6974 
  • Compiler/Nodes.py

    diff -r eb2d12f54344 -r 9611bac64935 Compiler/Nodes.py
    a b  
    742742            exc_check = self.caller_will_check_exceptions() 
    743743            if err_val is not None or exc_check: 
    744744                code.putln( 
    745                     '__Pyx_AddTraceback("%s");' %  
    746                         self.entry.qualified_name) 
     745                    '__Pyx_AddTraceback("%s",%s,%s);' %  
     746                        (self.entry.qualified_name,Naming.cfilenm_cname,Naming.clineno_cname)) 
    747747                if err_val is not None: 
    748748                    code.putln( 
    749749                        "%s = %s;" % ( 
     
    30393039            code.putln( 
    30403040                "/*except:*/ {") 
    30413041        code.putln( 
    3042             '__Pyx_AddTraceback("%s");' % (self.function_name)) 
     3042            '__Pyx_AddTraceback("%s",%s,%s);' % (self.function_name, Naming.cfilenm_cname,Naming.clineno_cname)) 
    30433043        # We always have to fetch the exception value even if 
    30443044        # there is no target, because this also normalises the  
    30453045        # exception and stores it in the thread state. 
     
    38073807 
    38083808traceback_utility_code = [ 
    38093809""" 
    3810 static void __Pyx_AddTraceback(char *funcname); /*proto*/ 
     3810static void __Pyx_AddTraceback(char *funcname, char* cfilename, unsigned int cfileline); /*proto*/ 
    38113811""",""" 
    38123812#include "compile.h" 
    38133813#include "frameobject.h" 
    38143814#include "traceback.h" 
    38153815 
    3816 static void __Pyx_AddTraceback(char *funcname) { 
     3816static void __Pyx_AddTraceback(char *funcname, char* cfilename, unsigned int cfileline) { 
    38173817    PyObject *py_srcfile = 0; 
    38183818    PyObject *py_funcname = 0; 
    38193819    PyObject *py_globals = 0; 
     
    38233823     
    38243824    py_srcfile = PyString_FromString(%(FILENAME)s); 
    38253825    if (!py_srcfile) goto bad; 
    3826     py_funcname = PyString_FromString(funcname); 
     3826    py_funcname = PyString_FromFormat( "%%s, %%s, %%u", funcname, cfilename, cfileline); 
    38273827    if (!py_funcname) goto bad; 
    38283828    py_globals = PyModule_GetDict(%(GLOBALS)s); 
    38293829    if (!py_globals) goto bad;