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