[pypy-svn] r15110 - in pypy/dist/pypy: interpreter objspace/std rpython translator/goal

hpk at codespeak.net hpk at codespeak.net
Tue Jul 26 14:29:44 CEST 2005


Author: hpk
Date: Tue Jul 26 14:29:42 2005
New Revision: 15110

Added:
   pypy/dist/pypy/rpython/error.py   (contents, props changed)
Modified:
   pypy/dist/pypy/interpreter/baseobjspace.py
   pypy/dist/pypy/objspace/std/longobject.py
   pypy/dist/pypy/rpython/rclass.py
   pypy/dist/pypy/rpython/rconstantdict.py
   pypy/dist/pypy/rpython/rdict.py
   pypy/dist/pypy/rpython/rlist.py
   pypy/dist/pypy/rpython/rmodel.py
   pypy/dist/pypy/rpython/rpbc.py
   pypy/dist/pypy/rpython/rtyper.py
   pypy/dist/pypy/translator/goal/translate_pypy.py
Log:
(hpk,pedronis)

- making rtyping more robust by 
  - Repr's now have a more controled way of
    initialization/setup phases 
  - more strictly tracking and flagging RTyper problems. 
  - factoring out the typer error printing to
    dump_typererrors() 

- "-fork" now checks that there are no random rpython 
  modules imported.  Some related changes like 
  factoring out a 'pypy/rpython/error.py' module 
  so that 'rmodel.py' doesn't need to imported 
  at pre-fork time. 

- longobject.py now doesn't have debugging on by default
  because the annotator doesn't like that and we are 
  running translation from the trunk currently. 



Modified: pypy/dist/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/dist/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/dist/pypy/interpreter/baseobjspace.py	Tue Jul 26 14:29:42 2005
@@ -197,8 +197,8 @@
             return PythonCompiler(self)
         elif self.options.compiler == 'cpython':
             return CPythonCompiler(self)
-        elif self.options.compiler == 'pyparseapp':
-            return PythonCompilerApp(self)
+        #elif self.options.compiler == 'pyparseapp':
+        #    return PythonCompilerApp(self)
         else:
             raise ValueError('unknown --compiler option value: %r' % (
                 self.options.compiler,))

Modified: pypy/dist/pypy/objspace/std/longobject.py
==============================================================================
--- pypy/dist/pypy/objspace/std/longobject.py	(original)
+++ pypy/dist/pypy/objspace/std/longobject.py	Tue Jul 26 14:29:42 2005
@@ -63,7 +63,7 @@
 # False == no checking at all
 # True == check 0 <= value <= MASK
 
-CHECK_DIGITS = True
+CHECK_DIGITS = False # True
 
 if CHECK_DIGITS:
     class DigitArray(list):

Added: pypy/dist/pypy/rpython/error.py
==============================================================================
--- (empty file)
+++ pypy/dist/pypy/rpython/error.py	Tue Jul 26 14:29:42 2005
@@ -0,0 +1,10 @@
+
+class TyperError(Exception):
+    def __str__(self):
+        result = Exception.__str__(self)
+        if hasattr(self, 'where'):
+            result += '\n.. %r\n.. %r' % self.where
+        return result
+
+class MissingRTypeOperation(TyperError):
+    pass

Modified: pypy/dist/pypy/rpython/rclass.py
==============================================================================
--- pypy/dist/pypy/rpython/rclass.py	(original)
+++ pypy/dist/pypy/rpython/rclass.py	Tue Jul 26 14:29:42 2005
@@ -66,7 +66,7 @@
         else:
             result = ClassRepr(rtyper, classdef)
         rtyper.class_reprs[classdef] = result
-        rtyper.reprs_must_call_setup.append(result)
+        rtyper.add_pendingsetup(result)
     return result
 
 def getinstancerepr(rtyper, classdef):
@@ -79,7 +79,7 @@
         else:
             result = InstanceRepr(rtyper,classdef)
         rtyper.instance_reprs[classdef] = result
