Author: Ronan Lamy <[email protected]>
Branch: translation-cleanup
Changeset: r58228:92cf20b78c89
Date: 2012-10-18 18:28 +0100
http://bitbucket.org/pypy/pypy/changeset/92cf20b78c89/

Log:    inline some Arguments code into ArgsFT

diff --git a/pypy/objspace/flow/argument.py b/pypy/objspace/flow/argument.py
--- a/pypy/objspace/flow/argument.py
+++ b/pypy/objspace/flow/argument.py
@@ -93,49 +93,9 @@
 
     ###  Construction  ###
 
-    def __init__(self, space, args_w, keywords=None, keywords_w=None,
-                 w_stararg=None, w_starstararg=None, keyword_names_w=None):
-        self.space = space
-        assert isinstance(args_w, list)
-        self.arguments_w = args_w
-        self.keywords = keywords
-        self.keywords_w = keywords_w
-        self.keyword_names_w = keyword_names_w  # matches the tail of .keywords
-        if keywords is not None:
-            assert keywords_w is not None
-            assert len(keywords_w) == len(keywords)
-            assert (keyword_names_w is None or
-                    len(keyword_names_w) <= len(keywords))
-            make_sure_not_resized(self.keywords)
-            make_sure_not_resized(self.keywords_w)
-
-        make_sure_not_resized(self.arguments_w)
-        self._combine_wrapped(w_stararg, w_starstararg)
-        # a flag that specifies whether the JIT can unroll loops that operate
-        # on the keywords
-        self._jit_few_keywords = self.keywords is None or 
jit.isconstant(len(self.keywords))
-
-    def __repr__(self):
-        """ NOT_RPYTHON """
-        name = self.__class__.__name__
-        if not self.keywords:
-            return '%s(%s)' % (name, self.arguments_w,)
-        else:
-            return '%s(%s, %s, %s)' % (name, self.arguments_w,
-                                       self.keywords, self.keywords_w)
-
 
     ###  Manipulation  ###
 
