[pypy-svn] r73854 - in pypy/trunk/pypy: objspace/flow rpython translator

benjamin at codespeak.net benjamin at codespeak.net
Sun Apr 18 01:15:46 CEST 2010


Author: benjamin
Date: Sun Apr 18 01:15:45 2010
New Revision: 73854

Modified:
   pypy/trunk/pypy/objspace/flow/flowcontext.py
   pypy/trunk/pypy/objspace/flow/model.py
   pypy/trunk/pypy/objspace/flow/objspace.py
   pypy/trunk/pypy/objspace/flow/operation.py
   pypy/trunk/pypy/rpython/rint.py
   pypy/trunk/pypy/translator/simplify.py
Log:
move things around in flowspace, to improve dependencies

It also locates more associated functionality in appropiate modules.



Modified: pypy/trunk/pypy/objspace/flow/flowcontext.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/flowcontext.py	(original)
+++ pypy/trunk/pypy/objspace/flow/flowcontext.py	Sun Apr 18 01:15:45 2010
@@ -3,18 +3,13 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter import pyframe
 from pypy.interpreter.argument import ArgumentsForTranslation
+from pypy.objspace.flow import operation
 from pypy.objspace.flow.model import *
 from pypy.objspace.flow.framestate import FrameState
 from pypy.rlib import jit
 from pypy.tool.stdlib_opcode import host_bytecode_spec
 import sys
 
-class OperationThatShouldNotBePropagatedError(OperationError):
-    pass
-
-class ImplicitOperationError(OperationError):
-    pass
-
 class StopFlowing(Exception):
     pass
 
@@ -271,13 +266,13 @@
                     self.crnt_frame = None
                     self.topframeref = old_frameref
 
-            except OperationThatShouldNotBePropagatedError, e:
+            except operation.OperationThatShouldNotBePropagatedError, e:
                 raise Exception(
                     'found an operation that always raises %s: %s' % (
                         self.space.unwrap(e.w_type).__name__,
                         self.space.unwrap(e.get_w_value(self.space))))
 
-            except ImplicitOperationError, e:
+            except operation.ImplicitOperationError, e:
                 if isinstance(e.w_type, Constant):
                     exc_cls = e.w_type.value
                 else:
@@ -380,7 +375,7 @@
 
     def sys_exc_info(self):
         operr = ExecutionContext.sys_exc_info(self)
-        if isinstance(operr, ImplicitOperationError):
+        if isinstance(operr, operation.ImplicitOperationError):
             # re-raising an implicit operation makes it an explicit one
             w_value = operr.get_w_value(self.space)
             operr = OperationError(operr.w_type, w_value)
@@ -491,7 +486,7 @@
 
     def handle_operation_error(self, ec, operr, *args, **kwds):
         # see test_propagate_attribute_error for why this is here
-        if isinstance(operr, OperationThatShouldNotBePropagatedError):
+        if isinstance(operr, operation.OperationThatShouldNotBePropagatedError):
             raise operr
         return pyframe.PyFrame.handle_operation_error(self, ec, operr,
                                                       *args, **kwds)

Modified: pypy/trunk/pypy/objspace/flow/model.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/model.py	(original)
+++ pypy/trunk/pypy/objspace/flow/model.py	Sun Apr 18 01:15:45 2010
@@ -322,6 +322,14 @@
             self.concretetype = concretetype
 
 
+class UnwrapException(Exception):
+    """Attempted to unwrap a Variable."""
+
+class WrapException(Exception):
+    """Attempted wrapping of a type that cannot sanely appear in flow graph or
+    during its construction"""
+
+
 class SpaceOperation(object):
     __slots__ = "opname args result offset".split()
 

Modified: pypy/trunk/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/objspace.py	(original)
+++ pypy/trunk/pypy/objspace/flow/objspace.py	Sun Apr 18 01:15:45 2010
@@ -6,18 +6,10 @@
 from pypy.interpreter.error import OperationError
 from pypy.interpreter import pyframe
 from pypy.objspace.flow.model import *
-from pypy.objspace.flow import flowcontext
-from pypy.objspace.flow.operation import FunctionByName
+from pypy.objspace.flow import flowcontext, operation
 from pypy.rlib.unroll import unrolling_iterable, _unroller
 from pypy.rlib import rstackovf
 
