[pypy-svn] r34165 - in pypy/branch/transparent-proxy/pypy: interpreter objspace/std

pedronis at codespeak.net pedronis at codespeak.net
Sat Nov 4 14:25:41 CET 2006


Author: pedronis
Date: Sat Nov  4 14:25:39 2006
New Revision: 34165

Modified:
   pypy/branch/transparent-proxy/pypy/interpreter/baseobjspace.py
   pypy/branch/transparent-proxy/pypy/interpreter/gateway.py
   pypy/branch/transparent-proxy/pypy/interpreter/typedef.py
   pypy/branch/transparent-proxy/pypy/objspace/std/tlistobject.py
Log:
(pedronis, fijal)

saner support for transparent proxy function calls.



Modified: pypy/branch/transparent-proxy/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/branch/transparent-proxy/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/branch/transparent-proxy/pypy/interpreter/baseobjspace.py	Sat Nov  4 14:25:39 2006
@@ -92,6 +92,12 @@
     def setslotvalue(self, index, w_val):
         raise NotImplementedError
 
+    def descr_call_mismatch(self, space, opname, RequiredClass, args):
+        msg = "'%s' object expected, got '%s' instead" % (
+            RequiredClass.typedef.name,
+            self.getclass(space).getname(space, '?'))
+        raise OperationError(space.w_TypeError, space.wrap(msg))
+
     # used by _weakref implemenation
 
     def getweakref(self):
@@ -101,12 +107,6 @@
         typename = space.type(self).getname(space, '?')
         raise OperationError(space.w_TypeError, space.wrap(
             "cannot create weak reference to '%s' object" % typename))
-    
-    def descr_call_not_understood(self, space, reqcls, name, args):
-        msg = "'%s' object expected, got '%s' instead" % (
-                reqcls.typedef.name,
-            self.getclass(space).getname(space, '?'))
-        raise OperationError(space.w_TypeError, space.wrap(msg))
 
 class Wrappable(W_Root):
     """A subclass of Wrappable is an internal, interpreter-level class
@@ -154,6 +154,9 @@
     def __str__(self):
         return self.msg
 
+class DescrMismatch(Exception):
+    pass
+
 class ObjSpace(object):
     """Base class for the interpreter-level implementations of object spaces.
     http://codespeak.net/pypy/dist/pypy/doc/objspace.html"""
@@ -477,6 +480,13 @@
             return w_obj
         return None
 
