[pypy-svn] r5289 - in pypy/trunk/src/pypy: annotation interpreter objspace objspace/flow objspace/std translator

arigo at codespeak.net arigo at codespeak.net
Fri Jun 25 14:10:45 CEST 2004


Author: arigo
Date: Fri Jun 25 14:10:44 2004
New Revision: 5289

Modified:
   pypy/trunk/src/pypy/annotation/factory.py
   pypy/trunk/src/pypy/annotation/model.py
   pypy/trunk/src/pypy/annotation/unaryop.py
   pypy/trunk/src/pypy/interpreter/baseobjspace.py
   pypy/trunk/src/pypy/interpreter/function.py
   pypy/trunk/src/pypy/interpreter/pyopcode.py
   pypy/trunk/src/pypy/objspace/descroperation.py
   pypy/trunk/src/pypy/objspace/flow/objspace.py
   pypy/trunk/src/pypy/objspace/std/cpythonobject.py
   pypy/trunk/src/pypy/objspace/std/typeobject.py
   pypy/trunk/src/pypy/objspace/trivial.py
   pypy/trunk/src/pypy/translator/annrpython.py
   pypy/trunk/src/pypy/translator/transform.py
Log:
Refactoring: space.call_function(w_callable, ...) is now the basic operation,
with a real tuple and a real dict with real strings containing wrapped
objects.  Small dicts with string keys are deemed acceptable for RPython.

This avoid quite a lot of packing and unpacking arguments around.  It is a
simplification and it speeds things up noticeably too.

The name 'call_function' is really inappropriate now.  It should probably be
renamed into 'call' after some time -- right now all tests pass but I'm not
entierely confident about not having forgotten some calls to Function.call(),
for example.  If we want to do that we should first scrap space.call()
completely -- which still exists but calls space.call_function() -- and make
sure nobody uses it any more.

The 'call' multimethod in StdObjSpace still uses the old w_args, w_kwds
convention.  XXX.

Now FlowObjSpace can produce 'simple_call' operations directly when
space.call_function() is invoked.  It simplifies annotation stuff, too, who
can deal with 'simple_call' instead of 'call' operations.

A lot of code was commented out and should probably be removed completely.



Modified: pypy/trunk/src/pypy/annotation/factory.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/factory.py	(original)
+++ pypy/trunk/src/pypy/annotation/factory.py	Fri Jun 25 14:10:44 2004
@@ -128,22 +128,22 @@
 
 class FuncCallFactory:
 
-    def pycall(self, func, arglist):
-        return self.bookkeeper.annotator.recursivecall(func, arglist, self)
+    def pycall(self, func, *args):
+        return self.bookkeeper.annotator.recursivecall(func, self, *args)
 
 
 class InstanceFactory(FuncCallFactory):
 
-    def create(self, cls, arglist):
+    def create(self, cls, *args):
         classdef = self.bookkeeper.getclassdef(cls)
         classdef.instancefactories[self] = True
         s_instance = SomeInstance(classdef)
         # flow into __init__() if the class has got one
         init = getattr(cls, '__init__', None)
         if init is not None and init != object.__init__:
-            self.pycall(init, [s_instance] + arglist)
+            self.pycall(init, s_instance, *args)
         else:
-            assert not arglist, "no __init__ found in %r" % (cls,)
+            assert not args, "no __init__ found in %r" % (cls,)
         return s_instance
 
 

Modified: pypy/trunk/src/pypy/annotation/model.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/model.py	(original)
+++ pypy/trunk/src/pypy/annotation/model.py	Fri Jun 25 14:10:44 2004
@@ -174,17 +174,17 @@
     else:
         return SomeObject()
 
-def decode_simple_call(s_args, s_kwds):
-    s_nbargs = s_args.len()
-    if not s_nbargs.is_constant():
-        return None
-    nbargs = s_nbargs.const
-    arglist = [pair(s_args, immutablevalue(j)).getitem()
-               for j in range(nbargs)]
-    s_nbkwds = s_kwds.len()
-    if not s_nbkwds.is_constant() or s_nbkwds.const != 0:
-        return None    # XXX deal with dictionaries with keywords
-    return arglist
+##def decode_simple_call(s_args, s_kwds):
+##    s_nbargs = s_args.len()
+##    if not s_nbargs.is_constant():
+##        return None
+##    nbargs = s_nbargs.const
+##    arglist = [pair(s_args, immutablevalue(j)).getitem()
+##               for j in range(nbargs)]
+##    s_nbkwds = s_kwds.len()
+##    if not s_nbkwds.is_constant() or s_nbkwds.const != 0:
+##        return None    # XXX deal with dictionaries with keywords
+##    return arglist
 
 
 # ____________________________________________________________