-        rtyper.reprs_must_call_setup.append(result)
+        rtyper.add_pendingsetup(result)
     return result
 
 class MissingRTypeAttribute(TyperError):
@@ -93,8 +93,6 @@
 
 
 class ClassRepr(Repr):
-    initialized = False
-
     def __init__(self, rtyper, classdef):
         self.rtyper = rtyper
         self.classdef = classdef
@@ -112,11 +110,7 @@
             cls = self.classdef.cls
         return '<ClassRepr for %s.%s>' % (cls.__module__, cls.__name__)
 
-    def setup(self):
-        if self.initialized:
-            assert self.initialized == True
-            return
-        self.initialized = "in progress"
+    def _setup_repr(self):
         # NOTE: don't store mutable objects like the dicts below on 'self'
         #       before they are fully built, to avoid strange bugs in case
         #       of recursion where other code would uses these
@@ -158,7 +152,6 @@
         self.pbcfields = pbcfields
         self.allmethods = allmethods
         self.vtable = None
-        self.initialized = True
 
     def prepare_method(self, name, s_value, allmethods):
         # special-casing for methods:
@@ -345,8 +338,6 @@
 
 
 class InstanceRepr(Repr):
-    initialized = False
-
     def __init__(self, rtyper, classdef):
         self.rtyper = rtyper
         self.classdef = classdef
@@ -364,11 +355,7 @@
             cls = self.classdef.cls
         return '<InstanceRepr for %s.%s>' % (cls.__module__, cls.__name__)
 
-    def setup(self):
-        if self.initialized:
-            assert self.initialized == True
-            return
-        self.initialized = "in progress"
+    def _setup_repr(self):
         # NOTE: don't store mutable objects like the dicts below on 'self'
         #       before they are fully built, to avoid strange bugs in case
         #       of recursion where other code would uses these
@@ -401,9 +388,8 @@
         self.fields = fields
         self.allinstancefields = allinstancefields
         attachRuntimeTypeInfo(self.object_type)
-        self.initialized = True
 
-    def setup_final_touch(self):
+    def _setup_repr_final(self):
         self.rtyper.attachRuntimeTypeInfoFunc(self.object_type,
                                               ll_runtime_type_info,
                                               OBJECT)

Modified: pypy/dist/pypy/rpython/rconstantdict.py
==============================================================================
--- pypy/dist/pypy/rpython/rconstantdict.py	(original)
+++ pypy/dist/pypy/rpython/rconstantdict.py	Tue Jul 26 14:29:42 2005
@@ -30,7 +30,7 @@
         self.value_repr = value_repr  
         self.dict_cache = {}
 
-    def setup(self):
+    def _setup_repr(self):
         if isinstance(self.CONSTANTDICT, lltype.ForwardReference):
             self.DICTKEY = self.key_repr.lowleveltype
             self.DICTVALUE = self.value_repr.lowleveltype

Modified: pypy/dist/pypy/rpython/rdict.py
==============================================================================
--- pypy/dist/pypy/rpython/rdict.py	(original)
+++ pypy/dist/pypy/rpython/rdict.py	Tue Jul 26 14:29:42 2005
@@ -67,7 +67,7 @@
         self.dict_cache = {}
         # setup() needs to be called to finish this initialization
 
-    def setup(self):
+    def _setup_repr(self):
         if 'value_repr' not in self.__dict__:
             self.value_repr = self._value_repr_computer()
         if isinstance(self.STRDICT, lltype.GcForwardReference):

Modified: pypy/dist/pypy/rpython/rlist.py
==============================================================================
--- pypy/dist/pypy/rpython/rlist.py	(original)
+++ pypy/dist/pypy/rpython/rlist.py	Tue Jul 26 14:29:42 2005
@@ -57,7 +57,7 @@
         self.list_cache = {}
         # setup() needs to be called to finish this initialization
 
-    def setup(self):
+    def _setup_repr(self):
         if 'item_repr' not in self.__dict__:
             self.item_repr = self._item_repr_computer()
         if isinstance(self.LIST, GcForwardReference):