+    def descr_self_interp_w(self, RequiredClass, w_obj):
+        obj = self.interpclass_w(w_obj)
+        if not isinstance(obj, RequiredClass):
+            raise DescrMismatch()
+        return obj
+    descr_self_interp_w._annspecialcase_ = 'specialize:arg(1)'
+    
     def interp_w(self, RequiredClass, w_obj, can_be_None=False):
         """
         Unwrap w_obj, checking that it is an instance of the required internal

Modified: pypy/branch/transparent-proxy/pypy/interpreter/gateway.py
==============================================================================
--- pypy/branch/transparent-proxy/pypy/interpreter/gateway.py	(original)
+++ pypy/branch/transparent-proxy/pypy/interpreter/gateway.py	Sat Nov  4 14:25:39 2006
@@ -16,7 +16,7 @@
 from pypy.interpreter import eval
 from pypy.interpreter.function import Function, Method
 from pypy.interpreter.baseobjspace import W_Root, ObjSpace, Wrappable
-from pypy.interpreter.baseobjspace import Wrappable, SpaceCache
+from pypy.interpreter.baseobjspace import Wrappable, SpaceCache, DescrMismatch
 from pypy.interpreter.argument import Arguments, AbstractArguments
 from pypy.tool.sourcetools import NiceCompile, compile2
 
@@ -55,7 +55,10 @@
         if isinstance(el, str):
             getattr(self, "visit_%s" % (el,))(el, *args)
         elif isinstance(el, tuple):
-            self.visit_function(el, *args)
+            if el[0] == 'self':
+                self.visit_self(el[1], *args)
+            else:
+                self.visit_function(el, *args)
         else:
             for typ in self.bases_order:
                 if issubclass(el, typ):
@@ -100,6 +103,9 @@
 
     def visit_function(self, (func, cls), app_sig):
         self.dispatch(cls, app_sig)
+
+    def visit_self(self, cls, app_sig):
+        self.visit__Wrappable(cls, app_sig)
         
     def visit__Wrappable(self, el, app_sig):
         name = el.__name__
@@ -170,6 +176,10 @@
         self.run_args.append("%s(%s)" % (self.use(func),
                                          self.scopenext()))
 
+    def visit_self(self, typ):
+        self.run_args.append("space.descr_self_interp_w(%s, %s)" %
+                             (self.use(typ), self.scopenext()))
+        
     def visit__Wrappable(self, typ):
         self.run_args.append("space.interp_w(%s, %s)" % (self.use(typ),
                                                          self.scopenext()))
@@ -197,9 +207,9 @@
         self.run_args.append("space.%s_w(%s)" %
                              (typ.__name__, self.scopenext()))
 
-    def _make_unwrap_activation_class(self, unwrap_spec, not_understood, cache={}):
+    def _make_unwrap_activation_class(self, unwrap_spec, cache={}):
         try:
-            key = (tuple(unwrap_spec), not_understood)
+            key = tuple(unwrap_spec)
             activation_factory_cls, run_args = cache[key]
             assert run_args == self.run_args, (
                 "unexpected: same spec, different run_args")
@@ -216,23 +226,10 @@
             #print label
 
             d = {}
-            if not_understood is None:
-                source = """if 1: 
-                    def _run_UWS_%s(self, space, scope_w):
-                        return self.behavior(%s)
-                    \n""" % (label, ', '.join(self.run_args))
-            else:
-                assert issubclass(unwrap_spec[0], Wrappable)
-                args = ', '.join(self.run_args[1:])
-                reqcls = self.use(unwrap_spec[0])
-                source = """if 1: 
-                    def _run_UWS_%s(self, space, scope_w):
-                        w_self = scope_w[0]
-                        if not isinstance(w_self, %s):
-                            return w_self.descr_call_not_understood(space, %s, %r, %s)
-                        return self.behavior(w_self, %s)
-                    \n""" % (label, reqcls, reqcls, not_understood, args, args)
-                
+            source = """if 1: 
+                def _run_UWS_%s(self, space, scope_w):
+                    return self.behavior(%s)
+                \n""" % (label, ', '.join(self.run_args))
             exec compile2(source) in self.miniglobals, d
             d['_run'] = d['_run_UWS_%s' % label]
             del d['_run_UWS_%s' % label]
@@ -243,11 +240,10 @@
             cache[key] = activation_cls, self.run_args
             return activation_cls
 
-    def make_activation(unwrap_spec, func, not_understood):
+    def make_activation(unwrap_spec, func):
         emit = UnwrapSpec_EmitRun()
         emit.apply_over(unwrap_spec)
-        activation_uw_cls = emit._make_unwrap_activation_class(unwrap_spec,
-                                                               not_understood)
+        activation_uw_cls = emit._make_unwrap_activation_class(unwrap_spec)
         return activation_uw_cls(func)
     make_activation = staticmethod(make_activation)
 
@@ -289,6 +285,10 @@
     def visit_function(self, (func, cls)):
         raise FastFuncNotSupported
 
+    def visit_self(self, typ):
+        self.unwrap.append("space.descr_self_interp_w(%s, %s)" %
+                           (self.use(typ), self.nextarg()))
+
     def visit__Wrappable(self, typ):
         self.unwrap.append("space.interp_w(%s, %s)" % (self.use(typ),
                                                        self.nextarg()))
@@ -316,12 +316,12 @@
         self.unwrap.append("space.%s_w(%s)" % (typ.__name__,
                                                self.nextarg()))
 
-    def make_fastfunc(unwrap_spec, func, not_understood):
+    def make_fastfunc(unwrap_spec, func):
         unwrap_info = UnwrapSpec_FastFunc_Unwrap()
         unwrap_info.apply_over(unwrap_spec)
         narg = unwrap_info.n
         args = ['space'] + unwrap_info.args
-        if args == unwrap_info.unwrap and not_understood is None:
+        if args == unwrap_info.unwrap:
             fastfunc = func
         else:
             # try to avoid excessive bloat
@@ -334,28 +334,12 @@
                     raise FastFuncNotSupported
             d = {}
             unwrap_info.miniglobals['func'] = func
-            if not_understood is None:
-                source = """if 1: 
-                    def fastfunc_%s_%d(%s):
-                        return func(%s)
-                    \n""" % (func.__name__, narg,
-                             ', '.join(args),
-                             ', '.join(unwrap_info.unwrap))
-            else:
-                #def _run_UWS_%s(self, space, scope_w):
-                #        w_self = scope_w[0]
-                #        if not isinstance(w_self, %s):
-                #            return w_self.descr_call_not_understood(space, %r, %s)
-                #        return self.behavior(w_self, %s)
-                assert issubclass(unwrap_spec[0], Wrappable)
-                reqcls = self.use(unwrap_spec[0])
-                source = """if 1:
-                    def fastfunc_%s_%d(%s):
-                        if not isinstance(w0, %s):
-                            return w0.descr_call_not_understood(space, %s, %r, %s)
-                        return func(%s)
-                    \n""" % (func.__name__, narg, ",".join(args), reqcls, reqcls,
-                        not_understood, ",".join(args[2:]), ",".join(unwrap_info.unwrap))
+            source = """if 1: 
+                def fastfunc_%s_%d(%s):
+                    return func(%s)
+                \n""" % (func.__name__, narg,
+                         ', '.join(args),
+                         ', '.join(unwrap_info.unwrap))
             exec compile2(source) in unwrap_info.miniglobals, d
             fastfunc = d['fastfunc_%s_%d' % (func.__name__, narg)]
         return narg, fastfunc
@@ -364,13 +348,16 @@
 class BuiltinCode(eval.Code):
     "The code object implementing a built-in (interpreter-level) hook."
     hidden_applevel = True
+    descrmismatch_op = None
+    descr_reqcls = None
 
     # When a BuiltinCode is stored in a Function object,
     # you get the functionality of CPython's built-in function type.
 
     NOT_RPYTHON_ATTRIBUTES = ['_bltin', '_unwrap_spec']
 
-    def __init__(self, func, unwrap_spec = None, self_type = None, not_understood=None):
+    def __init__(self, func, unwrap_spec = None, self_type = None,
+                 descrmismatch=None):
         "NOT_RPYTHON"
         # 'implfunc' is the interpreter-level function.
         # Note that this uses a lot of (construction-time) introspection.
@@ -405,9 +392,17 @@
         if self_type:
             assert unwrap_spec[0] == 'self',"self_type without 'self' spec element"
             unwrap_spec = list(unwrap_spec)
-            unwrap_spec[0] = self_type
+            if descrmismatch is not None:
+                assert issubclass(self_type, Wrappable)
+                unwrap_spec[0] = ('self', self_type)
+                self.descrmismatch_op = descrmismatch
+                self.descr_reqcls = self_type
+            else:
+                unwrap_spec[0] = self_type
         else:
-            assert not_understood is None, "not_understood without a self-type specified"
+            assert descrmismatch is None, (
+                "descrmismatch without a self-type specified")
+ 
 
         orig_sig = Signature(func, argnames, varargname, kwargname)
         app_sig = Signature(func)
@@ -423,8 +418,7 @@
         else:
             self.maxargs = self.minargs
 
-        self.activation = UnwrapSpec_EmitRun.make_activation(unwrap_spec, func,
-                                                             not_understood=not_understood)
+        self.activation = UnwrapSpec_EmitRun.make_activation(unwrap_spec, func)
         self._bltin = func
         self._unwrap_spec = unwrap_spec
 
@@ -432,15 +426,12 @@
         if 0 <= len(unwrap_spec) <= 5:
             try:
                 arity, fastfunc = UnwrapSpec_FastFunc_Unwrap.make_fastfunc(
-                                                 unwrap_spec, func,
-                                                 not_understood=not_understood)
+                                                 unwrap_spec, func)
             except FastFuncNotSupported:
                 if unwrap_spec == [ObjSpace, Arguments]:
-                    assert not_understood is None
                     self.__class__ = BuiltinCodePassThroughArguments0
                     self.func__args__ = func
                 elif unwrap_spec == [ObjSpace, W_Root, Arguments]:
-                    assert not_understood is None
                     self.__class__ = BuiltinCodePassThroughArguments1
                     self.func__args__ = func
             else:
@@ -469,7 +460,12 @@
             raise OperationError(space.w_MemoryError, space.w_None) 
         except RuntimeError, e: 
             raise OperationError(space.w_RuntimeError, 
-                                 space.wrap("internal error: " + str(e))) 
+                                 space.wrap("internal error: " + str(e)))
+        except DescrMismatch, e:
+            return scope_w[0].descr_call_mismatch(space,
+                                                  self.descrmismatch_op,
+                                                  self.descr_reqcls,
+                                                  args)
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -489,6 +485,11 @@
         except RuntimeError, e: 
             raise OperationError(space.w_RuntimeError, 
                                  space.wrap("internal error: " + str(e))) 
+        except DescrMismatch, e:
+            return scope_w[0].descr_call_mismatch(space,
+                                                  self.descrmismatch_op,
+                                                  self.descr_reqcls,
+                                                  args)
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -511,6 +512,11 @@
             except RuntimeError, e: 
                 raise OperationError(space.w_RuntimeError, 
                                      space.wrap("internal error: " + str(e))) 
+            except DescrMismatch, e:
+                return scope_w[0].descr_call_mismatch(space,
+                                                      self.descrmismatch_op,
+                                                      self.descr_reqcls,
+                                                      args)
             if w_result is None:
                 w_result = space.w_None
             return w_result
@@ -522,8 +528,8 @@
         except KeyboardInterrupt: 
             raise OperationError(space.w_KeyboardInterrupt, space.w_None) 
         except MemoryError: 
-            raise OperationError(space.w_MemoryError, space.w_None) 
-        except RuntimeError, e: 
+            raise OperationError(space.w_MemoryError, space.w_None)
+        except (RuntimeError, DescrMismatch), e: 
             raise OperationError(space.w_RuntimeError, 
                                  space.wrap("internal error: " + str(e))) 
         if w_result is None:
@@ -540,7 +546,12 @@
             raise OperationError(space.w_MemoryError, space.w_None) 
         except RuntimeError, e: 
             raise OperationError(space.w_RuntimeError, 
-                                 space.wrap("internal error: " + str(e))) 
+                                 space.wrap("internal error: " + str(e)))
+        except DescrMismatch, e:
+            return  w1.descr_call_mismatch(space,
+                                           self.descrmismatch_op,
+                                           self.descr_reqcls,
+                                           Arguments(space, [w1]))
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -556,6 +567,11 @@
         except RuntimeError, e: 
             raise OperationError(space.w_RuntimeError, 
                                  space.wrap("internal error: " + str(e))) 
+        except DescrMismatch, e:
+            return  w1.descr_call_mismatch(space,
+                                           self.descrmismatch_op,
+                                           self.descr_reqcls,
+                                           Arguments(space, [w1, w2]))
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -570,7 +586,12 @@
             raise OperationError(space.w_MemoryError, space.w_None) 
         except RuntimeError, e: 
             raise OperationError(space.w_RuntimeError, 
-                                 space.wrap("internal error: " + str(e))) 
+                                 space.wrap("internal error: " + str(e)))
+        except DescrMismatch, e:
+            return  w1.descr_call_mismatch(space,
+                                           self.descrmismatch_op,
+                                           self.descr_reqcls,
+                                           Arguments(space, [w1, w2, w3]))
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -585,7 +606,13 @@
             raise OperationError(space.w_MemoryError, space.w_None) 
         except RuntimeError, e: 
             raise OperationError(space.w_RuntimeError, 
-                                 space.wrap("internal error: " + str(e))) 
+                                 space.wrap("internal error: " + str(e)))
+        except DescrMismatch, e:
+            return  w1.descr_call_mismatch(space,
+                                           self.descrmismatch_op,
+                                           self.descr_reqcls,
+                                           Arguments(space,
+                                                     [w1, w2, w3, w4]))
         if w_result is None:
             w_result = space.w_None
         return w_result
@@ -605,7 +632,8 @@
 
     NOT_RPYTHON_ATTRIBUTES = ['_staticdefs']
     
-    def __init__(self, f, app_name=None, unwrap_spec = None, not_understood=None):
+    def __init__(self, f, app_name=None, unwrap_spec = None,
+                 descrmismatch=None):
         "NOT_RPYTHON"
         Wrappable.__init__(self)
         # f must be a function whose name does NOT start with 'app_'
@@ -620,8 +648,9 @@
                 raise ValueError, ("function name %r suspiciously starts "
                                    "with 'app_'" % f.func_name)
             app_name = f.func_name
-        self._code = BuiltinCode(f, unwrap_spec=unwrap_spec, self_type = self_type, 
-            not_understood=not_understood)
+        self._code = BuiltinCode(f, unwrap_spec=unwrap_spec,
+                                 self_type = self_type,
+                                 descrmismatch=descrmismatch)
         self.__name__ = f.func_name
         self.name = app_name
         self._staticdefs = list(f.func_defaults or ())

Modified: pypy/branch/transparent-proxy/pypy/interpreter/typedef.py
==============================================================================
--- pypy/branch/transparent-proxy/pypy/interpreter/typedef.py	(original)
+++ pypy/branch/transparent-proxy/pypy/interpreter/typedef.py	Sat Nov  4 14:25:39 2006
@@ -583,7 +583,8 @@
 Function.typedef = TypeDef("function",
     __new__ = interp2app(Function.descr_method__new__.im_func),
     __call__ = interp2app(Function.descr_function_call,
-                          unwrap_spec=['self', Arguments], not_understood="__call__"),
+                          unwrap_spec=['self', Arguments],
+                          descrmismatch='__call__'),
     __get__ = interp2app(descr_function_get),
     __repr__ = interp2app(Function.descr_function_repr),
     __reduce__ = interp2app(Function.descr_function__reduce__,

Modified: pypy/branch/transparent-proxy/pypy/objspace/std/tlistobject.py
==============================================================================
--- pypy/branch/transparent-proxy/pypy/objspace/std/tlistobject.py	(original)
+++ pypy/branch/transparent-proxy/pypy/objspace/std/tlistobject.py	Sat Nov  4 14:25:39 2006
@@ -66,7 +66,8 @@
     from pypy.interpreter.function import Function
     typedef = Function.typedef
     
-    def descr_call_not_understood(self, space, reqcls, name, args):
+    def descr_call_mismatch(self, space, name, reqcls, args):
+        _, args = args.popfirst()
         args = args.prepend(space.wrap(name))
         return space.call_args(self.w_controller, args)
 



More information about the Pypy-commit mailing list