Modified: pypy/trunk/src/pypy/annotation/unaryop.py
==============================================================================
--- pypy/trunk/src/pypy/annotation/unaryop.py	(original)
+++ pypy/trunk/src/pypy/annotation/unaryop.py	Fri Jun 25 14:10:44 2004
@@ -9,13 +9,13 @@
 from pypy.annotation.model import SomeTuple, SomeImpossibleValue
 from pypy.annotation.model import SomeInstance, SomeBuiltin, SomeClass
 from pypy.annotation.model import SomeFunction, SomeMethod, SomeIterator
-from pypy.annotation.model import immutablevalue, decode_simple_call
+from pypy.annotation.model import immutablevalue
 from pypy.annotation.model import unionof, set, setunion, missing_operation
 from pypy.annotation.factory import BlockedInference, getbookkeeper
 from pypy.annotation.factory import InstanceFactory, FuncCallFactory
 
 
-UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'call',
+UNARY_OPERATIONS = set(['len', 'is_true', 'getattr', 'setattr', 'simple_call',
                         'iter', 'next'])
 
 for opname in UNARY_OPERATIONS:
@@ -117,33 +117,25 @@
 
 class __extend__(SomeBuiltin):
 
-    def call(bltn, args, kwds):
-        # decode the arguments and forward the analysis of this builtin
-        arglist = decode_simple_call(args, kwds)
-        if arglist is not None:
-            if bltn.s_self is not None:
-                arglist.insert(0, bltn.s_self)
-            return bltn.analyser(*arglist)
+    def simple_call(bltn, *args):
+        if bltn.s_self is not None:
+            return bltn.analyser(bltn.s_self, *args)
         else:
-            return SomeObject()
+            return bltn.analyser(*args)
 
 
 class __extend__(SomeClass):
 
-    def call(cls, args, kwds):
-        arglist = decode_simple_call(args, kwds)
-        assert arglist is not None
+    def simple_call(cls, *args):
         factory = getbookkeeper().getfactory(InstanceFactory)
-        return factory.create(cls.cls, arglist)
+        return factory.create(cls.cls, *args)
 
 
 class __extend__(SomeFunction):
 
-    def call(fun, args, kwds):
-        arglist = decode_simple_call(args, kwds)
-        assert arglist is not None
+    def simple_call(fun, *args):
         factory = getbookkeeper().getfactory(FuncCallFactory)
-        results = [factory.pycall(func, arglist) for func in fun.funcs]
+        results = [factory.pycall(func, *args) for func in fun.funcs]
         return unionof(*results)
 
     def classattribute(fun, classdef):   # function -> unbound method
@@ -157,10 +149,7 @@
 
 class __extend__(SomeMethod):
 
-    def call(met, args, kwds):
-        arglist = decode_simple_call(args, kwds)
-        #print 'methodcall:', met, arglist
-        assert arglist is not None
+    def simple_call(met, *args):
         factory = getbookkeeper().getfactory(FuncCallFactory)
         results = []
         for func, classdef in met.meths.items():
@@ -168,5 +157,5 @@
             s_self = SomeInstance(classdef)
             classdef.instancefactories[factory] = True
             # call func(s_self, *arglist)
-            results.append(factory.pycall(func, [s_self]+arglist))
+            results.append(factory.pycall(func, s_self, *args))
         return unionof(*results)

Modified: pypy/trunk/src/pypy/interpreter/baseobjspace.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/baseobjspace.py	(original)
+++ pypy/trunk/src/pypy/interpreter/baseobjspace.py	Fri Jun 25 14:10:44 2004
@@ -182,10 +182,35 @@
                 check_list.extend(exclst)
         return False
 
