[pypy-svn] rev 1025 - pypy/trunk/src/pypy/objspace/ann

gvanrossum at codespeak.net gvanrossum at codespeak.net
Tue Jun 24 11:44:04 CEST 2003


Author: gvanrossum
Date: Tue Jun 24 11:44:04 2003
New Revision: 1025

Modified:
   pypy/trunk/src/pypy/objspace/ann/cloningcontext.py
   pypy/trunk/src/pypy/objspace/ann/objspace.py
   pypy/trunk/src/pypy/objspace/ann/wrapper.py
Log:
Made some improvements in annspace to be able to run more of the
standard tests in annspace.  The failing tests now all fail with
UnwrapException: W_Anything(), or they fail because we don't know
anything about modules yet.

M      objspace.py
        change wrap() to always return the same wrapper for
        fundamental constants (None, False etc.)
        add and call make_builtins() (simpler than the base class's)
        call make_sys()
        clone_locals() allows W_Constant
        newdict() can create constant dicts as well
        added newlist(), newstring(), str(), setattr()
        change is_() to return w_False if constants differ
        changed iter() to call reraise() instead of raising OperationError
M      wrapper.py
        add clone() to W_Constant (returns self)
        unify_frames() now unifies localcells rather than w_locals
        compatible_frames() checks the lengths of the lists of cells
        rename unite_frames() to unify_frames()
M      cloningcontext.py
        rename unite_frames() to unify_frames()


Modified: pypy/trunk/src/pypy/objspace/ann/cloningcontext.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/ann/cloningcontext.py	(original)
+++ pypy/trunk/src/pypy/objspace/ann/cloningcontext.py	Tue Jun 24 11:44:04 2003
@@ -1,7 +1,7 @@
 from pypy.interpreter.executioncontext import ExecutionContext
 from pypy.interpreter.pyframe import ControlFlowException, ExitFrame
 from pypy.objspace.ann.wrapper \
-     import union, compatible_frames, unite_frames, W_Anything, W_Constant
+     import union, compatible_frames, unify_frames, W_Anything, W_Constant
 
 class FunctionInfo(object):
 
@@ -77,7 +77,7 @@
         info = self.getfunctioninfo(frame)
         for f in info.iterknown(frame):
             if compatible_frames(frame, f):
-                c1, c2 = unite_frames(frame, f)
+                c1, c2 = unify_frames(frame, f)
                 if not c2:
                     # A fixpoint; abandon this frame
                     raise ExitFrame(None)

Modified: pypy/trunk/src/pypy/objspace/ann/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/ann/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/ann/objspace.py	Tue Jun 24 11:44:04 2003
@@ -1,6 +1,7 @@
 import sys
 import operator
 
+import pypy
 from pypy.interpreter.baseobjspace \
      import ObjSpace, OperationError, NoValue, PyPyError
 from pypy.interpreter.pycode import PyByteCode
@@ -22,20 +23,38 @@
 
     def initialize(self):
         self.bytecodecache = {}
-        self.w_None = self.wrap(None)
-        self.w_True = self.wrap(True)
-        self.w_False = self.wrap(False)
-        self.w_NotImplemented = self.wrap(NotImplemented)
-        self.w_Ellipsis = self.wrap(Ellipsis)
+        self.wrappercache = {}
+        self.w_None = self.wrapboot(None)
+        self.w_True = self.wrapboot(True)
+        self.w_False = self.wrapboot(False)
+        self.w_NotImplemented = self.wrapboot(NotImplemented)
+        self.w_Ellipsis = self.wrapboot(Ellipsis)
         import __builtin__, types
         for n, c in __builtin__.__dict__.iteritems():
             if isinstance(c, types.TypeType) or isinstance(c, types.ClassType):
                 setattr(self, 'w_'+n, self.wrap(c))
         self.w_builtins = self.wrap(__builtin__)
+        self.make_builtins()
+        self.make_sys()
+
+    def make_builtins(self):
+        self.builtin = pypy.module.builtin.Builtin(self)
 
     # Service methods whose interface is in the abstract base class
 
+    def wrapboot(self, obj):
+        w_obj = self.wrap(obj)
+        self.wrappercache[obj] = w_obj
+        return w_obj
+
     def wrap(self, obj):
+        try:
+            if obj in self.wrappercache:
+                return self.wrappercache[obj]
+        except (TypeError, AttributeError):
+            # This can happen when obj is not hashable, for instance
+            # XXX What about other errors???
+            pass
         return W_Constant(obj)
 
     def unwrap(self, w_obj):
@@ -71,7 +90,7 @@
         return CloningExecutionContext(self)
 
     def clone_locals(self, w_locals):
-        assert isinstance(w_locals, W_KnownKeysContainer)
+        assert isinstance(w_locals, (W_KnownKeysContainer, W_Constant))
         return w_locals.clone()
 
 
@@ -84,6 +103,20 @@
         return self.wrap(tuple(map(self.unwrap, args_w)))
 
     def newdict(self, items_w):
+        d = {}
+        for w_key, w_value in items_w:
+            try:
+                key = self.unwrap(w_key)
+                value = self.unwrap(w_value)
+            except UnwrapException:
+                break
+            else:
+                d[key] = value
+        else:
+            # All keys and values were unwrappable
+            return W_Constant(d)
+        # It's not quite constant.
+        # Maybe the keys are constant?
         values_w = {}
         for w_key, w_value in items_w:
             try:
@@ -102,9 +135,41 @@
     def newfunction(self, *stuff):
         return W_Anything()
 
+    def newlist(self, list_w):
+        unwrappedlist = []
+        try:
+            for w_obj in list_w:
+                obj = self.unwrap(w_obj)
+                unwrappedlist.append(obj)
+        except UnwrapException:
+            return W_Anything()
+        else:
+            return W_Constant(unwrappedlist)
+
+    def newstring(self, listofwrappedints):
+        unwrappedints = []
+        try:
+            for w_i in listofwrappedints:
+                i = self.unwrap(w_i)
+                unwrappedints.append(i)
+        except UnwrapException:
+            return W_Anything()
+        else:
+            try:
+                s = "".join(map(chr, unwrappedints))
+            except:
+                self.reraise()
+            return W_Constant(s)
+
     # Methods implementing Python operations
     # (Many missing ones are added by make_op() below)
 
+    def str(self, w_left):
+        if isinstance(w_left, W_Constant):
+            return self.wrap(str(w_left.value))
+        else:
+            return W_Anything()
+
     def is_(self, w_left, w_right):
         if w_left is w_right:
             return self.w_True
@@ -112,6 +177,8 @@
             # XXX Is this really safe?
             if w_left.value is w_right.value:
                 return self.w_True
+            else:
+                return self.w_False
         return W_Integer()
 
     def add(self, w_left, w_right):
@@ -159,8 +226,7 @@
             try:
                 it = iter(value)
             except:
-                raise OperationError(self.wrap(AttributeError),
-                                     self.wrap(AttributeError("__iter__")))
+                self.reraise()
         return W_Anything()
 
     def next(self, w_iterator):
@@ -206,6 +272,10 @@
             except:
                 return self.reraise()
 
+    def setattr(self, w_obj, w_name, w_value):
+        # XXX What about the side effect?
+        return self.w_None
+
     def len(self, w_obj):
         if isinstance(w_obj, W_KnownKeysContainer):
             return self.wrap(len(w_obj))

Modified: pypy/trunk/src/pypy/objspace/ann/wrapper.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/ann/wrapper.py	(original)
+++ pypy/trunk/src/pypy/objspace/ann/wrapper.py	Tue Jun 24 11:44:04 2003
@@ -56,8 +56,14 @@
     def __eq__(self, other):
         return type(other) is type(self) and self.value == other.value
 
+    def clone(self):
+        return self
+
 class W_KnownKeysContainer(W_Object):
-    """A dict with constant set of keys or a tuple with known length."""
+    """A dict with constant set of keys or a tuple with known length.
+
+    XXX This may be mutable!  Is that a good idea?
+    """
 
     def __init__(self, args_w):
         self.args_w = args_w
@@ -81,7 +87,7 @@
         # XXX Recurse down the values?
         return W_KnownKeysContainer(args_w)
 
-def unite_frames(f1, f2):
+def unify_frames(f1, f2):
     """Given two compatible frames, make them the same.
 
     This changes both f1 and f2 in-place to change all the values into
@@ -112,27 +118,29 @@
                 c2 = True
                 s2[i] = u
 
-    # Compare locals
-    # XXX uses W_KnownKeysContainer internals
-    assert isinstance(f1.w_locals, W_KnownKeysContainer)
-    assert isinstance(f2.w_locals, W_KnownKeysContainer)
-    l1 = f1.w_locals.args_w
-    l2 = f2.w_locals.args_w
-    keydict = {} # compute set of keys
-    for key in l1.iterkeys():
-        keydict[key] = 1
-    for key in l2.iterkeys():
-        keydict[key] = 1
-    for key in keydict.iterkeys():
-        v1 = l1.get(key, W_Undefined())
-        v2 = l2.get(key, W_Undefined())
+    # Compare locals.
+    # XXX This uses the fast locals now and ignores w_locals.
+    # XXX What about nested cells?
+    l1 = f1.localcells
+    l2 = f2.localcells
+    assert len(l1) == len(l2)
+    for i in range(len(l1)):
+        try:
+            v1 = l1[i].get()
+        except ValueError:
+            v1 = W_Undefined()
+        try:
+            v2 = l2[i].get()
+        except ValueError:
+            v2 = W_Undefined()
         u = union(v1, v2)
         if v1 != u:
             c1 = True
-            l1[key] = u
+            l1[i].set(u)
         if v2 != u:
             c2 = True
-            l2[key] = u
+            l2[i].set(u)
+
     return c1, c2
 
 def compatible_frames(f1, f2):
@@ -147,6 +155,8 @@
     return (f1.next_instr == f2.next_instr and
             f1.space is f2.space and
             f2.bytecode is f2.bytecode and
+            len(f1.localcells) == len(f2.localcells) and
+            len(f1.nestedcells) == len(f2.nestedcells) and
             f1.valuestack.depth() == f2.valuestack.depth() and
             equivalent(f1.w_globals, f2.w_globals) and
             equivalent(f1.w_builtins, f2.w_builtins) and


More information about the Pypy-commit mailing list