Commit 9f9b8b4c authored by Gary Furnish's avatar Gary Furnish

Circular cdef's

parent 4c48e8d4
......@@ -329,12 +329,14 @@ class CCodeWriter:
def error_goto(self, pos):
lbl = self.error_label
self.use_label(lbl)
return "{%s = %s[%s]; %s = %s; goto %s;}" % (
return "{%s = %s[%s]; %s = %s; %s = %s; goto %s;}" % (
Naming.filename_cname,
Naming.filetable_cname,
self.lookup_filename(pos[0]),
Naming.lineno_cname,
pos[1],
Naming.clineno_cname,
Naming.line_c_macro,
lbl)
def error_goto_if(self, cond, pos):
......
......@@ -310,6 +310,7 @@ def compile(source, options = None, c_compile = 0, c_link = 0,
#------------------------------------------------------------------------
def main(command_line = 0):
args = sys.argv[1:]
any_failures = 0
if command_line:
......
......@@ -19,6 +19,29 @@ from Errors import error
from PyrexTypes import py_object_type
from Cython.Utils import open_new_file, replace_suffix
def recurse_vtab_check_inheritance(entry,b, dict):
base = entry
while base is not None:
if base.type.base_type is None or base.type.base_type.vtabstruct_cname is None:
return False
if base.type.base_type.vtabstruct_cname == b.type.vtabstruct_cname:
return True
base = dict[base.type.base_type.vtabstruct_cname]
return False
def recurse_vtabslot_check_inheritance(entry,b, dict):
base = entry
while base is not None:
if base.type.base_type is None:
return False
if base.type.base_type.objstruct_cname == b.type.objstruct_cname:
return True
base = dict[base.type.base_type.objstruct_cname]
return False
class ModuleNode(Nodes.Node, Nodes.BlockNode):
# doc string or None
# body StatListNode
......@@ -226,14 +249,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_method_table(env, code)
self.generate_filename_init_prototype(code)
self.generate_module_init_func(modules[:-1], env, code)
self.generate_module_init2_func(modules[:-1], env, code)
code.mark_pos(None)
self.generate_module_cleanup_func(env, code)
self.generate_filename_table(code)
self.generate_utility_functions(env, code)
for module in modules:
self.generate_declarations_for_module(module, code.h,
definition = module is env)
self.generate_declarations_for_module(env, modules, code.h)
f = open_new_file(result.c_file)
f.write(code.h.f.getvalue())
......@@ -245,6 +267,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.annotate(code)
code.save_annotation(result.c_file[:-1] + "pyx") # change?
def find_referenced_modules(self, env, module_list, modules_seen):
if env not in modules_seen:
modules_seen[env] = 1
......@@ -294,6 +319,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
if Options.pre_import is not None:
code.putln('static PyObject *%s;' % Naming.preimport_cname)
code.putln('static int %s;' % Naming.lineno_cname)
code.putln('static int %s;' % Naming.clineno_cname)
code.putln('static char * %s= %s;' % (Naming.cfilenm_cname, Naming.file_c_macro))
code.putln('static char *%s;' % Naming.filename_cname)
code.putln('static char **%s;' % Naming.filetable_cname)
if env.doc:
......@@ -331,16 +358,100 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("0")
code.putln("};")
def generate_declarations_for_module(self, env, code, definition):
code.putln("")
code.putln("/* Declarations from %s */" % env.qualified_name)
self.generate_type_predeclarations(env, code)
self.generate_type_definitions(env, code, definition)
self.generate_global_declarations(env, code, definition)
self.generate_cfunction_predeclarations(env, code, definition)
def generate_vtab_dict(self, module_list):
vtab_dict = {}
for module in module_list:
for entry in module.c_class_entries:
if not entry.in_cinclude:
type = entry.type
scope = type.scope
if type.vtabstruct_cname:
vtab_dict[type.vtabstruct_cname]=entry
return vtab_dict
def generate_vtab_list(self, vtab_dict):
vtab_list = list()
for entry in vtab_dict.itervalues():
vtab_list.append(entry)
for i in range(0,len(vtab_list)):
for j in range(0,len(vtab_list)):
if(recurse_vtab_check_inheritance(vtab_list[j],vtab_list[i], vtab_dict)==1):
if i > j:
vtab_list.insert(j,vtab_list[i])
if i > j:
vtab_list.pop(i+1)
else:
vtab_list.pop(i)
#for entry in vtab_list:
#print entry.type.vtabstruct_cname
return vtab_list
def generate_vtabslot_dict(self, module_list, env):
vtab_dict={}
type_entries=[]
for module in module_list:
definition = module is env
if definition:
type_entries.extend( env.type_entries)
else:
for entry in module.type_entries:
if entry.defined_in_pxd:
type_entries.append(entry)
for entry in type_entries:
type = entry.type
if type.is_extension_type:
if not entry.in_cinclude:
type = entry.type
scope = type.scope
vtab_dict[type.objstruct_cname]=entry
return vtab_dict
def generate_vtabslot_list(self, vtab_dict):
vtab_list = list()
for entry in vtab_dict.itervalues():
vtab_list.append(entry)
for i in range(0,len(vtab_list)):
for j in range(0,len(vtab_list)):
if(recurse_vtabslot_check_inheritance(vtab_list[j],vtab_list[i], vtab_dict)==1):
if i > j:
vtab_list.insert(j,vtab_list[i])
if i > j:
vtab_list.pop(i+1)
else:
vtab_list.pop(i)
#for entry in vtab_list:
#print entry.type.vtabstruct_cname
return vtab_list
def generate_type_predeclarations(self, env, code):
pass
def generate_type_definitions(self, env, modules, vtab_list, vtabslot_list, code):
for module in modules:
definition = module is env
if definition:
type_entries = module.type_entries
else:
type_entries = []
for entry in module.type_entries:
if entry.defined_in_pxd:
type_entries.append(entry)
self.generate_type_header_code(type_entries, code)
for entry in vtabslot_list:
self.generate_obj_struct_definition(entry.type, code)
for entry in vtab_list:
self.generate_typeobject_predeclaration(entry, code)
self.generate_exttype_vtable_struct(entry, code)
self.generate_exttype_vtabptr_declaration(entry, code)
def generate_declarations_for_module(self, env, modules, code):
code.putln("")
code.putln("/* Declarations */")
vtab_dict = self.generate_vtab_dict(modules)
vtab_list = self.generate_vtab_list(vtab_dict)
vtabslot_dict = self.generate_vtabslot_dict(modules,env)
vtabslot_list = self.generate_vtabslot_list(vtabslot_dict)
self.generate_type_definitions(env, modules, vtab_list, vtabslot_list, code)
for module in modules:
definition = module is env
self.generate_global_declarations(module, code, definition)
self.generate_cfunction_predeclarations(module, code, definition)
def generate_type_header_code(self, type_entries, code):
# Generate definitions of structs/unions/enums/typedefs/objstructs.
......@@ -356,23 +467,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
self.generate_struct_union_definition(entry, code)
elif type.is_enum:
self.generate_enum_definition(entry, code)
elif type.is_extension_type:
self.generate_obj_struct_definition(type, code)
def generate_type_definitions(self, env, code, definition):
if definition:
type_entries = env.type_entries
else:
type_entries = []
for entry in env.type_entries:
if entry.defined_in_pxd:
type_entries.append(entry)
self.generate_type_header_code(type_entries, code)
for entry in env.c_class_entries:
if not entry.in_cinclude:
self.generate_typeobject_predeclaration(entry, code)
self.generate_exttype_vtable_struct(entry, code)
self.generate_exttype_vtabptr_declaration(entry, code)
def generate_gcc33_hack(self, env, code):
# Workaround for spurious warning generation in gcc 3.3
......@@ -1281,10 +1375,14 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("static void %s(void); /*proto*/" % Naming.fileinit_cname)
def generate_module_init_func(self, imported_modules, env, code):
code.putln("")
code.putln("PyMODINIT_FUNC init2%s(void);" % env.module_name)
code.putln("")
header = "PyMODINIT_FUNC init%s(void)" % env.module_name
code.putln("%s; /*proto*/" % header)
code.putln("%s {" % header)
code.putln("PyObject* __pyx_internal1;")
code.putln("PyObject* __pyx_internal2;")
code.put_var_declarations(env.temp_entries)
code.putln("/*--- Libary function declarations ---*/")
......@@ -1313,28 +1411,45 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("/*--- Function export code ---*/")
self.generate_c_function_export_code(env, code)
code.putln("/*--- Function import code ---*/")
for module in imported_modules:
self.generate_c_function_import_code_for_module(module, env, code)
env.use_utility_code(function_export_utility_code)
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) ) ) )
code.putln("/*--- Type init code ---*/")
self.generate_type_init_code(env, code)
code.putln("/*--- Type import code ---*/")
for module in imported_modules:
self.generate_type_import_code_for_module(module, env, code)
code.putln("/*--- Function import code ---*/")
for module in imported_modules:
self.generate_c_function_import_code_for_module(module, env, code)
env.use_utility_code(function_import_utility_code)
code.putln('init2%s();' % env.module_name)
if Options.generate_cleanup_code:
code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
code.putln("return;")
code.put_label(code.error_label)
code.put_var_xdecrefs(env.temp_entries)
code.putln('__Pyx_AddTraceback("%s",%s,%s);' % (env.qualified_name,Naming.cfilenm_cname,Naming.clineno_cname))
env.use_utility_code(Nodes.traceback_utility_code)
code.putln('}')
def generate_module_init2_func(self, imported_modules, env, code):
code.putln("")
header = "PyMODINIT_FUNC init2%s(void)" % env.module_name
code.putln("%s; /*proto*/" % header)
code.putln("%s {" % header)
code.putln("static int __Pyx_unique = 0;")
code.putln("if (__Pyx_unique==1) return;")
code.putln("__Pyx_unique = 1;")
code.put_var_declarations(env.temp_entries)
code.putln("/*--- Execution code ---*/")
code.mark_pos(None)
self.body.generate_execution_code(code)
if Options.generate_cleanup_code:
code.putln("if (__Pyx_RegisterCleanup()) %s;" % code.error_goto(self.pos))
code.putln("return;")
code.put_label(code.error_label)
code.put_var_xdecrefs(env.temp_entries)
code.putln('__Pyx_AddTraceback("%s");' % (env.qualified_name))
code.putln('__Pyx_AddTraceback("%s",%s,%s);' % (env.qualified_name,Naming.cfilenm_cname,Naming.clineno_cname))
env.use_utility_code(Nodes.traceback_utility_code)
code.putln('}')
......@@ -1656,6 +1771,49 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
#
#------------------------------------------------------------------------------------
call_module_function_code = [
"""
static PyObject *__Pyx_CallModuleFunction(char* module, char *name); /*proto*/
""","""
static PyObject *__Pyx_CallModuleFunction(char* module, char *name)
{
PyObject* py_name = 0;
PyObject* py_module_name = 0;
PyObject* py_module = 0;
PyObject* py_dict = 0;
PyObject* py_func = 0;
PyObject* py_tuple = PyTuple_New(0);
PyObject* ret = 0;
py_dict = PyImport_GetModuleDict();
if(py_dict == 0)
goto bad;
if(py_tuple == 0)
goto bad;
py_name = PyString_FromString(name);
if(py_name == 0)
goto bad;
py_module_name = PyString_FromString(module);
if(py_module_name == 0)
goto bad;
py_module = PyObject_GetItem(py_dict, py_module);
if(py_module == 0)
goto bad;
if ( (py_func = PyObject_GetAttr(py_module, py_name) ) == 0)
goto bad;
if ( (ret = PyObject_Call(py_func, py_tuple,NULL) ) == 0)
goto bad;
return ret;
bad:
Py_XDECREF(py_name);
Py_XDECREF(py_module_name);
Py_XDECREF(py_module);
Py_XDECREF(py_dict);
Py_XDECREF(py_func);
return 0;
}
"""]
import_module_utility_code = [
"""
static PyObject *__Pyx_ImportModule(char *name); /*proto*/
......@@ -1692,6 +1850,11 @@ static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
{
PyObject *py_module = 0;
PyObject *result = 0;
PyObject *py_name = 0;
py_name = PyString_FromString(module_name);
if (!py_name)
goto bad;
py_module = __Pyx_ImportModule(module_name);
if (!py_module)
......@@ -1713,6 +1876,7 @@ static PyTypeObject *__Pyx_ImportType(char *module_name, char *class_name,
}
return (PyTypeObject *)result;
bad:
Py_XDECREF(py_name);
Py_XDECREF(result);
return 0;
}
......@@ -1725,7 +1889,7 @@ function_export_utility_code = [
"""
static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/
""",r"""
static int __Pyx_ExportFunction(char *n, void *f, char *s) {
static int __Pyx_ExportFunction(char *name, void *f, char *sig) {
PyObject *d = 0;
PyObject *p = 0;
d = PyObject_GetAttrString(%(MODULE)s, "%(API)s");
......@@ -1738,10 +1902,10 @@ static int __Pyx_ExportFunction(char *n, void *f, char *s) {
if (PyModule_AddObject(%(MODULE)s, "%(API)s", d) < 0)
goto bad;
}
p = PyCObject_FromVoidPtrAndDesc(f, s, 0);
p = PyCObject_FromVoidPtrAndDesc(f, sig, 0);
if (!p)
goto bad;
if (PyDict_SetItemString(d, n, p) < 0)
if (PyDict_SetItemString(d, name, p) < 0)
goto bad;
Py_DECREF(d);
return 0;
......
......@@ -48,6 +48,8 @@ fileinit_cname = pyrex_prefix + "init_filenames"
intern_tab_cname = pyrex_prefix + "intern_tab"
kwds_cname = pyrex_prefix + "kwds"
lineno_cname = pyrex_prefix + "lineno"
clineno_cname = pyrex_prefix + "clineno"
cfilenm_cname = pyrex_prefix + "cfilenm"
module_cname = pyrex_prefix + "m"
moddoc_cname = pyrex_prefix + "mdoc"
methtable_cname = pyrex_prefix + "methods"
......@@ -64,6 +66,9 @@ cleanup_cname = pyrex_prefix + "module_cleanup"
optional_args_cname = pyrex_prefix + "optional_args"
no_opt_args = pyrex_prefix + "no_opt_args"
line_c_macro = "__LINE__"
file_c_macro = "__FILE__"
extern_c_macro = pyrex_prefix.upper() + "EXTERN_C"
......
......@@ -885,8 +885,8 @@ class FuncDefNode(StatNode, BlockNode):
exc_check = self.caller_will_check_exceptions()
if err_val is not None or exc_check:
code.putln(
'__Pyx_AddTraceback("%s");' %
self.entry.qualified_name)
'__Pyx_AddTraceback("%s",%s,%s);' %
(self.entry.qualified_name,Naming.cfilenm_cname,Naming.clineno_cname))
if err_val is not None:
code.putln(
"%s = %s;" % (
......@@ -3277,7 +3277,7 @@ class ExceptClauseNode(Node):
code.putln(
"/*except:*/ {")
code.putln(
'__Pyx_AddTraceback("%s");' % (self.function_name))
'__Pyx_AddTraceback("%s",%s,%s);' % (self.function_name, Naming.cfilenm_cname,Naming.clineno_cname))
# We always have to fetch the exception value even if
# there is no target, because this also normalises the
# exception and stores it in the thread state.
......@@ -4095,13 +4095,13 @@ static void __Pyx_WriteUnraisable(char *name) {
traceback_utility_code = [
"""
static void __Pyx_AddTraceback(char *funcname); /*proto*/
static void __Pyx_AddTraceback(char *funcname, char* cfilename, unsigned int cfileline); /*proto*/
""","""
#include "compile.h"
#include "frameobject.h"
#include "traceback.h"
static void __Pyx_AddTraceback(char *funcname) {
static void __Pyx_AddTraceback(char *funcname, char* cfilename, unsigned int cfileline) {
PyObject *py_srcfile = 0;
PyObject *py_funcname = 0;
PyObject *py_globals = 0;
......@@ -4111,7 +4111,7 @@ static void __Pyx_AddTraceback(char *funcname) {
py_srcfile = PyString_FromString(%(FILENAME)s);
if (!py_srcfile) goto bad;
py_funcname = PyString_FromString(funcname);
py_funcname = PyString_FromFormat( "%%s, %%s, %%u", funcname, cfilename, cfileline);
if (!py_funcname) goto bad;
py_globals = PyModule_GetDict(%(GLOBALS)s);
if (!py_globals) goto bad;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment