diff options
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 451 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 5 | ||||
-rw-r--r-- | Objects/bytesobject.c | 9 | ||||
-rw-r--r-- | Objects/codeobject.c | 5 | ||||
-rw-r--r-- | Objects/complexobject.c | 2 | ||||
-rw-r--r-- | Objects/descrobject.c | 5 | ||||
-rw-r--r-- | Objects/dict-common.h | 2 | ||||
-rw-r--r-- | Objects/dictobject.c | 418 | ||||
-rw-r--r-- | Objects/enumobject.c | 2 | ||||
-rw-r--r-- | Objects/exceptions.c | 49 | ||||
-rw-r--r-- | Objects/fileobject.c | 10 | ||||
-rw-r--r-- | Objects/floatobject.c | 6 | ||||
-rw-r--r-- | Objects/frameobject.c | 4 | ||||
-rw-r--r-- | Objects/genobject.c | 2 | ||||
-rw-r--r-- | Objects/longobject.c | 93 | ||||
-rw-r--r-- | Objects/moduleobject.c | 6 | ||||
-rw-r--r-- | Objects/object.c | 94 | ||||
-rw-r--r-- | Objects/odictobject.c | 6 | ||||
-rw-r--r-- | Objects/rangeobject.c | 41 | ||||
-rw-r--r-- | Objects/setobject.c | 2 | ||||
-rw-r--r-- | Objects/structseq.c | 4 | ||||
-rw-r--r-- | Objects/typeobject.c | 159 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 225 |
23 files changed, 752 insertions, 848 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index d838856..67b163d 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -103,7 +103,7 @@ PyObject_LengthHint(PyObject *o, Py_ssize_t defaultvalue) } return defaultvalue; } - result = PyObject_CallFunctionObjArgs(hint, NULL); + result = _PyObject_CallNoArg(hint); Py_DECREF(hint); if (result == NULL) { if (PyErr_ExceptionMatches(PyExc_TypeError)) { @@ -252,14 +252,6 @@ PyObject_DelItemString(PyObject *o, const char *key) cause issues later on. Don't use these functions in new code. */ int -PyObject_AsCharBuffer(PyObject *obj, - const char **buffer, - Py_ssize_t *buffer_len) -{ - return PyObject_AsReadBuffer(obj, (const void **)buffer, buffer_len); -} - -int PyObject_CheckReadBuffer(PyObject *obj) { PyBufferProcs *pb = obj->ob_type->tp_as_buffer; @@ -276,9 +268,8 @@ PyObject_CheckReadBuffer(PyObject *obj) return 1; } -int PyObject_AsReadBuffer(PyObject *obj, - const void **buffer, - Py_ssize_t *buffer_len) +static int +as_read_buffer(PyObject *obj, const void **buffer, Py_ssize_t *buffer_len) { Py_buffer view; @@ -295,6 +286,21 @@ int PyObject_AsReadBuffer(PyObject *obj, return 0; } +int +PyObject_AsCharBuffer(PyObject *obj, + const char **buffer, + Py_ssize_t *buffer_len) +{ + return as_read_buffer(obj, (const void **)buffer, buffer_len); +} + +int PyObject_AsReadBuffer(PyObject *obj, + const void **buffer, + Py_ssize_t *buffer_len) +{ + return as_read_buffer(obj, buffer, buffer_len); +} + int PyObject_AsWriteBuffer(PyObject *obj, void **buffer, Py_ssize_t *buffer_len) @@ -2167,24 +2173,24 @@ PyMapping_Values(PyObject *o) /* XXX PyCallable_Check() is in object.c */ PyObject * -PyObject_CallObject(PyObject *o, PyObject *a) +PyObject_CallObject(PyObject *callable, PyObject *args) { - return PyEval_CallObjectWithKeywords(o, a, NULL); + return PyEval_CallObjectWithKeywords(callable, args, NULL); } PyObject* -_Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where) +_Py_CheckFunctionResult(PyObject *callable, PyObject *result, const char *where) { int err_occurred = (PyErr_Occurred() != NULL); - assert((func != NULL) ^ (where != NULL)); + assert((callable != NULL) ^ (where != NULL)); if (result == NULL) { if (!err_occurred) { - if (func) + if (callable) PyErr_Format(PyExc_SystemError, "%R returned NULL without setting an error", - func); + callable); else PyErr_Format(PyExc_SystemError, "%s returned NULL without setting an error", @@ -2200,10 +2206,10 @@ _Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where) if (err_occurred) { Py_DECREF(result); - if (func) { + if (callable) { _PyErr_FormatFromCause(PyExc_SystemError, "%R returned a result with an error set", - func); + callable); } else { _PyErr_FormatFromCause(PyExc_SystemError, @@ -2221,7 +2227,7 @@ _Py_CheckFunctionResult(PyObject *func, PyObject *result, const char *where) } PyObject * -PyObject_Call(PyObject *func, PyObject *args, PyObject *kwargs) +PyObject_Call(PyObject *callable, PyObject *args, PyObject *kwargs) { ternaryfunc call; PyObject *result; @@ -2233,21 +2239,21 @@ PyObject_Call(PyObject *func, PyObject *args, PyObject *kwargs) assert(PyTuple_Check(args)); assert(kwargs == NULL || PyDict_Check(kwargs)); - call = func->ob_type->tp_call; + call = callable->ob_type->tp_call; if (call == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - func->ob_type->tp_name); + callable->ob_type->tp_name); return NULL; } if (Py_EnterRecursiveCall(" while calling a Python object")) return NULL; - result = (*call)(func, args, kwargs); + result = (*call)(callable, args, kwargs); Py_LeaveRecursiveCall(); - return _Py_CheckFunctionResult(func, result, NULL); + return _Py_CheckFunctionResult(callable, result, NULL); } PyObject* @@ -2271,7 +2277,7 @@ _PyStack_AsTuple(PyObject **stack, Py_ssize_t nargs) } PyObject * -_PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, +_PyObject_FastCallDict(PyObject *callable, PyObject **args, Py_ssize_t nargs, PyObject *kwargs) { ternaryfunc call; @@ -2282,7 +2288,7 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, caller loses its exception */ assert(!PyErr_Occurred()); - assert(func != NULL); + assert(callable != NULL); assert(nargs >= 0); assert(nargs == 0 || args != NULL); assert(kwargs == NULL || PyDict_Check(kwargs)); @@ -2291,20 +2297,20 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, return NULL; } - if (PyFunction_Check(func)) { - result = _PyFunction_FastCallDict(func, args, nargs, kwargs); + if (PyFunction_Check(callable)) { + result = _PyFunction_FastCallDict(callable, args, nargs, kwargs); } - else if (PyCFunction_Check(func)) { - result = _PyCFunction_FastCallDict(func, args, nargs, kwargs); + else if (PyCFunction_Check(callable)) { + result = _PyCFunction_FastCallDict(callable, args, nargs, kwargs); } else { PyObject *tuple; /* Slow-path: build a temporary tuple */ - call = func->ob_type->tp_call; + call = callable->ob_type->tp_call; if (call == NULL) { PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", - func->ob_type->tp_name); + callable->ob_type->tp_name); goto exit; } @@ -2313,10 +2319,10 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs, goto exit; } - result = (*call)(func, tuple, kwargs); + result = (*call)(callable, tuple, kwargs); Py_DECREF(tuple); - result = _Py_CheckFunctionResult(func, result, NULL); + result = _Py_CheckFunctionResult(callable, result, NULL); } exit: @@ -2325,12 +2331,13 @@ exit: return result; } -/* Positional arguments are obj followed by args. */ +/* Positional arguments are obj followed by args: + call callable(obj, *args, **kwargs) */ PyObject * -_PyObject_Call_Prepend(PyObject *func, +_PyObject_Call_Prepend(PyObject *callable, PyObject *obj, PyObject *args, PyObject *kwargs) { - PyObject *small_stack[8]; + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; Py_ssize_t argcount; PyObject *result; @@ -2355,7 +2362,7 @@ _PyObject_Call_Prepend(PyObject *func, &PyTuple_GET_ITEM(args, 0), argcount * sizeof(PyObject *)); - result = _PyObject_FastCallDict(func, + result = _PyObject_FastCallDict(callable, stack, argcount + 1, kwargs); if (stack != small_stack) { @@ -2371,7 +2378,7 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames) PyObject *kwdict; Py_ssize_t i; - kwdict = PyDict_New(); + kwdict = _PyDict_NewPresized(nkwargs); if (kwdict == NULL) { return NULL; } @@ -2446,56 +2453,120 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs, } PyObject * -_PyObject_FastCallKeywords(PyObject *func, PyObject **stack, Py_ssize_t nargs, +_PyObject_FastCallKeywords(PyObject *callable, PyObject **stack, Py_ssize_t nargs, PyObject *kwnames) { - PyObject *kwdict, *result; - Py_ssize_t nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); - assert(nargs >= 0); assert(kwnames == NULL || PyTuple_CheckExact(kwnames)); - assert((nargs == 0 && nkwargs == 0) || stack != NULL); + /* kwnames must only contains str strings, no subclass, and all keys must - be unique: these are implemented in Python/ceval.c and + be unique: these checks are implemented in Python/ceval.c and _PyArg_ParseStack(). */ - if (PyFunction_Check(func)) { - return _PyFunction_FastCallKeywords(func, stack, nargs, kwnames); + if (PyFunction_Check(callable)) { + return _PyFunction_FastCallKeywords(callable, stack, nargs, kwnames); } - - if (PyCFunction_Check(func)) { - return _PyCFunction_FastCallKeywords(func, stack, nargs, kwnames); + if (PyCFunction_Check(callable)) { + return _PyCFunction_FastCallKeywords(callable, stack, nargs, kwnames); } + else { + /* Slow-path: build a temporary tuple for positional arguments and a + temporary dictionary for keyword arguments (if any) */ + + ternaryfunc call; + PyObject *argtuple; + PyObject *kwdict, *result; + Py_ssize_t nkwargs; + + result = NULL; + nkwargs = (kwnames == NULL) ? 0 : PyTuple_GET_SIZE(kwnames); + assert((nargs == 0 && nkwargs == 0) || stack != NULL); - if (nkwargs > 0) { - kwdict = _PyStack_AsDict(stack + nargs, kwnames); - if (kwdict == NULL) { + if (Py_EnterRecursiveCall(" while calling a Python object")) { return NULL; } - } - else { - kwdict = NULL; - } - result = _PyObject_FastCallDict(func, stack, nargs, kwdict); - Py_XDECREF(kwdict); - return result; + call = callable->ob_type->tp_call; + if (call == NULL) { + PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable", + callable->ob_type->tp_name); + goto exit; + } + + argtuple = _PyStack_AsTuple(stack, nargs); + if (argtuple == NULL) { + goto exit; + } + + if (nkwargs > 0) { + kwdict = _PyStack_AsDict(stack + nargs, kwnames); + if (kwdict == NULL) { + Py_DECREF(argtuple); + goto exit; + } + } + else { + kwdict = NULL; + } + + result = (*call)(callable, argtuple, kwdict); + Py_DECREF(argtuple); + Py_XDECREF(kwdict); + + exit: + Py_LeaveRecursiveCall(); + return result; + } } -static PyObject* -call_function_tail(PyObject *callable, PyObject *args) +static PyObject * +_PyObject_CallFunctionVa(PyObject *callable, const char *format, + va_list va, int is_size_t) { + PyObject* small_stack[_PY_FASTCALL_SMALL_STACK]; + const Py_ssize_t small_stack_len = Py_ARRAY_LENGTH(small_stack); + PyObject **stack; + Py_ssize_t nargs, i; PyObject *result; - assert(args != NULL); + if (callable == NULL) { + return null_error(); + } + + if (!format || !*format) { + return _PyObject_CallNoArg(callable); + } + + if (is_size_t) { + stack = _Py_VaBuildStack(small_stack, small_stack_len, format, va, &nargs); + } + else { + stack = _Py_VaBuildStack_SizeT(small_stack, small_stack_len, format, va, &nargs); + } + if (stack == NULL) { + return NULL; + } - if (!PyTuple_Check(args)) { - result = _PyObject_CallArg1(callable, args); + if (nargs == 1 && PyTuple_Check(stack[0])) { + /* Special cases for backward compatibility: + - PyObject_CallFunction(func, "O", tuple) calls func(*tuple) + - PyObject_CallFunction(func, "(OOO)", arg1, arg2, arg3) calls + func(*(arg1, arg2, arg3)): func(arg1, arg2, arg3) */ + PyObject *args = stack[0]; + result = _PyObject_FastCall(callable, + &PyTuple_GET_ITEM(args, 0), + PyTuple_GET_SIZE(args)); } else { - result = PyObject_Call(callable, args, NULL); + result = _PyObject_FastCall(callable, stack, nargs); } + for (i = 0; i < nargs; ++i) { + Py_DECREF(stack[i]); + } + if (stack != small_stack) { + PyMem_Free(stack); + } return result; } @@ -2503,25 +2574,12 @@ PyObject * PyObject_CallFunction(PyObject *callable, const char *format, ...) { va_list va; - PyObject *args, *result; - - if (callable == NULL) { - return null_error(); - } - - if (!format || !*format) { - return _PyObject_CallNoArg(callable); - } + PyObject *result; va_start(va, format); - args = Py_VaBuildValue(format, va); + result = _PyObject_CallFunctionVa(callable, format, va, 0); va_end(va); - if (args == NULL) { - return NULL; - } - result = call_function_tail(callable, args); - Py_DECREF(args); return result; } @@ -2529,289 +2587,227 @@ PyObject * _PyObject_CallFunction_SizeT(PyObject *callable, const char *format, ...) { va_list va; - PyObject *args, *result; - - if (callable == NULL) { - return null_error(); - } - - if (!format || !*format) { - return _PyObject_CallNoArg(callable); - } + PyObject *result; va_start(va, format); - args = _Py_VaBuildValue_SizeT(format, va); + result = _PyObject_CallFunctionVa(callable, format, va, 1); va_end(va); - if (args == NULL) { - return NULL; - } - result = call_function_tail(callable, args); - Py_DECREF(args); return result; } static PyObject* -callmethod(PyObject* func, const char *format, va_list va, int is_size_t) +callmethod(PyObject* callable, const char *format, va_list va, int is_size_t) { - PyObject *args, *result; - - assert(func != NULL); + assert(callable != NULL); - if (!PyCallable_Check(func)) { - type_error("attribute of type '%.200s' is not callable", func); - return NULL; - } - - if (!format || !*format) { - return _PyObject_CallNoArg(func); - } - - if (is_size_t) { - args = _Py_VaBuildValue_SizeT(format, va); - } - else { - args = Py_VaBuildValue(format, va); - } - if (args == NULL) { + if (!PyCallable_Check(callable)) { + type_error("attribute of type '%.200s' is not callable", callable); return NULL; } - result = call_function_tail(func, args); - Py_DECREF(args); - return result; + return _PyObject_CallFunctionVa(callable, format, va, is_size_t); } PyObject * -PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...) +PyObject_CallMethod(PyObject *obj, const char *name, const char *format, ...) { va_list va; - PyObject *func = NULL; - PyObject *retval = NULL; + PyObject *callable, *retval; - if (o == NULL || name == NULL) { + if (obj == NULL || name == NULL) { return null_error(); } - func = PyObject_GetAttrString(o, name); - if (func == NULL) + callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) return NULL; va_start(va, format); - retval = callmethod(func, format, va, 0); + retval = callmethod(callable, format, va, 0); va_end(va); - Py_DECREF(func); + + Py_DECREF(callable); return retval; } PyObject * -_PyObject_CallMethodId(PyObject *o, _Py_Identifier *name, +_PyObject_CallMethodId(PyObject *obj, _Py_Identifier *name, const char *format, ...) { va_list va; - PyObject *func = NULL; - PyObject *retval = NULL; + PyObject *callable, *retval; - if (o == NULL || name == NULL) { + if (obj == NULL || name == NULL) { return null_error(); } - func = _PyObject_GetAttrId(o, name); - if (func == NULL) + callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) return NULL; va_start(va, format); - retval = callmethod(func, format, va, 0); + retval = callmethod(callable, format, va, 0); va_end(va); - Py_DECREF(func); + + Py_DECREF(callable); return retval; } PyObject * -_PyObject_CallMethod_SizeT(PyObject *o, const char *name, +_PyObject_CallMethod_SizeT(PyObject *obj, const char *name, const char *format, ...) { va_list va; - PyObject *func = NULL; - PyObject *retval; + PyObject *callable, *retval; - if (o == NULL || name == NULL) { + if (obj == NULL || name == NULL) { return null_error(); } - func = PyObject_GetAttrString(o, name); - if (func == NULL) + callable = PyObject_GetAttrString(obj, name); + if (callable == NULL) return NULL; + va_start(va, format); - retval = callmethod(func, format, va, 1); + retval = callmethod(callable, format, va, 1); va_end(va); - Py_DECREF(func); + + Py_DECREF(callable); return retval; } PyObject * -_PyObject_CallMethodId_SizeT(PyObject *o, _Py_Identifier *name, +_PyObject_CallMethodId_SizeT(PyObject *obj, _Py_Identifier *name, const char *format, ...) { va_list va; - PyObject *func = NULL; - PyObject *retval; + PyObject *callable, *retval; - if (o == NULL || name == NULL) { + if (obj == NULL || name == NULL) { return null_error(); } - func = _PyObject_GetAttrId(o, name); - if (func == NULL) { + callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) { return NULL; } + va_start(va, format); - retval = callmethod(func, format, va, 1); + retval = callmethod(callable, format, va, 1); va_end(va); - Py_DECREF(func); + + Py_DECREF(callable); return retval; } -static PyObject ** -objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size, - va_list va, Py_ssize_t *p_nargs) +PyObject * +_PyObject_VaCallFunctionObjArgs(PyObject *callable, va_list vargs) { - Py_ssize_t i, n; - va_list countva; + PyObject *small_stack[_PY_FASTCALL_SMALL_STACK]; PyObject **stack; + Py_ssize_t nargs; + PyObject *result; + Py_ssize_t i; + va_list countva; - /* Count the number of arguments */ - va_copy(countva, va); + if (callable == NULL) { + return null_error(); + } - n = 0; + /* Count the number of arguments */ + va_copy(countva, vargs); + nargs = 0; while (1) { PyObject *arg = va_arg(countva, PyObject *); if (arg == NULL) { break; } - n++; + nargs++; } - *p_nargs = n; + va_end(countva); /* Copy arguments */ - if (n <= small_stack_size) { + if (nargs <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) { stack = small_stack; } else { - stack = PyMem_Malloc(n * sizeof(stack[0])); + stack = PyMem_Malloc(nargs * sizeof(stack[0])); if (stack == NULL) { - va_end(countva); PyErr_NoMemory(); return NULL; } } - for (i = 0; i < n; ++i) { - stack[i] = va_arg(va, PyObject *); + for (i = 0; i < nargs; ++i) { + stack[i] = va_arg(vargs, PyObject *); } - va_end(countva); - return stack; + + /* Call the function */ + result = _PyObject_FastCall(callable, stack, nargs); + + if (stack != small_stack) { + PyMem_Free(stack); + } + return result; } PyObject * PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...) { - PyObject *small_stack[5]; - PyObject **stack; - Py_ssize_t nargs; - PyObject *result; va_list vargs; + PyObject *result; if (callable == NULL || name == NULL) { return null_error(); } callable = PyObject_GetAttr(callable, name); - if (callable == NULL) + if (callable == NULL) { return NULL; + } - /* count the args */ va_start(vargs, name); - stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), - vargs, &nargs); + result = _PyObject_VaCallFunctionObjArgs(callable, vargs); va_end(vargs); - if (stack == NULL) { - Py_DECREF(callable); - return NULL; - } - result = _PyObject_FastCall(callable, stack, nargs); Py_DECREF(callable); - if (stack != small_stack) { - PyMem_Free(stack); - } - return result; } PyObject * -_PyObject_CallMethodIdObjArgs(PyObject *callable, - struct _Py_Identifier *name, ...) +_PyObject_CallMethodIdObjArgs(PyObject *obj, + struct _Py_Identifier *name, ...) { - PyObject *small_stack[5]; - PyObject **stack; - Py_ssize_t nargs; - PyObject *result; va_list vargs; + PyObject *callable, *result; - if (callable == NULL || name == NULL) { + if (obj == NULL || name == NULL) { return null_error(); } - callable = _PyObject_GetAttrId(callable, name); - if (callable == NULL) + callable = _PyObject_GetAttrId(obj, name); + if (callable == NULL) { return NULL; + } - /* count the args */ va_start(vargs, name); - stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), - vargs, &nargs); + result = _PyObject_VaCallFunctionObjArgs(callable, vargs); va_end(vargs); - if (stack == NULL) { - Py_DECREF(callable); - return NULL; - } - result = _PyObject_FastCall(callable, stack, nargs); Py_DECREF(callable); - if (stack != small_stack) { - PyMem_Free(stack); - } - return result; } PyObject * PyObject_CallFunctionObjArgs(PyObject *callable, ...) { - PyObject *small_stack[5]; - PyObject **stack; - Py_ssize_t nargs; - PyObject *result; va_list vargs; + PyObject *result; - if (callable == NULL) { - return null_error(); - } - - /* count the args */ va_start(vargs, callable); - stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack), - vargs, &nargs); + result = _PyObject_VaCallFunctionObjArgs(callable, vargs); va_end(vargs); - if (stack == NULL) { - return NULL; - } - - result = _PyObject_FastCall(callable, stack, nargs); - if (stack != small_stack) { - PyMem_Free(stack); - } return result; } @@ -3111,7 +3107,8 @@ PyObject * PyObject_GetIter(PyObject *o) { PyTypeObject *t = o->ob_type; - getiterfunc f = NULL; + getiterfunc f; + f = t->tp_iter; if (f == NULL) { if (PySequence_Check(o)) diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index c6d0707..16b4fd7 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -2324,10 +2324,7 @@ bytearrayiter_reduce(bytesiterobject *it) return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), it->it_seq, it->it_index); } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); } } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 779fe29..0a5c0ae 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -549,7 +549,7 @@ format_obj(PyObject *v, const char **pbuf, Py_ssize_t *plen) /* does it support __bytes__? */ func = _PyObject_LookupSpecial(v, &PyId___bytes__); if (func != NULL) { - result = PyObject_CallFunctionObjArgs(func, NULL); + result = _PyObject_CallNoArg(func); Py_DECREF(func); if (result == NULL) return NULL; @@ -2569,7 +2569,7 @@ bytes_new(PyTypeObject *type, PyObject *args, PyObject *kwds) PyObject_Bytes doesn't do. */ func = _PyObject_LookupSpecial(x, &PyId___bytes__); if (func != NULL) { - new = PyObject_CallFunctionObjArgs(func, NULL); + new = _PyObject_CallNoArg(func); Py_DECREF(func); if (new == NULL) return NULL; @@ -3048,10 +3048,7 @@ striter_reduce(striterobject *it) return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), it->it_seq, it->it_index); } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); - if (u == NULL) - return NULL; - return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); + return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); } } diff --git a/Objects/codeobject.c b/Objects/codeobject.c index f7f91a8..788818d 100644 --- a/Objects/codeobject.c +++ b/Objects/codeobject.c @@ -115,7 +115,7 @@ PyCode_New(int argcount, int kwonlyargcount, /* Check argument types */ if (argcount < 0 || kwonlyargcount < 0 || nlocals < 0 || - code == NULL || + code == NULL || !PyBytes_Check(code) || consts == NULL || !PyTuple_Check(consts) || names == NULL || !PyTuple_Check(names) || varnames == NULL || !PyTuple_Check(varnames) || @@ -123,8 +123,7 @@ PyCode_New(int argcount, int kwonlyargcount, cellvars == NULL || !PyTuple_Check(cellvars) || name == NULL || !PyUnicode_Check(name) || filename == NULL || !PyUnicode_Check(filename) || - lnotab == NULL || !PyBytes_Check(lnotab) || - !PyObject_CheckReadBuffer(code)) { + lnotab == NULL || !PyBytes_Check(lnotab)) { PyErr_BadInternalCall(); return NULL; } diff --git a/Objects/complexobject.c b/Objects/complexobject.c index 31e1278..0d391e5 100644 --- a/Objects/complexobject.c +++ b/Objects/complexobject.c @@ -273,7 +273,7 @@ try_complex_special_method(PyObject *op) { f = _PyObject_LookupSpecial(op, &PyId___complex__); if (f) { - PyObject *res = PyObject_CallFunctionObjArgs(f, NULL); + PyObject *res = _PyObject_CallNoArg(f); Py_DECREF(f); if (res != NULL && !PyComplex_Check(res)) { PyErr_SetString(PyExc_TypeError, diff --git a/Objects/descrobject.c b/Objects/descrobject.c index 076e741..090c9cd 100644 --- a/Objects/descrobject.c +++ b/Objects/descrobject.c @@ -804,7 +804,8 @@ mappingproxy_get(mappingproxyobject *pp, PyObject *args) if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &def)) return NULL; - return _PyObject_CallMethodId(pp->mapping, &PyId_get, "(OO)", key, def); + return _PyObject_CallMethodIdObjArgs(pp->mapping, &PyId_get, + key, def, NULL); } static PyObject * @@ -1453,7 +1454,7 @@ property_copy(PyObject *old, PyObject *get, PyObject *set, PyObject *del) doc = pold->prop_doc ? pold->prop_doc : Py_None; } - new = PyObject_CallFunction(type, "OOOO", get, set, del, doc); + new = PyObject_CallFunctionObjArgs(type, get, set, del, doc, NULL); Py_DECREF(type); if (new == NULL) return NULL; diff --git a/Objects/dict-common.h b/Objects/dict-common.h index ce9edab..6218552 100644 --- a/Objects/dict-common.h +++ b/Objects/dict-common.h @@ -12,7 +12,7 @@ typedef struct { * -1 when no entry found, -3 when compare raises error. */ typedef Py_ssize_t (*dict_lookup_func) -(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject ***value_addr, +(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos); #define DKIX_EMPTY (-1) diff --git a/Objects/dictobject.c b/Objects/dictobject.c index 5fff34b..6a7e831 100644 --- a/Objects/dictobject.c +++ b/Objects/dictobject.c @@ -10,8 +10,9 @@ This implements the dictionary's hashtable. -As of Python 3.6, this is compact and ordered. Basic idea is described here. -https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html +As of Python 3.6, this is compact and ordered. Basic idea is described here: +* https://mail.python.org/pipermail/python-dev/2012-December/123028.html +* https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html layout: @@ -222,17 +223,17 @@ equally good collision statistics, needed less code & used less memory. /* forward declarations */ static Py_ssize_t lookdict(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos); static Py_ssize_t lookdict_unicode(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos); static Py_ssize_t lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos); static Py_ssize_t lookdict_split(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos); static int dictresize(PyDictObject *mp, Py_ssize_t minused); @@ -682,9 +683,9 @@ the <dummy> value. For both, when the key isn't found a DKIX_EMPTY is returned. hashpos returns where the key index should be inserted. */ -static Py_ssize_t +static Py_ssize_t _Py_HOT_FUNCTION lookdict(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, Py_ssize_t *hashpos) + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos) { size_t i, mask; Py_ssize_t ix, freeslot; @@ -713,7 +714,7 @@ top: ep = &ep0[ix]; assert(ep->me_key != NULL); if (ep->me_key == key) { - *value_addr = &ep->me_value; + *value_addr = ep->me_value; if (hashpos != NULL) *hashpos = i; return ix; @@ -729,7 +730,7 @@ top: } if (dk == mp->ma_keys && ep->me_key == startkey) { if (cmp > 0) { - *value_addr = &ep->me_value; + *value_addr = ep->me_value; if (hashpos != NULL) *hashpos = i; return ix; @@ -765,7 +766,7 @@ top: if (hashpos != NULL) { *hashpos = i; } - *value_addr = &ep->me_value; + *value_addr = ep->me_value; return ix; } if (ep->me_hash == hash) { @@ -782,7 +783,7 @@ top: if (hashpos != NULL) { *hashpos = i; } - *value_addr = &ep->me_value; + *value_addr = ep->me_value; return ix; } } @@ -797,9 +798,9 @@ top: } /* Specialized version for string-only keys */ -static Py_ssize_t +static Py_ssize_t _Py_HOT_FUNCTION lookdict_unicode(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, Py_ssize_t *hashpos) + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos) { size_t i; size_t mask = DK_MASK(mp->ma_keys); @@ -833,7 +834,7 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, || (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { if (hashpos != NULL) *hashpos = i; - *value_addr = &ep->me_value; + *value_addr = ep->me_value; return ix; } freeslot = -1; @@ -859,7 +860,7 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, assert(ep->me_key != NULL); if (ep->me_key == key || (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { - *value_addr = &ep->me_value; + *value_addr = ep->me_value; if (hashpos != NULL) { *hashpos = i; } @@ -872,9 +873,9 @@ lookdict_unicode(PyDictObject *mp, PyObject *key, /* Faster version of lookdict_unicode when it is known that no <dummy> keys * will be present. */ -static Py_ssize_t +static Py_ssize_t _Py_HOT_FUNCTION lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos) { size_t i; @@ -907,7 +908,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { if (hashpos != NULL) *hashpos = i; - *value_addr = &ep->me_value; + *value_addr = ep->me_value; return ix; } for (size_t perturb = hash;;) { @@ -927,7 +928,7 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { if (hashpos != NULL) *hashpos = i; - *value_addr = &ep->me_value; + *value_addr = ep->me_value; return ix; } } @@ -940,9 +941,9 @@ lookdict_unicode_nodummy(PyDictObject *mp, PyObject *key, * Split tables only contain unicode keys and no dummy keys, * so algorithm is the same as lookdict_unicode_nodummy. */ -static Py_ssize_t +static Py_ssize_t _Py_HOT_FUNCTION lookdict_split(PyDictObject *mp, PyObject *key, - Py_hash_t hash, PyObject ***value_addr, Py_ssize_t *hashpos) + Py_hash_t hash, PyObject **value_addr, Py_ssize_t *hashpos) { size_t i; size_t mask = DK_MASK(mp->ma_keys); @@ -954,7 +955,7 @@ lookdict_split(PyDictObject *mp, PyObject *key, if (!PyUnicode_CheckExact(key)) { ix = lookdict(mp, key, hash, value_addr, hashpos); if (ix >= 0) { - *value_addr = &mp->ma_values[ix]; + *value_addr = mp->ma_values[ix]; } return ix; } @@ -974,7 +975,7 @@ lookdict_split(PyDictObject *mp, PyObject *key, (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { if (hashpos != NULL) *hashpos = i; - *value_addr = &mp->ma_values[ix]; + *value_addr = mp->ma_values[ix]; return ix; } for (size_t perturb = hash;;) { @@ -994,7 +995,7 @@ lookdict_split(PyDictObject *mp, PyObject *key, (ep->me_hash == hash && unicode_eq(ep->me_key, key))) { if (hashpos != NULL) *hashpos = i; - *value_addr = &mp->ma_values[ix]; + *value_addr = mp->ma_values[ix]; return ix; } } @@ -1067,32 +1068,24 @@ _PyDict_MaybeUntrack(PyObject *op) when it is known that the key is not present in the dict. The dict must be combined. */ -static void -find_empty_slot(PyDictObject *mp, PyObject *key, Py_hash_t hash, - PyObject ***value_addr, Py_ssize_t *hashpos) +static Py_ssize_t +find_empty_slot(PyDictKeysObject *keys, PyObject *key, Py_hash_t hash) { size_t i; - size_t mask = DK_MASK(mp->ma_keys); + size_t mask = DK_MASK(keys); Py_ssize_t ix; - PyDictKeyEntry *ep, *ep0 = DK_ENTRIES(mp->ma_keys); - assert(!_PyDict_HasSplitTable(mp)); - assert(hashpos != NULL); assert(key != NULL); - if (!PyUnicode_CheckExact(key)) - mp->ma_keys->dk_lookup = lookdict; i = hash & mask; - ix = dk_get_index(mp->ma_keys, i); + ix = dk_get_index(keys, i); for (size_t perturb = hash; ix != DKIX_EMPTY;) { perturb >>= PERTURB_SHIFT; i = (i << 2) + i + perturb + 1; - ix = dk_get_index(mp->ma_keys, i & mask); + ix = dk_get_index(keys, i & mask); } - ep = &ep0[mp->ma_keys->dk_nentries]; - *hashpos = i & mask; - assert(ep->me_value == NULL); - *value_addr = &ep->me_value; + assert(DK_ENTRIES(keys)[keys->dk_nentries].me_value == NULL); + return i & mask; } static int @@ -1110,8 +1103,7 @@ static int insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) { PyObject *old_value; - PyObject **value_addr; - PyDictKeyEntry *ep, *ep0; + PyDictKeyEntry *ep; Py_ssize_t hashpos, ix; if (mp->ma_values != NULL && !PyUnicode_CheckExact(key)) { @@ -1119,7 +1111,7 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) return -1; } - ix = mp->ma_keys->dk_lookup(mp, key, hash, &value_addr, &hashpos); + ix = mp->ma_keys->dk_lookup(mp, key, hash, &old_value, &hashpos); if (ix == DKIX_ERROR) { return -1; } @@ -1132,28 +1124,28 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) * the key anymore. Convert this instance to combine table. */ if (_PyDict_HasSplitTable(mp) && - ((ix >= 0 && *value_addr == NULL && mp->ma_used != ix) || + ((ix >= 0 && old_value == NULL && mp->ma_used != ix) || (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { if (insertion_resize(mp) < 0) { Py_DECREF(value); return -1; } - find_empty_slot(mp, key, hash, &value_addr, &hashpos); + hashpos = find_empty_slot(mp->ma_keys, key, hash); ix = DKIX_EMPTY; } if (ix == DKIX_EMPTY) { /* Insert into new slot. */ + assert(old_value == NULL); if (mp->ma_keys->dk_usable <= 0) { /* Need to resize. */ if (insertion_resize(mp) < 0) { Py_DECREF(value); return -1; } - find_empty_slot(mp, key, hash, &value_addr, &hashpos); + hashpos = find_empty_slot(mp->ma_keys, key, hash); } - ep0 = DK_ENTRIES(mp->ma_keys); - ep = &ep0[mp->ma_keys->dk_nentries]; + ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries]; dk_set_index(mp->ma_keys, hashpos, mp->ma_keys->dk_nentries); Py_INCREF(key); ep->me_key = key; @@ -1174,64 +1166,41 @@ insertdict(PyDictObject *mp, PyObject *key, Py_hash_t hash, PyObject *value) return 0; } - assert(value_addr != NULL); - - old_value = *value_addr; - if (old_value != NULL) { - *value_addr = value; - mp->ma_version_tag = DICT_NEXT_VERSION(); - assert(_PyDict_CheckConsistency(mp)); - - Py_DECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ - return 0; + if (_PyDict_HasSplitTable(mp)) { + mp->ma_values[ix] = value; + if (old_value == NULL) { + /* pending state */ + assert(ix == mp->ma_used); + mp->ma_used++; + } + } + else { + assert(old_value != NULL); + DK_ENTRIES(mp->ma_keys)[ix].me_value = value; } - /* pending state */ - assert(_PyDict_HasSplitTable(mp)); - assert(ix == mp->ma_used); - *value_addr = value; - mp->ma_used++; mp->ma_version_tag = DICT_NEXT_VERSION(); + Py_XDECREF(old_value); /* which **CAN** re-enter (see issue #22653) */ assert(_PyDict_CheckConsistency(mp)); return 0; } /* -Internal routine used by dictresize() to insert an item which is -known to be absent from the dict. This routine also assumes that -the dict contains no deleted entries. Besides the performance benefit, -using insertdict() in dictresize() is dangerous (SF bug #1456209). -Note that no refcounts are changed by this routine; if needed, the caller -is responsible for incref'ing `key` and `value`. -Neither mp->ma_used nor k->dk_usable are modified by this routine; the caller -must set them correctly +Internal routine used by dictresize() to buid a hashtable of entries. */ static void -insertdict_clean(PyDictObject *mp, PyObject *key, Py_hash_t hash, - PyObject *value) +build_indices(PyDictKeysObject *keys, PyDictKeyEntry *ep, Py_ssize_t n) { - size_t i; - PyDictKeysObject *k = mp->ma_keys; - size_t mask = (size_t)DK_SIZE(k)-1; - PyDictKeyEntry *ep0 = DK_ENTRIES(mp->ma_keys); - PyDictKeyEntry *ep; - - assert(k->dk_lookup != NULL); - assert(value != NULL); - assert(key != NULL); - assert(PyUnicode_CheckExact(key) || k->dk_lookup == lookdict); - i = hash & mask; - for (size_t perturb = hash; dk_get_index(k, i) != DKIX_EMPTY;) { - perturb >>= PERTURB_SHIFT; - i = mask & ((i << 2) + i + perturb + 1); + size_t mask = (size_t)DK_SIZE(keys) - 1; + for (Py_ssize_t ix = 0; ix != n; ix++, ep++) { + Py_hash_t hash = ep->me_hash; + size_t i = hash & mask; + for (size_t perturb = hash; dk_get_index(keys, i) != DKIX_EMPTY;) { + perturb >>= PERTURB_SHIFT; + i = mask & ((i << 2) + i + perturb + 1); + } + dk_set_index(keys, i, ix); } - ep = &ep0[k->dk_nentries]; - assert(ep->me_value == NULL); - dk_set_index(k, i, k->dk_nentries); - k->dk_nentries++; - ep->me_key = key; - ep->me_hash = hash; - ep->me_value = value; } /* @@ -1247,10 +1216,10 @@ but can be resplit by make_keys_shared(). static int dictresize(PyDictObject *mp, Py_ssize_t minsize) { - Py_ssize_t i, newsize; + Py_ssize_t newsize, numentries; PyDictKeysObject *oldkeys; PyObject **oldvalues; - PyDictKeyEntry *ep0; + PyDictKeyEntry *oldentries, *newentries; /* Find the smallest table size > minused. */ for (newsize = PyDict_MINSIZE; @@ -1261,8 +1230,14 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize) PyErr_NoMemory(); return -1; } + oldkeys = mp->ma_keys; - oldvalues = mp->ma_values; + + /* NOTE: Current odict checks mp->ma_keys to detect resize happen. + * So we can't reuse oldkeys even if oldkeys->dk_size == newsize. + * TODO: Try reusing oldkeys when reimplement odict. + */ + /* Allocate a new table. */ mp->ma_keys = new_keys_object(newsize); if (mp->ma_keys == NULL) { @@ -1273,42 +1248,59 @@ dictresize(PyDictObject *mp, Py_ssize_t minsize) assert(mp->ma_keys->dk_usable >= mp->ma_used); if (oldkeys->dk_lookup == lookdict) mp->ma_keys->dk_lookup = lookdict; - mp->ma_values = NULL; - ep0 = DK_ENTRIES(oldkeys); - /* Main loop below assumes we can transfer refcount to new keys - * and that value is stored in me_value. - * Increment ref-counts and copy values here to compensate - * This (resizing a split table) should be relatively rare */ + + numentries = mp->ma_used; + oldentries = DK_ENTRIES(oldkeys); + newentries = DK_ENTRIES(mp->ma_keys); + oldvalues = mp->ma_values; if (oldvalues != NULL) { - for (i = 0; i < oldkeys->dk_nentries; i++) { - if (oldvalues[i] != NULL) { - Py_INCREF(ep0[i].me_key); - ep0[i].me_value = oldvalues[i]; - } - } - } - /* Main loop */ - for (i = 0; i < oldkeys->dk_nentries; i++) { - PyDictKeyEntry *ep = &ep0[i]; - if (ep->me_value != NULL) { - insertdict_clean(mp, ep->me_key, ep->me_hash, ep->me_value); + /* Convert split table into new combined table. + * We must incref keys; we can transfer values. + * Note that values of split table is always dense. + */ + for (Py_ssize_t i = 0; i < numentries; i++) { + assert(oldvalues[i] != NULL); + PyDictKeyEntry *ep = &oldentries[i]; + PyObject *key = ep->me_key; + Py_INCREF(key); + newentries[i].me_key = key; + newentries[i].me_hash = ep->me_hash; + newentries[i].me_value = oldvalues[i]; } - } - mp->ma_keys->dk_usable -= mp->ma_used; - if (oldvalues != NULL) { - /* NULL out me_value slot in oldkeys, in case it was shared */ - for (i = 0; i < oldkeys->dk_nentries; i++) - ep0[i].me_value = NULL; + DK_DECREF(oldkeys); + mp->ma_values = NULL; if (oldvalues != empty_values) { free_values(oldvalues); } } - else { + else { // combined table. + if (oldkeys->dk_nentries == numentries) { + memcpy(newentries, oldentries, numentries * sizeof(PyDictKeyEntry)); + } + else { + PyDictKeyEntry *ep = oldentries; + for (Py_ssize_t i = 0; i < numentries; i++) { + while (ep->me_value == NULL) + ep++; + newentries[i] = *ep++; + } + } + assert(oldkeys->dk_lookup != lookdict_split); assert(oldkeys->dk_refcnt == 1); - DK_DEBUG_DECREF PyObject_FREE(oldkeys); + if (oldkeys->dk_size == PyDict_MINSIZE && + numfreekeys < PyDict_MAXFREELIST) { + DK_DEBUG_DECREF keys_free_list[numfreekeys++] = oldkeys; + } + else { + DK_DEBUG_DECREF PyObject_FREE(oldkeys); + } } + + build_indices(mp->ma_keys, newentries, numentries); + mp->ma_keys->dk_usable -= numentries; + mp->ma_keys->dk_nentries = numentries; return 0; } @@ -1402,7 +1394,7 @@ PyDict_GetItem(PyObject *op, PyObject *key) Py_ssize_t ix; PyDictObject *mp = (PyDictObject *)op; PyThreadState *tstate; - PyObject **value_addr; + PyObject *value; if (!PyDict_Check(op)) return NULL; @@ -1421,25 +1413,25 @@ PyDict_GetItem(PyObject *op, PyObject *key) Let's just hope that no exception occurs then... This must be _PyThreadState_Current and not PyThreadState_GET() because in debug mode, the latter complains if tstate is NULL. */ - tstate = _PyThreadState_UncheckedGet(); + tstate = PyThreadState_GET(); if (tstate != NULL && tstate->curexc_type != NULL) { /* preserve the existing exception */ PyObject *err_type, *err_value, *err_tb; PyErr_Fetch(&err_type, &err_value, &err_tb); - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); /* ignore errors */ PyErr_Restore(err_type, err_value, err_tb); if (ix < 0) return NULL; } else { - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix < 0) { PyErr_Clear(); return NULL; } } - return *value_addr; + return value; } /* Same as PyDict_GetItemWithError() but with hash supplied by caller. @@ -1451,18 +1443,18 @@ _PyDict_GetItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) { Py_ssize_t ix; PyDictObject *mp = (PyDictObject *)op; - PyObject **value_addr; + PyObject *value; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix < 0) { return NULL; } - return *value_addr; + return value; } /* Variant of PyDict_GetItem() that doesn't suppress exceptions. @@ -1475,7 +1467,7 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) Py_ssize_t ix; Py_hash_t hash; PyDictObject*mp = (PyDictObject *)op; - PyObject **value_addr; + PyObject *value; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); @@ -1490,10 +1482,10 @@ PyDict_GetItemWithError(PyObject *op, PyObject *key) } } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix < 0) return NULL; - return *value_addr; + return value; } PyObject * @@ -1518,7 +1510,7 @@ _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) { Py_ssize_t ix; Py_hash_t hash; - PyObject **value_addr; + PyObject *value; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) @@ -1529,17 +1521,17 @@ _PyDict_LoadGlobal(PyDictObject *globals, PyDictObject *builtins, PyObject *key) } /* namespace 1: globals */ - ix = globals->ma_keys->dk_lookup(globals, key, hash, &value_addr, NULL); + ix = globals->ma_keys->dk_lookup(globals, key, hash, &value, NULL); if (ix == DKIX_ERROR) return NULL; - if (ix != DKIX_EMPTY && *value_addr != NULL) - return *value_addr; + if (ix != DKIX_EMPTY && value != NULL) + return value; /* namespace 2: builtins */ - ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value_addr, NULL); + ix = builtins->ma_keys->dk_lookup(builtins, key, hash, &value, NULL); if (ix < 0) return NULL; - return *value_addr; + return value; } /* CAUTION: PyDict_SetItem() must guarantee that it won't resize the @@ -1614,7 +1606,6 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) PyDictObject *mp; PyDictKeyEntry *ep; PyObject *old_key, *old_value; - PyObject **value_addr; if (!PyDict_Check(op)) { PyErr_BadInternalCall(); @@ -1623,10 +1614,10 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) assert(key); assert(hash != -1); mp = (PyDictObject *)op; - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value, &hashpos); if (ix == DKIX_ERROR) return -1; - if (ix == DKIX_EMPTY || *value_addr == NULL) { + if (ix == DKIX_EMPTY || old_value == NULL) { _PyErr_SetKeyError(key); return -1; } @@ -1637,13 +1628,11 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) if (dictresize(mp, DK_SIZE(mp->ma_keys))) { return -1; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value, &hashpos); assert(ix >= 0); } - old_value = *value_addr; assert(old_value != NULL); - *value_addr = NULL; mp->ma_used--; mp->ma_version_tag = DICT_NEXT_VERSION(); ep = &DK_ENTRIES(mp->ma_keys)[ix]; @@ -1651,6 +1640,7 @@ _PyDict_DelItem_KnownHash(PyObject *op, PyObject *key, Py_hash_t hash) ENSURE_ALLOWS_DELETIONS(mp); old_key = ep->me_key; ep->me_key = NULL; + ep->me_value = NULL; Py_DECREF(old_key); Py_DECREF(old_value); @@ -1703,7 +1693,7 @@ int _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, PyObject **pvalue, Py_hash_t *phash) { - Py_ssize_t i, n; + Py_ssize_t i; PyDictObject *mp; PyDictKeyEntry *entry_ptr; PyObject *value; @@ -1712,21 +1702,18 @@ _PyDict_Next(PyObject *op, Py_ssize_t *ppos, PyObject **pkey, return 0; mp = (PyDictObject *)op; i = *ppos; - n = mp->ma_keys->dk_nentries; - if ((size_t)i >= (size_t)n) - return 0; if (mp->ma_values) { - PyObject **value_ptr = &mp->ma_values[i]; - while (i < n && *value_ptr == NULL) { - value_ptr++; - i++; - } - if (i >= n) + if (i < 0 || i >= mp->ma_used) return 0; + /* values of split table is always dense */ entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; - value = *value_ptr; + value = mp->ma_values[i]; + assert(value != NULL); } else { + Py_ssize_t n = mp->ma_keys->dk_nentries; + if (i < 0 || i >= n) + return 0; entry_ptr = &DK_ENTRIES(mp->ma_keys)[i]; while (i < n && entry_ptr->me_value == NULL) { entry_ptr++; @@ -1778,7 +1765,6 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) Py_ssize_t ix, hashpos; PyObject *old_value, *old_key; PyDictKeyEntry *ep; - PyObject **value_addr; PyDictObject *mp; assert(PyDict_Check(dict)); @@ -1798,10 +1784,10 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) if (hash == -1) return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value, &hashpos); if (ix == DKIX_ERROR) return NULL; - if (ix == DKIX_EMPTY || *value_addr == NULL) { + if (ix == DKIX_EMPTY || old_value == NULL) { if (deflt) { Py_INCREF(deflt); return deflt; @@ -1815,13 +1801,11 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) if (dictresize(mp, DK_SIZE(mp->ma_keys))) { return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &old_value, &hashpos); assert(ix >= 0); } - old_value = *value_addr; assert(old_value != NULL); - *value_addr = NULL; mp->ma_used--; mp->ma_version_tag = DICT_NEXT_VERSION(); dk_set_index(mp->ma_keys, hashpos, DKIX_DUMMY); @@ -1829,6 +1813,7 @@ _PyDict_Pop(PyObject *dict, PyObject *key, PyObject *deflt) ENSURE_ALLOWS_DELETIONS(mp); old_key = ep->me_key; ep->me_key = NULL; + ep->me_value = NULL; Py_DECREF(old_key); assert(_PyDict_CheckConsistency(mp)); @@ -1844,7 +1829,7 @@ _PyDict_FromKeys(PyObject *cls, PyObject *iterable, PyObject *value) PyObject *d; int status; - d = PyObject_CallObject(cls, NULL); + d = _PyObject_CallNoArg(cls); if (d == NULL) return NULL; @@ -2046,10 +2031,9 @@ dict_length(PyDictObject *mp) static PyObject * dict_subscript(PyDictObject *mp, PyObject *key) { - PyObject *v; Py_ssize_t ix; Py_hash_t hash; - PyObject **value_addr; + PyObject *value; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -2057,10 +2041,10 @@ dict_subscript(PyDictObject *mp, PyObject *key) if (hash == -1) return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix == DKIX_ERROR) return NULL; - if (ix == DKIX_EMPTY || *value_addr == NULL) { + if (ix == DKIX_EMPTY || value == NULL) { if (!PyDict_CheckExact(mp)) { /* Look up __missing__ method if we're a subclass. */ PyObject *missing, *res; @@ -2078,9 +2062,8 @@ dict_subscript(PyDictObject *mp, PyObject *key) _PyErr_SetKeyError(key); return NULL; } - v = *value_addr; - Py_INCREF(v); - return v; + Py_INCREF(value); + return value; } static int @@ -2652,7 +2635,6 @@ dict_equal(PyDictObject *a, PyDictObject *b) if (aval != NULL) { int cmp; PyObject *bval; - PyObject **vaddr; PyObject *key = ep->me_key; /* temporarily bump aval's refcount to ensure it stays alive until we're done with it */ @@ -2660,10 +2642,7 @@ dict_equal(PyDictObject *a, PyDictObject *b) /* ditto for key */ Py_INCREF(key); /* reuse the known hash value */ - if ((b->ma_keys->dk_lookup)(b, key, ep->me_hash, &vaddr, NULL) < 0) - bval = NULL; - else - bval = *vaddr; + b->ma_keys->dk_lookup(b, key, ep->me_hash, &bval, NULL); Py_DECREF(key); if (bval == NULL) { Py_DECREF(aval); @@ -2719,7 +2698,7 @@ dict___contains__(PyDictObject *self, PyObject *key) register PyDictObject *mp = self; Py_hash_t hash; Py_ssize_t ix; - PyObject **value_addr; + PyObject *value; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -2727,10 +2706,10 @@ dict___contains__(PyDictObject *self, PyObject *key) if (hash == -1) return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix == DKIX_ERROR) return NULL; - if (ix == DKIX_EMPTY || *value_addr == NULL) + if (ix == DKIX_EMPTY || value == NULL) Py_RETURN_FALSE; Py_RETURN_TRUE; } @@ -2743,7 +2722,6 @@ dict_get(PyDictObject *mp, PyObject *args) PyObject *val = NULL; Py_hash_t hash; Py_ssize_t ix; - PyObject **value_addr; if (!PyArg_UnpackTuple(args, "get", 1, 2, &key, &failobj)) return NULL; @@ -2754,13 +2732,12 @@ dict_get(PyDictObject *mp, PyObject *args) if (hash == -1) return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &val, NULL); if (ix == DKIX_ERROR) return NULL; - if (ix == DKIX_EMPTY || *value_addr == NULL) + if (ix == DKIX_EMPTY || val == NULL) { val = failobj; - else - val = *value_addr; + } Py_INCREF(val); return val; } @@ -2772,7 +2749,6 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) PyObject *value; Py_hash_t hash; Py_ssize_t hashpos, ix; - PyObject **value_addr; if (!PyDict_Check(d)) { PyErr_BadInternalCall(); @@ -2791,17 +2767,17 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) return NULL; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, &hashpos); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, &hashpos); if (ix == DKIX_ERROR) return NULL; if (_PyDict_HasSplitTable(mp) && - ((ix >= 0 && *value_addr == NULL && mp->ma_used != ix) || + ((ix >= 0 && value == NULL && mp->ma_used != ix) || (ix == DKIX_EMPTY && mp->ma_used != mp->ma_keys->dk_nentries))) { if (insertion_resize(mp) < 0) { return NULL; } - find_empty_slot(mp, key, hash, &value_addr, &hashpos); + hashpos = find_empty_slot(mp->ma_keys, key, hash); ix = DKIX_EMPTY; } @@ -2812,7 +2788,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) if (insertion_resize(mp) < 0) { return NULL; } - find_empty_slot(mp, key, hash, &value_addr, &hashpos); + hashpos = find_empty_slot(mp->ma_keys, key, hash); } ep0 = DK_ENTRIES(mp->ma_keys); ep = &ep0[mp->ma_keys->dk_nentries]; @@ -2822,7 +2798,7 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) MAINTAIN_TRACKING(mp, key, value); ep->me_key = key; ep->me_hash = hash; - if (mp->ma_values) { + if (_PyDict_HasSplitTable(mp)) { assert(mp->ma_values[mp->ma_keys->dk_nentries] == NULL); mp->ma_values[mp->ma_keys->dk_nentries] = value; } @@ -2835,19 +2811,16 @@ PyDict_SetDefault(PyObject *d, PyObject *key, PyObject *defaultobj) mp->ma_keys->dk_nentries++; assert(mp->ma_keys->dk_usable >= 0); } - else if (*value_addr == NULL) { + else if (value == NULL) { value = defaultobj; assert(_PyDict_HasSplitTable(mp)); assert(ix == mp->ma_used); Py_INCREF(value); MAINTAIN_TRACKING(mp, key, value); - *value_addr = value; + mp->ma_values[ix] = value; mp->ma_used++; mp->ma_version_tag = DICT_NEXT_VERSION(); } - else { - value = *value_addr; - } assert(_PyDict_CheckConsistency(mp)); return value; @@ -3101,7 +3074,7 @@ PyDict_Contains(PyObject *op, PyObject *key) Py_hash_t hash; Py_ssize_t ix; PyDictObject *mp = (PyDictObject *)op; - PyObject **value_addr; + PyObject *value; if (!PyUnicode_CheckExact(key) || (hash = ((PyASCIIObject *) key)->hash) == -1) { @@ -3109,10 +3082,10 @@ PyDict_Contains(PyObject *op, PyObject *key) if (hash == -1) return -1; } - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix == DKIX_ERROR) return -1; - return (ix != DKIX_EMPTY && *value_addr != NULL); + return (ix != DKIX_EMPTY && value != NULL); } /* Internal version of PyDict_Contains used when the hash value is already known */ @@ -3120,13 +3093,13 @@ int _PyDict_Contains(PyObject *op, PyObject *key, Py_hash_t hash) { PyDictObject *mp = (PyDictObject *)op; - PyObject **value_addr; + PyObject *value; Py_ssize_t ix; - ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value_addr, NULL); + ix = (mp->ma_keys->dk_lookup)(mp, key, hash, &value, NULL); if (ix == DKIX_ERROR) return -1; - return (ix != DKIX_EMPTY && *value_addr != NULL); + return (ix != DKIX_EMPTY && value != NULL); } /* Hack to implement "key in dict" */ @@ -3391,7 +3364,7 @@ static PyObject* dictiter_iternextkey(dictiterobject *di) { PyObject *key; - Py_ssize_t i, n; + Py_ssize_t i; PyDictKeysObject *k; PyDictObject *d = di->di_dict; @@ -3408,18 +3381,15 @@ dictiter_iternextkey(dictiterobject *di) i = di->di_pos; k = d->ma_keys; - n = k->dk_nentries; + assert(i >= 0); if (d->ma_values) { - PyObject **value_ptr = &d->ma_values[i]; - while (i < n && *value_ptr == NULL) { - value_ptr++; - i++; - } - if (i >= n) + if (i >= d->ma_used) goto fail; key = DK_ENTRIES(k)[i].me_key; + assert(d->ma_values[i] != NULL); } else { + Py_ssize_t n = k->dk_nentries; PyDictKeyEntry *entry_ptr = &DK_ENTRIES(k)[i]; while (i < n && entry_ptr->me_value == NULL) { entry_ptr++; @@ -3477,7 +3447,7 @@ static PyObject * dictiter_iternextvalue(dictiterobject *di) { PyObject *value; - Py_ssize_t i, n; + Py_ssize_t i; PyDictObject *d = di->di_dict; if (d == NULL) @@ -3492,18 +3462,15 @@ dictiter_iternextvalue(dictiterobject *di) } i = di->di_pos; - n = d->ma_keys->dk_nentries; + assert(i >= 0); if (d->ma_values) { - PyObject **value_ptr = &d->ma_values[i]; - while (i < n && *value_ptr == NULL) { - value_ptr++; - i++; - } - if (i >= n) + if (i >= d->ma_used) goto fail; - value = *value_ptr; + value = d->ma_values[i]; + assert(value != NULL); } else { + Py_ssize_t n = d->ma_keys->dk_nentries; PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; while (i < n && entry_ptr->me_value == NULL) { entry_ptr++; @@ -3561,7 +3528,7 @@ static PyObject * dictiter_iternextitem(dictiterobject *di) { PyObject *key, *value, *result = di->di_result; - Py_ssize_t i, n; + Py_ssize_t i; PyDictObject *d = di->di_dict; if (d == NULL) @@ -3576,19 +3543,16 @@ dictiter_iternextitem(dictiterobject *di) } i = di->di_pos; - n = d->ma_keys->dk_nentries; + assert(i >= 0); if (d->ma_values) { - PyObject **value_ptr = &d->ma_values[i]; - while (i < n && *value_ptr == NULL) { - value_ptr++; - i++; - } - if (i >= n) + if (i >= d->ma_used) goto fail; key = DK_ENTRIES(d->ma_keys)[i].me_key; - value = *value_ptr; + value = d->ma_values[i]; + assert(value != NULL); } else { + Py_ssize_t n = d->ma_keys->dk_nentries; PyDictKeyEntry *entry_ptr = &DK_ENTRIES(d->ma_keys)[i]; while (i < n && entry_ptr->me_value == NULL) { entry_ptr++; diff --git a/Objects/enumobject.c b/Objects/enumobject.c index dae166d..72d31b1 100644 --- a/Objects/enumobject.c +++ b/Objects/enumobject.c @@ -258,7 +258,7 @@ reversed_new(PyTypeObject *type, PyObject *args, PyObject *kwds) return NULL; } if (reversed_meth != NULL) { - PyObject *res = PyObject_CallFunctionObjArgs(reversed_meth, NULL); + PyObject *res = _PyObject_CallNoArg(reversed_meth); Py_DECREF(reversed_meth); return res; } diff --git a/Objects/exceptions.c b/Objects/exceptions.c index f63f06a..57a786c 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -631,19 +631,17 @@ ImportError_init(PyImportErrorObject *self, PyObject *args, PyObject *kwds) } Py_DECREF(empty_tuple); - if (name) { - Py_INCREF(name); - Py_XSETREF(self->name, name); - } - if (path) { - Py_INCREF(path); - Py_XSETREF(self->path, path); - } + Py_XINCREF(name); + Py_XSETREF(self->name, name); + + Py_XINCREF(path); + Py_XSETREF(self->path, path); + if (PyTuple_GET_SIZE(args) == 1) { msg = PyTuple_GET_ITEM(args, 0); Py_INCREF(msg); - Py_XSETREF(self->msg, msg); } + Py_XSETREF(self->msg, msg); return 0; } @@ -1822,18 +1820,10 @@ UnicodeEncodeError_init(PyObject *self, PyObject *args, PyObject *kwds) Py_CLEAR(err->object); Py_CLEAR(err->reason); - if (!PyArg_ParseTuple(args, "O!O!nnO!", - &PyUnicode_Type, &err->encoding, - &PyUnicode_Type, &err->object, - &err->start, - &err->end, - &PyUnicode_Type, &err->reason)) { - err->encoding = err->object = err->reason = NULL; - return -1; - } - - if (PyUnicode_READY(err->object) < -1) { - err->encoding = NULL; + if (!PyArg_ParseTuple(args, "UUnnU", + &err->encoding, &err->object, + &err->start, &err->end, &err->reason)) { + err->encoding = err->object = err->reason = NULL; return -1; } @@ -1937,12 +1927,9 @@ UnicodeDecodeError_init(PyObject *self, PyObject *args, PyObject *kwds) Py_CLEAR(ude->object); Py_CLEAR(ude->reason); - if (!PyArg_ParseTuple(args, "O!OnnO!", - &PyUnicode_Type, &ude->encoding, - &ude->object, - &ude->start, - &ude->end, - &PyUnicode_Type, &ude->reason)) { + if (!PyArg_ParseTuple(args, "UOnnU", + &ude->encoding, &ude->object, + &ude->start, &ude->end, &ude->reason)) { ude->encoding = ude->object = ude->reason = NULL; return -1; } @@ -2052,11 +2039,9 @@ UnicodeTranslateError_init(PyUnicodeErrorObject *self, PyObject *args, Py_CLEAR(self->object); Py_CLEAR(self->reason); - if (!PyArg_ParseTuple(args, "O!nnO!", - &PyUnicode_Type, &self->object, - &self->start, - &self->end, - &PyUnicode_Type, &self->reason)) { + if (!PyArg_ParseTuple(args, "UnnU", + &self->object, + &self->start, &self->end, &self->reason)) { self->object = self->reason = NULL; return -1; } diff --git a/Objects/fileobject.c b/Objects/fileobject.c index f442418..fcdb5fd 100644 --- a/Objects/fileobject.c +++ b/Objects/fileobject.c @@ -146,7 +146,7 @@ PyFile_WriteObject(PyObject *v, PyObject *f, int flags) Py_DECREF(writer); return -1; } - result = _PyObject_CallArg1(writer, value); + result = PyObject_CallFunctionObjArgs(writer, value, NULL); Py_DECREF(value); Py_DECREF(writer); if (result == NULL) @@ -367,7 +367,7 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) { PyObject *unicode; PyObject *bytes = NULL; - char *str; + const char *str; Py_ssize_t n; int err; @@ -389,10 +389,8 @@ stdprinter_write(PyStdPrinter_Object *self, PyObject *args) bytes = _PyUnicode_AsUTF8String(unicode, "backslashreplace"); if (bytes == NULL) return NULL; - if (PyBytes_AsStringAndSize(bytes, &str, &n) < 0) { - Py_DECREF(bytes); - return NULL; - } + str = PyBytes_AS_STRING(bytes); + n = PyBytes_GET_SIZE(bytes); } n = _Py_write(self->fd, str, n); diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 80bf71e..17a55dd 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1225,7 +1225,7 @@ float_fromhex(PyObject *cls, PyObject *arg) PyObject *result; double x; long exp, top_exp, lsb, key_digit; - char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end; + const char *s, *coeff_start, *s_store, *coeff_end, *exp_start, *s_end; int half_eps, digit, round_up, negate=0; Py_ssize_t length, ndigits, fdigits, i; @@ -1288,7 +1288,7 @@ float_fromhex(PyObject *cls, PyObject *arg) s++; /* infinities and nans */ - x = _Py_parse_inf_or_nan(s, &coeff_end); + x = _Py_parse_inf_or_nan(s, (char **)&coeff_end); if (coeff_end != s) { s = coeff_end; goto finished; @@ -1619,7 +1619,7 @@ static float_format_type detected_double_format, detected_float_format; static PyObject * float_getformat(PyTypeObject *v, PyObject* arg) { - char* s; + const char *s; float_format_type r; if (!PyUnicode_Check(arg)) { diff --git a/Objects/frameobject.c b/Objects/frameobject.c index 62f9f34..eed5384 100644 --- a/Objects/frameobject.c +++ b/Objects/frameobject.c @@ -409,7 +409,7 @@ static int numfree = 0; /* number of frames currently in free_list */ /* max value for numfree */ #define PyFrame_MAXFREELIST 200 -static void +static void _Py_HOT_FUNCTION frame_dealloc(PyFrameObject *f) { PyObject **p, **valuestack; @@ -605,7 +605,7 @@ int _PyFrame_Init() return 1; } -PyFrameObject * +PyFrameObject* _Py_HOT_FUNCTION PyFrame_New(PyThreadState *tstate, PyCodeObject *code, PyObject *globals, PyObject *locals) { diff --git a/Objects/genobject.c b/Objects/genobject.c index 2680ab0..59f53ce 100644 --- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -1341,7 +1341,7 @@ async_gen_init_hooks(PyAsyncGenObject *o) PyObject *res; Py_INCREF(firstiter); - res = PyObject_CallFunction(firstiter, "O", o); + res = PyObject_CallFunctionObjArgs(firstiter, o, NULL); Py_DECREF(firstiter); if (res == NULL) { return 1; diff --git a/Objects/longobject.c b/Objects/longobject.c index ad239ce..c95f946 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -315,7 +315,6 @@ PyLong_FromUnsignedLong(unsigned long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = ndigits; while (ival) { *p++ = (digit)(ival & PyLong_MASK); ival >>= PyLong_SHIFT; @@ -709,12 +708,33 @@ _PyLong_Sign(PyObject *vv) return Py_SIZE(v) == 0 ? 0 : (Py_SIZE(v) < 0 ? -1 : 1); } +/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d < + 2**k if d is nonzero, else 0. */ + +static const unsigned char BitLengthTable[32] = { + 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 +}; + +static int +bits_in_digit(digit d) +{ + int d_bits = 0; + while (d >= 32) { + d_bits += 6; + d >>= 6; + } + d_bits += (int)BitLengthTable[d]; + return d_bits; +} + size_t _PyLong_NumBits(PyObject *vv) { PyLongObject *v = (PyLongObject *)vv; size_t result = 0; Py_ssize_t ndigits; + int msd_bits; assert(v != NULL); assert(PyLong_Check(v)); @@ -725,12 +745,10 @@ _PyLong_NumBits(PyObject *vv) if ((size_t)(ndigits - 1) > SIZE_MAX / (size_t)PyLong_SHIFT) goto Overflow; result = (size_t)(ndigits - 1) * (size_t)PyLong_SHIFT; - do { - ++result; - if (result == 0) - goto Overflow; - msd >>= 1; - } while (msd); + msd_bits = bits_in_digit(msd); + if (SIZE_MAX - msd_bits < result) + goto Overflow; + result += msd_bits; } return result; @@ -1102,7 +1120,6 @@ PyLong_FromUnsignedLongLong(unsigned long long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - Py_SIZE(v) = ndigits; while (ival) { *p++ = (digit)(ival & PyLong_MASK); ival >>= PyLong_SHIFT; @@ -1416,26 +1433,6 @@ PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) Py_RETURN_NOTIMPLEMENTED; \ } while(0) -/* bits_in_digit(d) returns the unique integer k such that 2**(k-1) <= d < - 2**k if d is nonzero, else 0. */ - -static const unsigned char BitLengthTable[32] = { - 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, - 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 -}; - -static int -bits_in_digit(digit d) -{ - int d_bits = 0; - while (d >= 32) { - d_bits += 6; - d >>= 6; - } - d_bits += (int)BitLengthTable[d]; - return d_bits; -} - /* x[0:m] and y[0:n] are digit vectors, LSD first, m >= n required. x[0:n] * is modified in place, by adding y to it. Carries are propagated as far as * x[m-1], and the remaining carry (0 or 1) is returned. @@ -2482,7 +2479,7 @@ _PyLong_FromBytes(const char *s, Py_ssize_t len, int base) PyObject * PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) { - PyObject *v, *unicode = PyUnicode_FromUnicode(u, length); + PyObject *v, *unicode = PyUnicode_FromWideChar(u, length); if (unicode == NULL) return NULL; v = PyLong_FromUnicodeObject(unicode, base); @@ -2494,7 +2491,8 @@ PyObject * PyLong_FromUnicodeObject(PyObject *u, int base) { PyObject *result, *asciidig; - char *buffer, *end = NULL; + const char *buffer; + char *end = NULL; Py_ssize_t buflen; asciidig = _PyUnicode_TransformDecimalAndSpaceToASCII(u); @@ -3105,9 +3103,7 @@ long_add(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { - PyObject *result = PyLong_FromLong(MEDIUM_VALUE(a) + - MEDIUM_VALUE(b)); - return result; + return PyLong_FromLong(MEDIUM_VALUE(a) + MEDIUM_VALUE(b)); } if (Py_SIZE(a) < 0) { if (Py_SIZE(b) < 0) { @@ -3141,9 +3137,7 @@ long_sub(PyLongObject *a, PyLongObject *b) CHECK_BINOP(a, b); if (Py_ABS(Py_SIZE(a)) <= 1 && Py_ABS(Py_SIZE(b)) <= 1) { - PyObject* r; - r = PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); - return r; + return PyLong_FromLong(MEDIUM_VALUE(a) - MEDIUM_VALUE(b)); } if (Py_SIZE(a) < 0) { if (Py_SIZE(b) < 0) @@ -4296,22 +4290,22 @@ long_rshift(PyLongObject *a, PyLongObject *b) PyLongObject *a1, *a2; a1 = (PyLongObject *) long_invert(a); if (a1 == NULL) - goto rshift_error; + return NULL; a2 = (PyLongObject *) long_rshift(a1, b); Py_DECREF(a1); if (a2 == NULL) - goto rshift_error; + return NULL; z = (PyLongObject *) long_invert(a2); Py_DECREF(a2); } else { shiftby = PyLong_AsSsize_t((PyObject *)b); if (shiftby == -1L && PyErr_Occurred()) - goto rshift_error; + return NULL; if (shiftby < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); - goto rshift_error; + return NULL; } wordshift = shiftby / PyLong_SHIFT; newsize = Py_ABS(Py_SIZE(a)) - wordshift; @@ -4323,19 +4317,15 @@ long_rshift(PyLongObject *a, PyLongObject *b) himask = PyLong_MASK ^ lomask; z = _PyLong_New(newsize); if (z == NULL) - goto rshift_error; - if (Py_SIZE(a) < 0) - Py_SIZE(z) = -(Py_SIZE(z)); + return NULL; for (i = 0, j = wordshift; i < newsize; i++, j++) { z->ob_digit[i] = (a->ob_digit[j] >> loshift) & lomask; if (i+1 < newsize) z->ob_digit[i] |= (a->ob_digit[j+1] << hishift) & himask; } - z = long_normalize(z); + z = maybe_small_long(long_normalize(z)); } - rshift_error: - return (PyObject *) maybe_small_long(z); - + return (PyObject *)z; } static PyObject * @@ -5089,7 +5079,8 @@ static PyObject * long_bit_length(PyLongObject *v) { PyLongObject *result, *x, *y; - Py_ssize_t ndigits, msd_bits = 0; + Py_ssize_t ndigits; + int msd_bits; digit msd; assert(v != NULL); @@ -5100,11 +5091,7 @@ long_bit_length(PyLongObject *v) return PyLong_FromLong(0); msd = v->ob_digit[ndigits-1]; - while (msd >= 32) { - msd_bits += 6; - msd >>= 6; - } - msd_bits += (long)(BitLengthTable[msd]); + msd_bits = bits_in_digit(msd); if (ndigits <= PY_SSIZE_T_MAX/PyLong_SHIFT) return PyLong_FromSsize_t((ndigits-1)*PyLong_SHIFT + msd_bits); diff --git a/Objects/moduleobject.c b/Objects/moduleobject.c index 79be51a..350f3bf 100644 --- a/Objects/moduleobject.c +++ b/Objects/moduleobject.c @@ -188,7 +188,7 @@ PyModule_Create2(struct PyModuleDef* module, int module_api_version) (if the name actually matches). */ if (_Py_PackageContext != NULL) { - char *p = strrchr(_Py_PackageContext, '.'); + const char *p = strrchr(_Py_PackageContext, '.'); if (p != NULL && strcmp(module->m_name, p+1) == 0) { name = _Py_PackageContext; _Py_PackageContext = NULL; @@ -231,7 +231,7 @@ PyModule_FromDefAndSpec2(struct PyModuleDef* def, PyObject *spec, int module_api PyObject *nameobj; PyObject *m = NULL; int has_execution_slots = 0; - char *name; + const char *name; int ret; PyModuleDef_Init(def); @@ -512,7 +512,7 @@ const char * PyModule_GetFilename(PyObject *m) { PyObject *fileobj; - char *utf8; + const char *utf8; fileobj = PyModule_GetFilenameObject(m); if (fileobj == NULL) return NULL; diff --git a/Objects/object.c b/Objects/object.c index d88ae3b..9a7c7f7 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -596,7 +596,7 @@ PyObject_Bytes(PyObject *v) func = _PyObject_LookupSpecial(v, &PyId___bytes__); if (func != NULL) { - result = PyObject_CallFunctionObjArgs(func, NULL); + result = _PyObject_CallNoArg(func); Py_DECREF(func); if (result == NULL) return NULL; @@ -1025,11 +1025,99 @@ _PyObject_NextNotImplemented(PyObject *self) return NULL; } -/* Generic GetAttr functions - put these in your tp_[gs]etattro slot */ + +/* Specialized version of _PyObject_GenericGetAttrWithDict + specifically for the LOAD_METHOD opcode. + + Return 1 if a method is found, 0 if it's a regular attribute + from __dict__ or something returned by using a descriptor + protocol. + + `method` will point to the resolved attribute or NULL. In the + latter case, an error will be set. +*/ +int +_PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) +{ + PyTypeObject *tp = Py_TYPE(obj); + PyObject *descr; + descrgetfunc f = NULL; + PyObject **dictptr, *dict; + PyObject *attr; + int meth_found = 0; + + assert(*method == NULL); + + if (Py_TYPE(obj)->tp_getattro != PyObject_GenericGetAttr + || !PyUnicode_Check(name)) { + *method = PyObject_GetAttr(obj, name); + return 0; + } + + if (tp->tp_dict == NULL && PyType_Ready(tp) < 0) + return 0; + + descr = _PyType_Lookup(tp, name); + if (descr != NULL) { + Py_INCREF(descr); + if (PyFunction_Check(descr)) { + /* A python method. */ + meth_found = 1; + } else { + f = descr->ob_type->tp_descr_get; + if (f != NULL && PyDescr_IsData(descr)) { + *method = f(descr, obj, (PyObject *)obj->ob_type); + Py_DECREF(descr); + return 0; + } + } + } + + dictptr = _PyObject_GetDictPtr(obj); + if (dictptr != NULL && (dict = *dictptr) != NULL) { + Py_INCREF(dict); + attr = PyDict_GetItem(dict, name); + if (attr != NULL) { + Py_INCREF(attr); + *method = attr; + Py_DECREF(dict); + Py_XDECREF(descr); + return 0; + } + Py_DECREF(dict); + } + + if (meth_found) { + *method = descr; + return 1; + } + + if (f != NULL) { + *method = f(descr, obj, (PyObject *)Py_TYPE(obj)); + Py_DECREF(descr); + return 0; + } + + if (descr != NULL) { + *method = descr; + return 0; + } + + PyErr_Format(PyExc_AttributeError, + "'%.50s' object has no attribute '%U'", + tp->tp_name, name); + return 0; +} + +/* Generic GetAttr functions - put these in your tp_[gs]etattro slot. */ PyObject * _PyObject_GenericGetAttrWithDict(PyObject *obj, PyObject *name, PyObject *dict) { + /* Make sure the logic of _PyObject_GetMethod is in sync with + this method. + */ + PyTypeObject *tp = Py_TYPE(obj); PyObject *descr = NULL; PyObject *res = NULL; @@ -1314,7 +1402,7 @@ _dir_object(PyObject *obj) return NULL; } /* use __dir__ */ - result = PyObject_CallFunctionObjArgs(dirfunc, NULL); + result = _PyObject_CallNoArg(dirfunc); Py_DECREF(dirfunc); if (result == NULL) return NULL; diff --git a/Objects/odictobject.c b/Objects/odictobject.c index 22b1f1d..6b33386 100644 --- a/Objects/odictobject.c +++ b/Objects/odictobject.c @@ -535,11 +535,11 @@ _odict_free_fast_nodes(PyODictObject *od) { static Py_ssize_t _odict_get_index_raw(PyODictObject *od, PyObject *key, Py_hash_t hash) { - PyObject **value_addr = NULL; + PyObject *value = NULL; PyDictKeysObject *keys = ((PyDictObject *)od)->ma_keys; Py_ssize_t ix; - ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value_addr, NULL); + ix = (keys->dk_lookup)((PyDictObject *)od, key, hash, &value, NULL); if (ix == DKIX_EMPTY) { return keys->dk_nentries; /* index of new entry */ } @@ -1256,7 +1256,7 @@ odict_copy(register PyODictObject *od) if (PyODict_CheckExact(od)) od_copy = PyODict_New(); else - od_copy = PyObject_CallFunctionObjArgs((PyObject *)Py_TYPE(od), NULL); + od_copy = _PyObject_CallNoArg((PyObject *)Py_TYPE(od)); if (od_copy == NULL) return NULL; diff --git a/Objects/rangeobject.c b/Objects/rangeobject.c index 8449fc7..45c557f 100644 --- a/Objects/rangeobject.c +++ b/Objects/rangeobject.c @@ -829,8 +829,6 @@ static PyMethodDef rangeiter_methods[] = { {NULL, NULL} /* sentinel */ }; -static PyObject *rangeiter_new(PyTypeObject *, PyObject *args, PyObject *kw); - PyTypeObject PyRangeIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) "range_iterator", /* tp_name */ @@ -862,15 +860,6 @@ PyTypeObject PyRangeIter_Type = { (iternextfunc)rangeiter_next, /* tp_iternext */ rangeiter_methods, /* tp_methods */ 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - rangeiter_new, /* tp_new */ }; /* Return number of items in range (lo, hi, step). step != 0 @@ -925,36 +914,6 @@ fast_range_iter(long start, long stop, long step) return (PyObject *)it; } -static PyObject * -rangeiter_new(PyTypeObject *type, PyObject *args, PyObject *kw) -{ - long start, stop, step; - - if (PyErr_WarnEx(PyExc_DeprecationWarning, - "range_iterator(): creating instances of range_iterator " - "by calling range_iterator type is deprecated", - 1)) { - return NULL; - } - - if (!_PyArg_NoKeywords("range_iterator()", kw)) { - return NULL; - } - - if (!PyArg_ParseTuple(args, - "lll;range_iterator() requires 3 int arguments", - &start, &stop, &step)) { - return NULL; - } - if (step == 0) { - PyErr_SetString(PyExc_ValueError, - "range_iterator() arg 3 must not be zero"); - return NULL; - } - - return fast_range_iter(start, stop, step); -} - typedef struct { PyObject_HEAD PyObject *index; diff --git a/Objects/setobject.c b/Objects/setobject.c index fdb9d36..b7e0617 100644 --- a/Objects/setobject.c +++ b/Objects/setobject.c @@ -2398,7 +2398,7 @@ static PyObject * test_c_api(PySetObject *so) { Py_ssize_t count; - char *s; + const char *s; Py_ssize_t i; PyObject *elem=NULL, *dup=NULL, *t, *f, *dup2, *x=NULL; PyObject *ob = (PyObject *)so; diff --git a/Objects/structseq.c b/Objects/structseq.c index 5489aef..c2ece5a 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -182,7 +182,7 @@ structseq_repr(PyStructSequence *obj) for (i=0; i < VISIBLE_SIZE(obj); i++) { PyObject *val, *repr; - char *cname, *crepr; + const char *cname, *crepr; cname = typ->tp_members[i].name; if (cname == NULL) { @@ -256,7 +256,7 @@ structseq_reduce(PyStructSequence* self) } for (; i < n_fields; i++) { - char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name; + const char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name; if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0) goto error; } diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 329261b..391eed3 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1420,42 +1420,26 @@ _PyObject_LookupSpecial(PyObject *self, _Py_Identifier *attrid) return lookup_maybe(self, attrid); } -/* A variation of PyObject_CallMethod that uses lookup_method() +/* A variation of PyObject_CallMethodObjArgs that uses lookup_method() instead of PyObject_GetAttrString(). This uses the same convention as lookup_method to cache the interned name string object. */ static PyObject * -call_method(PyObject *o, _Py_Identifier *nameid, const char *format, ...) +call_method(PyObject *obj, _Py_Identifier *name, ...) { va_list va; - PyObject *func = NULL, *retval; + PyObject *func, *retval; - func = lookup_maybe(o, nameid); + func = lookup_maybe(obj, name); if (func == NULL) { if (!PyErr_Occurred()) - PyErr_SetObject(PyExc_AttributeError, nameid->object); + PyErr_SetObject(PyExc_AttributeError, name->object); return NULL; } - if (format && *format) { - PyObject *args; - - va_start(va, format); - args = Py_VaBuildValue(format, va); - va_end(va); - - if (args == NULL) { - Py_DECREF(func); - return NULL; - } - assert(PyTuple_Check(args)); - - retval = PyObject_Call(func, args, NULL); - Py_DECREF(args); - } - else { - retval = _PyObject_CallNoArg(func); - } + va_start(va, name); + retval = _PyObject_VaCallFunctionObjArgs(func, va); + va_end(va); Py_DECREF(func); @@ -1465,37 +1449,21 @@ call_method(PyObject *o, _Py_Identifier *nameid, const char *format, ...) /* Clone of call_method() that returns NotImplemented when the lookup fails. */ static PyObject * -call_maybe(PyObject *o, _Py_Identifier *nameid, const char *format, ...) +call_maybe(PyObject *obj, _Py_Identifier *name, ...) { va_list va; - PyObject *func = NULL, *retval; + PyObject *func, *retval; - func = lookup_maybe(o, nameid); + func = lookup_maybe(obj, name); if (func == NULL) { if (!PyErr_Occurred()) Py_RETURN_NOTIMPLEMENTED; return NULL; } - if (format && *format) { - PyObject *args; - - va_start(va, format); - args = Py_VaBuildValue(format, va); - va_end(va); - - if (args == NULL) { - Py_DECREF(func); - return NULL; - } - assert(PyTuple_Check(args)); - - retval = PyObject_Call(func, args, NULL); - Py_DECREF(args); - } - else { - retval = _PyObject_CallNoArg(func); - } + va_start(va, name); + retval = _PyObject_VaCallFunctionObjArgs(func, va); + va_end(va); Py_DECREF(func); @@ -1624,7 +1592,7 @@ consistent method resolution\norder (MRO) for bases"); i = 0; while (PyDict_Next(set, &i, &k, &v) && (size_t)off < sizeof(buf)) { PyObject *name = class_name(k); - char *name_str; + const char *name_str; if (name != NULL) { name_str = PyUnicode_AsUTF8(name); if (name_str == NULL) @@ -1856,7 +1824,7 @@ mro_invoke(PyTypeObject *type) PyObject *mro_meth = lookup_method((PyObject *)type, &PyId_mro); if (mro_meth == NULL) return NULL; - mro_result = PyObject_CallObject(mro_meth, NULL); + mro_result = _PyObject_CallNoArg(mro_meth); Py_DECREF(mro_meth); } else { @@ -2572,7 +2540,7 @@ type_new(PyTypeObject *metatype, PyObject *args, PyObject *kwds) PyObject *doc = _PyDict_GetItemId(dict, &PyId___doc__); if (doc != NULL && PyUnicode_Check(doc)) { Py_ssize_t len; - char *doc_str; + const char *doc_str; char *tp_doc; doc_str = PyUnicode_AsUTF8(doc); @@ -3082,7 +3050,7 @@ type_setattro(PyTypeObject *type, PyObject *name, PyObject *value) type->tp_name); return -1; } - if (PyObject_GenericSetAttr((PyObject *)type, name, value) < 0) + if (_PyObject_GenericSetAttrWithDict((PyObject *)type, name, value, NULL) < 0) return -1; return update_slot(type, name); } @@ -4032,7 +4000,7 @@ _PyObject_GetState(PyObject *obj, int required) Py_DECREF(slotnames); } else { /* getstate != NULL */ - state = PyObject_CallObject(getstate, NULL); + state = _PyObject_CallNoArg(getstate); Py_DECREF(getstate); if (state == NULL) return NULL; @@ -4057,7 +4025,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) __getnewargs_ex__ on the object. */ getnewargs_ex = _PyObject_LookupSpecial(obj, &PyId___getnewargs_ex__); if (getnewargs_ex != NULL) { - PyObject *newargs = PyObject_CallObject(getnewargs_ex, NULL); + PyObject *newargs = _PyObject_CallNoArg(getnewargs_ex); Py_DECREF(getnewargs_ex); if (newargs == NULL) { return -1; @@ -4110,7 +4078,7 @@ _PyObject_GetNewArguments(PyObject *obj, PyObject **args, PyObject **kwargs) __getnewargs__ instead. */ getnewargs = _PyObject_LookupSpecial(obj, &PyId___getnewargs__); if (getnewargs != NULL) { - *args = PyObject_CallObject(getnewargs, NULL); + *args = _PyObject_CallNoArg(getnewargs); Py_DECREF(getnewargs); if (*args == NULL) { return -1; @@ -4362,7 +4330,7 @@ object_reduce_ex(PyObject *self, PyObject *args) override = (clsreduce != objreduce); Py_DECREF(clsreduce); if (override) { - res = PyObject_CallObject(reduce, NULL); + res = _PyObject_CallNoArg(reduce); Py_DECREF(reduce); return res; } @@ -5736,12 +5704,12 @@ FUNCNAME(PyObject *self) \ return call_method(self, &id, NULL); \ } -#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE, ARGCODES) \ +#define SLOT1(FUNCNAME, OPSTR, ARG1TYPE) \ static PyObject * \ FUNCNAME(PyObject *self, ARG1TYPE arg1) \ { \ _Py_static_string(id, OPSTR); \ - return call_method(self, &id, "(" ARGCODES ")", arg1); \ + return call_method(self, &id, arg1, NULL); \ } /* Boolean helper for SLOT1BINFULL(). @@ -5794,20 +5762,20 @@ FUNCNAME(PyObject *self, PyObject *other) \ if (do_other && \ PyType_IsSubtype(Py_TYPE(other), Py_TYPE(self)) && \ method_is_overloaded(self, other, &rop_id)) { \ - r = call_maybe(other, &rop_id, "(O)", self); \ + r = call_maybe(other, &rop_id, self, NULL); \ if (r != Py_NotImplemented) \ return r; \ Py_DECREF(r); \ do_other = 0; \ } \ - r = call_maybe(self, &op_id, "(O)", other); \ + r = call_maybe(self, &op_id, other, NULL); \ if (r != Py_NotImplemented || \ Py_TYPE(other) == Py_TYPE(self)) \ return r; \ Py_DECREF(r); \ } \ if (do_other) { \ - return call_maybe(other, &rop_id, "(O)", self); \ + return call_maybe(other, &rop_id, self, NULL); \ } \ Py_RETURN_NOTIMPLEMENTED; \ } @@ -5815,14 +5783,6 @@ FUNCNAME(PyObject *self, PyObject *other) \ #define SLOT1BIN(FUNCNAME, SLOTNAME, OPSTR, ROPSTR) \ SLOT1BINFULL(FUNCNAME, FUNCNAME, SLOTNAME, OPSTR, ROPSTR) -#define SLOT2(FUNCNAME, OPSTR, ARG1TYPE, ARG2TYPE, ARGCODES) \ -static PyObject * \ -FUNCNAME(PyObject *self, ARG1TYPE arg1, ARG2TYPE arg2) \ -{ \ - _Py_static_string(id, #OPSTR); \ - return call_method(self, &id, "(" ARGCODES ")", arg1, arg2); \ -} - static Py_ssize_t slot_sq_length(PyObject *self) { @@ -5873,7 +5833,7 @@ slot_sq_item(PyObject *self, Py_ssize_t i) goto error; } - retval = _PyObject_CallArg1(func, ival); + retval = PyObject_CallFunctionObjArgs(func, ival, NULL); Py_DECREF(func); Py_DECREF(ival); return retval; @@ -5887,13 +5847,22 @@ static int slot_sq_ass_item(PyObject *self, Py_ssize_t index, PyObject *value) { PyObject *res; + PyObject *index_obj; + + index_obj = PyLong_FromSsize_t(index); + if (index_obj == NULL) { + return -1; + } if (value == NULL) - res = call_method(self, &PyId___delitem__, "(n)", index); + res = call_method(self, &PyId___delitem__, index_obj, NULL); else - res = call_method(self, &PyId___setitem__, "(nO)", index, value); - if (res == NULL) + res = call_method(self, &PyId___setitem__, index_obj, value, NULL); + Py_DECREF(index_obj); + + if (res == NULL) { return -1; + } Py_DECREF(res); return 0; } @@ -5914,7 +5883,7 @@ slot_sq_contains(PyObject *self, PyObject *value) return -1; } if (func != NULL) { - res = _PyObject_CallArg1(func, value); + res = PyObject_CallFunctionObjArgs(func, value, NULL); Py_DECREF(func); if (res != NULL) { result = PyObject_IsTrue(res); @@ -5931,7 +5900,7 @@ slot_sq_contains(PyObject *self, PyObject *value) #define slot_mp_length slot_sq_length -SLOT1(slot_mp_subscript, "__getitem__", PyObject *, "O") +SLOT1(slot_mp_subscript, "__getitem__", PyObject *) static int slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) @@ -5939,9 +5908,9 @@ slot_mp_ass_subscript(PyObject *self, PyObject *key, PyObject *value) PyObject *res; if (value == NULL) - res = call_method(self, &PyId___delitem__, "(O)", key); + res = call_method(self, &PyId___delitem__, key, NULL); else - res = call_method(self, &PyId___setitem__, "(OO)", key, value); + res = call_method(self, &PyId___setitem__, key, value, NULL); if (res == NULL) return -1; @@ -5973,7 +5942,7 @@ slot_nb_power(PyObject *self, PyObject *other, PyObject *modulus) slot_nb_power, so check before calling self.__pow__. */ if (Py_TYPE(self)->tp_as_number != NULL && Py_TYPE(self)->tp_as_number->nb_power == slot_nb_power) { - return call_method(self, &PyId___pow__, "(OO)", other, modulus); + return call_method(self, &PyId___pow__, other, modulus, NULL); } Py_RETURN_NOTIMPLEMENTED; } @@ -6053,28 +6022,28 @@ SLOT1BIN(slot_nb_or, nb_or, "__or__", "__ror__") SLOT0(slot_nb_int, "__int__") SLOT0(slot_nb_float, "__float__") -SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *, "O") -SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *, "O") -SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *, "O") -SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *, "O") -SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *, "O") +SLOT1(slot_nb_inplace_add, "__iadd__", PyObject *) +SLOT1(slot_nb_inplace_subtract, "__isub__", PyObject *) +SLOT1(slot_nb_inplace_multiply, "__imul__", PyObject *) +SLOT1(slot_nb_inplace_matrix_multiply, "__imatmul__", PyObject *) +SLOT1(slot_nb_inplace_remainder, "__imod__", PyObject *) /* Can't use SLOT1 here, because nb_inplace_power is ternary */ static PyObject * slot_nb_inplace_power(PyObject *self, PyObject * arg1, PyObject *arg2) { _Py_IDENTIFIER(__ipow__); - return call_method(self, &PyId___ipow__, "(" "O" ")", arg1); + return call_method(self, &PyId___ipow__, arg1, NULL); } -SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *, "O") -SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *, "O") -SLOT1(slot_nb_inplace_and, "__iand__", PyObject *, "O") -SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *, "O") -SLOT1(slot_nb_inplace_or, "__ior__", PyObject *, "O") +SLOT1(slot_nb_inplace_lshift, "__ilshift__", PyObject *) +SLOT1(slot_nb_inplace_rshift, "__irshift__", PyObject *) +SLOT1(slot_nb_inplace_and, "__iand__", PyObject *) +SLOT1(slot_nb_inplace_xor, "__ixor__", PyObject *) +SLOT1(slot_nb_inplace_or, "__ior__", PyObject *) SLOT1BIN(slot_nb_floor_divide, nb_floor_divide, "__floordiv__", "__rfloordiv__") SLOT1BIN(slot_nb_true_divide, nb_true_divide, "__truediv__", "__rtruediv__") -SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *, "O") -SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *, "O") +SLOT1(slot_nb_inplace_floor_divide, "__ifloordiv__", PyObject *) +SLOT1(slot_nb_inplace_true_divide, "__itruediv__", PyObject *) static PyObject * slot_tp_repr(PyObject *self) @@ -6184,7 +6153,7 @@ slot_tp_call(PyObject *self, PyObject *args, PyObject *kwds) static PyObject * slot_tp_getattro(PyObject *self, PyObject *name) { - return call_method(self, &PyId___getattribute__, "(O)", name); + return call_method(self, &PyId___getattribute__, name, NULL); } static PyObject * @@ -6256,9 +6225,9 @@ slot_tp_setattro(PyObject *self, PyObject *name, PyObject *value) _Py_IDENTIFIER(__setattr__); if (value == NULL) - res = call_method(self, &PyId___delattr__, "(O)", name); + res = call_method(self, &PyId___delattr__, name, NULL); else - res = call_method(self, &PyId___setattr__, "(OO)", name, value); + res = call_method(self, &PyId___setattr__, name, value, NULL); if (res == NULL) return -1; Py_DECREF(res); @@ -6284,7 +6253,7 @@ slot_tp_richcompare(PyObject *self, PyObject *other, int op) PyErr_Clear(); Py_RETURN_NOTIMPLEMENTED; } - res = _PyObject_CallArg1(func, other); + res = PyObject_CallFunctionObjArgs(func, other, NULL); Py_DECREF(func); return res; } @@ -6359,9 +6328,9 @@ slot_tp_descr_set(PyObject *self, PyObject *target, PyObject *value) _Py_IDENTIFIER(__set__); if (value == NULL) - res = call_method(self, &PyId___delete__, "(O)", target); + res = call_method(self, &PyId___delete__, target, NULL); else - res = call_method(self, &PyId___set__, "(OO)", target, value); + res = call_method(self, &PyId___set__, target, value, NULL); if (res == NULL) return -1; Py_DECREF(res); diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 4491167..3fdce82 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1029,8 +1029,7 @@ resize_copy(PyObject *unicode, Py_ssize_t length) if (_PyUnicode_KIND(unicode) != PyUnicode_WCHAR_KIND) { PyObject *copy; - if (PyUnicode_READY(unicode) == -1) - return NULL; + assert(PyUnicode_IS_READY(unicode)); copy = PyUnicode_New(length, PyUnicode_MAX_CHAR_VALUE(unicode)); if (copy == NULL) @@ -1974,14 +1973,11 @@ unicode_char(Py_UCS4 ch) unicode = PyUnicode_New(1, ch); if (unicode == NULL) return NULL; - switch (PyUnicode_KIND(unicode)) { - case PyUnicode_1BYTE_KIND: - PyUnicode_1BYTE_DATA(unicode)[0] = (Py_UCS1)ch; - break; - case PyUnicode_2BYTE_KIND: + + assert(PyUnicode_KIND(unicode) != PyUnicode_1BYTE_KIND); + if (PyUnicode_KIND(unicode) == PyUnicode_2BYTE_KIND) { PyUnicode_2BYTE_DATA(unicode)[0] = (Py_UCS2)ch; - break; - default: + } else { assert(PyUnicode_KIND(unicode) == PyUnicode_4BYTE_KIND); PyUnicode_4BYTE_DATA(unicode)[0] = ch; } @@ -1992,12 +1988,32 @@ unicode_char(Py_UCS4 ch) PyObject * PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size) { + if (u == NULL) + return (PyObject*)_PyUnicode_New(size); + + if (size < 0) { + PyErr_BadInternalCall(); + return NULL; + } + + return PyUnicode_FromWideChar(u, size); +} + +PyObject * +PyUnicode_FromWideChar(const wchar_t *u, Py_ssize_t size) +{ PyObject *unicode; Py_UCS4 maxchar = 0; Py_ssize_t num_surrogates; - if (u == NULL) - return (PyObject*)_PyUnicode_New(size); + if (u == NULL && size != 0) { + PyErr_BadInternalCall(); + return NULL; + } + + if (size == -1) { + size = wcslen(u); + } /* If the Unicode data is known at construction time, we can apply some optimizations which share commonly used objects. */ @@ -2482,27 +2498,6 @@ PyUnicode_AsUCS4Copy(PyObject *string) return as_ucs4(string, NULL, 0, 1); } -#ifdef HAVE_WCHAR_H - -PyObject * -PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size) -{ - if (w == NULL) { - if (size == 0) - _Py_RETURN_UNICODE_EMPTY(); - PyErr_BadInternalCall(); - return NULL; - } - - if (size == -1) { - size = wcslen(w); - } - - return PyUnicode_FromUnicode(w, size); -} - -#endif /* HAVE_WCHAR_H */ - /* maximum number of characters required for output of %lld or %p. We need at most ceil(log10(256)*SIZEOF_LONG_LONG) digits, plus 1 for the sign. 53/22 is an upper bound for log10(256). */ @@ -3300,7 +3295,7 @@ PyUnicode_Encode(const Py_UNICODE *s, { PyObject *v, *unicode; - unicode = PyUnicode_FromUnicode(s, size); + unicode = PyUnicode_FromWideChar(s, size); if (unicode == NULL) return NULL; v = PyUnicode_AsEncodedString(unicode, encoding, errors); @@ -3412,11 +3407,9 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) { Py_ssize_t wlen, wlen2; wchar_t *wstr; - PyObject *bytes = NULL; char *errmsg; - PyObject *reason = NULL; - PyObject *exc; - size_t error_pos; + PyObject *bytes, *reason, *exc; + size_t error_pos, errlen; int surrogateescape; if (locale_error_handler(errors, &surrogateescape) < 0) @@ -3471,6 +3464,7 @@ PyUnicode_EncodeLocale(PyObject *unicode, const char *errors) len2 = wcstombs(PyBytes_AS_STRING(bytes), wstr, len+1); if (len2 == (size_t)-1 || len2 > len) { + Py_DECREF(bytes); error_pos = (size_t)-1; goto encode_error; } @@ -3486,17 +3480,15 @@ encode_error: error_pos = wcstombs_errorpos(wstr); PyMem_Free(wstr); - Py_XDECREF(bytes); - - if (errmsg != NULL) { - size_t errlen; - wstr = Py_DecodeLocale(errmsg, &errlen); - if (wstr != NULL) { - reason = PyUnicode_FromWideChar(wstr, errlen); - PyMem_RawFree(wstr); - } else - errmsg = NULL; + + wstr = Py_DecodeLocale(errmsg, &errlen); + if (wstr != NULL) { + reason = PyUnicode_FromWideChar(wstr, errlen); + PyMem_RawFree(wstr); + } else { + errmsg = NULL; } + if (errmsg == NULL) reason = PyUnicode_FromString( "wcstombs() encountered an unencodable " @@ -3512,7 +3504,7 @@ encode_error: Py_DECREF(reason); if (exc != NULL) { PyCodec_StrictErrors(exc); - Py_XDECREF(exc); + Py_DECREF(exc); } return NULL; } @@ -3719,10 +3711,9 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, size_t wlen, wlen2; PyObject *unicode; int surrogateescape; - size_t error_pos; + size_t error_pos, errlen; char *errmsg; - PyObject *reason = NULL; /* initialize to prevent gcc warning */ - PyObject *exc; + PyObject *exc, *reason = NULL; /* initialize to prevent gcc warning */ if (locale_error_handler(errors, &surrogateescape) < 0) return NULL; @@ -3780,19 +3771,16 @@ PyUnicode_DecodeLocaleAndSize(const char *str, Py_ssize_t len, return unicode; decode_error: - reason = NULL; errmsg = strerror(errno); assert(errmsg != NULL); error_pos = mbstowcs_errorpos(str, len); - if (errmsg != NULL) { - size_t errlen; - wstr = Py_DecodeLocale(errmsg, &errlen); - if (wstr != NULL) { - reason = PyUnicode_FromWideChar(wstr, errlen); - PyMem_RawFree(wstr); - } + wstr = Py_DecodeLocale(errmsg, &errlen); + if (wstr != NULL) { + reason = PyUnicode_FromWideChar(wstr, errlen); + PyMem_RawFree(wstr); } + if (reason == NULL) reason = PyUnicode_FromString( "mbstowcs() encountered an invalid multibyte sequence"); @@ -3807,7 +3795,7 @@ decode_error: Py_DECREF(reason); if (exc != NULL) { PyCodec_StrictErrors(exc); - Py_XDECREF(exc); + Py_DECREF(exc); } return NULL; } @@ -4140,7 +4128,11 @@ PyUnicode_GetSize(PyObject *unicode) PyErr_BadArgument(); goto onError; } - return PyUnicode_GET_SIZE(unicode); + if (_PyUnicode_WSTR(unicode) == NULL) { + if (PyUnicode_AsUnicode(unicode) == NULL) + goto onError; + } + return PyUnicode_WSTR_LENGTH(unicode); onError: return -1; @@ -4248,7 +4240,7 @@ unicode_decode_call_errorhandler_wchar( Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr, PyObject **output, Py_ssize_t *outpos) { - static const char *argparse = "O!n;decoding error handler must return (str, int) tuple"; + static const char *argparse = "Un;decoding error handler must return (str, int) tuple"; PyObject *restuple = NULL; PyObject *repunicode = NULL; @@ -4281,10 +4273,10 @@ unicode_decode_call_errorhandler_wchar( if (restuple == NULL) goto onError; if (!PyTuple_Check(restuple)) { - PyErr_SetString(PyExc_TypeError, &argparse[4]); + PyErr_SetString(PyExc_TypeError, &argparse[3]); goto onError; } - if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &repunicode, &newpos)) + if (!PyArg_ParseTuple(restuple, argparse, &repunicode, &newpos)) goto onError; /* Copy back the bytes variables, which might have been modified by the @@ -4292,9 +4284,6 @@ unicode_decode_call_errorhandler_wchar( inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject); if (!inputobj) goto onError; - if (!PyBytes_Check(inputobj)) { - PyErr_Format(PyExc_TypeError, "exception attribute object must be bytes"); - } *input = PyBytes_AS_STRING(inputobj); insize = PyBytes_GET_SIZE(inputobj); *inend = *input + insize; @@ -4335,7 +4324,7 @@ unicode_decode_call_errorhandler_wchar( *inptr = *input + newpos; /* we made it! */ - Py_XDECREF(restuple); + Py_DECREF(restuple); return 0; overflow: @@ -4356,7 +4345,7 @@ unicode_decode_call_errorhandler_writer( Py_ssize_t *endinpos, PyObject **exceptionObject, const char **inptr, _PyUnicodeWriter *writer /* PyObject **output, Py_ssize_t *outpos */) { - static const char *argparse = "O!n;decoding error handler must return (str, int) tuple"; + static const char *argparse = "Un;decoding error handler must return (str, int) tuple"; PyObject *restuple = NULL; PyObject *repunicode = NULL; @@ -4383,10 +4372,10 @@ unicode_decode_call_errorhandler_writer( if (restuple == NULL) goto onError; if (!PyTuple_Check(restuple)) { - PyErr_SetString(PyExc_TypeError, &argparse[4]); + PyErr_SetString(PyExc_TypeError, &argparse[3]); goto onError; } - if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, &repunicode, &newpos)) + if (!PyArg_ParseTuple(restuple, argparse, &repunicode, &newpos)) goto onError; /* Copy back the bytes variables, which might have been modified by the @@ -4394,9 +4383,6 @@ unicode_decode_call_errorhandler_writer( inputobj = PyUnicodeDecodeError_GetObject(*exceptionObject); if (!inputobj) goto onError; - if (!PyBytes_Check(inputobj)) { - PyErr_Format(PyExc_TypeError, "exception attribute object must be bytes"); - } *input = PyBytes_AS_STRING(inputobj); insize = PyBytes_GET_SIZE(inputobj); *inend = *input + insize; @@ -4411,8 +4397,6 @@ unicode_decode_call_errorhandler_writer( goto onError; } - if (PyUnicode_READY(repunicode) < 0) - goto onError; replen = PyUnicode_GET_LENGTH(repunicode); if (replen > 1) { writer->min_length += replen - 1; @@ -4428,7 +4412,7 @@ unicode_decode_call_errorhandler_writer( *inptr = *input + newpos; /* we made it! */ - Py_XDECREF(restuple); + Py_DECREF(restuple); return 0; onError: @@ -4834,7 +4818,7 @@ PyUnicode_EncodeUTF7(const Py_UNICODE *s, const char *errors) { PyObject *result; - PyObject *tmp = PyUnicode_FromUnicode(s, size); + PyObject *tmp = PyUnicode_FromWideChar(s, size); if (tmp == NULL) return NULL; result = _PyUnicode_EncodeUTF7(tmp, base64SetO, @@ -5190,7 +5174,7 @@ PyUnicode_EncodeUTF8(const Py_UNICODE *s, { PyObject *v, *unicode; - unicode = PyUnicode_FromUnicode(s, size); + unicode = PyUnicode_FromWideChar(s, size); if (unicode == NULL) return NULL; v = _PyUnicode_AsUTF8String(unicode, errors); @@ -5515,7 +5499,7 @@ PyUnicode_EncodeUTF32(const Py_UNICODE *s, int byteorder) { PyObject *result; - PyObject *tmp = PyUnicode_FromUnicode(s, size); + PyObject *tmp = PyUnicode_FromWideChar(s, size); if (tmp == NULL) return NULL; result = _PyUnicode_EncodeUTF32(tmp, errors, byteorder); @@ -5868,7 +5852,7 @@ PyUnicode_EncodeUTF16(const Py_UNICODE *s, int byteorder) { PyObject *result; - PyObject *tmp = PyUnicode_FromUnicode(s, size); + PyObject *tmp = PyUnicode_FromWideChar(s, size); if (tmp == NULL) return NULL; result = _PyUnicode_EncodeUTF16(tmp, errors, byteorder); @@ -6259,7 +6243,7 @@ PyUnicode_EncodeUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) { PyObject *result; - PyObject *tmp = PyUnicode_FromUnicode(s, size); + PyObject *tmp = PyUnicode_FromWideChar(s, size); if (tmp == NULL) { return NULL; } @@ -6476,7 +6460,7 @@ PyUnicode_EncodeRawUnicodeEscape(const Py_UNICODE *s, Py_ssize_t size) { PyObject *result; - PyObject *tmp = PyUnicode_FromUnicode(s, size); + PyObject *tmp = PyUnicode_FromWideChar(s, size); if (tmp == NULL) return NULL; result = PyUnicode_AsRawUnicodeEscapeString(tmp); @@ -6814,7 +6798,7 @@ unicode_encode_ucs1(PyObject *unicode, goto onError; /* subtract preallocated bytes */ - writer.min_size -= 1; + writer.min_size -= newpos - collstart; if (PyBytes_Check(rep)) { /* Directly copy bytes result to output. */ @@ -6830,33 +6814,19 @@ unicode_encode_ucs1(PyObject *unicode, if (PyUnicode_READY(rep) < 0) goto onError; - if (PyUnicode_IS_ASCII(rep)) { - /* Fast path: all characters are smaller than limit */ - assert(limit >= 128); - assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); - str = _PyBytesWriter_WriteBytes(&writer, str, - PyUnicode_DATA(rep), - PyUnicode_GET_LENGTH(rep)); - } - else { - Py_ssize_t repsize = PyUnicode_GET_LENGTH(rep); - - str = _PyBytesWriter_Prepare(&writer, str, repsize); - if (str == NULL) - goto onError; - - /* check if there is anything unencodable in the - replacement and copy it to the output */ - for (i = 0; repsize-->0; ++i, ++str) { - ch = PyUnicode_READ_CHAR(rep, i); - if (ch >= limit) { - raise_encode_exception(&exc, encoding, unicode, - pos, pos+1, reason); - goto onError; - } - *str = (char)ch; - } + if (limit == 256 ? + PyUnicode_KIND(rep) != PyUnicode_1BYTE_KIND : + !PyUnicode_IS_ASCII(rep)) + { + /* Not all characters are smaller than limit */ + raise_encode_exception(&exc, encoding, unicode, + collstart, collend, reason); + goto onError; } + assert(PyUnicode_KIND(rep) == PyUnicode_1BYTE_KIND); + str = _PyBytesWriter_WriteBytes(&writer, str, + PyUnicode_DATA(rep), + PyUnicode_GET_LENGTH(rep)); } pos = newpos; Py_CLEAR(rep); @@ -6887,7 +6857,7 @@ PyUnicode_EncodeLatin1(const Py_UNICODE *p, const char *errors) { PyObject *result; - PyObject *unicode = PyUnicode_FromUnicode(p, size); + PyObject *unicode = PyUnicode_FromWideChar(p, size); if (unicode == NULL) return NULL; result = unicode_encode_ucs1(unicode, errors, 256); @@ -7028,7 +6998,7 @@ PyUnicode_EncodeASCII(const Py_UNICODE *p, const char *errors) { PyObject *result; - PyObject *unicode = PyUnicode_FromUnicode(p, size); + PyObject *unicode = PyUnicode_FromWideChar(p, size); if (unicode == NULL) return NULL; result = unicode_encode_ucs1(unicode, errors, 128); @@ -7754,7 +7724,7 @@ PyUnicode_EncodeMBCS(const Py_UNICODE *p, const char *errors) { PyObject *unicode, *res; - unicode = PyUnicode_FromUnicode(p, size); + unicode = PyUnicode_FromWideChar(p, size); if (unicode == NULL) return NULL; res = encode_code_page(CP_ACP, unicode, errors); @@ -8602,7 +8572,7 @@ PyUnicode_EncodeCharmap(const Py_UNICODE *p, const char *errors) { PyObject *result; - PyObject *unicode = PyUnicode_FromUnicode(p, size); + PyObject *unicode = PyUnicode_FromWideChar(p, size); if (unicode == NULL) return NULL; result = _PyUnicode_EncodeCharmap(unicode, mapping, errors); @@ -8657,7 +8627,7 @@ unicode_translate_call_errorhandler(const char *errors, Py_ssize_t startpos, Py_ssize_t endpos, Py_ssize_t *newpos) { - static const char *argparse = "O!n;translating error handler must return (str, int) tuple"; + static const char *argparse = "Un;translating error handler must return (str, int) tuple"; Py_ssize_t i_newpos; PyObject *restuple; @@ -8679,11 +8649,11 @@ unicode_translate_call_errorhandler(const char *errors, if (restuple == NULL) return NULL; if (!PyTuple_Check(restuple)) { - PyErr_SetString(PyExc_TypeError, &argparse[4]); + PyErr_SetString(PyExc_TypeError, &argparse[3]); Py_DECREF(restuple); return NULL; } - if (!PyArg_ParseTuple(restuple, argparse, &PyUnicode_Type, + if (!PyArg_ParseTuple(restuple, argparse, &resunicode, &i_newpos)) { Py_DECREF(restuple); return NULL; @@ -9042,7 +9012,7 @@ PyUnicode_TranslateCharmap(const Py_UNICODE *p, const char *errors) { PyObject *result; - PyObject *unicode = PyUnicode_FromUnicode(p, size); + PyObject *unicode = PyUnicode_FromWideChar(p, size); if (!unicode) return NULL; result = _PyUnicode_TranslateCharmap(unicode, mapping, errors); @@ -9170,14 +9140,10 @@ PyUnicode_EncodeDecimal(Py_UNICODE *s, return -1; } - unicode = PyUnicode_FromUnicode(s, length); + unicode = PyUnicode_FromWideChar(s, length); if (unicode == NULL) return -1; - if (PyUnicode_READY(unicode) == -1) { - Py_DECREF(unicode); - return -1; - } kind = PyUnicode_KIND(unicode); data = PyUnicode_DATA(unicode); @@ -15359,7 +15325,7 @@ unicodeiter_reduce(unicodeiterobject *it) return Py_BuildValue("N(O)n", _PyObject_GetBuiltin("iter"), it->it_seq, it->it_index); } else { - PyObject *u = PyUnicode_FromUnicode(NULL, 0); + PyObject *u = (PyObject *)_PyUnicode_New(0); if (u == NULL) return NULL; return Py_BuildValue("N(N)", _PyObject_GetBuiltin("iter"), u); @@ -15454,10 +15420,7 @@ unicode_iter(PyObject *seq) size_t Py_UNICODE_strlen(const Py_UNICODE *u) { - int res = 0; - while(*u++) - res++; - return res; + return wcslen(u); } Py_UNICODE* @@ -15482,8 +15445,8 @@ Py_UNICODE* Py_UNICODE_strcat(Py_UNICODE *s1, const Py_UNICODE *s2) { Py_UNICODE *u1 = s1; - u1 += Py_UNICODE_strlen(u1); - Py_UNICODE_strcpy(u1, s2); + u1 += wcslen(u1); + while ((*u1++ = *s2++)); return s1; } @@ -15532,7 +15495,7 @@ Py_UNICODE* Py_UNICODE_strrchr(const Py_UNICODE *s, Py_UNICODE c) { const Py_UNICODE *p; - p = s + Py_UNICODE_strlen(s); + p = s + wcslen(s); while (p != s) { p--; if (*p == c) |