-    def call_function(self, w_func, *args_w, **kw_w):
-        w_kw = self.newdict([(self.wrap(k), w_v) for k, w_v in kw_w.iteritems()])
-        w_args = self.newtuple(list(args_w))
-        return self.call(w_func, w_args, w_kw)
+    def unpackdictionary(self, w_mapping):
+        "Turns a wrapped dictionary into a {'string': w_value} dict."
+        if not self.is_mapping(w_mapping):
+            raise OperationError(self.w_TypeError,
+                                 self.wrap("the keywords must be a dictionary"))
+        result = {}
+        for w_key in self.unpackiterable(w_mapping):
+            key = self.unwrap(w_key)
+            if not isinstance(key, str):
+                raise OperationError(self.w_TypeError,
+                                     self.wrap("keywords must be strings"))
+            result[key] = self.getitem(w_mapping, w_key)
+        return result
+
+    def is_mapping(self, w_mapping):
+        # XXX extend to detect general mappings
+        return self.is_true(self.isinstance(w_mapping, self.w_dict))
+
+    def call(self, w_callable, w_args, w_kwds=None):
+        "Deprecated.  Use call_function() instead."
+        args_w = self.unpacktuple(w_args)
+        if w_kwds is None:
+            return self.call_function(w_callable, *args_w)
+        else:
+            kwds_w = self.unpackdictionary(w_kwds)
+            return self.call_function(w_callable, *args_w, **kwds_w)
+
+##    def call_function(self, w_func, *args_w, **kw_w):
+##        implemented by subclasses
 
     def call_method(self, w_obj, methname, *arg_w, **kw_w):
         w_meth = self.getattr(w_obj, self.wrap(methname))
@@ -288,7 +313,7 @@
     ('contains',        'contains',  2, ['__contains__']),
     ('iter',            'iter',      1, ['__iter__']),
     ('next',            'next',      1, ['next']),
-    ('call',            'call',      3, ['__call__']),
+#    ('call',            'call',      3, ['__call__']),
     ('get',             'get',       3, ['__get__']),
     ('set',             'set',       3, ['__set__']),
     ('delete',          'delete',    2, ['__delete__']),
@@ -352,4 +377,4 @@
 #      newstring([w_1, w_2,...]) -> w_string from ascii numbers (bytes)
 # newdict([(w_key,w_value),...]) -> w_dict
 #newslice(w_start,w_stop,w_step) -> w_slice (any argument may be a real None)
-#
+#   call_function(w_obj,*args_w,**kwds_w)

Modified: pypy/trunk/src/pypy/interpreter/function.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/function.py	(original)
+++ pypy/trunk/src/pypy/interpreter/function.py	Fri Jun 25 14:10:44 2004
@@ -24,93 +24,81 @@
         self.defs_w    = defs_w     # list of w_default's
         self.w_func_dict = space.newdict([])
 
-    def call(self, w_args, w_kwds=None):
-        scope_w = self.parse_args(w_args, w_kwds)
+    def call_function(self, *args_w, **kwds_w):
+        scope_w = self.parse_args(list(args_w), kwds_w)
         frame = self.code.create_frame(self.space, self.w_func_globals,
                                             self.closure)
         frame.setfastscope(scope_w)
         return frame.run()
 
-    def parse_args(self, w_args, w_kwds=None):
+    def parse_args(self, args_w, kwds_w):
         """ parse args and kwargs to initialize the frame.
         """
         space = self.space
         signature = self.code.signature()
         argnames, varargname, kwargname = signature
         #
-        #   w_args = wrapped sequence of the normal actual parameters
-        #   args_w = the same, as a list of wrapped actual parameters
-        #   w_kwds = wrapped dictionary of keyword parameters or a real None
+        #   args_w = list of the normal actual parameters, wrapped
+        #   kwds_w = real dictionary {'keyword': wrapped parameter}
         #   argnames = list of formal parameter names
         #   scope_w = resulting list of wrapped values
         #
         # We try to give error messages following CPython's, which are
         # very informative.
         #
-        if w_kwds is not None:
-            if space.is_true(w_kwds):
-                # space.is_true() avoids infinite recursion copy<->parse_args
-                w_kwargs = space.call_method(w_kwds, "copy")
-            else:
-                w_kwargs = None
         co_argcount = len(argnames) # expected formal arguments, without */**
 
         # put as many positional input arguments into place as available
-        args_w = space.unpacktuple(w_args)
         scope_w = args_w[:co_argcount]
         input_argcount = len(scope_w)
 
         # check that no keyword argument conflicts with these
