[pypy-commit] pypy py3.5: Finish handling positional and keyword args on function call
raffael_t
pypy.commits at gmail.com
Wed Jun 1 16:21:01 EDT 2016
Author: Raffael Tfirst <raffael.tfirst at gmail.com>
Branch: py3.5
Changeset: r84872:ae9d71da76a0
Date: 2016-06-01 22:20 +0200
http://bitbucket.org/pypy/pypy/changeset/ae9d71da76a0/
Log: Finish handling positional and keyword args on function call
diff --git a/pypy/interpreter/astcompiler/codegen.py b/pypy/interpreter/astcompiler/codegen.py
--- a/pypy/interpreter/astcompiler/codegen.py
+++ b/pypy/interpreter/astcompiler/codegen.py
@@ -1115,8 +1115,7 @@
for elt in args:
if isinstance(elt.kind, ast.Starred):
# A star-arg. If we've seen positional arguments,
- # pack the positional arguments into a
- # tuple.
+ # pack the positional arguments into a tuple.
if nseen != 0:
ops.BUILD_TUPLE(nseen)
nseen = 0
@@ -1137,18 +1136,48 @@
# Pack up any trailing positional arguments.
ops.BUILD_TUPLE(nseen)
nsubargs += 1
- #TODO
- #------------old
- self.visit_sequence(args)
- if keywords:
- self.visit_sequence(keywords)
- arg |= len(keywords) << 8
- if starargs:
- starargs.walkabout(self)
+ if nsubargs != 0:
call_type |= 1
- if kwargs:
- kwargs.walkabout(self)
+ if nsubargs > 1:
+ # If we ended up with more than one stararg, we need
+ # to concatenate them into a single sequence.
+ ops.BUILD_LIST_UNPACK(nsubargs)
+
+ # Repeat procedure for keyword args
+ nseen = 0 # the number of keyword arguments on the stack following
+ for kw in keywords:
+ if kw.arg is None:
+ # A keyword argument unpacking.
+ if nseen != 0:
+ ops.BUILD_MAP(nseen)
+ nseen = 0
+ nsubkwargs += 1
+ self.visit(kw.value) # probably wrong, elt->v.Starred.value
+ nsubkwargs += 1
+ elif nsubkwargs != 0:
+ # A keyword argument and we already have a dict.
+ ops.LOAD_CONST(kw.arg, consts)
+ self.visit(kw.value)
+ nseen += 1
+ else:
+ # keyword argument
+ self.visit(kw)
+ nkw += 1
+ if nseen != 0:
+ # Pack up any trailing keyword arguments.
+ ops.BUILD_MAP(nseen)
+ nsubkwargs += 1
+ if nsubargs != 0:
call_type |= 2
+ if nsubkwargs > 1:
+ # Pack it all up
+ function_pos = n + (code & 1) + nkw + 1
+ ops.BUILD_MAP_UNPACK_WITH_CALL(nsubkwargs | (function_pos << 8))
+
+ assert n < 1<<8
+ assert nkw < 1<<24
+ n |= nkw << 8;
+
op = 0
if call_type == 0:
op = ops.CALL_FUNCTION
@@ -1159,6 +1188,7 @@
elif call_type == 3:
op = ops.CALL_FUNCTION_VAR_KW
self.emit_op_arg(op, arg)
+ #TODO emip_op_arg on each call
def visit_Call(self, call):
self.update_position(call.lineno)
More information about the pypy-commit
mailing list