-debug = 0
-
-class UnwrapException(Exception):
-    "Attempted to unwrap a Variable."
-
-class WrapException(Exception):
-    """Attempted wrapping of a type that cannot sanely appear in flow graph or during its construction"""
 
 # method-wrappers have not enough introspection in CPython
 if hasattr(complex.real.__get__, 'im_self'):
@@ -25,6 +17,22 @@
 else:
     type_with_bad_introspection = type(complex.real.__get__)
 
+# the following gives us easy access to declare more for applications:
+NOT_REALLY_CONST = {
+    Constant(sys): {
+        Constant('maxint'): True,
+        Constant('maxunicode'): True,
+        Constant('api_version'): True,
+        Constant('exit'): True,
+        Constant('exc_info'): True,
+        Constant('getrefcount'): True,
+        Constant('getdefaultencoding'): True,
+        # this is an incomplete list of true constants.
+        # if we add much more, a dedicated class
+        # might be considered for special objects.
+        }
+    }
+
 # ______________________________________________________________________
 class FlowObjSpace(ObjSpace):
     """NOT_RPYTHON.
@@ -32,7 +40,7 @@
     the space operations that the interpreter generates when it interprets
     (the bytecode of) some function.
     """
-    
+
     full_exceptions = False
     do_imports_immediately = True
     FrameClass = flowcontext.FlowSpaceFrame
@@ -41,7 +49,8 @@
         import __builtin__
         self.concrete_mode = 1
         self.w_None     = Constant(None)
-        self.builtin    = Module(self, Constant('__builtin__'), Constant(__builtin__.__dict__))
+        self.builtin    = Module(self, Constant('__builtin__'),
+                                 Constant(__builtin__.__dict__))
         def pick_builtin(w_globals):
             return self.builtin
         self.builtin.pick_builtin = pick_builtin
@@ -301,7 +310,7 @@
 
     def do_operation_with_implicit_exceptions(self, name, *args_w):
         w_result = self.do_operation(name, *args_w)
-        self.handle_implicit_exceptions(implicit_exceptions.get(name))
+        self.handle_implicit_exceptions(operation.implicit_exceptions.get(name))
         return w_result
 
     def is_true(self, w_obj):
@@ -347,8 +356,8 @@
         if outcome is StopIteration:
             raise OperationError(self.w_StopIteration, w_exc_value)
         elif outcome is RuntimeError:
-            raise flowcontext.ImplicitOperationError(Constant(RuntimeError),
-                                                     w_exc_value)
+            raise operation.ImplicitOperationError(Constant(RuntimeError),
+                                                    w_exc_value)
         else:
             return w_item
 
@@ -404,7 +413,7 @@
         #    raise SomeError(x)
         #
         # as shown by test_objspace.test_raise3.
-        
+
         exceptions = [Exception]   # *any* exception by default
         if isinstance(w_callable, Constant):
             c = w_callable.value
@@ -414,7 +423,7 @@
                                    types.ClassType,
                                    types.TypeType)) and
                       c.__module__ in ['__builtin__', 'exceptions']):
-                    exceptions = implicit_exceptions.get(c, None)
+                    exceptions = operation.implicit_exceptions.get(c, None)
         self.handle_implicit_exceptions(exceptions)
         return w_res
 
@@ -442,8 +451,7 @@
                 #if outcome is not Exception:
                     #w_exc_cls = Constant(outcome) Now done by guessexception itself
                     #pass
-                 raise flowcontext.ImplicitOperationError(w_exc_cls,
-                                                         w_exc_value)
+                 raise operation.ImplicitOperationError(w_exc_cls, w_exc_value)
 
     def w_KeyboardInterrupt(self):
         # the reason to do this is: if you interrupt the flowing of a function
@@ -458,85 +466,8 @@
         raise RuntimeError("the interpreter raises RuntimeError during "
                            "flow graph construction")
     w_RuntimeError = prebuilt_recursion_error = property(w_RuntimeError)
+operation.add_operations(FlowObjSpace)
 