-        if w_kwargs is not None:
+        if kwds_w:
             for name in argnames[:input_argcount]:
-                w_name = space.wrap(name)
-                if space.is_true(space.contains(w_kwargs, w_name)):
+                if name in kwds_w:
                     self.raise_argerr_multiple_values(name)
 
+        remainingkwds_w = kwds_w.copy()
         if input_argcount < co_argcount:
             # not enough args, fill in kwargs or defaults if exists
             def_first = co_argcount - len(self.defs_w)
             for i in range(input_argcount, co_argcount):
-                w_name = space.wrap(argnames[i])
-                if (w_kwargs is not None and
-                        space.is_true(space.contains(w_kwargs, w_name))):
-                    scope_w.append(space.getitem(w_kwargs, w_name))
-                    space.delitem(w_kwargs, w_name)
+                name = argnames[i]
+                if name in remainingkwds_w:
+                    scope_w.append(remainingkwds_w[name])
+                    del remainingkwds_w[name]
                 elif i >= def_first:
                     scope_w.append(self.defs_w[i-def_first])
                 else:
-                    self.raise_argerr(w_args, w_kwds, False)
+                    self.raise_argerr(args_w, kwds_w, False)
                     
         # collect extra positional arguments into the *vararg
         if varargname is not None:
             scope_w.append(space.newtuple(args_w[co_argcount:]))
         elif len(args_w) > co_argcount:
-            self.raise_argerr(w_args, w_kwds, True)
+            self.raise_argerr(args_w, kwds_w, True)
 
         # collect extra keyword arguments into the **kwarg
-        if w_kwargs:
-            if kwargname is not None:
-                # XXX this doesn't check that the keys of kwargs are strings
-                scope_w.append(w_kwargs)
-            elif space.is_true(w_kwargs):
-                self.raise_argerr_unknown_kwds(w_kwds)
-        else:
-            if kwargname is not None:
-                scope_w.append(space.newdict([]))
+        if kwargname is not None:
+            w_kwds = space.newdict([(space.wrap(key), w_value)
+                                    for key, w_value in remainingkwds_w.items()])
+            scope_w.append(w_kwds)
+        elif remainingkwds_w:
+            self.raise_argerr_unknown_kwds(remainingkwds_w)
         return scope_w
 
     # helper functions to build error message for the above
 
-    def raise_argerr(self, w_args, w_kwds, too_many):
+    def raise_argerr(self, args_w, kwds_w, too_many):
         argnames, varargname, kwargname = self.code.signature()
-        nargs = self.space.unwrap(self.space.len(w_args))
+        nargs = len(args_w)
         n = len(argnames)
         if n == 0:
             if kwargname is not None:
                 msg2 = "non-keyword "
             else:
                 msg2 = ""
-                nargs += self.space.unwrap(self.space.len(w_kwds))
+                nargs += len(kwds_w)
             msg = "%s() takes no %sargument (%d given)" % (
                 self.name, 
                 msg2,
@@ -147,18 +135,15 @@
             argname)
         raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
 
-    def raise_argerr_unknown_kwds(self, w_kwds):
-        nkwds = self.space.unwrap(self.space.len(w_kwds))
-        if nkwds == 1:
-            w_iter = self.space.iter(w_kwds)
-            w_key = self.space.next(w_iter)
+    def raise_argerr_unknown_kwds(self, kwds_w):
+        if len(kwds_w) == 1:
             msg = "%s() got an unexpected keyword argument '%s'" % (
                 self.name,
-                self.space.unwrap(w_key))
+                kwds_w.keys()[0])
         else:
             msg = "%s() got %d unexpected keyword arguments" % (
                 self.name,
-                nkwds)
+                len(kwds_w))
         raise OperationError(self.space.w_TypeError, self.space.wrap(msg))
 
     def getdict(self):
@@ -181,11 +166,7 @@
             return wrap(Method(space, wrap(self), None, w_cls))
 
     def descr_function_call(self, *args_w, **kwds_w):
-        # XXX refactor to avoid unwrapping and rewrapping all around
-        space = self.space
-        return self.call(space.newtuple(list(args_w)),
-                         space.newdict([(space.wrap(key), w_item)
-                                        for key, w_item in kwds_w.items()]))
+        return self.call_function(*args_w, **kwds_w)
 
     def fget_func_defaults(space, w_self):
         self = space.unwrap(w_self)
