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
- try:
- base = dict[base.type.base_type.vtabstruct_cname]
- except KeyError:
- return True
- 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
- try:
- base = dict[base.type.base_type.objstruct_cname]
- except KeyError:
- return True
- return False
-
-
-
class ModuleNode(Nodes.Node, Nodes.BlockNode):
# doc string or None
# body StatListNode
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)
- self.generate_declarations_for_modules(env, modules, code.h)
+ for module in modules:
+ self.generate_declarations_for_module(module, code.h,
+ definition = module is env)
f = open_new_file(result.c_file)
f.write(code.h.f.getvalue())
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
# Some C compilers don't like an empty array
code.putln("0")
code.putln("};")
-
- 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_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_modules(self, env, modules, code):
+
+ def generate_declarations_for_module(self, env, code, definition):
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)
-
+ 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_type_predeclarations(self, env, code):
+ pass
+
def generate_type_header_code(self, type_entries, code):
# Generate definitions of structs/unions/enums/typedefs/objstructs.
#self.generate_gcc33_hack(env, code) # Is this still needed?
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
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)
- # do we need any of these here, or just in init2?
code.put_var_declarations(env.temp_entries)
code.putln("/*--- Libary function declarations ---*/")
code.putln("/*--- Function export code ---*/")
self.generate_c_function_export_code(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("/*--- Function import code ---*/")
+ for module in imported_modules:
+ self.generate_c_function_import_code_for_module(module, env, code)
+
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)
- 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");' % env.qualified_name)
- env.use_utility_code(Nodes.traceback_utility_code)
- code.putln('}')
- def generate_module_init2_func(self, imported_modules, env, code):
- code.init_labels()
- 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)
env.use_utility_code(Nodes.traceback_utility_code)
- code.putln('}')
-
+ code.putln('}')
+
def generate_module_cleanup_func(self, env, code):
if not Options.generate_cleanup_code:
return
self.generate_exttype_vtable_init_code(entry, code)
self.generate_type_ready_code(env, entry, code)
self.generate_typeptr_assignment_code(entry, code)
-
+
def generate_base_type_import_code(self, env, entry, code):
base_type = entry.type.base_type
if base_type and base_type.module_name != env.qualified_name:
#
#------------------------------------------------------------------------------------
-
-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*/
py_name = PyString_FromString(module_name);
if (!py_name)
goto bad;
-
+
py_module = __Pyx_ImportModule(module_name);
if (!py_module)
goto bad;
function_export_utility_code = [
"""
-static int __Pyx_ExportFunction(char *n, void *f, char *s); /*proto*/
+static int __Pyx_ExportFunction(char *name, void *f, char *sig); /*proto*/
""",r"""
static int __Pyx_ExportFunction(char *name, void *f, char *sig) {
PyObject *d = 0;