Skip to content

Commit 877e857

Browse files
committed
byterun/pyvm2.py: Fix CALL_FUNCTION_KW and add _EX (need nedbat#20 PR)
1 parent 1240e36 commit 877e857

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

byterun/pyvm2.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1019,16 +1019,45 @@ def byte_MAKE_CLOSURE(self, argc):
10191019
fn = Function(name, code, globs, defaults, closure, self)
10201020
self.push(fn)
10211021

1022+
def byte_CALL_FUNCTION_EX(self, arg):
1023+
# Calls a function. The lowest bit of flags indicates whether the
1024+
# var-keyword argument is placed at the top of the stack. Below
1025+
# the var-keyword argument, the var-positional argument is on the
1026+
# stack. Below the arguments, the function object to call is placed.
1027+
# Pops all function arguments, and the function itself off the stack,
1028+
# and pushes the return value.
1029+
# Note that this opcode pops at most three items from the stack.
1030+
#Var-positional and var-keyword arguments are packed by
1031+
#BUILD_TUPLE_UNPACK_WITH_CALL and BUILD_MAP_UNPACK_WITH_CALL.
1032+
# new in 3.6
1033+
varkw = self.pop() if (arg & 0x1) else {}
1034+
varpos = self.pop()
1035+
return self.call_function(0, varpos, varkw)
1036+
10221037
def byte_CALL_FUNCTION(self, arg):
1038+
# Calls a function. argc indicates the number of positional arguments.
1039+
# The positional arguments are on the stack, with the right-most
1040+
# argument on top. Below the arguments, the function object to call is
1041+
# on the stack. Pops all function arguments, and the function itself
1042+
# off the stack, and pushes the return value.
1043+
# 3.6: Only used for calls with positional args
10231044
return self.call_function(arg, [], {})
10241045

10251046
def byte_CALL_FUNCTION_VAR(self, arg):
10261047
args = self.pop()
10271048
return self.call_function(arg, args, {})
10281049

1029-
def byte_CALL_FUNCTION_KW(self, arg):
1030-
kwargs = self.pop()
1031-
return self.call_function(arg, [], kwargs)
1050+
def byte_CALL_FUNCTION_KW(self, argc):
1051+
if not(six.PY3 and sys.version_info.minor >= 6):
1052+
kwargs = self.pop()
1053+
return self.call_function(arg, [], kwargs)
1054+
# changed in 3.6: keyword arguments are packed in a tuple instead
1055+
# of a dict. argc indicates total number of args.
1056+
kwargnames = self.pop()
1057+
lkwargs = len(kwargnames)
1058+
kwargs = self.popn(lkwargs)
1059+
arg = argc - lkwargs
1060+
return self.call_function(arg, [], dict(zip(kwargnames, kwargs)))
10321061

10331062
def byte_CALL_FUNCTION_VAR_KW(self, arg):
10341063
args, kwargs = self.popn(2)

0 commit comments

Comments
 (0)