-# the following gives us easy access to declare more for applications:
-NOT_REALLY_CONST = {
-    Constant(sys): {
-        Constant('maxint'): True,
-        Constant('maxunicode'): True,
-        Constant('api_version'): True,
-        Constant('exit'): True,
-        Constant('exc_info'): True,
-        Constant('getrefcount'): True,
-        Constant('getdefaultencoding'): True,
-        # this is an incomplete list of true constants.
-        # if we add much more, a dedicated class
-        # might be considered for special objects.
-        }
-    }
-
-# ______________________________________________________________________
-
-op_appendices = {
-    OverflowError: 'ovf',
-    IndexError: 'idx',
-    KeyError: 'key',
-    AttributeError: 'att',
-    TypeError: 'typ',
-    ZeroDivisionError: 'zer',
-    ValueError: 'val',
-    }
-
-implicit_exceptions = {
-    int: [ValueError],      # built-ins that can always raise exceptions
-    float: [ValueError],
-    chr: [ValueError],
-    unichr: [ValueError],
-    unicode: [UnicodeDecodeError],
-    # specifying IndexError, and KeyError beyond Exception,
-    # allows the annotator to be more precise, see test_reraiseAnything/KeyError in
-    # the annotator tests
-    'getitem': [IndexError, KeyError, Exception],
-    'setitem': [IndexError, KeyError, Exception],
-    'delitem': [IndexError, KeyError, Exception],
-    'contains': [Exception],    # from an r_dict
-    }
-
-def _add_exceptions(names, exc):
-    for name in names.split():
-        lis = implicit_exceptions.setdefault(name, [])
-        if exc in lis:
-            raise ValueError, "your list is causing duplication!"
-        lis.append(exc)
-        assert exc in op_appendices
-
-def _add_except_ovf(names):
-    # duplicate exceptions and add OverflowError
-    for name in names.split():
-        lis = implicit_exceptions.setdefault(name, [])[:]
-        lis.append(OverflowError)
-        implicit_exceptions[name+"_ovf"] = lis
-
-for _name in 'getattr', 'delattr':
-    _add_exceptions(_name, AttributeError)
-for _name in 'iter', 'coerce':
-    _add_exceptions(_name, TypeError)
-del _name
-
-_add_exceptions("""div mod divmod truediv floordiv pow
-                   inplace_div inplace_mod inplace_divmod inplace_truediv
-                   inplace_floordiv inplace_pow""", ZeroDivisionError)
-_add_exceptions("""pow inplace_pow lshift inplace_lshift rshift
-                   inplace_rshift""", ValueError)
-_add_exceptions("""truediv divmod
-                   inplace_add inplace_sub inplace_mul inplace_truediv
-                   inplace_floordiv inplace_div inplace_mod inplace_pow
-                   inplace_lshift""", OverflowError) # without a _ovf version
-_add_except_ovf("""neg abs add sub mul
-                   floordiv div mod pow lshift""")   # with a _ovf version
-_add_exceptions("""pow""",
-                OverflowError) # for the float case
-del _add_exceptions, _add_except_ovf
 
 def extract_cell_content(c):
     """Get the value contained in a CPython 'cell', as read through
@@ -559,127 +490,5 @@
             return x.other    # crashes if the cell is actually empty
         except AttributeError:
             raise ValueError("empty cell")
-
-def make_op(name, symbol, arity, specialnames):
-    if hasattr(FlowObjSpace, name):
-        return # Shouldn't do it
-
-    import __builtin__
-
-    op = None
-    skip = False
-    arithmetic = False
-
-    if name.startswith('del') or name.startswith('set') or name.startswith('inplace_'):
-        # skip potential mutators
-        if debug: print "Skip", name
-        skip = True
-    elif name in ['id', 'hash', 'iter', 'userdel']: 
-        # skip potential runtime context dependecies
-        if debug: print "Skip", name
-        skip = True
-    elif name in ['repr', 'str']:
-        rep = getattr(__builtin__, name)
-        def op(obj):
-            s = rep(obj)
-            if s.find("at 0x") > -1:
-                print >>sys.stderr, "Warning: captured address may be awkward"
-            return s
-    else:
-        op = FunctionByName[name]
-        arithmetic = (name + '_ovf') in FunctionByName
-
-    if not op:
-        if not skip:
-            if debug: print >> sys.stderr, "XXX missing operator:", name
-    else:
-        if debug: print "Can constant-fold operation: %s" % name
-
-    def generic_operator(self, *args_w):
-        assert len(args_w) == arity, name+" got the wrong number of arguments"
-        if op:
-            args = []
-            for w_arg in args_w:
-                try:
-                    arg = self.unwrap_for_computation(w_arg)
-                except UnwrapException:
-                    break
-                else:
-                    args.append(arg)
-            else:
-                # All arguments are constants: call the operator now
-                #print >> sys.stderr, 'Constant operation', op
-                try:
-                    result = op(*args)
-                except:
-                    etype, evalue, etb = sys.exc_info()
-                    msg = "generated by a constant operation:  %s%r" % (
-                        name, tuple(args))
-                    raise flowcontext.OperationThatShouldNotBePropagatedError(
-                        self.wrap(etype), self.wrap(msg))
-                else:
-                    # don't try to constant-fold operations giving a 'long'
-                    # result.  The result is probably meant to be sent to
-                    # an intmask(), but the 'long' constant confuses the
-                    # annotator a lot.
-                    if arithmetic and type(result) is long:
-                        pass
-                    # don't constant-fold getslice on lists, either
-                    elif name == 'getslice' and type(result) is list:
-                        pass
-                    # otherwise, fine
-                    else:
-                        try:
-                            return self.wrap(result)
-                        except WrapException:
-                            # type cannot sanely appear in flow graph,
-                            # store operation with variable result instead
-                            pass
-
-        #print >> sys.stderr, 'Variable operation', name, args_w
-        w_result = self.do_operation_with_implicit_exceptions(name, *args_w)
-        return w_result
-
-    setattr(FlowObjSpace, name, generic_operator)
-
-for line in ObjSpace.MethodTable:
-    make_op(*line)
-
-"""
-This is just a placeholder for some code I'm checking in elsewhere.
-It is provenly possible to determine constantness of certain expressions
-a little later. I introduced this a bit too early, together with tieing
-this to something being global, which was a bad idea.
-The concept is still valid, and it can  be used to force something to
-be evaluated immediately because it is supposed to be a constant.
-One good possible use of this is loop unrolling.
-This will be found in an 'experimental' folder with some use cases.
-"""
-
-def override():
-    def getattr(self, w_obj, w_name):
-        # handling special things like sys
-        # unfortunately this will never vanish with a unique import logic :-(
-        if w_obj in self.not_really_const:
-            const_w = self.not_really_const[w_obj]
-            if w_name not in const_w:
-                return self.do_operation_with_implicit_exceptions('getattr', w_obj, w_name)
-        return self.regular_getattr(w_obj, w_name)
-
-    FlowObjSpace.regular_getattr = FlowObjSpace.getattr
-    FlowObjSpace.getattr = getattr
-
-    # protect us from globals write access
-    def setitem(self, w_obj, w_key, w_val):
-        ec = self.getexecutioncontext()
-        if not (ec and w_obj is ec.w_globals):
-            return self.regular_setitem(w_obj, w_key, w_val)
-        raise SyntaxError, "attempt to modify global attribute %r in %r" % (w_key, ec.graph.func)
-
-    FlowObjSpace.regular_setitem = FlowObjSpace.setitem
-    FlowObjSpace.setitem = setitem
-
-override()
-
 # ______________________________________________________________________
 # End of objspace.py

Modified: pypy/trunk/pypy/objspace/flow/operation.py
==============================================================================
--- pypy/trunk/pypy/objspace/flow/operation.py	(original)
+++ pypy/trunk/pypy/objspace/flow/operation.py	Sun Apr 18 01:15:45 2010
@@ -2,10 +2,25 @@
 This module defines mappings between operation names and Python's
 built-in functions (or type constructors) implementing them.
 """
