[pypy-svn] r33895 - in pypy/dist/pypy/translator: cli js oosupport

antocuni at codespeak.net antocuni at codespeak.net
Mon Oct 30 15:46:49 CET 2006


Author: antocuni
Date: Mon Oct 30 15:46:41 2006
New Revision: 33895

Modified:
   pypy/dist/pypy/translator/cli/class_.py
   pypy/dist/pypy/translator/cli/database.py
   pypy/dist/pypy/translator/cli/gencli.py
   pypy/dist/pypy/translator/js/_class.py
   pypy/dist/pypy/translator/js/asmgen.py
   pypy/dist/pypy/translator/js/database.py
   pypy/dist/pypy/translator/js/function.py
   pypy/dist/pypy/translator/js/js.py
   pypy/dist/pypy/translator/oosupport/genoo.py
Log:
(antocuni, niko)

Refactor of oosupport so that gencli, genjs and (later) genjvm can
share more code.



Modified: pypy/dist/pypy/translator/cli/class_.py
==============================================================================
--- pypy/dist/pypy/translator/cli/class_.py	(original)
+++ pypy/dist/pypy/translator/cli/class_.py	Mon Oct 30 15:46:41 2006
@@ -10,7 +10,7 @@
 class Class(Node):
     def __init__(self, db, INSTANCE, namespace, name):
         self.db = db
-        self.cts = db.type_system_class(db)
+        self.cts = db.genoo.TypeSystem(db)
         self.INSTANCE = INSTANCE
         self.namespace = namespace
         self.name = name
@@ -96,7 +96,7 @@
                 SELF = args[0].concretetype
                 if not ootype.isSubclass(self.INSTANCE, SELF):
                     continue
-                f = self.db.function_class(self.db, m_meth.graph, m_name, is_method = True)
+                f = self.db.genoo.Function(self.db, m_meth.graph, m_name, is_method = True)
                 f.render(ilasm)
             else:
                 # abstract method

Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py	(original)
+++ pypy/dist/pypy/translator/cli/database.py	Mon Oct 30 15:46:41 2006
@@ -49,13 +49,11 @@
     return v!=0 and (v == v*2)
 
 class LowLevelDatabase(object):
-    def __init__(self, type_system_class = CTS, opcode_dict = opcodes, function_class = Function):
+    def __init__(self, genoo):
         self._pending_nodes = set()
-        self.opcode_dict = opcode_dict
         self._rendered_nodes = set()
-        self.function_class = function_class
-        self.type_system_class = type_system_class
-        self.cts = type_system_class(self)
+        self.genoo = genoo
+        self.cts = genoo.TypeSystem(self)
         self.classes = {} # INSTANCE --> class_name
         self.classnames = set() # (namespace, name)
         self.recordnames = {} # RECORD --> name
@@ -92,7 +90,7 @@
 
     def pending_function(self, graph, functype=None):
         if functype is None:
-            function = self.function_class(self, graph)
+            function = self.genoo.Function(self, graph)
         else:
             function = functype(self, graph)
         self.pending_node(function)

Modified: pypy/dist/pypy/translator/cli/gencli.py
==============================================================================
--- pypy/dist/pypy/translator/cli/gencli.py	(original)
+++ pypy/dist/pypy/translator/cli/gencli.py	Mon Oct 30 15:46:41 2006
@@ -5,6 +5,7 @@
 from py.compat import subprocess
 from pypy.config.config import Config
 from pypy.config.pypyoption import pypy_optiondescription
+from pypy.translator.oosupport.genoo import GenOO
 from pypy.translator.cli import conftest
 from pypy.translator.cli.ilgenerator import IlasmGenerator
 from pypy.translator.cli.function import Function, log
@@ -28,84 +29,37 @@
 #USE_STACKOPT = True and not getoption('nostackopt')
 USE_STACKOPT = False
 
-class GenCli(object):
-    def __init__(self, tmpdir, translator, entrypoint=None, type_system_class=CTS,
-                 opcode_dict=opcodes, name_suffix='.il', function_class=Function,
-                 database_class = LowLevelDatabase, pending_graphs=(), config=None):
-        self.tmpdir = tmpdir
-        self.translator = translator
-        self.entrypoint = entrypoint
-        self.db = database_class(type_system_class = type_system_class, opcode_dict = opcode_dict,
-            function_class = function_class)
 
+class GenCli(GenOO):
+    TypeSystem = CTS
+    Function = Function
+    opcodes = opcodes
+    Database = LowLevelDatabase
+    log = log
+
+    def __init__(self, tmpdir, translator, entrypoint, config=None):
+        GenOO.__init__(self, tmpdir, translator, entrypoint, config)
         for node in get_prebuilt_nodes(translator, self.db):
             self.db.pending_node(node)
