Author Mark.Shannon
Recipients Demur Rumed, Mark.Shannon, serhiy.storchaka
Date 2016-06-19.18:42:48
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1466361769.58.0.815030541765.issue27213@psf.upfronthosting.co.za>
In-reply-to
Content
I seemed to have been added to the nosy list. I guess that means that my opinions are wanted ;)

I have wanted to clean up the code around making calls for quite a while. I just haven't had time.

I agree that adding a simpler opcode for making calls with positional only args is worthwhile.
However creating the tuple and/or dict at every call site is going to lead to slow downs. It gets even worse for bound-methods, as yet another tuple will need to be created to accommodate self.

What I would suggest is a new internal calling convention which embodies the six-part form of CALL_FUNCTION_VAR_KW, that is (number-of-postionals, pointer-to-positionals, number-of-keywords, pointer-to-keywords, starargs-tuple, doublestarargs-dict). 
As a first step, each of the four current CALL_FUNCTION variants could then call this function, filling in the relevant parameters.

The new function would look something like this:
PyEval_Call_Callable(
PyObject *callable,
int npos,
PyObject **positionals,
int nkws,
PyObject **keywords,
PyObject *starargs,
PyObject *dictargs) {
    if (Is_PyFunction(callable))
        return PyFunction_Call(callable, npos, ...);

    if (Is_CFunction(callable))
        return CFunction_Call(callable, npos, ...);

    // Otherwise general object...

    // We might want PyType_Call as well, since object creation is
    // another common form of call.

    // Create tuple and dict from args.
    return PyObject_Call(callable, tuple, dict);
}

This would mean that the logic for frame creation would be where it belongs (in the code for the Function object) and that special casing the various forms of CFunctions could be moved to where that belongs.

Given what Serhiy says about calls with just positional parameters being by far the most common, it sounds as if it would make sense to add 
PyFunction_CallSimple(PyObject *callable, int npos, PyObject**args)
and 
CFuntion_CallSimple(PyObject *callable, int npos, PyObject**args) 
variants for the new CALL_FUNCTION opcode to use.

With those changes, it would then make sense to replace the four opcodes
CALL_FUNCTION, CALL_FUNCTION_VAR, CALL_FUNCTION_KW, CALL_FUNCTION_VAR_KW

with 
CALL_FUNCTION -- As Serhiy suggests
CALL_FUNCTION_KW -- As Serhiy suggests
CALL_FUNCTION_VAR_KW -- As currently exists
History
Date User Action Args
2016-06-19 18:42:49Mark.Shannonsetrecipients: + Mark.Shannon, serhiy.storchaka, Demur Rumed
2016-06-19 18:42:49Mark.Shannonsetmessageid: <1466361769.58.0.815030541765.issue27213@psf.upfronthosting.co.za>
2016-06-19 18:42:49Mark.Shannonlinkissue27213 messages
2016-06-19 18:42:48Mark.Shannoncreate