support cleanup code for utility code
authorStefan Behnel <scoder@users.berlios.de>
Sun, 26 Oct 2008 15:43:10 +0000 (16:43 +0100)
committerStefan Behnel <scoder@users.berlios.de>
Sun, 26 Oct 2008 15:43:10 +0000 (16:43 +0100)
Cython/Compiler/Code.py
Cython/Compiler/ModuleNode.py
Cython/Utils.py

index 9adcdb9b3b3d1b5552c7851fc848b97c9556b383..761bd967c6d4043555d65214f76416d55d8135c3 100644 (file)
@@ -184,6 +184,7 @@ class GlobalState(object):
         self.pystring_table = rootwriter.new_writer()
         self.init_cached_builtins_writer = rootwriter.new_writer()
         self.initwriter = rootwriter.new_writer()
+        self.cleanupwriter = rootwriter.new_writer()
 
         if Options.cache_builtins:
             self.init_cached_builtins_writer.enter_cfunc_scope()
@@ -193,6 +194,10 @@ class GlobalState(object):
         self.initwriter.putln("")
         self.initwriter.putln("static int __Pyx_InitGlobals(void) {")
 
+        self.cleanupwriter.enter_cfunc_scope()
+        self.cleanupwriter.putln("")
+        self.cleanupwriter.putln("static void __Pyx_CleanupGlobals(void) {")
+
         self.pystring_table.putln("")
         self.pystring_table.putln("static __Pyx_StringTabEntry %s[] = {" %
                 Naming.stringtab_cname)
@@ -230,6 +235,10 @@ class GlobalState(object):
         w.putln("return -1;")
         w.putln("}")
         w.exit_cfunc_scope()
+
+        w = self.cleanupwriter
+        w.putln("}")
+        w.exit_cfunc_scope()
          
     def insert_initcode_into(self, code):
         if self.pystring_table_needed:
@@ -238,6 +247,9 @@ class GlobalState(object):
             code.insert(self.init_cached_builtins_writer)
         code.insert(self.initwriter)
 
+    def insert_cleanupcode_into(self, code):
+        code.insert(self.cleanupwriter)
+
     def put_pyobject_decl(self, entry):
         self.decls_writer.putln("static PyObject *%s;" % entry.cname)
 
@@ -351,6 +363,7 @@ class GlobalState(object):
             if utility_code.impl:
                 self.utildefwriter.put(utility_code.impl)
             utility_code.write_init_code(self.initwriter, self.module_pos)
+            utility_code.write_cleanup_code(self.cleanupwriter, self.module_pos)
 
     def has_code(self, name):
         return name in self.used_utility_code
index e6de94e92442b345b13760357b37d75dc7a999c3..a5dd578d10220db82b5a7371ee04d4981dd75225 100644 (file)
@@ -1542,7 +1542,7 @@ 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
+        # Insert code stream of __Pyx_InitGlobals()
         code.globalstate.insert_initcode_into(code)
         
         code.enter_cfunc_scope()
@@ -1627,6 +1627,8 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
             return
         env.use_utility_code(import_module_utility_code)
         env.use_utility_code(register_cleanup_utility_code)
+        # Insert code stream of __Pyx_CleanupGlobals()
+        code.globalstate.insert_cleanupcode_into(code)
         code.putln()
         code.putln('static PyObject* %s(PyObject *self, PyObject *unused) {' % Naming.cleanup_cname)
         if Options.generate_cleanup_code >= 2:
@@ -1637,6 +1639,7 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
                 if entry.visibility != 'extern':
                     if entry.type.is_pyobject and entry.used:
                         code.put_var_decref_clear(entry)
+        code.putln("__Pyx_CleanupGlobals();")
         if Options.generate_cleanup_code >= 3:
             code.putln("/*--- Type import cleanup code ---*/")
             for type, _ in env.types_imported.items():
index 7d3e08967810a52a4f6197f2c9bf5c0ecc473d45..5da150b7609c9a1b051b2e45e46f3dc1b5e57e87 100644 (file)
@@ -105,3 +105,11 @@ class UtilityCode(object):
             self.init(writer, pos)
         else:
             writer.put(self.init)
+
+    def write_cleanup_code(self, writer, pos):
+        if not self.cleanup:
+            return
+        if callable(self.cleanup):
+            self.cleanup(writer, pos)
+        else:
+            writer.put(self.cleanup)