-
-        if entrypoint is None:
-            self.assembly_name = self.translator.graphs[0].name
-        else:
-            entrypoint.set_db(self.db)
-            self.assembly_name = entrypoint.get_name()
-
-        self.tmpfile = tmpdir.join(self.assembly_name + name_suffix)
+        self.assembly_name = entrypoint.get_name()
+        self.tmpfile = tmpdir.join(self.assembly_name + '.il')
         self.const_stat = str(tmpdir.join('const_stat'))
-        if config is None:
-            config = Config(pypy_optiondescription)
-        self.config = config
 
-    def generate_source(self , asm_class = IlasmGenerator ):
+    def generate_source(self):
+        GenOO.generate_source(self)
+        self.db.const_count.dump(self.const_stat)
+        query.savedesc()
+        return self.tmpfile.strpath
+
+    def create_assembler(self):
         out = self.tmpfile.open('w')
         if getoption('stdout'):
             out = Tee(sys.stdout, out)
 
         if USE_STACKOPT:
-            self.ilasm = StackOptGenerator(out, self.assembly_name, self.config)
+            return StackOptGenerator(out, self.assembly_name, self.config)
         else:
-            self.ilasm = asm_class(out, self.assembly_name, self.config)
-
-        # TODO: instance methods that are also called as unbound
-        # methods are rendered twice, once within the class and once
-        # as an external function. Fix this.
-        self.fix_names()
-        self.gen_entrypoint()
-        self.gen_pendings()
-        self.db.gen_constants(self.ilasm)
-        out.close()
-        self.db.const_count.dump(self.const_stat)
-        query.savedesc()
-        return self.tmpfile.strpath
-
-    def gen_entrypoint(self):
-        if self.entrypoint:
-            self.entrypoint.db = self.db
-            self.db.pending_node(self.entrypoint)
-        else:
-            self.db.pending_function(self.translator.graphs[0])
-
-    def gen_pendings(self):
-        n = 0
-        while self.db._pending_nodes:
-            node = self.db._pending_nodes.pop()
-            node.render(self.ilasm)
-            self.db._rendered_nodes.add(node)
-
-            n+=1
-            if (n%100) == 0:
-                total = len(self.db._pending_nodes) + n
-                log.graphs('Rendered %d/%d (approx. %.2f%%)' %\
-                           (n, total, n*100.0/total))
-
-    def fix_names(self):
-        # it could happen that two distinct graph have the same name;
-        # here we assign an unique name to each graph.
-        names = set()
-        for graph in self.translator.graphs:
-            base_name = graph.name
-            i = 0
-            while graph.name in names:
-                graph.name = '%s_%d' % (base_name, i)
-                i+=1
-            names.add(graph.name)
+            return IlasmGenerator(out, self.assembly_name, self.config)
 
     def build_exe(self):        
         if getoption('source'):

Modified: pypy/dist/pypy/translator/js/_class.py
==============================================================================
--- pypy/dist/pypy/translator/js/_class.py	(original)
+++ pypy/dist/pypy/translator/js/_class.py	Mon Oct 30 15:46:41 2006
@@ -8,7 +8,7 @@
 class Class(Node):
     def __init__(self, db, classdef):
         self.db = db
-        self.cts = db.type_system_class(db)
+        self.cts = db.genoo.TypeSystem(db)
         self.classdef = classdef
         self.name = classdef._name.replace('.', '_')#[-1]
 
@@ -63,7 +63,7 @@
                 ilasm.inherits(self.name, basename)
         
         for m_name, m_meth in self.classdef._methods.iteritems():
-            f = self.db.function_class(self.db, m_meth.graph, m_name, is_method = True, _class = self.name)
+            f = self.db.genoo.Function(self.db, m_meth.graph, m_name, is_method = True, _class = self.name)
             f.render(ilasm)
         
         

Modified: pypy/dist/pypy/translator/js/asmgen.py
==============================================================================
--- pypy/dist/pypy/translator/js/asmgen.py	(original)
+++ pypy/dist/pypy/translator/js/asmgen.py	Mon Oct 30 15:46:41 2006
@@ -63,6 +63,9 @@
         self.subst_table = {}
         self.right_hand = Queue([], self.subst_table)
         self.codegenerator = CodeGenerator(outfile)
+
+    def close(self):
+        self.outfile.close()
     
     def begin_function(self, name, arglist):
         args = ",".join([i[1] for i in arglist])

Modified: pypy/dist/pypy/translator/js/database.py
==============================================================================
--- pypy/dist/pypy/translator/js/database.py	(original)
+++ pypy/dist/pypy/translator/js/database.py	Mon Oct 30 15:46:41 2006
@@ -26,12 +26,10 @@
     from sets import Set as set
 
 class LowLevelDatabase(object):
-    def __init__(self, backend_mapping = None):
+    def __init__(self, genoo):
         self._pending_nodes = set()