Modified: pypy/dist/pypy/rpython/rmodel.py
==============================================================================
--- pypy/dist/pypy/rpython/rmodel.py	(original)
+++ pypy/dist/pypy/rpython/rmodel.py	Tue Jul 26 14:29:42 2005
@@ -5,7 +5,15 @@
 from pypy.rpython.lltype import typeOf, LowLevelType, Ptr, PyObject
 from pypy.rpython.lltype import FuncType, functionptr
 from pypy.tool.ansi_print import ansi_print
+from pypy.rpython.error import TyperError, MissingRTypeOperation 
 
+# initialization states for Repr instances 
+
+class setupstate: 
+    NOTINITIALIZED = 0 
+    INPROGRESS = 1
+    BROKEN = 2 
+    FINISHED = 3 
 
 class Repr:
     """ An instance of Repr is associated with each instance of SomeXxx.
@@ -16,27 +24,66 @@
     iterating over.
     """
     __metaclass__ = extendabletype
+    _initialized = setupstate.NOTINITIALIZED 
 
     def __repr__(self):
         return '<%s %s>' % (self.__class__.__name__, self.lowleveltype)
 
-    def setup(self):
+    def setup(self): 
+        """ call _setup_repr() and keep track of the initializiation
+            status to e.g. detect recursive _setup_repr invocations.
+            the '_initialized' attr has four states: 
+        """
+        if self._initialized == setupstate.FINISHED: 
+            return 
+        elif self._initialized == setupstate.BROKEN: 
+            raise BrokenReprTyperError(
+                "cannot setup already failed Repr: %r" %(self,))
+        elif self._initialized == setupstate.INPROGRESS: 
+            raise AssertionError(
+                "recursive invocation of Repr setup(): %r" %(self,))
+        assert self._initialized == setupstate.NOTINITIALIZED 
+        self._initialized = setupstate.INPROGRESS 
+        try: 
+            self._setup_repr() 
+        except TyperError, e: 
+            self._initialized = setupstate.BROKEN 
+            raise 
+        else: 
+            self._initialized = setupstate.FINISHED 
+
+    def _setup_repr(self):
         "For recursive data structure, which must be initialized in two steps."
 
-    def setup_final_touch(self):
+    def setup_final(self):
         """Same as setup(), called a bit later, for effects that are only
         needed after the typer finished (as opposed to needed for other parts
         of the typer itself)."""
+        if self._initialized == setupstate.BROKEN: 
+            raise BrokenReprTyperError("cannot perform setup_final_touch "
+                             "on failed Repr: %r" %(self,))
+        assert self._initialized == setupstate.FINISHED, (
+                "setup_final() on repr with state %s: %r" %
+                (self._initialized, self))
+        self._setup_repr_final() 
+
+    def _setup_repr_final(self): 
+        pass 
 
     def __getattr__(self, name):
         # Assume that when an attribute is missing, it's because setup() needs
         # to be called
-        self.setup()
-        try:
-            return self.__dict__[name]
-        except KeyError:
-            raise AttributeError("%s instance has no attribute %s" % (
-                self.__class__.__name__, name))
+        if name[:2] != '__' or name[-2:] != '__': 
+            if self._initialized != setupstate.NOTINITIALIZED: 
+                warning("__getattr__ %r in strange state %r" %(name, self,))
+            else: 
+                self.setup()
+                try:
+                    return self.__dict__[name]
+                except KeyError:
+                    pass
+        raise AttributeError("%s instance has no attribute %s" % (
+            self.__class__.__name__, name))
 
     def _freeze_(self):
         return True
@@ -148,15 +195,6 @@
 
 # ____________________________________________________________
 
