Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(179129)

Delta Between Two Patch Sets: Python/ceval.c

Issue 27809: _PyObject_FastCall(): add support for keyword arguments
Left Patch Set: Created 2 years, 11 months ago
Right Patch Set: Created 2 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Left: Side by side diff | Download
Right: Side by side diff | Download
« no previous file with change/comment | « Objects/typeobject.c ('k') | Python/pythonrun.c » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
1 1
2 /* Execute compiled code */ 2 /* Execute compiled code */
3 3
4 /* XXX TO DO: 4 /* XXX TO DO:
5 XXX speed up searching for keywords by using a dictionary 5 XXX speed up searching for keywords by using a dictionary
6 XXX document it! 6 XXX document it!
7 */ 7 */
8 8
9 /* enable more aggressive intra-module optimizations, where available */ 9 /* enable more aggressive intra-module optimizations, where available */
10 #define PY_LOCAL_AGGRESSIVE 10 #define PY_LOCAL_AGGRESSIVE
(...skipping 3766 matching lines...) Expand 10 before | Expand all | Expand 10 after
3777 given == 1 && !kwonly_given ? "was" : "were"); 3777 given == 1 && !kwonly_given ? "was" : "were");
3778 Py_DECREF(sig); 3778 Py_DECREF(sig);
3779 Py_DECREF(kwonly_sig); 3779 Py_DECREF(kwonly_sig);
3780 } 3780 }
3781 3781
3782 3782
3783 /* This is gonna seem *real weird*, but if you put some other code between 3783 /* This is gonna seem *real weird*, but if you put some other code between
3784 PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust 3784 PyEval_EvalFrame() and PyEval_EvalCodeEx() you will need to adjust
3785 the test in the if statements in Misc/gdbinit (pystack and pystackv). */ 3785 the test in the if statements in Misc/gdbinit (pystack and pystackv). */
3786 3786
3787 static int 3787 static PyObject *
3788 fastlocals_dict(PyObject **fastlocals, PyCodeObject *co, 3788 _PyEval_EvalCodeWithName(PyObject *_co, PyObject *globals, PyObject *locals,
3789 PyObject *kwdict, PyObject *kwargs) 3789 PyObject **args, int argcount, PyObject **kws, int kwcount,
3790 { 3790 PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure,
3791 PyObject *name, PyObject *qualname)
3792 {
3793 PyCodeObject* co = (PyCodeObject*)_co;
3794 PyFrameObject *f;
3795 PyObject *retval = NULL;
3796 PyObject **fastlocals, **freevars;
3797 PyThreadState *tstate;
3798 PyObject *x, *u;
3791 const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount; 3799 const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
3792 _Py_IDENTIFIER(items); 3800 Py_ssize_t i, n;
3793 PyObject *items, *iter; 3801 PyObject *kwdict;
3794 PyObject *item = NULL; 3802
3795 3803 assert((kwcount == 0) || (kws != NULL));
3796 assert(PyDict_Check(kwargs)); 3804
3797 3805 if (globals == NULL) {
3798 items = _PyObject_CallMethodId((PyObject *)kwargs, &PyId_items, NULL); 3806 PyErr_SetString(PyExc_SystemError,
3799 if (items == NULL) { 3807 "PyEval_EvalCodeEx: NULL globals");
3800 return -1; 3808 return NULL;
3801 } 3809 }
3802 3810
3803 iter = PyObject_GetIter(items); 3811 /* Create the frame */
3804 Py_DECREF(items); 3812 tstate = PyThreadState_GET();
3805 if (iter == NULL) { 3813 assert(tstate != NULL);
3806 goto fail; 3814 f = PyFrame_New(tstate, co, globals, locals);
3807 } 3815 if (f == NULL) {
3808 3816 return NULL;
3809 do { 3817 }
3818 fastlocals = f->f_localsplus;
3819 freevars = f->f_localsplus + co->co_nlocals;
3820
3821 /* Create a dictionary for keyword parameters (**kwags) */
3822 if (co->co_flags & CO_VARKEYWORDS) {
3823 kwdict = PyDict_New();
3824 if (kwdict == NULL)
3825 goto fail;
3826 i = total_args;
3827 if (co->co_flags & CO_VARARGS) {
3828 i++;
3829 }
3830 SETLOCAL(i, kwdict);
3831 }
3832 else {
3833 kwdict = NULL;
3834 }
3835
3836 /* Copy positional arguments into local variables */
3837 if (argcount > co->co_argcount) {
3838 n = co->co_argcount;
3839 }
3840 else {
3841 n = argcount;
3842 }
3843 for (i = 0; i < n; i++) {
3844 x = args[i];
3845 Py_INCREF(x);
3846 SETLOCAL(i, x);
3847 }
3848
3849 /* Pack other positional arguments into the *args argument */
3850 if (co->co_flags & CO_VARARGS) {
3851 u = PyTuple_New(argcount - n);
3852 if (u == NULL) {
3853 goto fail;
3854 }
3855 SETLOCAL(total_args, u);
3856 for (i = n; i < argcount; i++) {
3857 x = args[i];
3858 Py_INCREF(x);
3859 PyTuple_SET_ITEM(u, i-n, x);
3860 }
3861 }
3862
3863 /* Handle keyword arguments (passed as an array of (key, value)) */
3864 for (i = 0; i < kwcount; i++) {
3810 PyObject **co_varnames; 3865 PyObject **co_varnames;
3811 PyObject *keyword, *value; 3866 PyObject *keyword = kws[2*i];
3812 int j; 3867 PyObject *value = kws[2*i + 1];
3813 3868 Py_ssize_t j;
3814 /* Get first item */
3815 item = PyIter_Next(iter);
3816 if (item == NULL) {
3817 if (PyErr_Occurred()) {
3818 goto fail;
3819 }
3820
3821 /* nothing more to add */
3822 break;
3823 }
3824 assert(PyTuple_CheckExact(item) && PyTuple_GET_SIZE(item) == 2);
3825
3826 keyword = PyTuple_GET_ITEM(item, 0);
3827 value = PyTuple_GET_ITEM(item, 1);
3828 3869
3829 if (keyword == NULL || !PyUnicode_Check(keyword)) { 3870 if (keyword == NULL || !PyUnicode_Check(keyword)) {
3830 PyErr_Format(PyExc_TypeError, 3871 PyErr_Format(PyExc_TypeError,
3831 "%U() keywords must be strings", 3872 "%U() keywords must be strings",
3832 co->co_name); 3873 co->co_name);
3833 goto fail; 3874 goto fail;
3834 } 3875 }
3835 3876
3836 /* Speed hack: do raw pointer compares. As names are 3877 /* Speed hack: do raw pointer compares. As names are
3837 normally interned this should almost always hit. */ 3878 normally interned this should almost always hit. */
(...skipping 20 matching lines...) Expand all
3858 "%U() got an unexpected " 3899 "%U() got an unexpected "
3859 "keyword argument '%S'", 3900 "keyword argument '%S'",
3860 co->co_name, 3901 co->co_name,
3861 keyword); 3902 keyword);
3862 goto fail; 3903 goto fail;
3863 } 3904 }
3864 3905
3865 if (PyDict_SetItem(kwdict, keyword, value) == -1) { 3906 if (PyDict_SetItem(kwdict, keyword, value) == -1) {
3866 goto fail; 3907 goto fail;
3867 } 3908 }
3868 Py_DECREF(item);
3869 continue; 3909 continue;
3870 3910
3871 kw_found: 3911 kw_found:
3872 if (GETLOCAL(j) != NULL) { 3912 if (GETLOCAL(j) != NULL) {
3873 PyErr_Format(PyExc_TypeError, 3913 PyErr_Format(PyExc_TypeError,
3874 "%U() got multiple " 3914 "%U() got multiple "
3875 "values for argument '%S'", 3915 "values for argument '%S'",
3876 co->co_name, 3916 co->co_name,
3877 keyword); 3917 keyword);
3878 goto fail; 3918 goto fail;
3879 } 3919 }
3880 Py_INCREF(value); 3920 Py_INCREF(value);
3881 SETLOCAL(j, value); 3921 SETLOCAL(j, value);
3882
3883 Py_CLEAR(item);
3884 } while (1);
3885
3886 Py_DECREF(iter);
3887 return 0;
3888
3889 fail:
3890 Py_DECREF(iter);
3891 Py_XDECREF(item);
3892 return -1;
3893 }
3894
3895 static PyObject *
3896 _PyEval_EvalCode(PyObject *_co, PyObject *globals, PyObject *locals,
3897 PyObject **args, int argcount,
3898 PyObject **kws, int kwcount, PyObject *kwargs,
3899 PyObject **defs, int defcount,
3900 PyObject *kwdefs, PyObject *closure,
3901 PyObject *name, PyObject *qualname)
3902 {
3903 PyCodeObject* co = (PyCodeObject*)_co;
3904 PyFrameObject *f;
3905 PyObject *retval = NULL;
3906 PyObject **fastlocals, **freevars;
3907 PyThreadState *tstate;
3908 PyObject *x, *u;
3909 const Py_ssize_t total_args = co->co_argcount + co->co_kwonlyargcount;
3910 Py_ssize_t i, n;
3911 PyObject *kwdict;
3912
3913 assert((kwcount == 0) || (kws != NULL));
3914 /* kws and kwargs are mutually exclusive
3915 (arbitrary limit to detect bugs) */
3916 assert(!((kws != NULL) && (kwargs != NULL)));
3917
3918 if (globals == NULL) {
3919 PyErr_SetString(PyExc_SystemError,
3920 "PyEval_EvalCodeEx: NULL globals");
3921 return NULL;
3922 }
3923
3924 /* Create the frame */
3925 tstate = PyThreadState_GET();
3926 assert(tstate != NULL);
3927 f = PyFrame_New(tstate, co, globals, locals);
3928 if (f == NULL) {
3929 return NULL;
3930 }
3931 fastlocals = f->f_localsplus;
3932 freevars = f->f_localsplus + co->co_nlocals;
3933
3934 /* Create a dictionary for keyword parameters (**kwags) */
3935 if (co->co_flags & CO_VARKEYWORDS) {
3936 kwdict = PyDict_New();
3937 if (kwdict == NULL)
3938 goto fail;
3939 i = total_args;
3940 if (co->co_flags & CO_VARARGS) {
3941 i++;
3942 }
3943 SETLOCAL(i, kwdict);
3944 }
3945 else {
3946 kwdict = NULL;
3947 }
3948
3949 /* Copy positional arguments into local variables */
3950 if (argcount > co->co_argcount) {
3951 n = co->co_argcount;
3952 }
3953 else {
3954 n = argcount;
3955 }
3956 for (i = 0; i < n; i++) {
3957 x = args[i];
3958 Py_INCREF(x);
3959 SETLOCAL(i, x);
3960 }
3961
3962 /* Pack other positional arguments into the *args argument */
3963 if (co->co_flags & CO_VARARGS) {
3964 u = PyTuple_New(argcount - n);
3965 if (u == NULL) {
3966 goto fail;
3967 }
3968 SETLOCAL(total_args, u);
3969 for (i = n; i < argcount; i++) {
3970 x = args[i];
3971 Py_INCREF(x);
3972 PyTuple_SET_ITEM(u, i-n, x);
3973 }
3974 }
3975
3976 /* Handle keyword arguments (passed as an array of (key, value)) */
3977 for (i = 0; i < kwcount; i++) {
3978 PyObject **co_varnames;
3979 PyObject *keyword = kws[2*i];
3980 PyObject *value = kws[2*i + 1];
3981 Py_ssize_t j;
3982
3983 if (keyword == NULL || !PyUnicode_Check(keyword)) {
3984 PyErr_Format(PyExc_TypeError,
3985 "%U() keywords must be strings",
3986 co->co_name);
3987 goto fail;
3988 }
3989
3990 /* Speed hack: do raw pointer compares. As names are
3991 normally interned this should almost always hit. */
3992 co_varnames = ((PyTupleObject *)(co->co_varnames))->ob_item;
3993 for (j = 0; j < total_args; j++) {
3994 PyObject *nm = co_varnames[j];
3995 if (nm == keyword)
3996 goto kw_found;
3997 }
3998
3999 /* Slow fallback, just in case */
4000 for (j = 0; j < total_args; j++) {
4001 PyObject *nm = co_varnames[j];
4002 int cmp = PyObject_RichCompareBool(
4003 keyword, nm, Py_EQ);
4004 if (cmp > 0)
4005 goto kw_found;
4006 else if (cmp < 0)
4007 goto fail;
4008 }
4009
4010 if (j >= total_args && kwdict == NULL) {
4011 PyErr_Format(PyExc_TypeError,
4012 "%U() got an unexpected "
4013 "keyword argument '%S'",
4014 co->co_name,
4015 keyword);
4016 goto fail;
4017 }
4018
4019 if (PyDict_SetItem(kwdict, keyword, value) == -1) {
4020 goto fail;
4021 }
4022 continue;
4023
4024 kw_found:
4025 if (GETLOCAL(j) != NULL) {
4026 PyErr_Format(PyExc_TypeError,
4027 "%U() got multiple "
4028 "values for argument '%S'",
4029 co->co_name,
4030 keyword);
4031 goto fail;
4032 }
4033 Py_INCREF(value);
4034 SETLOCAL(j, value);
4035 }
4036
4037 /* Handle keyword arguments (passed as a dictionary) */
4038 if (kwargs != NULL) {
4039 if (fastlocals_dict(fastlocals, co, kwdict, kwargs) < 0) {
4040 goto fail;
4041 }
4042 } 3922 }
4043 3923
4044 /* Check the number of positional arguments */ 3924 /* Check the number of positional arguments */
4045 if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) { 3925 if (argcount > co->co_argcount && !(co->co_flags & CO_VARARGS)) {
4046 too_many_positional(co, argcount, defcount, fastlocals); 3926 too_many_positional(co, argcount, defcount, fastlocals);
4047 goto fail; 3927 goto fail;
4048 } 3928 }
4049 3929
4050 /* Add missing positional arguments (copy default values from defs) */ 3930 /* Add missing positional arguments (copy default values from defs) */
4051 if (argcount < co->co_argcount) { 3931 if (argcount < co->co_argcount) {
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
4181 Py_DECREF(f); 4061 Py_DECREF(f);
4182 --tstate->recursion_depth; 4062 --tstate->recursion_depth;
4183 return retval; 4063 return retval;
4184 } 4064 }
4185 4065
4186 PyObject * 4066 PyObject *
4187 PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals, 4067 PyEval_EvalCodeEx(PyObject *_co, PyObject *globals, PyObject *locals,
4188 PyObject **args, int argcount, PyObject **kws, int kwcount, 4068 PyObject **args, int argcount, PyObject **kws, int kwcount,
4189 PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure) 4069 PyObject **defs, int defcount, PyObject *kwdefs, PyObject *closure)
4190 { 4070 {
4191 return _PyEval_EvalCode(_co, globals, locals, 4071 return _PyEval_EvalCodeWithName(_co, globals, locals,
4192 args, argcount, 4072 args, argcount,
4193 kws, kwcount, NULL, 4073 kws, kwcount,
4194 defs, defcount, 4074 defs, defcount,
4195 kwdefs, closure, 4075 kwdefs, closure,
4196 NULL, NULL); 4076 NULL, NULL);
4197 } 4077 }
4198 4078
4199 static PyObject * 4079 static PyObject *
4200 special_lookup(PyObject *o, _Py_Identifier *id) 4080 special_lookup(PyObject *o, _Py_Identifier *id)
4201 { 4081 {
4202 PyObject *res; 4082 PyObject *res;
4203 res = _PyObject_LookupSpecial(o, id); 4083 res = _PyObject_LookupSpecial(o, id);
4204 if (res == NULL && !PyErr_Occurred()) { 4084 if (res == NULL && !PyErr_Occurred()) {
4205 PyErr_SetObject(PyExc_AttributeError, id->object); 4085 PyErr_SetObject(PyExc_AttributeError, id->object);
4206 return NULL; 4086 return NULL;
(...skipping 499 matching lines...) Expand 10 before | Expand all | Expand 10 after
4706 4586
4707 #ifdef Py_DEBUG 4587 #ifdef Py_DEBUG
4708 /* PyEval_CallObjectWithKeywords() must not be called with an exception 4588 /* PyEval_CallObjectWithKeywords() must not be called with an exception
4709 set. It raises a new exception if parameters are invalid or if 4589 set. It raises a new exception if parameters are invalid or if
4710 PyTuple_New() fails, and so the original exception is lost. */ 4590 PyTuple_New() fails, and so the original exception is lost. */
4711 assert(!PyErr_Occurred()); 4591 assert(!PyErr_Occurred());
4712 #endif 4592 #endif
4713 4593
4714 if (args == NULL) { 4594 if (args == NULL) {
4715 if (kwargs == NULL) { 4595 if (kwargs == NULL) {
4716 return _PyObject_FastCall(func, NULL, 0, 0); 4596 return _PyObject_CallNoArg(func);
4717 } 4597 }
4718 4598
4719 args = PyTuple_New(0); 4599 args = PyTuple_New(0);
4720 if (args == NULL) 4600 if (args == NULL)
4721 return NULL; 4601 return NULL;
4722 } 4602 }
4723 else if (!PyTuple_Check(args)) { 4603 else if (!PyTuple_Check(args)) {
4724 PyErr_SetString(PyExc_TypeError, 4604 PyErr_SetString(PyExc_TypeError,
4725 "argument list must be a tuple"); 4605 "argument list must be a tuple");
4726 return NULL; 4606 return NULL;
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
4914 /* The fast_function() function optimize calls for which no argument 4794 /* The fast_function() function optimize calls for which no argument
4915 tuple is necessary; the objects are passed directly from the stack. 4795 tuple is necessary; the objects are passed directly from the stack.
4916 For the simplest case -- a function that takes only positional 4796 For the simplest case -- a function that takes only positional
4917 arguments and is called with only positional arguments -- it 4797 arguments and is called with only positional arguments -- it
4918 inlines the most primitive frame setup code from 4798 inlines the most primitive frame setup code from
4919 PyEval_EvalCodeEx(), which vastly reduces the checks that must be 4799 PyEval_EvalCodeEx(), which vastly reduces the checks that must be
4920 done before evaluating the frame. 4800 done before evaluating the frame.
4921 */ 4801 */
4922 4802
4923 static PyObject* 4803 static PyObject*
4924 _PyFunction_FastCallNoKw(PyObject **args, Py_ssize_t na, 4804 _PyFunction_FastCallNoKw(PyCodeObject *co, PyObject **args, Py_ssize_t na,
4925 PyCodeObject *co, PyObject *globals) 4805 PyObject *globals)
4926 { 4806 {
4927 PyFrameObject *f; 4807 PyFrameObject *f;
4928 PyThreadState *tstate = PyThreadState_GET(); 4808 PyThreadState *tstate = PyThreadState_GET();
4929 PyObject **fastlocals; 4809 PyObject **fastlocals;
4930 Py_ssize_t i; 4810 Py_ssize_t i;
4931 PyObject *result; 4811 PyObject *result;
4932 4812
4933 PCALL(PCALL_FASTER_FUNCTION); 4813 PCALL(PCALL_FASTER_FUNCTION);
4934 assert(globals != NULL); 4814 assert(globals != NULL);
4935 /* XXX Perhaps we should create a specialized 4815 /* XXX Perhaps we should create a specialized
(...skipping 14 matching lines...) Expand all
4950 } 4830 }
4951 result = PyEval_EvalFrameEx(f,0); 4831 result = PyEval_EvalFrameEx(f,0);
4952 4832
4953 ++tstate->recursion_depth; 4833 ++tstate->recursion_depth;
4954 Py_DECREF(f); 4834 Py_DECREF(f);
4955 --tstate->recursion_depth; 4835 --tstate->recursion_depth;
4956 4836
4957 return result; 4837 return result;
4958 } 4838 }
4959 4839
4840 /* Similar to _PyFunction_FastCall() but keywords are passed a (key, value)
4841 pairs in stack */
4960 static PyObject * 4842 static PyObject *
4961 fast_function(PyObject *func, PyObject **stack, int n, int na, int nk) 4843 fast_function(PyObject *func, PyObject **stack, int n, int nargs, int nk)
4962 { 4844 {
4963 PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); 4845 PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
4964 PyObject *globals = PyFunction_GET_GLOBALS(func); 4846 PyObject *globals = PyFunction_GET_GLOBALS(func);
4965 PyObject *argdefs = PyFunction_GET_DEFAULTS(func); 4847 PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
4966 PyObject *kwdefs, *closure, *name, *qualname; 4848 PyObject *kwdefs, *closure, *name, *qualname;
4967 PyObject **d; 4849 PyObject **d;
4968 int nd; 4850 int nd;
4969 4851
4970 PCALL(PCALL_FUNCTION); 4852 PCALL(PCALL_FUNCTION);
4971 PCALL(PCALL_FAST_FUNCTION); 4853 PCALL(PCALL_FAST_FUNCTION);
4972 4854
4973 if (argdefs == NULL && co->co_argcount == na && 4855 if (co->co_kwonlyargcount == 0 && nk == 0 &&
4974 co->co_kwonlyargcount == 0 && nk == 0 &&
4975 co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) 4856 co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
4976 { 4857 {
4977 return _PyFunction_FastCallNoKw(stack, na, co, globals); 4858 if (argdefs == NULL && co->co_argcount == nargs) {
4859 return _PyFunction_FastCallNoKw(co, stack, nargs, globals);
4860 }
4861 else if (nargs == 0 && argdefs != NULL
4862 && co->co_argcount == Py_SIZE(argdefs)) {
4863 /* function called with no arguments, but all parameters have
4864 a default value: use default values as arguments .*/
4865 stack = &PyTuple_GET_ITEM(argdefs, 0);
4866 return _PyFunction_FastCallNoKw(co, stack, Py_SIZE(argdefs),
4867 globals);
4868 }
4978 } 4869 }
4979 4870
4980 kwdefs = PyFunction_GET_KW_DEFAULTS(func); 4871 kwdefs = PyFunction_GET_KW_DEFAULTS(func);
4981 closure = PyFunction_GET_CLOSURE(func); 4872 closure = PyFunction_GET_CLOSURE(func);
4982 name = ((PyFunctionObject *)func) -> func_name; 4873 name = ((PyFunctionObject *)func) -> func_name;
4983 qualname = ((PyFunctionObject *)func) -> func_qualname; 4874 qualname = ((PyFunctionObject *)func) -> func_qualname;
4984 4875
4985 if (argdefs != NULL) { 4876 if (argdefs != NULL) {
4986 d = &PyTuple_GET_ITEM(argdefs, 0); 4877 d = &PyTuple_GET_ITEM(argdefs, 0);
4987 nd = Py_SIZE(argdefs); 4878 nd = Py_SIZE(argdefs);
4988 } 4879 }
4989 else { 4880 else {
4990 d = NULL; 4881 d = NULL;
4991 nd = 0; 4882 nd = 0;
4992 } 4883 }
4993 return _PyEval_EvalCode((PyObject*)co, globals, (PyObject *)NULL, 4884 return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
4994 stack, na, 4885 stack, nargs,
4995 stack + na, nk, NULL, 4886 stack + nargs, nk,
4996 d, nd, kwdefs, 4887 d, nd, kwdefs,
4997 closure, name, qualname); 4888 closure, name, qualname);
4998 } 4889 }
4999 4890
5000 PyObject * 4891 PyObject *
5001 _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg s) 4892 _PyFunction_FastCall(PyObject *func, PyObject **args, int nargs, PyObject *kwarg s)
5002 { 4893 {
5003 PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func); 4894 PyCodeObject *co = (PyCodeObject *)PyFunction_GET_CODE(func);
5004 PyObject *globals = PyFunction_GET_GLOBALS(func); 4895 PyObject *globals = PyFunction_GET_GLOBALS(func);
5005 PyObject *argdefs = PyFunction_GET_DEFAULTS(func); 4896 PyObject *argdefs = PyFunction_GET_DEFAULTS(func);
5006 PyObject *kwdefs, *closure, *name, *qualname; 4897 PyObject *kwdefs, *closure, *name, *qualname;
5007 PyObject **d; 4898 PyObject **d;
5008 int nd; 4899 int nd;
5009 4900
5010 PCALL(PCALL_FUNCTION); 4901 PCALL(PCALL_FUNCTION);
5011 PCALL(PCALL_FAST_FUNCTION); 4902 PCALL(PCALL_FAST_FUNCTION);
5012 4903
5013 assert(kwargs == NULL || PyDict_Check(kwargs)); 4904 /* issue #27128: support for keywords will come later */
5014 4905 assert(kwargs == NULL);
5015 if (argdefs == NULL && co->co_argcount == nargs && 4906
5016 co->co_kwonlyargcount == 0 && 4907 if (co->co_kwonlyargcount == 0 && kwargs == NULL &&
5017 (kwargs == NULL || ((PyDictObject *)kwargs)->ma_used == 0) &&
5018 co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE)) 4908 co->co_flags == (CO_OPTIMIZED | CO_NEWLOCALS | CO_NOFREE))
5019 { 4909 {
5020 return _PyFunction_FastCallNoKw(args, nargs, co, globals); 4910 if (argdefs == NULL && co->co_argcount == nargs) {
4911 return _PyFunction_FastCallNoKw(co, args, nargs, globals);
4912 }
4913 else if (nargs == 0 && argdefs != NULL
4914 && co->co_argcount == Py_SIZE(argdefs)) {
4915 /* function called with no arguments, but all parameters have
4916 a default value: use default values as arguments .*/
4917 args = &PyTuple_GET_ITEM(argdefs, 0);
4918 return _PyFunction_FastCallNoKw(co, args, Py_SIZE(argdefs),
4919 globals);
4920 }
5021 } 4921 }
5022 4922
5023 kwdefs = PyFunction_GET_KW_DEFAULTS(func); 4923 kwdefs = PyFunction_GET_KW_DEFAULTS(func);
5024 closure = PyFunction_GET_CLOSURE(func); 4924 closure = PyFunction_GET_CLOSURE(func);
5025 name = ((PyFunctionObject *)func) -> func_name; 4925 name = ((PyFunctionObject *)func) -> func_name;
5026 qualname = ((PyFunctionObject *)func) -> func_qualname; 4926 qualname = ((PyFunctionObject *)func) -> func_qualname;
5027 4927
5028 if (argdefs != NULL) { 4928 if (argdefs != NULL) {
5029 d = &PyTuple_GET_ITEM(argdefs, 0); 4929 d = &PyTuple_GET_ITEM(argdefs, 0);
5030 nd = Py_SIZE(argdefs); 4930 nd = Py_SIZE(argdefs);
5031 } 4931 }
5032 else { 4932 else {
5033 d = NULL; 4933 d = NULL;
5034 nd = 0; 4934 nd = 0;
5035 } 4935 }
5036 return _PyEval_EvalCode((PyObject*)co, globals, (PyObject *)NULL, 4936 return _PyEval_EvalCodeWithName((PyObject*)co, globals, (PyObject *)NULL,
5037 args, nargs, 4937 args, nargs,
5038 NULL, 0, kwargs, 4938 NULL, 0,
5039 d, nd, kwdefs, 4939 d, nd, kwdefs,
5040 closure, name, qualname); 4940 closure, name, qualname);
5041 } 4941 }
5042 4942
5043 static PyObject * 4943 static PyObject *
5044 update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack, 4944 update_keyword_args(PyObject *orig_kwdict, int nk, PyObject ***pp_stack,
5045 PyObject *func) 4945 PyObject *func)
5046 { 4946 {
5047 PyObject *kwdict = NULL; 4947 PyObject *kwdict = NULL;
5048 if (orig_kwdict == NULL) 4948 if (orig_kwdict == NULL)
5049 kwdict = PyDict_New(); 4949 kwdict = PyDict_New();
5050 else { 4950 else {
(...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after
5391 return res; 5291 return res;
5392 } 5292 }
5393 5293
5394 Py_INCREF(import_func); 5294 Py_INCREF(import_func);
5395 5295
5396 stack[0] = name; 5296 stack[0] = name;
5397 stack[1] = f->f_globals; 5297 stack[1] = f->f_globals;
5398 stack[2] = f->f_locals == NULL ? Py_None : f->f_locals; 5298 stack[2] = f->f_locals == NULL ? Py_None : f->f_locals;
5399 stack[3] = fromlist; 5299 stack[3] = fromlist;
5400 stack[4] = level; 5300 stack[4] = level;
5401 res = _PyObject_FastCall(import_func, stack, 5, NULL); 5301 res = _PyObject_FastCall(import_func, stack, 5);
5402 Py_DECREF(import_func); 5302 Py_DECREF(import_func);
5403 return res; 5303 return res;
5404 } 5304 }
5405 5305
5406 static PyObject * 5306 static PyObject *
5407 import_from(PyObject *v, PyObject *name) 5307 import_from(PyObject *v, PyObject *name)
5408 { 5308 {
5409 PyObject *x; 5309 PyObject *x;
5410 _Py_IDENTIFIER(__name__); 5310 _Py_IDENTIFIER(__name__);
5411 PyObject *fullmodname, *pkgname; 5311 PyObject *fullmodname, *pkgname;
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after
5624 Py_DECREF(l); 5524 Py_DECREF(l);
5625 return NULL; 5525 return NULL;
5626 } 5526 }
5627 PyList_SetItem(l, i, x); 5527 PyList_SetItem(l, i, x);
5628 } 5528 }
5629 return l; 5529 return l;
5630 #endif 5530 #endif
5631 } 5531 }
5632 5532
5633 #endif 5533 #endif
LEFTRIGHT

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+