@@ -218,12 +199,11 @@
         self.w_instance = w_instance   # or None
         self.w_class = w_class
 
-    def call(self, w_args, w_kwds=None):
-        args_w = self.space.unpacktuple(w_args)
+    def call_function(self, *args_w, **kwds_w):
         if self.w_instance is not None:
             # bound method
-            args_w = [self.w_instance] + args_w
-            w_args = self.space.newtuple(args_w)
+            return self.space.call_function(self.w_function, self.w_instance,
+                                            *args_w, **kwds_w)
         else:
             # unbound method
             if (len(args_w) >= 1 and self.space.is_true(
@@ -234,14 +214,10 @@
                        "instance as first argument")     # XXX fix error msg
                 raise OperationError(self.space.w_TypeError,
                                      self.space.wrap(msg))
-        return self.space.call(self.w_function, w_args, w_kwds)
+            return self.space.call_function(self.w_function, *args_w, **kwds_w)
 
     def descr_method_call(self, *args_w, **kwds_w):
-        # XXX refactor to avoid unwrapping and rewrapping all around
-        space = self.space
-        return self.call(space.newtuple(list(args_w)),
-                         space.newdict([(space.wrap(key), w_item)
-                                        for key, w_item in kwds_w.items()]))
+        return self.call_function(*args_w, **kwds_w)
 
 class StaticMethod(Wrappable):
     """A static method.  Note that there is one class staticmethod at

Modified: pypy/trunk/src/pypy/interpreter/pyopcode.py
==============================================================================
--- pypy/trunk/src/pypy/interpreter/pyopcode.py	(original)
+++ pypy/trunk/src/pypy/interpreter/pyopcode.py	Fri Jun 25 14:10:44 2004
@@ -687,38 +687,28 @@
             w_varkw = f.valuestack.pop()
         if with_varargs:
             w_varargs = f.valuestack.pop()
-        keywords = []
+        keywords = {}
         for i in range(n_keywords):
             w_value = f.valuestack.pop()
             w_key   = f.valuestack.pop()
-            keywords.append((w_key, w_value))
+            key = f.space.unwrap(w_key)   # XXX type check: str
+            keywords[key] = w_value
         arguments = [f.valuestack.pop() for i in range(n_arguments)]
         arguments.reverse()
         w_function  = f.valuestack.pop()
-        w_arguments = f.space.newtuple(arguments)
-        w_keywords  = f.space.newdict(keywords)
-        if with_varargs:
-            w_arguments = f.update_star_args(w_arguments, w_varargs)
-        if with_varkw:
-            w_keywords  = f.update_keyword_args(w_keywords, w_varkw)
-        w_result = f.space.call(w_function, w_arguments, w_keywords)
+        if with_varargs:    # add the arguments provided by the *args syntax
+            arguments += tuple(f.space.unpackiterable(w_varargs))
+        if with_varkw:      # add the arguments provided by the **kwds syntax
+            kwds_w = f.space.unpackdictionary(w_varkw)
+            for key, w_value in kwds_w.items():
+                if key in keywords:
+                    raise OperationError(f.space.w_TypeError,
+                            f.space.wrap("got multiple values for "
+                                         "keyword argument '%s'" % key))
+                keywords[key] = w_value
+        w_result = f.space.call_function(w_function, *arguments, **keywords)
         f.valuestack.push(w_result)
 
-    def app_update_star_args(f, args, extra_args):
-        return args + tuple(extra_args)
-
-    def app_update_keyword_args(f, kw, extra_kw):
-        if not isinstance(extra_kw, dict):
-            raise TypeError, "argument after ** must be a dictionary"
-        result = kw.copy()
-        for key, value in extra_kw.items():
-            if key in result:
-                # XXX should mention the function name in error message
-                raise TypeError, ("got multiple values "
-                                  "for keyword argument '%s'" % key)
-            result[key] = value
-        return result
-
     def CALL_FUNCTION(f, oparg):
         f.call_function_extra(oparg, False, False)
 

Modified: pypy/trunk/src/pypy/objspace/descroperation.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/descroperation.py	(original)
+++ pypy/trunk/src/pypy/objspace/descroperation.py	Fri Jun 25 14:10:44 2004
@@ -58,27 +58,23 @@
     def is_data_descr(space, w_obj):
         return space.lookup(w_obj, '__set__') is not None
 
-    def get_and_call(space, w_descr, w_obj, w_args, w_kwargs):
-        descr = space.unwrap_builtin(w_descr)
-        if isinstance(descr, Function):
-            # special-case Functions to avoid infinite recursion
-            args_w = space.unpacktuple(w_args)
-            args_w = [w_obj] + args_w
-            w_args = space.newtuple(args_w)
-            return descr.call(w_args, w_kwargs)
-        else:
-            w_impl = space.get(w_descr, w_obj)
-            return space.call(w_impl, w_args, w_kwargs)
+##    def get_and_call(space, w_descr, w_obj, w_args, w_kwargs):
+##        descr = space.unwrap_builtin(w_descr)
+##        if isinstance(descr, Function):
+##            # special-case Functions to avoid infinite recursion
+##            args_w = space.unpacktuple(w_args)
+##            args_w = [w_obj] + args_w
+##            w_args = space.newtuple(args_w)
+##            return descr.call(w_args, w_kwargs)
+##        else:
+##            w_impl = space.get(w_descr, w_obj)
+##            return space.call(w_impl, w_args, w_kwargs)
 
     def get_and_call_function(space, w_descr, w_obj, *args_w, **kwargs_w):
         descr = space.unwrap_builtin(w_descr)
         if isinstance(descr, Function):
             # special-case Functions to avoid infinite recursion
-            args_w = [w_obj] + list(args_w)
-            w_args = space.newtuple(args_w)
-            w_kwargs = space.newdict([(space.wrap(key), w_item)
-                                      for key, w_item in kwargs_w])
-            return descr.call(w_args, w_kwargs)
+            return descr.call_function(w_obj, *args_w, **kwargs_w)
         else:
             w_impl = space.get(w_descr, w_obj)
             return space.call_function(w_impl, *args_w, **kwargs_w)
@@ -86,13 +82,20 @@
     def unwrap_builtin(self, w_obj):
         return w_obj    # hook for hack by TrivialObjSpace
 
-    def call(space, w_obj, w_args, w_kwargs):
-        #print "call %r, %r, %r" %(w_obj, w_args, w_kwargs)
+##    def call(space, w_obj, w_args, w_kwargs):
+##        #print "call %r, %r, %r" %(w_obj, w_args, w_kwargs)
+##        w_descr = space.lookup(w_obj, '__call__')
+##        if w_descr is None:
+##            raise OperationError(space.w_TypeError, 
+##                              space.wrap('object %r is not callable' % (w_obj,)))
+##        return space.get_and_call(w_descr, w_obj, w_args, w_kwargs)
+
+    def call_function(space, w_obj, *args_w, **kwds_w):
         w_descr = space.lookup(w_obj, '__call__')
         if w_descr is None:
             raise OperationError(space.w_TypeError, 
-                              space.wrap('object %r is not callable' % (w_obj,)))
-        return space.get_and_call(w_descr, w_obj, w_args, w_kwargs)
+                                 space.wrap('object %r is not callable' % (w_obj,)))
+        return space.get_and_call_function(w_descr, w_obj, *args_w, **kwds_w)
 
     def get(space,w_descr,w_obj,w_type=None):
         w_get = space.lookup(w_descr,'__get__')

Modified: pypy/trunk/src/pypy/objspace/flow/objspace.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/flow/objspace.py	(original)
+++ pypy/trunk/src/pypy/objspace/flow/objspace.py	Fri Jun 25 14:10:44 2004
@@ -147,6 +147,10 @@
         else:
             return w_item
 
+    def call_function(self, w_callable, *args_w, **kwds_w):
+        assert not kwds_w, "don't know yet about keyword arguments"
+        return self.do_operation('simple_call', w_callable, *args_w)
+
 # ______________________________________________________________________
 
 implicit_exceptions = {

Modified: pypy/trunk/src/pypy/objspace/std/cpythonobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/cpythonobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/cpythonobject.py	Fri Jun 25 14:10:44 2004
@@ -16,14 +16,12 @@
         self.space = space
         self.cpyfunc = cpyfunc
 
-    def call(self, w_args, w_kwds):
+    def call_function(self, *args_w, **kwds_w):
         space = self.space
         try:
-            args = space.unwrap(w_args)
-            kwds = {}
-            keys_w = space.unpackiterable(w_kwds)
-            for w_key in keys_w:
-                kwds[space.unwrap(w_key)] = space.unwrap(space.getitem(w_kwds, w_key))
+            args = [space.unwrap(w_arg) for w_arg in args_w]
+            kwds = dict([(key, space.unwrap(w_value))
+                         for key, w_value in kwds_w.items()])
         except UnwrapError, e:
             raise UnwrapError('calling %s: %s' % (self.cpyfunc, e))
         try:
@@ -87,9 +85,8 @@
     name = exc.__name__
     if hasattr(space, 'w_' + name):
         w_exc = getattr(space, 'w_' + name)
-        w_value = space.call(w_exc,
-            space.newtuple([space.wrap(a) for a in value.args]),
-            space.newdict([]))
+        w_value = space.call_function(w_exc,
+            *[space.wrap(a) for a in value.args])
         for key, value in value.__dict__.items():
             if not key.startswith('_'):
                 space.setattr(w_value, space.wrap(key), space.wrap(value))

Modified: pypy/trunk/src/pypy/objspace/std/typeobject.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/std/typeobject.py	(original)
+++ pypy/trunk/src/pypy/objspace/std/typeobject.py	Fri Jun 25 14:10:44 2004
@@ -92,18 +92,18 @@
 
 def call__Type(space, w_type, w_args, w_kwds):
     args_w = space.unpacktuple(w_args)
+    kwds_w = space.unpackdictionary(w_kwds)
     # special case for type(x)
     if (space.is_true(space.is_(w_type, space.w_type)) and
-        len(args_w) == 1 and not space.is_true(w_kwds)):
+        len(args_w) == 1 and not kwds_w):
         return space.type(args_w[0])
     # invoke the __new__ of the type
-    w_descr = space.getattr(w_type, space.wrap('__new__'))
-    w_extendedargs = space.newtuple([w_type] + args_w)
-    w_newobject = space.call(w_descr, w_extendedargs, w_kwds)
+    w_newfunc = space.getattr(w_type, space.wrap('__new__'))
+    w_newobject = space.call_function(w_newfunc, w_type, *args_w, **kwds_w)
     # maybe invoke the __init__ of the type
     if space.is_true(space.isinstance(w_newobject, w_type)):
         w_descr = space.lookup(w_newobject, '__init__')
-        space.get_and_call(w_descr, w_newobject, w_args, w_kwds)
+        space.get_and_call_function(w_descr, w_newobject, *args_w, **kwds_w)
     return w_newobject
 
 def issubtype__Type_Type(space, w_type1, w_type2):

Modified: pypy/trunk/src/pypy/objspace/trivial.py
==============================================================================
--- pypy/trunk/src/pypy/objspace/trivial.py	(original)
+++ pypy/trunk/src/pypy/objspace/trivial.py	Fri Jun 25 14:10:44 2004
@@ -479,18 +479,18 @@
                     return cls.__dict__[name]
             return None
 
-    def get_and_call(self, w_descr, w_obj, w_args, w_kwargs):
-        if isinstance(w_descr, CPyWrapper):
-            return DescrOperation.get_and_call(self, w_descr, w_obj,
-                                               w_args, w_kwargs)
-        else:
-            try:
-                obj = self.unwrap(w_obj)
-                if hasattr(w_descr, '__get__'):
-                    obj = w_descr.__get__(obj, type(obj))
-                return obj(*w_args, **w_kwargs)
-            except:
-                self.reraise()
+##    def get_and_call(self, w_descr, w_obj, w_args, w_kwargs):
+##        if isinstance(w_descr, CPyWrapper):
+##            return DescrOperation.get_and_call(self, w_descr, w_obj,
+##                                               w_args, w_kwargs)
+##        else:
+##            try:
+##                obj = self.unwrap(w_obj)
+##                if hasattr(w_descr, '__get__'):
+##                    obj = w_descr.__get__(obj, type(obj))
+##                return obj(*w_args, **w_kwargs)
+##            except:
+##                self.reraise()
 
     def get_and_call_function(self, w_descr, w_obj, *args_w, **kwargs_w):
         if isinstance(w_descr, CPyWrapper):

Modified: pypy/trunk/src/pypy/translator/annrpython.py
==============================================================================
--- pypy/trunk/src/pypy/translator/annrpython.py	(original)
+++ pypy/trunk/src/pypy/translator/annrpython.py	Fri Jun 25 14:10:44 2004
@@ -119,7 +119,7 @@
 
     #___ interface for annotator.factory _______
 
-    def recursivecall(self, func, inputcells, factory):
+    def recursivecall(self, func, factory, *args):
         graph = self.translator.getflowgraph(func)
         # self.notify[graph.returnblock] is a dictionary of
         # FuncCallFactories (call points to this func) which triggers a
@@ -128,6 +128,7 @@
         callfactories[factory] = True
         # generalize the function's input arguments
         block = graph.startblock
+        inputcells = list(args)
         assert len(inputcells) == len(block.inputargs)
         self.addpendingblock(block, inputcells)
         # get the (current) return value
@@ -289,9 +290,9 @@
         factory = self.bookkeeper.getfactory(DictFactory)
         return factory.create()
 
-    def decode_simple_call(self, s_varargs, s_varkwds):
-        # XXX replace all uses of this with direct calls into annmodel
-        return annmodel.decode_simple_call(s_varargs, s_varkwds)
+##    def decode_simple_call(self, s_varargs, s_varkwds):
+##        # XXX replace all uses of this with direct calls into annmodel
+##        return annmodel.decode_simple_call(s_varargs, s_varkwds)
 
 ##    def consider_op_call(self, s_func, s_varargs, s_kwargs):
 ##        if not s_func.is_constant():

Modified: pypy/trunk/src/pypy/translator/transform.py
==============================================================================
--- pypy/trunk/src/pypy/translator/transform.py	(original)
+++ pypy/trunk/src/pypy/translator/transform.py	Fri Jun 25 14:10:44 2004
@@ -67,34 +67,35 @@
 # -->
 # e = simple_call(a, *b)
 
-def transform_simple_call(self):
-    """Transforms call(a, (...), {}) to simple_call(a, ...)"""
-    for block in self.annotated:
-        known_vars = block.inputargs[:]
-        operations = []
-        for op in block.operations:
-            try:
-                if op.opname != 'call':
-                    raise CannotSimplify
-                varargs_cell = self.binding(op.args[1])
-                varkwds_cell = self.binding(op.args[2])
-                arg_cells = self.decode_simple_call(varargs_cell,
-                                                    varkwds_cell)
-                if arg_cells is None:
-                    raise CannotSimplify
-
-                args = [self.reverse_binding(known_vars, c) for c in arg_cells]
-                args.insert(0, op.args[0])
-                new_ops = [SpaceOperation('simple_call', args, op.result)]
+## REMOVED: now FlowObjSpace produces 'simple_call' operations only
+##def transform_simple_call(self):
+##    """Transforms call(a, (...), {}) to simple_call(a, ...)"""
+##    for block in self.annotated:
+##        known_vars = block.inputargs[:]
+##        operations = []
+##        for op in block.operations:
+##            try:
+##                if op.opname != 'call':
+##                    raise CannotSimplify
+##                varargs_cell = self.binding(op.args[1])
+##                varkwds_cell = self.binding(op.args[2])
+##                arg_cells = self.decode_simple_call(varargs_cell,
+##                                                    varkwds_cell)
+##                if arg_cells is None:
+##                    raise CannotSimplify
+
+##                args = [self.reverse_binding(known_vars, c) for c in arg_cells]
+##                args.insert(0, op.args[0])
+##                new_ops = [SpaceOperation('simple_call', args, op.result)]
                 
-            except CannotSimplify:
-                new_ops = [op]
+##            except CannotSimplify:
+##                new_ops = [op]
 
-            for op in new_ops:
-                operations.append(op)
-                known_vars.append(op.result)
+##            for op in new_ops:
+##                operations.append(op)
+##                known_vars.append(op.result)
 
-        block.operations = operations
+##        block.operations = operations
 
 def transform_dead_op_vars(self):
     """Remove dead operations and variables that are passed over a link
@@ -172,7 +173,6 @@
     """Apply set of transformations available."""
     transform_allocate(ann)
     transform_slice(ann)
-    transform_simple_call(ann)
     # do this last, after the previous transformations had a
     # chance to remove dependency on certain variables
     transform_dead_op_vars(ann)



More information about the Pypy-commit mailing list