Commits

Antonio Cuni committed 387deab

General refactoring of constants generation. Now AbstractConst is an
instance of Node and constants are treated as other pending nodes. The
difference is that they are not render()ed, but instead they are
stored in the db to be rendered all togheter at the end of code
generation.

Comments (0)

Files changed (5)

pypy/translator/cli/class_.py

         self.cts = db.type_system_class(db)
         self.classdef = classdef
         self.namespace, self.name = self.cts.split_class_name(classdef._name)
-        
-        if not self.is_root(classdef):
-            self.db.pending_class(classdef._superclass)
+
+    def dependencies(self):
+        if not self.is_root(self.classdef):
+            self.db.pending_class(self.classdef._superclass)
 
     def __hash__(self):
         return hash(self.classdef)
     def get_name(self):
         return self.name
 
+    def __repr__(self):
+        return '<Class %s>' % self.name
+
     def get_base_class(self):
         base_class = self.classdef._superclass
         if self.is_root(base_class):

pypy/translator/cli/database.py

 from pypy.translator.cli.function import Function
 from pypy.translator.cli.class_ import Class
 from pypy.translator.cli.record import Record
+from pypy.translator.cli.node import Node
 from pypy.rpython.ootypesystem import ootype
 from pypy.rpython.lltypesystem import lltype
 from pypy.translator.cli.opcodes import opcodes
         self.functions = {} # graph --> function_name
         self.methods = {} # graph --> method_name
         self.consts = {}  # value --> AbstractConst
-        self.pending_consts = {} # value --> AbstractConst
         self.delegates = {} # StaticMethod --> type_name
         self.const_names = set()
         self.name_count = 0
     def pending_node(self, node):
         if node in self._pending_nodes or node in self._rendered_nodes:
             return
+
         self._pending_nodes.add(node)
+        node.dependencies()
 
     def record_function(self, graph, name):
         self.functions[graph] = name
     def record_const(self, value):
         if value in self.consts:
             const = self.consts[value]
-        elif value in self.pending_consts:
-            const = self.pending_consts[value]
         else:
             const = AbstractConst.make(self, value, self.next_count())
-            self.pending_consts[value] = const
+            self.consts[value] = const
+            self.pending_node(const)
 
         return '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, const.name)
 
             ilasm.end_function()
             ilasm.end_class()
 
-    def collect_constants(self):
-        # traverse the forest of the constants to collect all the constants needed
-        while self.pending_consts:
-            pending_consts = self.pending_consts
-            self.consts.update(pending_consts)
-            self.pending_consts = {}
-            for const in pending_consts.itervalues():
-                const.dependencies()
-
     def gen_constants(self, ilasm):
         ilasm.begin_namespace(CONST_NAMESPACE)
         ilasm.begin_class(CONST_CLASS)
         ilasm.end_namespace()
 
 
-class AbstractConst(object):
+class AbstractConst(Node):
     def make(db, value, count):
         if isinstance(value, ootype._view):
             static_type = value._TYPE
     def __ne__(self, other):
         return not self == other
 
+    def __repr__(self):
+        return '<Const %s %s>' % (self.name, self.value)
+
     def get_name(self):
         pass
 
             return
         self.db.record_const(value)
 
+    def render(self, ilasm):
+        pass
+
     def dependencies(self):
         """
         Record all constants that are needed to correctly initialize
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.value._TYPE, include_class)
 
+    def dependencies(self):
+        if self.value is ootype.null(self.value._TYPE):
+            return
+        self.db.pending_function(self.value.graph)
+
     def instantiate(self, ilasm):
         if self.value is ootype.null(self.value._TYPE):
             ilasm.opcode('ldnull')
             return
-        self.db.pending_function(self.value.graph)
         signature = self.cts.graph_to_signature(self.value.graph)
         delegate_type = self.db.record_delegate_type(self.value._TYPE)
         ilasm.opcode('ldnull')
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.value._TYPE, include_class)
 
+    def dependencies(self):
+        INSTANCE = self.value._INSTANCE
+        if INSTANCE is not None:
+            self.cts.lltype_to_cts(INSTANCE) # force scheduling class generation
+
     def instantiate(self, ilasm):
         INSTANCE = self.value._INSTANCE
         if INSTANCE is None:
             ilasm.opcode('ldnull')
         else:
-            self.cts.lltype_to_cts(INSTANCE) # force scheduling class generation
             ilasm.opcode('ldtoken', INSTANCE._name)
             ilasm.call('class [mscorlib]System.Type class [mscorlib]System.Type::GetTypeFromHandle(valuetype [mscorlib]System.RuntimeTypeHandle)')
 
     def dependencies(self):
         if not self.value:
             return
+
         INSTANCE = self.value._TYPE
         while INSTANCE is not None:
             for name, (TYPE, default) in INSTANCE._fields.iteritems():
                 if TYPE is ootype.Void:
                     continue
-                type_ = self.cts.lltype_to_cts(TYPE) # record type                
+                type_ = self.cts.lltype_to_cts(TYPE) # record type
                 value = getattr(self.value, name) # record value
                 self.record_const_maybe(TYPE, value)
             INSTANCE = INSTANCE._superclass                

pypy/translator/cli/function.py

     def get_name(self):
         return self.name
 
+    def __repr__(self):
+        return '<Function %s>' % self.name
+
     def __hash__(self):
         return hash(self.graph)
 

pypy/translator/cli/gencli.py

         self.fix_names()
         self.gen_entrypoint()
         self.gen_pendings()
-        self.db.collect_constants()
-        self.db.gen_constants(self.ilasm)        
         self.db.gen_delegate_types(self.ilasm)
-        self.gen_pendings()
+        self.db.gen_constants(self.ilasm)
+
         out.close()
         return self.tmpfile.strpath
 

pypy/translator/cli/node.py

     def get_name(self):
         pass
 
+    def dependencies(self):
+        pass
+
     def render(self, ilasm):
         pass