fixes: generate constant declarations before we access them, write cleanup code as...
authorStefan Behnel <scoder@users.berlios.de>
Tue, 13 May 2008 17:59:36 +0000 (19:59 +0200)
committerStefan Behnel <scoder@users.berlios.de>
Tue, 13 May 2008 17:59:36 +0000 (19:59 +0200)
Cython/Compiler/ModuleNode.py
Cython/Compiler/Nodes.py
Cython/Compiler/Symtab.py

index 1e11b256e8d68ad279a7f72e8d7a9d0d64eb0449..d94f886bef2111203fab7d247acd1a8a60377ec5 100644 (file)
@@ -221,6 +221,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("/* Implementation of %s */" % env.qualified_name)
         self.generate_const_definitions(env, code)
         self.generate_interned_num_decls(env, code)
+        self.generate_interned_string_decls(env, code)
         self.generate_py_string_decls(env, code)
         self.generate_cached_builtins_decls(env, code)
         self.body.generate_function_definitions(env, code, options.transforms)
@@ -1365,11 +1366,6 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         entries = env.all_pystring_entries
         if entries:
             code.putln("")
-            for entry in entries:
-                if entry.is_interned:
-                    code.putln('static char %s[] = "%s";' % (
-                            entry.cname, entry.init))
-            code.putln("")
             code.putln(
                 "static __Pyx_StringTabEntry %s[] = {" %
                     Naming.stringtab_cname)
@@ -1476,9 +1472,11 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
         code.putln("/*--- Intern cleanup code ---*/")
         for entry in env.pynum_entries:
             code.put_var_decref_clear(entry)
-        if env.intern_map:
-            for name, cname in env.intern_map.items():
-                code.put_decref_clear(cname, PyrexTypes.py_object_type)
+        if env.all_pystring_entries:
+            for entry in env.all_pystring_entries:
+                if entry.is_interned:
+                    code.put_decref_clear(
+                        entry.pystring_cname, PyrexTypes.py_object_type)
         code.putln("Py_INCREF(Py_None); return Py_None;")
         code.putln('}')
 
index 9eca7a2daf78a5e66efe64e2170cc828c941ced2..04e77104406faf289248a1d1d5757e0aa020e723 100644 (file)
@@ -230,7 +230,18 @@ class BlockNode:
             for entry in env.const_entries:
                 if not entry.is_interned:
                     code.put_var_declaration(entry, static = 1)
-    
+
+    def generate_interned_string_decls(self, env, code):
+        entries = env.global_scope().new_interned_string_entries
+        if entries:
+            code.putln("")
+            for entry in entries:
+                code.put_var_declaration(entry, static = 1)
+            for entry in entries:
+                code.putln(
+                    "static PyObject *%s;" % entry.pystring_cname)
+            del entries[:]
+
     def generate_py_string_decls(self, env, code):
         entries = env.pystring_entries
         if entries:
@@ -238,7 +249,7 @@ class BlockNode:
             for entry in entries:
                 code.putln(
                     "static PyObject *%s;" % entry.pystring_cname)
-    
+
     def generate_interned_num_decls(self, env, code):
         #  Flush accumulated interned nums from the global scope
         #  and generate declarations for them.
@@ -865,6 +876,7 @@ class FuncDefNode(StatNode, BlockNode):
         # if we supported them, which we probably won't.
         # ----- Top-level constants used by this function
         self.generate_interned_num_decls(lenv, code)
+        self.generate_interned_string_decls(lenv, code)
         self.generate_py_string_decls(lenv, code)
         self.generate_cached_builtins_decls(lenv, code)
         #code.putln("")
index 3b0bffbdb4b521b1cdb9ede2d3182ca7e75da4d8..0c023ad42f97c47c356ef6e10353effd586acea3 100644 (file)
@@ -461,13 +461,15 @@ class Scope:
         # a string literal, and add it to the list of Python strings to
         # be created at module init time. If the string resembles a
         # Python identifier, it will be interned.
-        if not entry.pystring_cname:
-            value = entry.init
-            if possible_identifier(value):
-                entry.is_interned = 1
-            entry.pystring_cname = entry.cname + "p"
-            self.pystring_entries.append(entry)
-            self.global_scope().all_pystring_entries.append(entry)
+        if entry.pystring_cname:
+            return
+        value = entry.init
+        entry.pystring_cname = entry.cname + "p"
+        self.pystring_entries.append(entry)
+        self.global_scope().all_pystring_entries.append(entry)
+        if possible_identifier(value):
+            entry.is_interned = 1
+            self.global_scope().new_interned_string_entries.append(entry)
 
     def add_py_num(self, value):
         # Add an entry for an int constant.
@@ -673,7 +675,7 @@ class ModuleScope(Scope):
     # type_names           {string : 1}       Set of type names (used during parsing)
     # pxd_file_loaded      boolean            Corresponding .pxd file has been processed
     # cimported_modules    [ModuleScope]      Modules imported with cimport
-    # intern_map           {string : string}  Mapping from Python names to interned strs
+    # new_interned_string_entries [Entry]     New interned strings waiting to be declared
     # interned_nums        [int/long]         Interned numeric constants
     # all_pystring_entries [Entry]            Python string consts from all scopes
     # types_imported       {PyrexType : 1}    Set of types for which import code generated
@@ -700,7 +702,7 @@ class ModuleScope(Scope):
         self.type_names = dict(outer_scope.type_names)
         self.pxd_file_loaded = 0
         self.cimported_modules = []
-        self.intern_map = {}
+        self.new_interned_string_entries = []
         self.interned_nums = []
         self.interned_objs = []
         self.all_pystring_entries = []
@@ -739,7 +741,7 @@ class ModuleScope(Scope):
         return entry
 
     def intern(self, name):
-        string_entry = self.add_string_const(name)
+        string_entry = self.get_string_const(name)
         self.add_py_string(string_entry)
         return string_entry.pystring_cname