Author: Carl Friedrich Bolz <cfb...@gmx.de>
Branch: virtual-arguments
Changeset: r54390:73f4eae55465
Date: 2012-04-14 10:34 +0200
http://bitbucket.org/pypy/pypy/changeset/73f4eae55465/

Log:    move dangerous loops from _match_signature to the global level

diff --git a/pypy/interpreter/argument.py b/pypy/interpreter/argument.py
--- a/pypy/interpreter/argument.py
+++ b/pypy/interpreter/argument.py
@@ -336,32 +336,12 @@
         # argnames is typically not too large
         num_remainingkwds = num_kwds
         used_keywords = None
-        if keywords:
-            # letting JIT unroll the loop is *only* safe if the callsite didn't
-            # use **args because num_kwds can be arbitrarily large otherwise.
+        if num_kwds:
             used_keywords = [False] * num_kwds
-            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 < 0:
-                    continue
-                elif 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:
-                    assert scope_w[j] is None
-                    scope_w[j] = keywords_w[i]
-                    used_keywords[i] = True # mark as used
-                    num_remainingkwds -= 1
+            num_remainingkwds = _match_keywords(
+                    signature, blindargs, input_argcount, keywords,
+                    keywords_w, scope_w, used_keywords,
+                    self._dont_jit)
         missing = 0
         if input_argcount < co_argcount:
             def_first = co_argcount - (0 if defaults_w is None else 
len(defaults_w))
@@ -377,21 +357,13 @@
                     # keyword arguments, which will be checked for below.
                     missing += 1
 
-        # collect extra keyword arguments into the **kwarg
         if has_kwarg:
             w_kwds = self.space.newdict(kwargs=True)
+            # collect extra keyword arguments into the **kwarg
             if num_remainingkwds:
-                #
-                limit = len(keywords)
-                if self.keyword_names_w is not None:
-                    limit -= len(self.keyword_names_w)
-                for i in range(len(keywords)):
-                    if not used_keywords[i]:
-                        if i < limit:
-                            w_key = self.space.wrap(keywords[i])
-                        else:
-                            w_key = self.keyword_names_w[i - limit]
-                        self.space.setitem(w_kwds, w_key, keywords_w[i])
+                _collect_keyword_args(
+                        self.space, keywords, keywords_w, w_kwds,
+                        used_keywords, self.keyword_names_w, self._dont_jit)
                 #
             scope_w[co_argcount + has_vararg] = w_kwds
         elif num_remainingkwds:
@@ -489,6 +461,53 @@
                                       "for keyword argument "
                                       "'%s'", key)
 
+@jit.look_inside_iff(
+    lambda signature, blindargs, input_argcount, keywords, keywords_w,
+           scope_w, used_keywords, jitoff: not jitoff)
+def _match_keywords(signature, blindargs, input_argcount,
+                    keywords, keywords_w, scope_w, used_keywords, _):
+    # 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 < 0:
+            continue
+        elif 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:
+            assert scope_w[j] is None
+            scope_w[j] = keywords_w[i]
+            used_keywords[i] = True # mark as used
+            num_remainingkwds -= 1
+    return num_remainingkwds
+
+@jit.look_inside_iff(
+    lambda space, keywords, keywords_w, w_kwds, used_keywords,
+           keyword_names_w, jitoff: not jitoff)
+def _collect_keyword_args(space, keywords, keywords_w, w_kwds, used_keywords,
+                          keyword_names_w, _):
+    limit = len(keywords)
+    if keyword_names_w is not None:
+        limit -= len(keyword_names_w)
+    for i in range(len(keywords)):
+        if not used_keywords[i]:
+            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,
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to