+
+import __builtin__
+import __future__
+import operator
+import types
+import sys
 from pypy.interpreter.baseobjspace import ObjSpace
-import operator, types, __future__
+from pypy.interpreter.error import OperationError
 from pypy.tool.sourcetools import compile2
 from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift
+from pypy.objspace.flow import model
+
+
+class OperationThatShouldNotBePropagatedError(OperationError):
+    pass
+
+class ImplicitOperationError(OperationError):
+    pass
+
 
 FunctionByName = {}   # dict {"operation_name": <built-in function>}
 OperationName  = {}   # dict {<built-in function>: "operation_name"}
@@ -216,8 +231,6 @@
     ]
 
 def setup():
-    if not hasattr(operator, 'is_'):   # Python 2.2
-        Table.append(('is_', lambda x, y: x is y))
     # insert all operators
     for line in ObjSpace.MethodTable:
         name = line[0]
@@ -235,4 +248,184 @@
         Arity[name] = line[2]
         assert name in FunctionByName
 setup()
-del Table   # INTERNAL ONLY, use the dicts declared at the top of the file
+del Table, setup # INTERNAL ONLY, use the dicts declared at the top of the file
+
+op_appendices = {
+    OverflowError: 'ovf',
+    IndexError: 'idx',
+    KeyError: 'key',
+    AttributeError: 'att',
+    TypeError: 'typ',
+    ZeroDivisionError: 'zer',
+    ValueError: 'val',
+    }
+
+implicit_exceptions = {
+    int: [ValueError],      # built-ins that can always raise exceptions
+    float: [ValueError],
+    chr: [ValueError],
+    unichr: [ValueError],
+    unicode: [UnicodeDecodeError],
+    # specifying IndexError, and KeyError beyond Exception,
+    # allows the annotator to be more precise, see test_reraiseAnything/KeyError in
+    # the annotator tests
+    'getitem': [IndexError, KeyError, Exception],
+    'setitem': [IndexError, KeyError, Exception],
+    'delitem': [IndexError, KeyError, Exception],
+    'contains': [Exception],    # from an r_dict
+    }
+
+def _add_exceptions(names, exc):
+    for name in names.split():
+        lis = implicit_exceptions.setdefault(name, [])
+        if exc in lis:
+            raise ValueError, "your list is causing duplication!"
+        lis.append(exc)
+        assert exc in op_appendices
+
+def _add_except_ovf(names):
+    # duplicate exceptions and add OverflowError
+    for name in names.split():
+        lis = implicit_exceptions.setdefault(name, [])[:]
+        lis.append(OverflowError)
+        implicit_exceptions[name+"_ovf"] = lis
+
+for _name in 'getattr', 'delattr':
+    _add_exceptions(_name, AttributeError)
+for _name in 'iter', 'coerce':
+    _add_exceptions(_name, TypeError)
+del _name
+
+_add_exceptions("""div mod divmod truediv floordiv pow
+                   inplace_div inplace_mod inplace_divmod inplace_truediv
+                   inplace_floordiv inplace_pow""", ZeroDivisionError)
+_add_exceptions("""pow inplace_pow lshift inplace_lshift rshift
+                   inplace_rshift""", ValueError)
+_add_exceptions("""truediv divmod
+                   inplace_add inplace_sub inplace_mul inplace_truediv
+                   inplace_floordiv inplace_div inplace_mod inplace_pow
+                   inplace_lshift""", OverflowError) # without a _ovf version
+_add_except_ovf("""neg abs add sub mul
+                   floordiv div mod pow lshift""")   # with a _ovf version
+_add_exceptions("""pow""",
+                OverflowError) # for the float case
+del _add_exceptions, _add_except_ovf
+
+def make_op(fs, name, symbol, arity, specialnames):
+    if hasattr(fs, name):
+        return
+
+    op = None
+    skip = False
+    arithmetic = False
+
+    if (name.startswith('del') or
+        name.startswith('set') or
+        name.startswith('inplace_')):
+        # skip potential mutators
+        skip = True
+    elif name in ('id', 'hash', 'iter', 'userdel'):
+        # skip potential runtime context dependecies
+        skip = True
+    elif name in ('repr', 'str'):
+        rep = getattr(__builtin__, name)
+        def op(obj):
+            s = rep(obj)
+            if "at 0x" in s:
+                print >>sys.stderr, "Warning: captured address may be awkward"
+            return s
+    else:
+        op = FunctionByName[name]
+        arithmetic = (name + '_ovf') in FunctionByName
+
+    if not op and not skip:
+        raise ValueError("XXX missing operator: %s" % (name,))
+
+    def generic_operator(self, *args_w):
+        assert len(args_w) == arity, name + " got the wrong number of arguments"
+        if op:
+            args = []
+            for w_arg in args_w:
+                try:
+                    arg = self.unwrap_for_computation(w_arg)
+                except model.UnwrapException:
+                    break
+                else:
+                    args.append(arg)
+            else:
+                # All arguments are constants: call the operator now
+                try:
+                    result = op(*args)
+                except:
+                    etype, evalue, etb = sys.exc_info()
+                    msg = "generated by a constant operation:  %s%r" % (
+                        name, tuple(args))
+                    raise OperationThatShouldNotBePropagatedError(
+                        self.wrap(etype), self.wrap(msg))
+                else:
+                    # don't try to constant-fold operations giving a 'long'
+                    # result.  The result is probably meant to be sent to
+                    # an intmask(), but the 'long' constant confuses the
+                    # annotator a lot.
+                    if arithmetic and type(result) is long:
+                        pass
+                    # don't constant-fold getslice on lists, either
+                    elif name == 'getslice' and type(result) is list:
+                        pass
+                    # otherwise, fine
+                    else:
+                        try:
+                            return self.wrap(result)
+                        except model.WrapException:
+                            # type cannot sanely appear in flow graph,
+                            # store operation with variable result instead
+                            pass
+        w_result = self.do_operation_with_implicit_exceptions(name, *args_w)
+        return w_result
+
+    setattr(fs, name, generic_operator)
+
+
+"""
+This is just a placeholder for some code I'm checking in elsewhere.
+It is provenly possible to determine constantness of certain expressions
+a little later. I introduced this a bit too early, together with tieing
+this to something being global, which was a bad idea.
+The concept is still valid, and it can  be used to force something to
+be evaluated immediately because it is supposed to be a constant.
+One good possible use of this is loop unrolling.
+This will be found in an 'experimental' folder with some use cases.
+"""
+
+def special_overrides(fs):
+    def getattr(self, w_obj, w_name):
+        # handling special things like sys
+        # unfortunately this will never vanish with a unique import logic :-(
+        if w_obj in self.not_really_const:
+            const_w = self.not_really_const[w_obj]
+            if w_name not in const_w:
+                return self.do_operation_with_implicit_exceptions('getattr',
+                                                                  w_obj, w_name)
+        return self.regular_getattr(w_obj, w_name)
+
+    fs.regular_getattr = fs.getattr
+    fs.getattr = getattr
+
+    # protect us from globals write access
+    def setitem(self, w_obj, w_key, w_val):
+        ec = self.getexecutioncontext()
+        if not (ec and w_obj is ec.w_globals):
+            return self.regular_setitem(w_obj, w_key, w_val)
+        raise SyntaxError("attempt to modify global attribute %r in %r"
+                          % (w_key, ec.graph.func))
+
+    fs.regular_setitem = fs.setitem
+    fs.setitem = setitem
+
+
+def add_operations(fs):
+    """Add function operations to the flow space."""
+    for line in ObjSpace.MethodTable:
+        print line
+        make_op(fs, *line)
+    special_overrides(fs)

