Skip to content

Commit ce8baa0

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

File tree

1 file changed

+32
-3
lines changed

1 file changed

+32
-3
lines changed

byterun/pyvm2.py

+32-3
Original file line numberDiff line numberDiff line change
@@ -1022,16 +1022,45 @@ def byte_MAKE_CLOSURE(self, argc):
10221022
fn = Function(name, code, globs, defaults, closure, self)
10231023
self.push(fn)
10241024

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

10281049
def byte_CALL_FUNCTION_VAR(self, arg):
10291050
args = self.pop()
10301051
return self.call_function(arg, args, {})
10311052

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

10361065
def byte_CALL_FUNCTION_VAR_KW(self, arg):
10371066
args, kwargs = self.popn(2)

0 commit comments

Comments
 (0)