-class TyperError(Exception):
-    def __str__(self):
-        result = Exception.__str__(self)
-        if hasattr(self, 'where'):
-            result += '\n.. %r\n.. %r' % self.where
-        return result
-
-class MissingRTypeOperation(TyperError):
-    pass
 
 def missing_rtype_operation(self, hop):
     raise MissingRTypeOperation("unimplemented operation: '%s' on %r" % (
@@ -240,6 +278,11 @@
     c.concretetype = lltype
     return c
 
+class BrokenReprTyperError(TyperError): 
+    """ raised when trying to setup a Repr whose setup 
+        has failed already. 
+    """
+
 # __________ utilities __________
 
 PyObjPtr = Ptr(PyObject)

Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py	(original)
+++ pypy/dist/pypy/rpython/rpbc.py	Tue Jul 26 14:29:42 2005
@@ -127,7 +127,7 @@
         except KeyError:
             result = MultipleFrozenPBCRepr(rtyper, access)
             rtyper.pbc_reprs[access] = result
-            rtyper.reprs_must_call_setup.append(result)
+            rtyper.add_pendingsetup(result) 
             return result
 
 
@@ -183,8 +183,6 @@
 
 class MultipleFrozenPBCRepr(Repr):
     """Representation selected for multiple non-callable pre-built constants."""
-    initialized = False
-
     def __init__(self, rtyper, access_set):
         self.rtyper = rtyper
         self.access_set = access_set
@@ -192,11 +190,7 @@
         self.lowleveltype = Ptr(self.pbc_type)
         self.pbc_cache = {}
 
-    def setup(self):
-        if self.initialized:
-            assert self.initialized == True
-            return
-        self.initialized = "in progress"
+    def _setup_repr(self):
         llfields = []
         llfieldmap = {}
         if self.access_set is not None:
@@ -210,7 +204,6 @@
                 llfieldmap[attr] = mangled_name, r_value
         self.pbc_type.become(Struct('pbc', *llfields))
         self.llfieldmap = llfieldmap
-        self.initialized = True
 
     def convert_const(self, pbc):
         if pbc is None:

Modified: pypy/dist/pypy/rpython/rtyper.py
==============================================================================
--- pypy/dist/pypy/rpython/rtyper.py	(original)
+++ pypy/dist/pypy/rpython/rtyper.py	Tue Jul 26 14:29:42 2005
@@ -24,7 +24,9 @@
 from pypy.rpython.lltype import attachRuntimeTypeInfo, Primitive
 from pypy.tool.sourcetools import func_with_new_name, valid_identifier
 from pypy.translator.unsimplify import insert_empty_block
-from pypy.rpython.rmodel import Repr, inputconst, TyperError, getfunctionptr
+from pypy.rpython.rmodel import Repr, inputconst
+from pypy.rpython.rmodel import TyperError, BrokenReprTyperError
+from pypy.rpython.rmodel import getfunctionptr, warning
 from pypy.rpython.normalizecalls import perform_normalizations
 from pypy.rpython.annlowlevel import annotate_lowlevel_helper
 from pypy.rpython.exceptiondata import ExceptionData
@@ -38,7 +40,8 @@
     def __init__(self, annotator):
         self.annotator = annotator
         self.reprs = {}
-        self.reprs_must_call_setup = []
+        self._reprs_must_call_setup = []
+        self._seen_reprs_must_call_setup = {}
         self.specialized_ll_functions = {}
         self.class_reprs = {}
         self.instance_reprs = {}
@@ -71,8 +74,14 @@
             print '*' * len(s)
         self.crash_on_first_typeerror = True
 
-
-
+    def add_pendingsetup(self, repr): 
+        assert isinstance(repr, Repr)
+        if repr in self._seen_reprs_must_call_setup: 
+            warning("ignoring already seen repr for setup: %r" %(repr,))
+            return 
+        self._reprs_must_call_setup.append(repr) 
+        self._seen_reprs_must_call_setup[repr] = True 
+        
     def getexceptiondata(self):
         return self.exceptiondata    # built at the end of specialize()
 
@@ -88,7 +97,7 @@
                 "missing a Ptr in the type specification "
                 "of %s:\n%r" % (s_obj, result.lowleveltype))
             self.reprs[key] = result
-            self.reprs_must_call_setup.append(result)
+            self.add_pendingsetup(result)
         return result
 
     def binding(self, var):
@@ -153,35 +162,43 @@
             # make sure all reprs so far have had their setup() called
             self.call_all_setups()
 
-        if self.typererrors:
-            c = 1
-            for err in self.typererrors:
-                block, position = err.where
-                func = self.annotator.annotated.get(block, None)
-                if func:
-                    func = "(%s:%s)" %(func.__module__ or '?', func.__name__)
-                else:
-                    func = "(?:?)"
-                print "TyperError-%d: %s" % (c, func)
-                print str(err)
-                print ""
-                c += 1
+        if self.typererrors: 
+            self.dump_typererrors() 
             raise TyperError("there were %d error" % len(self.typererrors))
-        
         # make sure that the return variables of all graphs are concretetype'd
         for graph in self.annotator.translator.flowgraphs.values():
             v = graph.getreturnvar()
             self.setconcretetype(v)
 
+    def dump_typererrors(self, num=None, minimize=True): 
+        c = 0
+        bc = 0
+        for err in self.typererrors[:num]: 
+            c += 1
+            if minimize and isinstance(err, BrokenReprTyperError): 
+                bc += 1
+                continue
+            block, position = err.where
+            func = self.annotator.annotated.get(block, None)
+            if func:
+                func = "(%s:%s)" %(func.__module__ or '?', func.__name__)
+            else:
+                func = "(?:?)"
+            print "TyperError-%d: %s" % (c, func)
+            print str(err)
+            print ""
+        if bc: 
+            print "(minimized %d errors away for this dump)" % (bc,)
+
     def call_all_setups(self):
         # make sure all reprs so far have had their setup() called
         must_setup_more = []
-        while self.reprs_must_call_setup:
-            r = self.reprs_must_call_setup.pop()
+        while self._reprs_must_call_setup:
+            r = self._reprs_must_call_setup.pop()
             r.setup()
             must_setup_more.append(r)
         for r in must_setup_more:
-            r.setup_final_touch()
+            r.setup_final()
 
     def setconcretetype(self, v):
         assert isinstance(v, Variable)

Modified: pypy/dist/pypy/translator/goal/translate_pypy.py
==============================================================================
--- pypy/dist/pypy/translator/goal/translate_pypy.py	(original)
+++ pypy/dist/pypy/translator/goal/translate_pypy.py	Tue Jul 26 14:29:42 2005
@@ -76,7 +76,7 @@
 from pypy.tool.ansi_print import ansi_print
 from pypy.translator.pickle.main import load, save
 # catch TyperError to allow for post-mortem dump
-from pypy.rpython.rmodel import TyperError
+from pypy.rpython.error import TyperError
 
 # XXX this tries to make compiling faster
 from pypy.translator.tool import buildpyxmodule
@@ -112,6 +112,7 @@
         a.simplify()
     if a and options['-fork']:
         from pypy.translator.goal import unixcheckpoint
+        assert_rpython_mostly_not_imported() 
         unixcheckpoint.restartable_point(auto='run')
     if a and not options['-no-t']:
         print 'Specializing...'
@@ -123,6 +124,19 @@
     if a:
         t.frozen = True   # cannot freeze if we don't have annotations
 
+def assert_rpython_mostly_not_imported(): 
+    prefix = 'pypy.rpython.'
+    oknames = 'rarithmetic extfunctable lltype objectmodel error'.split() 
+    wrongimports = []
+    for name, module in sys.modules.items(): 
+        if module is not None and name.startswith(prefix): 
+            sname = name[len(prefix):]
+            if sname not in oknames: 
+                wrongimports.append(name) 
+    if wrongimports: 
+       raise RuntimeError("cannot fork because improper rtyper code"
+                          " has already been imported: %r" %(wrongimports,))
+                
 def sanity_check_exceptblocks(translator):
     annotator = translator.annotator
     irreg = 0



More information about the Pypy-commit mailing list