2010/10/26 M.-A. Lemburg <span dir="ltr"><<a href="mailto:mal@egenix.com">mal@egenix.com</a>></span><br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;"><div><div class="h5">
Cesare Di Mauro wrote:<br>
> 2010/10/26 M.-A. Lemburg <<a href="mailto:mal@egenix.com">mal@egenix.com</a>><br>
><br> > I was referring to the solution (which I prefer) that I proposed answering<br>
> to Greg, two days ago.<br>
><br>
> Unfortunately, the stack must be used whatever the solution we will use.<br>
><br>
> Pushing the "final" tuple and/or dictionary is a possible optimization, but<br>
> we can use it only when we have a tuple or dict of constants; otherwise we<br>
> need to use the stack.<br>
><br>
> Good case: f(1, 2, 3, a = 1, b = 2)<br>
> We can push (1, 2, 3) tuple and {'a' : 1, 'b' : 2}, then calling f with<br>
> CALL_FUNCTION_VAR_KW opcode passing narg = nkarg = 0.<br>
><br>
> Worst case: f(1, x, 3, a = x, b = 2)<br>
> We can't push the tuple and dict as a whole, because they need first to be<br>
> built using the stack.<br>
><br>
> The good case is possible, and I have already done some work in wpython<br>
> collecting constants on parameters push (even partial constant sequences),<br>
> but some additional work must be done recognizing costants-only tuple /<br>
> dict.<br>
><br>
> However, the worst case rest unresolved.<br>
<br>
</div></div>I don't understand. What is the difference between pushing values<br>
on the stack and building a tuple/dict and then pushing those on<br>
the stack ?<br>
<br>
In your worst case example, the compiler would first build<br>
a tuple/dict using the args already on the stack (BUILD_TUPLE,<br>
BUILD_MAP) and then call the function with this tuple/dict<br>
combination - you'd basically move the tuple/dict building to<br>
the compiler rather than having the CALL* opcodes do this<br>
internally.<br>
<br>
It would essentially run:<br>
<div class="im"><br>
f(*(1,x,3), **{'a':x, 'b':2})<br>
<br>
</div>and bypass the "max. number of opcode args" limit without<br>
degrading performance, since BUILD_TUPLE et al. essentially<br>
run the same code for building the call arguments as the<br>
helpers for calling a function.<br>
<div><div class="h5"><br>
--<br>
Marc-Andre Lemburg<br></div></div></blockquote><div><br></div><div>Yes, the idea is to let the compiler emit proper code to build the tuple/dict, instead of using the CALL_* to do it, in order to bypass the current limits.</div>
<div><br></div><div>That's if we don't want to change the current CALL_* behavior, so speeding up the common cases and introducing a slower (but working) path for the uncommon ones.</div><div><br></div><div>Another solution can be to introduce a specific opcode, but I don't see it well if the purpose is just to permit more than 255 arguments.</div>
<div><br></div><div>At this time I have no other ideas to solve this problem.</div><div><br></div><div>Please, let me know if there's interest on a new patch to implement the "compiler-based" solution.</div>
<div><br></div><div>Cesare</div>