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