-    @jit.look_inside_iff(lambda self: self._jit_few_keywords)
-    def unpack(self): # slowish
-        "Return a ([w1,w2...], {'kw':w3...}) pair."
-        kwds_w = {}
-        if self.keywords:
-            for i in range(len(self.keywords)):
-                kwds_w[self.keywords[i]] = self.keywords_w[i]
-        return self.arguments_w, kwds_w
-
     def replace_arguments(self, args_w):
         "Return a new Arguments with a args_w as positional arguments."
         return Arguments(self.space, args_w, self.keywords, self.keywords_w,
@@ -228,7 +188,192 @@
 
     ###  Parsing for function calls  ###
 
-    @jit.unroll_safe
+    def parse_into_scope(self, w_firstarg,
+                         scope_w, fnname, signature, defaults_w=None):
+        """Parse args and kwargs to initialize a frame
+        according to the signature of code object.
+        Store the argumentvalues into scope_w.
+        scope_w must be big enough for signature.
+        """
+        try:
+            self._match_signature(w_firstarg,
+                                  scope_w, signature, defaults_w, 0)
+        except ArgErr, e:
+            raise operationerrfmt(self.space.w_TypeError,
+                                  "%s() %s", fnname, e.getmsg())
+        return signature.scope_length()
+
+    def _parse(self, w_firstarg, signature, defaults_w, blindargs=0):
+        """Parse args and kwargs according to the signature of a code object,
+        or raise an ArgErr in case of failure.
+        """
+        scopelen = signature.scope_length()
+        scope_w = [None] * scopelen
+        self._match_signature(w_firstarg, scope_w, signature, defaults_w,
+                              blindargs)
+        return scope_w
+
+
+    def parse_obj(self, w_firstarg,
+                  fnname, signature, defaults_w=None, blindargs=0):
+        """Parse args and kwargs to initialize a frame
+        according to the signature of code object.
+        """
+        try:
+            return self._parse(w_firstarg, signature, defaults_w, blindargs)
+        except ArgErr, e:
+            raise operationerrfmt(self.space.w_TypeError,
+                                  "%s() %s", fnname, e.getmsg())
+
+    @staticmethod
+    def frompacked(space, w_args=None, w_kwds=None):
+        """Convenience static method to build an Arguments
+           from a wrapped sequence and a wrapped dictionary."""
+        return Arguments(space, [], w_stararg=w_args, w_starstararg=w_kwds)
+
+    def topacked(self):
+        """Express the Argument object as a pair of wrapped w_args, w_kwds."""
+        space = self.space
+        w_args = space.newtuple(self.arguments_w)
+        w_kwds = space.newdict()
+        if self.keywords is not None:
+            limit = len(self.keywords)
+            if self.keyword_names_w is not None:
+                limit -= len(self.keyword_names_w)
+            for i in range(len(self.keywords)):
+                if i < limit:
+                    w_key = space.wrap(self.keywords[i])
+                else:
+                    w_key = self.keyword_names_w[i - limit]
+                space.setitem(w_kwds, w_key, self.keywords_w[i])
+        return w_args, w_kwds
+
+# JIT helper functions
+# these functions contain functionality that the JIT is not always supposed to
+# look at. They should not get a self arguments, which makes the amount of
+# arguments annoying :-(
+
+def _check_not_duplicate_kwargs(space, existingkeywords, keywords, keywords_w):
+    # looks quadratic, but the JIT should remove all of it nicely.
+    # Also, all the lists should be small
+    for key in keywords:
+        for otherkey in existingkeywords:
+            if otherkey == key:
+                raise operationerrfmt(space.w_TypeError,
+                                      "got multiple values "
+                                      "for keyword argument "
+                                      "'%s'", key)
+
+def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords,
+        keywords_w, existingkeywords):
+    i = 0
+    for w_key in keys_w:
+        try:
+            key = space.str_w(w_key)
+        except OperationError, e:
+            if e.match(space, space.w_TypeError):
+                raise OperationError(
+                    space.w_TypeError,
+                    space.wrap("keywords must be strings"))
+            if e.match(space, space.w_UnicodeEncodeError):
+                # Allow this to pass through
+                key = None
+            else:
+                raise
+        else:
+            if existingkeywords and key in existingkeywords:
+                raise operationerrfmt(space.w_TypeError,
+                                      "got multiple values "
+                                      "for keyword argument "
+                                      "'%s'", key)
+        keywords[i] = key
+        keywords_w[i] = space.getitem(w_starstararg, w_key)
+        i += 1
+
+def _match_keywords(signature, blindargs, input_argcount,
+                    keywords, kwds_mapping):
+    # letting JIT unroll the loop is *only* safe if the callsite didn't
+    # use **args because num_kwds can be arbitrarily large otherwise.
+    num_kwds = num_remainingkwds = len(keywords)
+    for i in range(num_kwds):
+        name = keywords[i]
+        # If name was not encoded as a string, it could be None. In that
+        # case, it's definitely not going to be in the signature.
+        if name is None:
+            continue
+        j = signature.find_argname(name)
+        # if j == -1 nothing happens, because j < input_argcount and
+        # blindargs > j
+        if j < input_argcount:
+            # check that no keyword argument conflicts with these. note
+            # that for this purpose we ignore the first blindargs,
+            # which were put into place by prepend().  This way,
+            # keywords do not conflict with the hidden extra argument
+            # bound by methods.
+            if blindargs <= j:
+                raise ArgErrMultipleValues(name)
+        else:
+            kwds_mapping[j - input_argcount] = i # map to the right index
+            num_remainingkwds -= 1
+    return num_remainingkwds
+
+def _collect_keyword_args(space, keywords, keywords_w, w_kwds, kwds_mapping,
+                          keyword_names_w):
+    limit = len(keywords)
+    if keyword_names_w is not None:
+        limit -= len(keyword_names_w)
+    for i in range(len(keywords)):
+        # again a dangerous-looking loop that either the JIT unrolls
+        # or that is not too bad, because len(kwds_mapping) is small
+        for j in kwds_mapping:
+            if i == j:
+                break
+        else:
+            if i < limit:
+                w_key = space.wrap(keywords[i])
+            else:
+                w_key = keyword_names_w[i - limit]
+            space.setitem(w_kwds, w_key, keywords_w[i])
+
+class ArgumentsForTranslation(Arguments):
+    def __init__(self, space, args_w, keywords=None, keywords_w=None,
+                 w_stararg=None, w_starstararg=None):
+        self.w_stararg = w_stararg
+        self.w_starstararg = w_starstararg
+        self.combine_has_happened = False
+        self.space = space
+        assert isinstance(args_w, list)
+        self.arguments_w = args_w
+        self.keywords = keywords
+        self.keywords_w = keywords_w
+        self.keyword_names_w = None
+
+    def __repr__(self):
+        """ NOT_RPYTHON """
+        name = self.__class__.__name__
+        if not self.keywords:
+            return '%s(%s)' % (name, self.arguments_w,)
+        else:
+            return '%s(%s, %s, %s)' % (name, self.arguments_w,
+                                       self.keywords, self.keywords_w)
+
+    def combine_if_necessary(self):
+        if self.combine_has_happened:
+            return
+        self._combine_wrapped(self.w_stararg, self.w_starstararg)
+        self.combine_has_happened = True
+
+    def prepend(self, w_firstarg): # used often
+        "Return a new Arguments with a new argument inserted first."
+        return ArgumentsForTranslation(self.space, [w_firstarg] + 
self.arguments_w,
+                                       self.keywords, self.keywords_w, 
self.w_stararg,
+                                       self.w_starstararg)
+
+    def copy(self):
+        return ArgumentsForTranslation(self.space, self.arguments_w,
+                                       self.keywords, self.keywords_w, 
self.w_stararg,
+                                       self.w_starstararg)
+
     def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None,
                          blindargs=0):
         """Parse args and kwargs according to the signature of a code object,
@@ -238,10 +383,7 @@
         #   args_w = list of the normal actual parameters, wrapped
         #   scope_w = resulting list of wrapped values
         #
-
-        # some comments about the JIT: it assumes that signature is a constant,
-        # so all values coming from there can be assumed constant. It assumes
-        # that the length of the defaults_w does not vary too much.
+        self.combine_if_necessary()
         co_argcount = signature.num_argnames() # expected formal arguments, 
without */**
 
         # put the special w_firstarg into the scope, if it exists
@@ -311,13 +453,12 @@
             # escape
             num_remainingkwds = _match_keywords(
                     signature, blindargs, input_argcount, keywords,
-                    kwds_mapping, self._jit_few_keywords)
+                    kwds_mapping)
             if num_remainingkwds:
                 if w_kwds is not None:
                     # collect extra keyword arguments into the **kwarg
-                    _collect_keyword_args(
-                            self.space, keywords, keywords_w, w_kwds,
-                            kwds_mapping, self.keyword_names_w, 
self._jit_few_keywords)
+                    _collect_keyword_args( self.space, keywords, keywords_w,
+                            w_kwds, kwds_mapping, self.keyword_names_w)
                 else:
                     if co_argcount == 0:
                         raise ArgErrCount(avail, num_kwds, signature, 
defaults_w, 0)
@@ -346,203 +487,16 @@
             if missing:
                 raise ArgErrCount(avail, num_kwds, signature, defaults_w, 
missing)
 
+    def unpack(self):
+        "Return a ([w1,w2...], {'kw':w3...}) pair."
+        self.combine_if_necessary()
+        kwds_w = {}
+        if self.keywords:
+            for i in range(len(self.keywords)):
+                kwds_w[self.keywords[i]] = self.keywords_w[i]
+        return self.arguments_w, kwds_w
 
 
-    def parse_into_scope(self, w_firstarg,
-                         scope_w, fnname, signature, defaults_w=None):
-        """Parse args and kwargs to initialize a frame
-        according to the signature of code object.
-        Store the argumentvalues into scope_w.
-        scope_w must be big enough for signature.
-        """
-        try:
-            self._match_signature(w_firstarg,
-                                  scope_w, signature, defaults_w, 0)
-        except ArgErr, e:
-            raise operationerrfmt(self.space.w_TypeError,
-                                  "%s() %s", fnname, e.getmsg())
-        return signature.scope_length()
-
-    def _parse(self, w_firstarg, signature, defaults_w, blindargs=0):
-        """Parse args and kwargs according to the signature of a code object,
-        or raise an ArgErr in case of failure.
-        """
-        scopelen = signature.scope_length()
-        scope_w = [None] * scopelen
-        self._match_signature(w_firstarg, scope_w, signature, defaults_w,
-                              blindargs)
-        return scope_w
-
-
-    def parse_obj(self, w_firstarg,
-                  fnname, signature, defaults_w=None, blindargs=0):
-        """Parse args and kwargs to initialize a frame
-        according to the signature of code object.
-        """
-        try:
-            return self._parse(w_firstarg, signature, defaults_w, blindargs)
-        except ArgErr, e:
-            raise operationerrfmt(self.space.w_TypeError,
-                                  "%s() %s", fnname, e.getmsg())
-
-    @staticmethod
-    def frompacked(space, w_args=None, w_kwds=None):
-        """Convenience static method to build an Arguments
-           from a wrapped sequence and a wrapped dictionary."""
-        return Arguments(space, [], w_stararg=w_args, w_starstararg=w_kwds)
-
-    def topacked(self):
-        """Express the Argument object as a pair of wrapped w_args, w_kwds."""
-        space = self.space
-        w_args = space.newtuple(self.arguments_w)
-        w_kwds = space.newdict()
-        if self.keywords is not None:
-            limit = len(self.keywords)
-            if self.keyword_names_w is not None:
-                limit -= len(self.keyword_names_w)
-            for i in range(len(self.keywords)):
-                if i < limit:
-                    w_key = space.wrap(self.keywords[i])
-                else:
-                    w_key = self.keyword_names_w[i - limit]
-                space.setitem(w_kwds, w_key, self.keywords_w[i])
-        return w_args, w_kwds
-
-# JIT helper functions
-# these functions contain functionality that the JIT is not always supposed to
-# look at. They should not get a self arguments, which makes the amount of
-# arguments annoying :-(
-
[email protected]_inside_iff(lambda space, existingkeywords, keywords, keywords_w:
-        jit.isconstant(len(keywords) and
-        jit.isconstant(existingkeywords)))
-def _check_not_duplicate_kwargs(space, existingkeywords, keywords, keywords_w):
-    # looks quadratic, but the JIT should remove all of it nicely.
-    # Also, all the lists should be small
-    for key in keywords:
-        for otherkey in existingkeywords:
-            if otherkey == key:
-                raise operationerrfmt(space.w_TypeError,
-                                      "got multiple values "
-                                      "for keyword argument "
-                                      "'%s'", key)
-
-def _do_combine_starstarargs_wrapped(space, keys_w, w_starstararg, keywords,
-        keywords_w, existingkeywords):
-    i = 0
-    for w_key in keys_w:
-        try:
-            key = space.str_w(w_key)
-        except OperationError, e:
-            if e.match(space, space.w_TypeError):
-                raise OperationError(
-                    space.w_TypeError,
-                    space.wrap("keywords must be strings"))
-            if e.match(space, space.w_UnicodeEncodeError):
-                # Allow this to pass through
-                key = None
-            else:
-                raise
-        else:
-            if existingkeywords and key in existingkeywords:
-                raise operationerrfmt(space.w_TypeError,
-                                      "got multiple values "
-                                      "for keyword argument "
-                                      "'%s'", key)
-        keywords[i] = key
-        keywords_w[i] = space.getitem(w_starstararg, w_key)
-        i += 1
-
[email protected]_inside_iff(
-    lambda signature, blindargs, input_argcount,
-           keywords, kwds_mapping, jiton: jiton)
-def _match_keywords(signature, blindargs, input_argcount,
-                    keywords, kwds_mapping, _):
-    # letting JIT unroll the loop is *only* safe if the callsite didn't
-    # use **args because num_kwds can be arbitrarily large otherwise.
-    num_kwds = num_remainingkwds = len(keywords)
-    for i in range(num_kwds):
-        name = keywords[i]
-        # If name was not encoded as a string, it could be None. In that
-        # case, it's definitely not going to be in the signature.
-        if name is None:
-            continue
-        j = signature.find_argname(name)
-        # if j == -1 nothing happens, because j < input_argcount and
-        # blindargs > j
-        if j < input_argcount:
-            # check that no keyword argument conflicts with these. note
-            # that for this purpose we ignore the first blindargs,
-            # which were put into place by prepend().  This way,
-            # keywords do not conflict with the hidden extra argument
-            # bound by methods.
-            if blindargs <= j:
-                raise ArgErrMultipleValues(name)
-        else:
-            kwds_mapping[j - input_argcount] = i # map to the right index
-            num_remainingkwds -= 1
-    return num_remainingkwds
-
[email protected]_inside_iff(
-    lambda space, keywords, keywords_w, w_kwds, kwds_mapping,
-        keyword_names_w, jiton: jiton)
-def _collect_keyword_args(space, keywords, keywords_w, w_kwds, kwds_mapping,
-                          keyword_names_w, _):
-    limit = len(keywords)
-    if keyword_names_w is not None:
-        limit -= len(keyword_names_w)
-    for i in range(len(keywords)):
-        # again a dangerous-looking loop that either the JIT unrolls
-        # or that is not too bad, because len(kwds_mapping) is small
-        for j in kwds_mapping:
-            if i == j:
-                break
-        else:
-            if i < limit:
-                w_key = space.wrap(keywords[i])
-            else:
-                w_key = keyword_names_w[i - limit]
-            space.setitem(w_kwds, w_key, keywords_w[i])
-
-class ArgumentsForTranslation(Arguments):
-    def __init__(self, space, args_w, keywords=None, keywords_w=None,
-                 w_stararg=None, w_starstararg=None):
-        self.w_stararg = w_stararg
-        self.w_starstararg = w_starstararg
-        self.combine_has_happened = False
-        Arguments.__init__(self, space, args_w, keywords, keywords_w)
-
-    def combine_if_necessary(self):
-        if self.combine_has_happened:
-            return
-        self._combine_wrapped(self.w_stararg, self.w_starstararg)
-        self.combine_has_happened = True
-
-    def prepend(self, w_firstarg): # used often
-        "Return a new Arguments with a new argument inserted first."
-        return ArgumentsForTranslation(self.space, [w_firstarg] + 
self.arguments_w,
-                                       self.keywords, self.keywords_w, 
self.w_stararg,
-                                       self.w_starstararg)
-
-    def copy(self):
-        return ArgumentsForTranslation(self.space, self.arguments_w,
-                                       self.keywords, self.keywords_w, 
self.w_stararg,
-                                       self.w_starstararg)
-
-
-
-    def _match_signature(self, w_firstarg, scope_w, signature, defaults_w=None,
-                         blindargs=0):
-        self.combine_if_necessary()
-        # _match_signature is destructive
-        return Arguments._match_signature(
-               self, w_firstarg, scope_w, signature,
-               defaults_w, blindargs)
-
-    def unpack(self):
-        self.combine_if_necessary()
-        return Arguments.unpack(self)
-
     def match_signature(self, signature, defaults_w):
         """Parse args and kwargs according to the signature of a code object,
         or raise an ArgErr in case of failure.
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to