Modified: pypy/trunk/pypy/rpython/rint.py
==============================================================================
--- pypy/trunk/pypy/rpython/rint.py	(original)
+++ pypy/trunk/pypy/rpython/rint.py	Sun Apr 18 01:15:45 2010
@@ -1,7 +1,7 @@
 import sys
 from pypy.tool.pairtype import pairtype
 from pypy.annotation import model as annmodel
-from pypy.objspace.flow.objspace import op_appendices
+from pypy.objspace.flow.operation import op_appendices
 from pypy.rpython.lltypesystem.lltype import Signed, Unsigned, Bool, Float, \
      Void, Char, UniChar, malloc, pyobjectptr, UnsignedLongLong, \
      SignedLongLong, build_number, Number, cast_primitive, typeOf

Modified: pypy/trunk/pypy/translator/simplify.py
==============================================================================
--- pypy/trunk/pypy/translator/simplify.py	(original)
+++ pypy/trunk/pypy/translator/simplify.py	Sun Apr 18 01:15:45 2010
@@ -110,7 +110,7 @@
     Instead, it will be replaced by an OP_LSHIFT_OVF operation.
     """
     from pypy.rlib.rarithmetic import ovfcheck, ovfcheck_lshift
-    from pypy.objspace.flow.objspace import implicit_exceptions
+    from pypy.objspace.flow.operation import implicit_exceptions
     covf = Constant(ovfcheck)
     covfls = Constant(ovfcheck_lshift)
 



More information about the Pypy-commit mailing list