From: Dag Sverre Seljebotn Date: Sat, 2 Aug 2008 09:19:54 +0000 (+0200) Subject: Moved string and int init code generation to Code.py X-Git-Tag: 0.9.8.1~49^2~31 X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=b7ffe1165418230b2d552bbfab23039d4934a984;p=cython.git Moved string and int init code generation to Code.py --- diff --git a/Cython/Compiler/Code.py b/Cython/Compiler/Code.py index 684e419d..1dcfe42d 100644 --- a/Cython/Compiler/Code.py +++ b/Cython/Compiler/Code.py @@ -161,11 +161,23 @@ class GlobalState(object): self.input_file_contents = {} self.used_utility_code = set() self.declared_cnames = {} + self.pystring_table_needed = False def initwriters(self, rootwriter): self.utilprotowriter = rootwriter.new_writer() self.utildefwriter = rootwriter.new_writer() self.decls_writer = rootwriter.new_writer() + self.pystring_table = rootwriter.new_writer() + self.initwriter = rootwriter.new_writer() + + self.initwriter.enter_cfunc_scope() + self.initwriter.putln("").putln("static int __Pyx_InitGlobals(void) {") + + (self.pystring_table + .putln("") + .putln("static __Pyx_StringTabEntry %s[] = {" % + Naming.stringtab_cname) + ) # # Global constants, interned objects, etc. @@ -173,10 +185,41 @@ class GlobalState(object): def insert_global_var_declarations_into(self, code): code.insert(self.decls_writer) + def close_global_decls(self): + # This is called when it is known that no more global declarations will + # declared (but can be called before or after insert_XXX). + if self.pystring_table_needed: + self.pystring_table.putln("{0, 0, 0, 0, 0}").putln("};") + import Nodes + self.use_utility_code(Nodes.init_string_tab_utility_code) + self.initwriter.putln( + "if (__Pyx_InitStrings(%s) < 0) %s;" % ( + Naming.stringtab_cname, + self.initwriter.error_goto(self.module_pos))) + + (self.initwriter + .putln("return 0;") + .put_label(self.initwriter.error_label) + .putln("return -1;") + .putln("}") + ) + self.initwriter.exit_cfunc_scope() + + def insert_py_string_table_into(self, code): + if self.pystring_table_needed: + code.insert(self.pystring_table) + + def insert_initglobals_into(self, code): + code.insert(self.initwriter) + + def put_pyobject_decl(self, entry): + self.decls_writer.putln("static PyObject *%s;" % entry.cname) + # The functions below are there in a transition phase only # and will be deprecated. They are called from Nodes.BlockNode. # The copy&paste duplication is intentional in order to be able - # to see quickly how BlockNode worked, until this is replaced. + # to see quickly how BlockNode worked, until this is replaced. + def should_declare(self, cname, entry): if cname in self.declared_cnames: other = self.declared_cnames[cname] @@ -194,20 +237,33 @@ class GlobalState(object): def add_interned_string_decl(self, entry): if self.should_declare(entry.cname, entry): self.decls_writer.put_var_declaration(entry, static = 1) - if self.should_declare(entry.pystring_cname, entry): - self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname) + self.add_py_string_decl(entry) def add_py_string_decl(self, entry): if self.should_declare(entry.pystring_cname, entry): self.decls_writer.putln("static PyObject *%s;" % entry.pystring_cname) - + self.pystring_table_needed = True + self.pystring_table.putln("{&%s, %s, sizeof(%s), %d, %d, %d}," % ( + entry.pystring_cname, + entry.cname, + entry.cname, + entry.type.is_unicode, + entry.is_interned, + entry.is_identifier + )) + def add_interned_num_decl(self, entry): if self.should_declare(entry.cname, entry): - self.decls_writer.putln("static PyObject *%s;" % entry.cname) - + self.initwriter.putln("%s = PyInt_FromLong(%s); %s;" % ( + entry.cname, + entry.init, + self.initwriter.error_goto_if_null(entry.cname, self.module_pos))) # todo: fix pos + self.put_pyobject_decl(entry) + def add_cached_builtin_decl(self, entry): if self.should_declare(entry.cname, entry): - self.decls_writer.putln("static PyObject *%s;" % entry.cname) + self.put_pyobject_decl(entry) + # # File name state @@ -418,6 +474,7 @@ class CCodeWriter(object): self.put(code) self.write("\n"); self.bol = 1 + return self def emit_marker(self): self.write("\n"); @@ -425,6 +482,7 @@ class CCodeWriter(object): self.write("/* %s */\n" % self.marker[1]) self.last_marker_line = self.marker[0] self.marker = None + return self def put(self, code): dl = code.count("{") - code.count("}") @@ -440,20 +498,25 @@ class CCodeWriter(object): self.level += dl elif dl == 0 and code.startswith('}'): self.level += 1 + return self def increase_indent(self): self.level = self.level + 1 + return self def decrease_indent(self): self.level = self.level - 1 + return self def begin_block(self): self.putln("{") self.increase_indent() + return self def end_block(self): self.decrease_indent() self.putln("}") + return self def indent(self): self.write(" " * self.level) @@ -481,10 +544,12 @@ class CCodeWriter(object): def put_label(self, lbl): if lbl in self.funcstate.labels_used: self.putln("%s:;" % lbl) + return self def put_goto(self, lbl): self.funcstate.use_label(lbl) self.putln("goto %s;" % lbl) + return self def put_var_declarations(self, entries, static = 0, dll_linkage = None, definition = True): diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py index a08e102a..5d23f79b 100644 --- a/Cython/Compiler/ModuleNode.py +++ b/Cython/Compiler/ModuleNode.py @@ -242,6 +242,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): h_code = code.insertion_point() self.generate_module_preamble(env, modules, h_code) + code.globalstate.module_pos = self.pos + code.putln("") code.putln("/* Implementation of %s */" % env.qualified_name) self.generate_const_definitions(env, code) @@ -270,6 +272,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): self.generate_declarations_for_modules(env, modules, h_code) h_code.write('\n') + code.globalstate.close_global_decls() + f = open_new_file(result.c_file) code.copyto(f) f.close() @@ -1450,27 +1454,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): "};") def generate_py_string_table(self, env, code): -# raise Exception() - entries = env.all_pystring_entries - if entries: - code.putln("") - code.putln( - "static __Pyx_StringTabEntry %s[] = {" % - Naming.stringtab_cname) - for entry in entries: - code.putln( - "{&%s, %s, sizeof(%s), %d, %d, %d}," % ( - entry.pystring_cname, - entry.cname, - entry.cname, - entry.type.is_unicode, - entry.is_interned, - entry.is_identifier - )) - code.putln( - "{0, 0, 0, 0, 0}") - code.putln( - "};") + code.globalstate.insert_py_string_table_into(code) def generate_filename_init_prototype(self, code): code.putln(""); @@ -1539,6 +1523,9 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): code.exit_cfunc_scope() # done with labels def generate_module_init_func(self, imported_modules, env, code): + # Insert code stream of __Pyx_InitGlobals + code.globalstate.insert_initglobals_into(code) + code.enter_cfunc_scope() code.putln("") header2 = "PyMODINIT_FUNC init%s(void)" % env.module_name @@ -1558,15 +1545,12 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): env.generate_library_function_declarations(code) self.generate_filename_init_call(code) + code.putln("/*--- Initialize various global constants etc. ---*/") + code.putln(code.error_goto_if_neg("__Pyx_InitGlobals()", self.pos)) + code.putln("/*--- Module creation code ---*/") self.generate_module_creation_code(env, code) - code.putln("/*--- Intern code ---*/") - self.generate_intern_code(env, code) - - code.putln("/*--- String init code ---*/") - self.generate_string_init_code(env, code) - if Options.cache_builtins: code.putln("/*--- Builtin init code ---*/") self.generate_builtin_init_code(env, code) @@ -1726,21 +1710,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode): "if (!%s) %s;" % ( Naming.preimport_cname, code.error_goto(self.pos))); - - def generate_intern_code(self, env, code): - for entry in env.pynum_entries: - code.putln("%s = PyInt_FromLong(%s); %s;" % ( - entry.cname, - entry.init, - code.error_goto_if_null(entry.cname, self.pos))) - - def generate_string_init_code(self, env, code): - if env.all_pystring_entries: - env.use_utility_code(Nodes.init_string_tab_utility_code) - code.putln( - "if (__Pyx_InitStrings(%s) < 0) %s;" % ( - Naming.stringtab_cname, - code.error_goto(self.pos))) def generate_builtin_init_code(self, env, code): # Lookup and cache builtin objects.