Author: Amaury Forgeot d'Arc <amaur...@gmail.com>
Branch: remove-PYPY_NOT_MAIN_FILE
Changeset: r57166:1ff2a829ce6c
Date: 2012-09-05 23:02 +0200
http://bitbucket.org/pypy/pypy/changeset/1ff2a829ce6c/

Log:    Attempt to reduce code duplication in genc. "split" and
        "one_source_file" now share more parts.

diff --git a/pypy/translator/c/genc.py b/pypy/translator/c/genc.py
--- a/pypy/translator/c/genc.py
+++ b/pypy/translator/c/genc.py
@@ -1,4 +1,5 @@
 import autopath
+import contextlib
 import py
 import sys, os
 from pypy.translator.c.database import LowLevelDatabase
@@ -669,8 +670,6 @@
                 funcnodes.append(node)
             else:
                 othernodes.append(node)
-        # for now, only split for stand-alone programs.
-        #if self.database.standalone:
         if split:
             self.one_source_file = False
         self.funcnodes = funcnodes
@@ -709,11 +708,14 @@
                         return relpypath.replace('.py', '.c')
             return None
         if hasattr(node.obj, 'graph'):
+            # Regular RPython functions
             name = invent_nice_name(node.obj.graph)
             if name is not None:
                 return name
         elif node._funccodegen_owner is not None:
-            name = invent_nice_name(node._funccodegen_owner.graph)
+            # Data nodes that belong to a known function
+            graph = getattr(node._funccodegen_owner, 'graph', None)
+            name = invent_nice_name(graph)
             if name is not None:
                 return "data_" + name
         return basecname
@@ -751,6 +753,27 @@
             while not done[0]:
                 yield self.uniquecname(basecname), subiter()
 
+    @contextlib.contextmanager
+    def write_on_maybe_included_file(self, f, name):
+        if self.one_source_file:
+            print >> f
+            yield f
+        else:
+            fi = self.makefile(name)
+            print >> f, '#include "%s"' % name
+            yield fi
+            fi.close()
+
+    @contextlib.contextmanager
+    def write_on_maybe_separate_source(self, f, name):
+        print >> f, '/* %s */' % name
+        if self.one_source_file:
+            yield f
+        else:
+            fi = self.makefile(name)
+            yield fi
+            fi.close()
+
     def gen_readable_parts_of_source(self, f):
         split_criteria_big = SPLIT_CRITERIA
         if py.std.sys.platform != "win32":
@@ -758,24 +781,14 @@
                 pass    # XXX gcc uses toooooons of memory???
             else:
                 split_criteria_big = SPLIT_CRITERIA * 4 
-        if self.one_source_file:
-            return gen_readable_parts_of_main_c_file(f, self.database,
-                                                     self.preimpl)
+
         #
         # All declarations
         #
-        database = self.database
-        structdeflist = database.getstructdeflist()
-        name = 'structdef.h'
-        fi = self.makefile(name)
-        print >> f, '#include "%s"' % name
-        gen_structdef(fi, database)
-        fi.close()
-        name = 'forwarddecl.h'
-        fi = self.makefile(name)
-        print >> f, '#include "%s"' % name
-        gen_forwarddecl(fi, database)
-        fi.close()
+        with self.write_on_maybe_included_file(f, 'structdef.h') as fi:
+            gen_structdef(fi, self.database)
+        with self.write_on_maybe_included_file(f, 'forwarddecl.h') as fi:
+            gen_forwarddecl(fi, self.database)
 
         #
         # Implementation of functions and global structures and arrays
@@ -784,75 +797,59 @@
         print >> f, 
'/***********************************************************/'
         print >> f, '/***  Implementations                                    
***/'
         print >> f
+
+        print >> f, '#define PYPY_FILE_NAME "%s"' % os.path.basename(f.name)
         for line in self.preimpl:
             print >> f, line
         print >> f, '#include "src/g_include.h"'
         print >> f
-        name = self.uniquecname('structimpl.c')
-        print >> f, '/* %s */' % name
-        fc = self.makefile(name)
-        print >> fc, 
'/***********************************************************/'
-        print >> fc, '/***  Structure Implementations                          
***/'
-        print >> fc
-        print >> fc, '#include "common_header.h"'
-        print >> fc, '#include "structdef.h"'
-        print >> fc, '#include "forwarddecl.h"'
-        print >> fc
-        print >> fc, '#include "src/g_include.h"'
-        print >> fc
-        print >> fc, MARKER
-
-        print >> fc, 
'/***********************************************************/'
-        fc.close()
 
         nextralines = 11 + 1
         for name, nodeiter in self.splitnodesimpl('nonfuncnodes.c',
                                                    self.othernodes,
                                                    nextralines, 1):
-            print >> f, '/* %s */' % name
-            fc = self.makefile(name)
-            print >> fc, 
'/***********************************************************/'
-            print >> fc, '/***  Non-function Implementations                   
    ***/'
