[pypy-svn] r29658 - pypy/dist/pypy/translator/cli

antocuni at codespeak.net antocuni at codespeak.net
Wed Jul 5 22:59:21 CEST 2006


Author: antocuni
Date: Wed Jul  5 22:59:18 2006
New Revision: 29658

Modified:
   pypy/dist/pypy/translator/cli/database.py
   pypy/dist/pypy/translator/cli/ilgenerator.py
Log:
New protocol for initializing constants: first all objects are
instantiated (i.e., they are created with a 'new'), then initialized.




Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py	(original)
+++ pypy/dist/pypy/translator/cli/database.py	Wed Jul  5 22:59:18 2006
@@ -135,10 +135,18 @@
                 ilasm.field(const.name, const.get_type(), static=True)
 
             ilasm.begin_function('step%d' % step, [], 'void', False, 'static')
+
+            # instantiation
+            for const in pending_consts.itervalues():
+                type_ = const.get_type()
+                const.instantiate(ilasm)
+                ilasm.store_static_constant(type_, CONST_NAMESPACE, CONST_CLASS, const.name)
+
+            # initialization
             for const in pending_consts.itervalues():
-                const.init(ilasm)
                 type_ = const.get_type()
-                ilasm.set_static_field (type_, CONST_NAMESPACE, CONST_CLASS, const.name)
+                ilasm.load_static_constant(type_, CONST_NAMESPACE, CONST_CLASS, const.name)
+                const.init(ilasm)
 
             ilasm.ret()
             ilasm.end_function()
@@ -218,8 +226,20 @@
     def get_type(self):
         pass
 
+    def instantiate(self, ilasm):
+        """
+        Instantiate the the object which represent the constant and
+        leave a reference to it on the stack.
+        """
+        raise NotImplementedError
+
     def init(self, ilasm):
-        pass
+        """
+        Do some sort of extra initialization, if needed. It assume the
+        object to be initialized is on the stack. Don't leave anything
+        on the stack.
+        """
+        ilasm.opcode('pop')
 
 class StringConst(AbstractConst):
     def __init__(self, db, string, count):
@@ -237,12 +257,13 @@
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(ootype.String, include_class)
 
-    def init(self, ilasm):
+    def instantiate(self, ilasm):
         if self.string._str is None:
             ilasm.opcode('ldnull')
         else:
             ilasm.opcode('ldstr', '"%s"' % self.string._str)
 
+
 class RecordConst(AbstractConst):
     def __init__(self, db, record, count):
         self.db = db
@@ -259,13 +280,16 @@
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.record._TYPE, include_class)
 
-    def init(self, ilasm):
+    def instantiate(self, ilasm):
         if self.record is ootype.null(self.record._TYPE):
             ilasm.opcode('ldnull')
             return
 
         class_name = self.get_type(False)
         ilasm.new('instance void class %s::.ctor()' % class_name)
+
+    def init(self, ilasm):
+        class_name = self.get_type(False)        
         for f_name, (FIELD_TYPE, f_default) in self.record._TYPE._fields.iteritems():
             if FIELD_TYPE is not ootype.Void:
                 f_type = self.cts.lltype_to_cts(FIELD_TYPE)
@@ -273,6 +297,7 @@
                 ilasm.opcode('dup')
                 AbstractConst.load(self.db, FIELD_TYPE, value, ilasm)            
                 ilasm.set_field((f_type, class_name, f_name))
+        ilasm.opcode('pop')
 
 class StaticMethodConst(AbstractConst):
     def __init__(self, db, sm, count):
@@ -290,7 +315,7 @@
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.sm._TYPE, include_class)
 
-    def init(self, ilasm):
+    def instantiate(self, ilasm):
         if self.sm is ootype.null(self.sm._TYPE):
             ilasm.opcode('ldnull')
             return
@@ -317,7 +342,7 @@
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.class_._TYPE, include_class)
 
-    def init(self, ilasm):
+    def instantiate(self, ilasm):
         INSTANCE = self.class_._INSTANCE
         if INSTANCE is None:
             ilasm.opcode('ldnull')
@@ -342,20 +367,25 @@
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.list._TYPE, include_class)
 
-    def init(self, ilasm):
+    def instantitate(self, ilasm):
         if not self.list: # it is a null list
             ilasm.opcode('ldnull')
             return
 
         class_name = self.get_type(False)
+        ilasm.new('instance void class %s::.ctor()' % class_name)
+
+    def init(self, ilasm):
+        if not self.list:
+            ilasm.opcode('pop')
+            return
+
         ITEMTYPE = self.list._TYPE._ITEMTYPE
         itemtype = self.cts.lltype_to_cts(ITEMTYPE)
         itemtype_T = self.cts.lltype_to_cts(self.list._TYPE.ITEMTYPE_T)
-        ilasm.new('instance void class %s::.ctor()' % class_name)
 
         # special case: List(Void); only resize it, don't care of the contents
         if ITEMTYPE is ootype.Void:
-            ilasm.opcode('dup')
             AbstractConst.load(self.db, ootype.Signed, len(self.list._list), ilasm)            
             meth = 'void class %s::_ll_resize(int32)' % PYPY_LIST_OF_VOID
             ilasm.call_method(meth, False)
