[pypy-svn] r14587 - in pypy/dist/pypy/rpython: . test
arigo at codespeak.net
arigo at codespeak.net
Tue Jul 12 22:59:48 CEST 2005
Author: arigo
Date: Tue Jul 12 22:59:46 2005
New Revision: 14587
Modified:
pypy/dist/pypy/rpython/rpbc.py
pypy/dist/pypy/rpython/test/test_rpbc.py
Log:
Support for call to functions taking *args.
Modified: pypy/dist/pypy/rpython/rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/rpbc.py (original)
+++ pypy/dist/pypy/rpython/rpbc.py Tue Jul 12 22:59:46 2005
@@ -1,4 +1,5 @@
import types
+import sys
from pypy.annotation.pairtype import pairtype, pair
from pypy.annotation import model as annmodel
from pypy.annotation.classdef import isclassdef
@@ -8,6 +9,8 @@
from pypy.rpython.rmodel import Repr, TyperError, inputconst, warning
from pypy.rpython import rclass
from pypy.rpython import robject
+from pypy.rpython import rtuple
+from pypy.tool.sourcetools import has_varargs
class __extend__(annmodel.SomePBC):
def rtyper_makerepr(self, rtyper):
@@ -336,25 +339,44 @@
def rtype_simple_call(self, hop):
f, rinputs, rresult = self.function_signatures().itervalues().next()
- defaultclist = []
- if len(rinputs) != hop.nb_args-1: # argument count mismatch
- assert not getattr(f._obj.graph, 'normalized_for_calls', False), (
- "normalization bug")
- assert len(self.function_signatures()) == 1, "normalization bug too"
+ extravlist = []
+ if getattr(f._obj.graph, 'normalized_for_calls', False):
+ # should not have an argument count mismatch
+ assert len(rinputs) == hop.nb_args-1, "normalization bug"
+ else:
+ # if not normalized, should be a call to a known function
+ assert len(self.function_signatures()) == 1, "normalization bug"
func, = self.function_signatures().keys()
+ if has_varargs(func):
+ # collect the arguments for '*arg' into a tuple
+ rstar = rinputs[-1]
+ rinputs = rinputs[:-1]
+ assert isinstance(rstar, rtuple.TupleRepr)
+ tupleitems_v = []
+ for i in range(1+len(rinputs), hop.nb_args):
+ v = hop.inputarg(rstar.items_r[len(tupleitems_v)], arg=i)
+ tupleitems_v.append(v)
+ vtuple = rtuple.newtuple(hop.llops, rstar, tupleitems_v)
+ extravlist.append(vtuple)
+ hop = hop.copy()
+ del hop.args_v[1+len(rinputs):]
+ del hop.args_s[1+len(rinputs):]
+ del hop.args_r[1+len(rinputs):]
+ hop.nb_args = len(hop.args_v)
+
defaults = func.func_defaults or ()
if len(rinputs) - len(defaults) <= hop.nb_args-1 <= len(rinputs):
rinputs = list(rinputs)
defaults = list(defaults)
- while len(rinputs) != hop.nb_args-1:
+ while len(rinputs) > hop.nb_args-1:
c = hop.inputconst(rinputs.pop(), defaults.pop())
- defaultclist.insert(0, c)
+ extravlist.insert(0, c)
else:
if hop.nb_args-1 > len(rinputs):
- raise RTyperError("too many arguments in function call")
+ raise TyperError("too many arguments in function call")
else:
- raise RTyperError("not enough arguments in function call")
- vlist = hop.inputargs(self, *rinputs) + defaultclist
+ raise TyperError("not enough arguments in function call")
+ vlist = hop.inputargs(self, *rinputs) + extravlist
if self.lowleveltype == Void:
assert len(self.function_signatures()) == 1
vlist[0] = hop.inputconst(typeOf(f), f)
Modified: pypy/dist/pypy/rpython/test/test_rpbc.py
==============================================================================
--- pypy/dist/pypy/rpython/test/test_rpbc.py (original)
+++ pypy/dist/pypy/rpython/test/test_rpbc.py Tue Jul 12 22:59:46 2005
@@ -390,3 +390,27 @@
assert res.inst_z == -7645
assert res._obj._parentstructure().inst_extra == 42
+def test_call_starargs():
+ def g(x=-100, *arg):
+ return x + len(arg)
+ def f(i):
+ if i == -1:
+ return g()
+ elif i == 0:
+ return g(4)
+ elif i == 1:
+ return g(5, 15)
+ elif i == 2:
+ return g(7, 17, 27)
+ else:
+ return g(10, 198, 1129, 13984)
+ res = interpret(f, [-1])
+ assert res == -100
+ res = interpret(f, [0])
+ assert res == 4
+ res = interpret(f, [1])
+ assert res == 6
+ res = interpret(f, [2])
+ assert res == 9
+ res = interpret(f, [3])
+ assert res == 13
More information about the Pypy-commit
mailing list