-        self.opcode_dict = backend_mapping['opcode_dict']
+        self.genoo = genoo
         self._rendered_nodes = set()
-        self.function_class = backend_mapping['function_class']
-        self.type_system_class = backend_mapping['type_system_class']
         self.classes = {} # classdef --> class_name
         self.functions = {} # graph --> function_name
         self.function_names = {} # graph --> real_name
@@ -43,8 +41,7 @@
         self.const_var = Variable("__consts")
         self.name_manager = JavascriptNameManager(self)
         self.pending_consts = []
-        self.backend_mapping = backend_mapping
-        self.cts = self.type_system_class(self)
+        self.cts = self.genoo.TypeSystem(self)
         self.prepare_builtins()
         self.proxies = []
     
@@ -64,7 +61,7 @@
         return False
 
     def pending_function(self, graph):
-        self.pending_node(self.function_class(self, graph))
+        self.pending_node(self.genoo.Function(self, graph))
 
     def pending_class(self, classdef):
         c = Class(self, classdef)
@@ -199,7 +196,7 @@
     def __init__(self, db, const):
         self.db = db
         self.const = const
-        self.cts = db.type_system_class(db)
+        self.cts = db.genoo.TypeSystem(db)
         self.depends = set()
         self.depends_on = set()
 
@@ -256,7 +253,7 @@
         self.depends = set()
         self.depends_on = set()
         self.db = db
-        self.cts = db.type_system_class(db)
+        self.cts = db.genoo.TypeSystem(db)
         self.obj = obj
         if static_type is None:
             self.static_type = obj._TYPE

Modified: pypy/dist/pypy/translator/js/function.py
==============================================================================
--- pypy/dist/pypy/translator/js/function.py	(original)
+++ pypy/dist/pypy/translator/js/function.py	Mon Oct 30 15:46:41 2006
@@ -58,7 +58,7 @@
 class Function(Node, Generator):
     def __init__(self, db, graph, name=None, is_method=False, is_entrypoint=False, _class = None):
         self.db = db
-        self.cts = db.type_system_class(db)
+        self.cts = db.genoo.TypeSystem(db)
         self.graph = graph
         self.name = name or self.db.get_uniquename(self.graph, graph.name)
         self.is_method = is_method
@@ -347,7 +347,7 @@
 
     def _render_op(self, op):
         # FIXME: what to do here?
-        instr_list = self.db.opcode_dict.get(op.opname, None)
+        instr_list = self.db.genoo.opcodes.get(op.opname, None)
         if instr_list is not None:
             #assert isinstance(instr_list, InstructionList)
             instr_list.render(self, op)

Modified: pypy/dist/pypy/translator/js/js.py
==============================================================================
--- pypy/dist/pypy/translator/js/js.py	(original)
+++ pypy/dist/pypy/translator/js/js.py	Mon Oct 30 15:46:41 2006
@@ -33,24 +33,39 @@
         path = os.path.join(path, p)
     return path
 
+class Tee(object):
+    def __init__(self, *args):
+        self.outfiles = args
+
+    def write(self, s):
+        for outfile in self.outfiles:
+            outfile.write(s)
+
+    def close(self):
+        for outfile in self.outfiles:
+            if outfile is not sys.stdout:
+                outfile.close()
+
 class JS(GenOO):
+    TypeSystem = JTS
+    opcodes = opcodes
+    Function = Function
+    Database = LowLevelDatabase
+    
     def __init__(self, translator, functions=[], stackless=False, compress=False, \
             logging=False, use_debug=False):
-        backend_mapping = {
-            'type_system_class' : JTS,
-            'opcode_dict' : opcodes,
-            'name_suffix' : '.js',
-            'function_class' : Function,
-            'database_class' : LowLevelDatabase,
-            'asm_class' : AsmGen,
-        }
         if not isinstance(functions, list):
             functions = [functions]
-        GenOO.__init__(self, udir, translator, backend_mapping = backend_mapping, pending_graphs = [
-            translator.annotator.bookkeeper.getdesc(f).cachedgraph(None) for f in functions ])
-        self.translator = translator
+        GenOO.__init__(self, udir, translator, None)
+
+        pending_graphs = [translator.annotator.bookkeeper.getdesc(f).cachedgraph(None) for f in functions ]
+        for graph in pending_graphs:
+            self.db.pending_function(graph)
+
         self.db.translator = translator
         self.use_debug = use_debug
+        self.assembly_name = self.translator.graphs[0].name        
+        self.tmpfile = udir.join(self.assembly_name + '.js')
     
     def gen_pendings(self):
         while self.db._pending_nodes:
@@ -72,6 +87,21 @@
         """
         for proxy in self.db.proxies:
             proxy.render(self.ilasm)
+
+
+    def create_assembler(self):
+        out = self.tmpfile.open('w')        
+        return AsmGen(out, self.assembly_name)
+
+    def generate_source(self):
+        self.ilasm = self.create_assembler()
+        self.fix_names()
+        self.gen_entrypoint()
+        while self.db._pending_nodes:
+            self.gen_pendings()
+            self.db.gen_constants(self.ilasm)
+        self.ilasm.close()
+        return self.tmpfile.strpath
         
     def write_source(self):
         
@@ -87,7 +117,7 @@
         f = self.tmpfile.open("w")
         s = open(src_filename).read()
         f.write(s)
-        self.ilasm = self.backend_mapping['asm_class'](f, self.assembly_name )
+        self.ilasm = AsmGen(f, self.assembly_name )
         self.generate_communication_proxy()
         f.write(data)
         f.close()

Modified: pypy/dist/pypy/translator/oosupport/genoo.py
==============================================================================
--- pypy/dist/pypy/translator/oosupport/genoo.py	(original)
+++ pypy/dist/pypy/translator/oosupport/genoo.py	Mon Oct 30 15:46:41 2006
@@ -1,79 +1,63 @@
-
 """ basic oogenerator
 """
+from pypy.config.config import Config
+from pypy.config.pypyoption import pypy_optiondescription
 
-class Tee(object):
-    def __init__(self, *args):
-        self.outfiles = args
-
-    def write(self, s):
-        for outfile in self.outfiles:
-            outfile.write(s)
-
-    def close(self):
-        for outfile in self.outfiles:
-            if outfile is not sys.stdout:
-                outfile.close()
 
 class GenOO(object):
-    def __init__(self, tmpdir, translator, entrypoint=None, backend_mapping=None, pending_graphs = [],\
-        stdout = False):
-        
-        self.stdout = stdout
-        self.backend_mapping = backend_mapping
-    #def __init__(self, tmpdir, translator, entrypoint=None, type_system_class=CTS,
-    #             opcode_dict=opcodes, name_suffix='.il', function_class=Function,
-    #             database_class = LowLevelDatabase, pending_graphs=()):
+    TypeSystem = None
+    Function = None
+    Database = None
+    opcodes = None
+    log = None
+
+    def __init__(self, tmpdir, translator, entrypoint, config=None):
         self.tmpdir = tmpdir
         self.translator = translator
         self.entrypoint = entrypoint
-        self.db = self.backend_mapping['database_class'](self.backend_mapping)
-
-        for graph in pending_graphs:
-            self.db.pending_function(graph)
-
-        if entrypoint is None:
-            self.assembly_name = self.translator.graphs[0].name
-        else:
-            self.assembly_name = entrypoint.get_name()
-
-        self.tmpfile = tmpdir.join(self.assembly_name + self.backend_mapping['name_suffix'])
+        self.db = self.Database(self)
+        if config is None:
+            config = Config(pypy_optiondescription)
+        self.config = config
 
     def generate_source(self):
-        out = self.tmpfile.open('w')
-        if self.stdout:
-            out = Tee(sys.stdout, out)
-
-        self.ilasm = self.backend_mapping['asm_class'](out, self.assembly_name )
-        
-        # TODO: instance methods that are also called as unbound
-        # methods are rendered twice, once within the class and once
-        # as an external function. Fix this.
+        self.ilasm = self.create_assembler()
         self.fix_names()
         self.gen_entrypoint()
-        while self.db._pending_nodes:
-            self.gen_pendings()
-            self.db.gen_constants(self.ilasm)
-        out.close()
-        return self.tmpfile.strpath
+        self.gen_pendings()
+        self.db.gen_constants(self.ilasm)
+        self.ilasm.close()
 
     def gen_entrypoint(self):
         if self.entrypoint:
-            self.entrypoint.db = self.db
+            self.entrypoint.set_db(self.db)
             self.db.pending_node(self.entrypoint)
         else:
             self.db.pending_function(self.translator.graphs[0])
 
     def gen_pendings(self):
+        n = 0
         while self.db._pending_nodes:
             node = self.db._pending_nodes.pop()
             node.render(self.ilasm)
+            self.db._rendered_nodes.add(node)
+            n+=1
+            if (n%100) == 0:
+                total = len(self.db._pending_nodes) + n
+                self.log.graphs('Rendered %d/%d (approx. %.2f%%)' %\
+                           (n, total, n*100.0/total))
 
     def fix_names(self):
         # it could happen that two distinct graph have the same name;
         # here we assign an unique name to each graph.
         names = set()
         for graph in self.translator.graphs:
+            base_name = graph.name
+            i = 0
             while graph.name in names:
-                graph.name += '_'
+                graph.name = '%s_%d' % (base_name, i)
+                i+=1
             names.add(graph.name)
+
+    def create_assembler(self):
+        raise NotImplementedError



More information about the Pypy-commit mailing list