-            print >> fc
-            print >> fc, '#include "common_header.h"'
-            print >> fc, '#include "structdef.h"'
-            print >> fc, '#include "forwarddecl.h"'
-            print >> fc
-            print >> fc, '#include "src/g_include.h"'
-            print >> fc
-            print >> fc, MARKER
-            for node, impl in nodeiter:
-                print >> fc, '\n'.join(impl)
+            with self.write_on_maybe_separate_source(f, name) as fc:
+                if fc is not f:
+                    print >> fc, 
'/***********************************************************/'
+                    print >> fc, '/***  Non-function Implementations           
            ***/'
+                    print >> fc
+                    print >> fc, '#include "common_header.h"'
+                    print >> fc, '#include "structdef.h"'
+                    print >> fc, '#include "forwarddecl.h"'
+                    print >> fc
+                    print >> fc, '#include "src/g_include.h"'
+                    print >> fc
                 print >> fc, MARKER
-            print >> fc, 
'/***********************************************************/'
-            fc.close()
+                for node, impl in nodeiter:
+                    print >> fc, '\n'.join(impl)
+                    print >> fc, MARKER
+                print >> fc, 
'/***********************************************************/'
 
         nextralines = 8 + len(self.preimpl) + 4 + 1
         for name, nodeiter in self.splitnodesimpl('implement.c',
                                                    self.funcnodes,
                                                    nextralines, 1,
                                                    split_criteria_big):
-            print >> f, '/* %s */' % name
-            fc = self.makefile(name)
-            print >> fc, 
'/***********************************************************/'
-            print >> fc, '/***  Implementations                                
    ***/'
-            print >> fc
-            print >> fc, '#define PYPY_FILE_NAME "%s"' % name
-            print >> fc, '#include "common_header.h"'
-            print >> fc, '#include "structdef.h"'
-            print >> fc, '#include "forwarddecl.h"'
-            print >> fc
-            for line in self.preimpl:
-                print >> fc, line
-            print >> fc
-            print >> fc, '#include "src/g_include.h"'
-            print >> fc
-            print >> fc, MARKER
-            for node, impl in nodeiter:
-                print >> fc, '\n'.join(impl)
+            with self.write_on_maybe_separate_source(f, name) as fc:
+                if fc is not f:
+                    print >> fc, 
'/***********************************************************/'
+                    print >> fc, '/***  Implementations                        
            ***/'
+                    print >> fc
+                    print >> fc, '#define PYPY_FILE_NAME "%s"' % name
+                    print >> fc, '#include "common_header.h"'
+                    print >> fc, '#include "structdef.h"'
+                    print >> fc, '#include "forwarddecl.h"'
+                    print >> fc
+                    for line in self.preimpl:
+                        print >> fc, line
+                    print >> fc
+                    print >> fc, '#include "src/g_include.h"'
+                    print >> fc
                 print >> fc, MARKER
-            print >> fc, 
'/***********************************************************/'
-            fc.close()
+                for node, impl in nodeiter:
+                    print >> fc, '\n'.join(impl)
+                    print >> fc, MARKER
+                print >> fc, 
'/***********************************************************/'
         print >> f
 
 
@@ -880,43 +877,6 @@
         for line in node.forward_declaration():
             print >> f, line
 
-# this function acts as the fallback for small sources for now.
-# Maybe we drop this completely if source splitting is the way
-# to go. Currently, I'm quite fine with keeping a working fallback.
-# XXX but we need to reduce code duplication.
-
-def gen_readable_parts_of_main_c_file(f, database, preimplementationlines=[]):
-    #
-    # All declarations
-    #
-    print >> f
-    gen_structdef(f, database)
-    print >> f
-    gen_forwarddecl(f, database)
-
-    #
-    # Implementation of functions and global structures and arrays
-    #
-    print >> f
-    print >> f, '/***********************************************************/'
-    print >> f, '/***  Implementations                                    ***/'
-    print >> f
-    print >> f, '#define PYPY_FILE_NAME "%s"' % os.path.basename(f.name)
-    for line in preimplementationlines:
-        print >> f, line
-    print >> f, '#include "src/g_include.h"'
-    print >> f
-    blank = True
-    graphs = database.all_graphs()
-    database.gctransformer.prepare_inline_helpers(graphs)
-    for node in database.globalcontainers():
-        if blank:
-            print >> f
-            blank = False
-        for line in node.implementation():
-            print >> f, line
-            blank = True
-
 def gen_startupcode(f, database):
     # generate the start-up code and put it into a function
     print >> f, 'char *RPython_StartupCode(void) {'
@@ -999,8 +959,7 @@
     #
     sg = SourceGenerator(database, preimplementationlines)
     sg.set_strategy(targetdir, split)
-    if split:
-        database.prepare_inline_helpers()
+    database.prepare_inline_helpers()
     sg.gen_readable_parts_of_source(f)
 
     gen_startupcode(f, database)
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to