@@ -366,7 +396,7 @@
             AbstractConst.load(self.db, ITEMTYPE, item, ilasm)
             meth = 'void class [pypylib]pypy.runtime.List`1<%s>::Add(%s)' % (itemtype, itemtype_T)
             ilasm.call_method(meth, False)
-
+        ilasm.opcode('pop')
 
 class DictConst(AbstractConst):
     def __init__(self, db, dict_, count):
@@ -384,12 +414,20 @@
     def get_type(self, include_class=True):
         return self.cts.lltype_to_cts(self.dict._TYPE, include_class)
 
-    def init(self, ilasm):
+    def instantiate(self, ilasm):
         if not self.dict: # it is a null dict
             ilasm.opcode('ldnull')
             return
 
         class_name = self.get_type(False)
+        ilasm.new('instance void class %s::.ctor()' % class_name)
+        
+    def init(self, ilasm):
+        if not self.dict:
+            ilasm.opcode('pop')
+            return
+        
+        class_name = self.get_type(False)
         KEYTYPE = self.dict._TYPE._KEYTYPE
         keytype = self.cts.lltype_to_cts(KEYTYPE)
         keytype_T = self.cts.lltype_to_cts(self.dict._TYPE.KEYTYPE_T)
@@ -397,8 +435,6 @@
         VALUETYPE = self.dict._TYPE._VALUETYPE
         valuetype = self.cts.lltype_to_cts(VALUETYPE)
         valuetype_T = self.cts.lltype_to_cts(self.dict._TYPE.VALUETYPE_T)
-        
-        ilasm.new('instance void class %s::.ctor()' % class_name)
 
         if KEYTYPE is ootype.Void:
             assert False, "gencli doesn't support dict with void keys"
@@ -411,6 +447,7 @@
                 AbstractConst.load(self.db, KEYTYPE, key, ilasm)
                 meth = 'void class %s::ll_set(%s)' % (class_name, keytype_T)
                 ilasm.call_method(meth, False)
+            ilasm.opcode('pop')
             return
 
         for key, value in self.dict._dict.iteritems():
@@ -420,6 +457,7 @@
             meth = 'void class [pypylib]pypy.runtime.Dict`2<%s, %s>::ll_set(%s, %s)' %\
                    (keytype, valuetype, keytype_T, valuetype_T)
             ilasm.call_method(meth, False)
+        ilasm.opcode('pop')
 
 
 class InstanceConst(AbstractConst):
@@ -444,21 +482,29 @@
     def get_type(self):
         return self.cts.lltype_to_cts(self.static_type)
 
-    def init(self, ilasm):
+    def instantiate(self, ilasm):
         if not self.obj:
+            import pdb; pdb.set_trace()            
             ilasm.opcode('ldnull')
             return
 
         classdef = self.obj._TYPE        
         ilasm.new('instance void class %s::.ctor()' % classdef._name)
-        while classdef is not None:
-            for name, (TYPE, default) in classdef._fields.iteritems():
+
+    def init(self, ilasm):
+        if not self.obj:
+            ilasm.opcode('pop')
+            return
+
+        INSTANCE = self.obj._TYPE
+        while INSTANCE is not None:
+            for name, (TYPE, default) in INSTANCE._fields.iteritems():
                 if TYPE is ootype.Void:
                     continue
                 value = getattr(self.obj, name)
                 type_ = self.cts.lltype_to_cts(TYPE)
                 ilasm.opcode('dup')
                 AbstractConst.load(self.db, TYPE, value, ilasm)
-                ilasm.opcode('stfld %s %s::%s' % (type_, classdef._name, name))
-            classdef = classdef._superclass
-
+                ilasm.opcode('stfld %s %s::%s' % (type_, INSTANCE._name, name))
+            INSTANCE = INSTANCE._superclass
+        ilasm.opcode('pop')

Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py	(original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py	Wed Jul  5 22:59:18 2006
@@ -151,9 +151,6 @@
 
     def get_field(self, field_data):
         self.opcode('ldfld %s %s::%s' % field_data )
-
-    def load_static_field(self, cts_type, name):
-        self.opcode('ldsfld %s %s' % (cts_type, name))
     
     def throw(self):
         self.opcode('throw')
@@ -191,8 +188,14 @@
     def store_local ( self , v ):
         self.opcode('stloc', repr(v.name))
 
-    def set_static_field ( self, type_, CONST_NAMESPACE, CONST_CLASS, name ):
-        self.opcode('stsfld %s %s.%s::%s' % (type_, CONST_NAMESPACE, CONST_CLASS, name))
+    def store_static_constant(self, cts_type, CONST_NAMESPACE, CONST_CLASS, name):
+        self.opcode('stsfld %s %s.%s::%s' % (cts_type, CONST_NAMESPACE, CONST_CLASS, name))
+
+    def load_static_constant(self, cts_type, CONST_NAMESPACE, CONST_CLASS, name):
+        self.opcode('ldsfld %s %s.%s::%s' % (cts_type, CONST_NAMESPACE, CONST_CLASS, name))
+
+    def load_static_field(self, cts_type, name):
+        self.opcode('ldsfld %s %s' % (cts_type, name))
 
     def emit ( self , opcode , *args ):
         self.opcode ( opcode , *args )



More information about the Pypy-commit mailing list