mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-23 22:02:27 +00:00
Make numerous improvements
- Python static hello world now 1.8mb - Python static fully loaded now 10mb - Python HTTPS client now uses MbedTLS - Python REPL now completes import stmts - Increase stack size for Python for now - Begin synthesizing posixpath and ntpath - Restore Python \N{UNICODE NAME} support - Restore Python NFKD symbol normalization - Add optimized code path for Intel SHA-NI - Get more Python unit tests passing faster - Get Python help() pagination working on NT - Python hashlib now supports MbedTLS PBKDF2 - Make memcpy/memmove/memcmp/bcmp/etc. faster - Add Mersenne Twister and Vigna to LIBC_RAND - Provide privileged __printf() for error code - Fix zipos opendir() so that it reports ENOTDIR - Add basic chmod() implementation for Windows NT - Add Cosmo's best functions to Python cosmo module - Pin function trace indent depth to that of caller - Show memory diagram on invalid access in MODE=dbg - Differentiate stack overflow on crash in MODE=dbg - Add stb_truetype and tools for analyzing font files - Upgrade to UNICODE 13 and reduce its binary footprint - COMPILE.COM now logs resource usage of build commands - Start implementing basic poll() support on bare metal - Set getauxval(AT_EXECFN) to GetModuleFileName() on NT - Add descriptions to strerror() in non-TINY build modes - Add COUNTBRANCH() macro to help with micro-optimizations - Make error / backtrace / asan / memory code more unbreakable - Add fast perfect C implementation of μ-Law and a-Law audio codecs - Make strtol() functions consistent with other libc implementations - Improve Linenoise implementation (see also github.com/jart/bestline) - COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
parent
fa7b4f5bd1
commit
39bf41f4eb
806 changed files with 77494 additions and 63859 deletions
303
third_party/python/Objects/abstract.c
vendored
303
third_party/python/Objects/abstract.c
vendored
|
@ -54,11 +54,9 @@ PyObject *
|
|||
PyObject_Type(PyObject *o)
|
||||
{
|
||||
PyObject *v;
|
||||
|
||||
if (o == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
v = (PyObject *)o->ob_type;
|
||||
Py_INCREF(v);
|
||||
return v;
|
||||
|
@ -68,16 +66,13 @@ Py_ssize_t
|
|||
PyObject_Size(PyObject *o)
|
||||
{
|
||||
PySequenceMethods *m;
|
||||
|
||||
if (o == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
m = o->ob_type->tp_as_sequence;
|
||||
if (m && m->sq_length)
|
||||
return m->sq_length(o);
|
||||
|
||||
return PyMapping_Size(o);
|
||||
}
|
||||
|
||||
|
@ -767,6 +762,38 @@ PyNumber_Check(PyObject *o)
|
|||
#define NB_TERNOP(nb_methods, slot) \
|
||||
(*(ternaryfunc*)(& ((char*)nb_methods)[slot]))
|
||||
|
||||
static noinline PyObject *
|
||||
binop_type_error(PyObject *v, PyObject *w, const char *op_name)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"unsupported operand type(s) for %.100s: "
|
||||
"'%.100s' and '%.100s'",
|
||||
op_name,
|
||||
v->ob_type->tp_name,
|
||||
w->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static noinline PyObject *
|
||||
binop_not_implemented(PyObject *v, PyObject *w,
|
||||
const int op_slot, const char *op_name)
|
||||
{
|
||||
if (op_slot == NB_SLOT(nb_rshift) &&
|
||||
PyCFunction_Check(v) &&
|
||||
strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"unsupported operand type(s) for %.100s: "
|
||||
"'%.100s' and '%.100s'. Did you mean \"print(<message>, "
|
||||
"file=<output_stream>)\"?",
|
||||
op_name,
|
||||
v->ob_type->tp_name,
|
||||
w->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
return binop_type_error(v, w, op_name);
|
||||
}
|
||||
|
||||
/*
|
||||
Calling scheme used for binary operations:
|
||||
|
||||
|
@ -783,7 +810,6 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
|
|||
PyObject *x;
|
||||
binaryfunc slotv = NULL;
|
||||
binaryfunc slotw = NULL;
|
||||
|
||||
if (v->ob_type->tp_as_number != NULL)
|
||||
slotv = NB_BINOP(v->ob_type->tp_as_number, op_slot);
|
||||
if (w->ob_type != v->ob_type &&
|
||||
|
@ -814,44 +840,59 @@ binary_op1(PyObject *v, PyObject *w, const int op_slot)
|
|||
Py_RETURN_NOTIMPLEMENTED;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
binop_type_error(PyObject *v, PyObject *w, const char *op_name)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"unsupported operand type(s) for %.100s: "
|
||||
"'%.100s' and '%.100s'",
|
||||
op_name,
|
||||
v->ob_type->tp_name,
|
||||
w->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
binary_op(PyObject *v, PyObject *w, const int op_slot, const char *op_name)
|
||||
{
|
||||
PyObject *result = binary_op1(v, w, op_slot);
|
||||
if (result == Py_NotImplemented) {
|
||||
PyObject *result;
|
||||
if ((result = binary_op1(v, w, op_slot)) != Py_NotImplemented) {
|
||||
return result;
|
||||
} else {
|
||||
Py_DECREF(result);
|
||||
|
||||
if (op_slot == NB_SLOT(nb_rshift) &&
|
||||
PyCFunction_Check(v) &&
|
||||
strcmp(((PyCFunctionObject *)v)->m_ml->ml_name, "print") == 0)
|
||||
{
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"unsupported operand type(s) for %.100s: "
|
||||
"'%.100s' and '%.100s'. Did you mean \"print(<message>, "
|
||||
"file=<output_stream>)\"?",
|
||||
op_name,
|
||||
v->ob_type->tp_name,
|
||||
w->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return binop_type_error(v, w, op_name);
|
||||
return binop_not_implemented(v, w, op_slot, op_name);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_Subtract(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_subtract), "-");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_Or(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_or), "|");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_Xor(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_xor), "^");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_And(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_and), "&");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_Lshift(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_lshift), "<<");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_Rshift(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_rshift), ">>");
|
||||
}
|
||||
|
||||
PyObject *
|
||||
PyNumber_Divmod(PyObject *v, PyObject *w)
|
||||
{
|
||||
return binary_op(v, w, offsetof(PyNumberMethods, nb_divmod), "divmod()");
|
||||
}
|
||||
|
||||
/*
|
||||
Calling scheme used for ternary operations:
|
||||
|
@ -872,7 +913,6 @@ ternary_op(PyObject *v,
|
|||
ternaryfunc slotv = NULL;
|
||||
ternaryfunc slotw = NULL;
|
||||
ternaryfunc slotz = NULL;
|
||||
|
||||
mv = v->ob_type->tp_as_number;
|
||||
mw = w->ob_type->tp_as_number;
|
||||
if (mv != NULL)
|
||||
|
@ -914,7 +954,6 @@ ternary_op(PyObject *v,
|
|||
Py_DECREF(x); /* can't do it */
|
||||
}
|
||||
}
|
||||
|
||||
if (z == Py_None)
|
||||
PyErr_Format(
|
||||
PyExc_TypeError,
|
||||
|
@ -933,20 +972,6 @@ ternary_op(PyObject *v,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
#define BINARY_FUNC(func, op, op_name) \
|
||||
PyObject * \
|
||||
func(PyObject *v, PyObject *w) { \
|
||||
return binary_op(v, w, NB_SLOT(op), op_name); \
|
||||
}
|
||||
|
||||
BINARY_FUNC(PyNumber_Or, nb_or, "|")
|
||||
BINARY_FUNC(PyNumber_Xor, nb_xor, "^")
|
||||
BINARY_FUNC(PyNumber_And, nb_and, "&")
|
||||
BINARY_FUNC(PyNumber_Lshift, nb_lshift, "<<")
|
||||
BINARY_FUNC(PyNumber_Rshift, nb_rshift, ">>")
|
||||
BINARY_FUNC(PyNumber_Subtract, nb_subtract, "-")
|
||||
BINARY_FUNC(PyNumber_Divmod, nb_divmod, "divmod()")
|
||||
|
||||
PyObject *
|
||||
PyNumber_Add(PyObject *v, PyObject *w)
|
||||
{
|
||||
|
@ -1292,11 +1317,16 @@ PyNumber_Index(PyObject *item)
|
|||
Py_ssize_t
|
||||
PyNumber_AsSsize_t(PyObject *item, PyObject *err)
|
||||
{
|
||||
Py_ssize_t result;
|
||||
PyObject *value;
|
||||
PyObject *runerr;
|
||||
PyObject *value = PyNumber_Index(item);
|
||||
if (value == NULL)
|
||||
Py_ssize_t result;
|
||||
|
||||
if (item && PyLong_Check(item)) {
|
||||
Py_INCREF(item);
|
||||
value = item;
|
||||
} else if (!(value = PyNumber_Index(item))) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* We're done if PyLong_AsSsize_t() returns without error. */
|
||||
result = PyLong_AsSsize_t(value);
|
||||
|
@ -2089,11 +2119,9 @@ PyObject *
|
|||
PyMapping_GetItemString(PyObject *o, const char *key)
|
||||
{
|
||||
PyObject *okey, *r;
|
||||
|
||||
if (key == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
okey = PyUnicode_FromString(key);
|
||||
if (okey == NULL)
|
||||
return NULL;
|
||||
|
@ -2107,12 +2135,10 @@ PyMapping_SetItemString(PyObject *o, const char *key, PyObject *value)
|
|||
{
|
||||
PyObject *okey;
|
||||
int r;
|
||||
|
||||
if (key == NULL) {
|
||||
null_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
okey = PyUnicode_FromString(key);
|
||||
if (okey == NULL)
|
||||
return -1;
|
||||
|
@ -2125,7 +2151,6 @@ int
|
|||
PyMapping_HasKeyString(PyObject *o, const char *key)
|
||||
{
|
||||
PyObject *v;
|
||||
|
||||
v = PyMapping_GetItemString(o, key);
|
||||
if (v) {
|
||||
Py_DECREF(v);
|
||||
|
@ -2139,7 +2164,6 @@ int
|
|||
PyMapping_HasKey(PyObject *o, PyObject *key)
|
||||
{
|
||||
PyObject *v;
|
||||
|
||||
v = PyObject_GetItem(o, key);
|
||||
if (v) {
|
||||
Py_DECREF(v);
|
||||
|
@ -2155,7 +2179,6 @@ PyMapping_Keys(PyObject *o)
|
|||
PyObject *keys;
|
||||
PyObject *fast;
|
||||
_Py_IDENTIFIER(keys);
|
||||
|
||||
if (PyDict_CheckExact(o))
|
||||
return PyDict_Keys(o);
|
||||
keys = _PyObject_CallMethodId(o, &PyId_keys, NULL);
|
||||
|
@ -2172,7 +2195,6 @@ PyMapping_Items(PyObject *o)
|
|||
PyObject *items;
|
||||
PyObject *fast;
|
||||
_Py_IDENTIFIER(items);
|
||||
|
||||
if (PyDict_CheckExact(o))
|
||||
return PyDict_Items(o);
|
||||
items = _PyObject_CallMethodId(o, &PyId_items, NULL);
|
||||
|
@ -2189,7 +2211,6 @@ PyMapping_Values(PyObject *o)
|
|||
PyObject *values;
|
||||
PyObject *fast;
|
||||
_Py_IDENTIFIER(values);
|
||||
|
||||
if (PyDict_CheckExact(o))
|
||||
return PyDict_Values(o);
|
||||
values = _PyObject_CallMethodId(o, &PyId_values, NULL);
|
||||
|
@ -2200,10 +2221,6 @@ PyMapping_Values(PyObject *o)
|
|||
return fast;
|
||||
}
|
||||
|
||||
/* Operations on callable objects */
|
||||
|
||||
/* XXX PyCallable_Check() is in object.c */
|
||||
|
||||
PyObject *
|
||||
PyObject_CallObject(PyObject *o, PyObject *a)
|
||||
{
|
||||
|
@ -2214,9 +2231,7 @@ PyObject*
|
|||
(_Py_CheckFunctionResult)(PyObject *func, PyObject *result, const char *where)
|
||||
{
|
||||
int err_occurred = (PyErr_Occurred() != NULL);
|
||||
|
||||
assert((func != NULL) ^ (where != NULL));
|
||||
|
||||
if (result == NULL) {
|
||||
if (!err_occurred) {
|
||||
if (func)
|
||||
|
@ -2237,7 +2252,6 @@ PyObject*
|
|||
else {
|
||||
if (err_occurred) {
|
||||
Py_DECREF(result);
|
||||
|
||||
if (func) {
|
||||
_PyErr_FormatFromCause(PyExc_SystemError,
|
||||
"%R returned a result with an error set",
|
||||
|
@ -2263,49 +2277,40 @@ PyObject_Call(PyObject *func, PyObject *args, PyObject *kwargs)
|
|||
{
|
||||
ternaryfunc call;
|
||||
PyObject *result;
|
||||
|
||||
/* PyObject_Call() must not be called with an exception set,
|
||||
because it may clear it (directly or indirectly) and so the
|
||||
caller loses its exception */
|
||||
assert(!PyErr_Occurred());
|
||||
assert(PyTuple_Check(args));
|
||||
assert(kwargs == NULL || PyDict_Check(kwargs));
|
||||
|
||||
call = func->ob_type->tp_call;
|
||||
if (call == NULL) {
|
||||
PyErr_Format(PyExc_TypeError, "'%.200s' object is not callable",
|
||||
func->ob_type->tp_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (Py_EnterRecursiveCall(" while calling a Python object"))
|
||||
return NULL;
|
||||
|
||||
result = (*call)(func, args, kwargs);
|
||||
|
||||
Py_LeaveRecursiveCall();
|
||||
|
||||
return _Py_CheckFunctionResult(func, result, NULL);
|
||||
}
|
||||
|
||||
PyObject*
|
||||
PyObject *
|
||||
_PyStack_AsTuple(PyObject **stack, Py_ssize_t nargs)
|
||||
{
|
||||
PyObject *args;
|
||||
Py_ssize_t i;
|
||||
|
||||
args = PyTuple_New(nargs);
|
||||
if (args == NULL) {
|
||||
return NULL;
|
||||
PyObject *item, *args;
|
||||
if ((args = PyTuple_New(nargs))) {
|
||||
for (i=0; i < nargs; i++) {
|
||||
item = stack[i];
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(args, i, item);
|
||||
}
|
||||
return args;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i=0; i < nargs; i++) {
|
||||
PyObject *item = stack[i];
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(args, i, item);
|
||||
}
|
||||
|
||||
return args;
|
||||
}
|
||||
|
||||
PyObject *
|
||||
|
@ -2314,21 +2319,17 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
|
|||
{
|
||||
ternaryfunc call;
|
||||
PyObject *result = NULL;
|
||||
|
||||
/* _PyObject_FastCallDict() must not be called with an exception set,
|
||||
because it may clear it (directly or indirectly) and so the
|
||||
caller loses its exception */
|
||||
assert(!PyErr_Occurred());
|
||||
|
||||
assert(func != NULL);
|
||||
assert(nargs >= 0);
|
||||
assert(nargs == 0 || args != NULL);
|
||||
assert(kwargs == NULL || PyDict_Check(kwargs));
|
||||
|
||||
if (Py_EnterRecursiveCall(" while calling a Python object")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PyFunction_Check(func)) {
|
||||
result = _PyFunction_FastCallDict(func, args, nargs, kwargs);
|
||||
}
|
||||
|
@ -2336,8 +2337,8 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
|
|||
result = _PyCFunction_FastCallDict(func, args, nargs, kwargs);
|
||||
}
|
||||
else {
|
||||
PyObject *tuple;
|
||||
|
||||
Py_ssize_t i;
|
||||
PyObject *item, *tuple;
|
||||
/* Slow-path: build a temporary tuple */
|
||||
call = func->ob_type->tp_call;
|
||||
if (call == NULL) {
|
||||
|
@ -2345,21 +2346,19 @@ _PyObject_FastCallDict(PyObject *func, PyObject **args, Py_ssize_t nargs,
|
|||
func->ob_type->tp_name);
|
||||
goto exit;
|
||||
}
|
||||
|
||||
tuple = _PyStack_AsTuple(args, nargs);
|
||||
if (tuple == NULL) {
|
||||
goto exit;
|
||||
/* [jart] inlined _PyStack_AsTuple b/c profiling */
|
||||
if (!(tuple = PyTuple_New(nargs))) return 0;
|
||||
for (i = 0; i < nargs; i++) {
|
||||
item = args[i];
|
||||
Py_INCREF(item);
|
||||
PyTuple_SET_ITEM(tuple, i, item);
|
||||
}
|
||||
|
||||
result = (*call)(func, tuple, kwargs);
|
||||
Py_DECREF(tuple);
|
||||
|
||||
result = _Py_CheckFunctionResult(func, result, NULL);
|
||||
}
|
||||
|
||||
exit:
|
||||
Py_LeaveRecursiveCall();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2372,9 +2371,7 @@ _PyObject_Call_Prepend(PyObject *func,
|
|||
PyObject **stack;
|
||||
Py_ssize_t argcount;
|
||||
PyObject *result;
|
||||
|
||||
assert(PyTuple_Check(args));
|
||||
|
||||
argcount = PyTuple_GET_SIZE(args);
|
||||
if (argcount + 1 <= (Py_ssize_t)Py_ARRAY_LENGTH(small_stack)) {
|
||||
stack = small_stack;
|
||||
|
@ -2386,13 +2383,11 @@ _PyObject_Call_Prepend(PyObject *func,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* use borrowed references */
|
||||
stack[0] = obj;
|
||||
memcpy(&stack[1],
|
||||
&PyTuple_GET_ITEM(args, 0),
|
||||
argcount * sizeof(PyObject *));
|
||||
|
||||
result = _PyObject_FastCallDict(func,
|
||||
stack, argcount + 1,
|
||||
kwargs);
|
||||
|
@ -2408,12 +2403,10 @@ _PyStack_AsDict(PyObject **values, PyObject *kwnames)
|
|||
Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames);
|
||||
PyObject *kwdict;
|
||||
Py_ssize_t i;
|
||||
|
||||
kwdict = PyDict_New();
|
||||
if (kwdict == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < nkwargs; i++) {
|
||||
PyObject *key = PyTuple_GET_ITEM(kwnames, i);
|
||||
PyObject *value = *values++;
|
||||
|
@ -2436,36 +2429,29 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
|
|||
Py_ssize_t pos, i;
|
||||
PyObject *key, *value;
|
||||
PyObject *kwnames;
|
||||
|
||||
assert(nargs >= 0);
|
||||
assert(kwargs == NULL || PyDict_CheckExact(kwargs));
|
||||
|
||||
if (kwargs == NULL || (nkwargs = PyDict_Size(kwargs)) == 0) {
|
||||
*p_stack = args;
|
||||
*p_kwnames = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((size_t)nargs > PY_SSIZE_T_MAX / sizeof(stack[0]) - (size_t)nkwargs) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
|
||||
stack = PyMem_Malloc((nargs + nkwargs) * sizeof(stack[0]));
|
||||
if (stack == NULL) {
|
||||
PyErr_NoMemory();
|
||||
return -1;
|
||||
}
|
||||
|
||||
kwnames = PyTuple_New(nkwargs);
|
||||
if (kwnames == NULL) {
|
||||
PyMem_Free(stack);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copy position arguments (borrowed references) */
|
||||
memcpy(stack, args, nargs * sizeof(stack[0]));
|
||||
|
||||
kwstack = stack + nargs;
|
||||
pos = i = 0;
|
||||
/* This loop doesn't support lookup function mutating the dictionary
|
||||
|
@ -2478,7 +2464,6 @@ _PyStack_UnpackDict(PyObject **args, Py_ssize_t nargs, PyObject *kwargs,
|
|||
kwstack[i] = value;
|
||||
i++;
|
||||
}
|
||||
|
||||
*p_stack = stack;
|
||||
*p_kwnames = kwnames;
|
||||
return 0;
|
||||
|
@ -2490,22 +2475,18 @@ _PyObject_FastCallKeywords(PyObject *func, PyObject **stack, Py_ssize_t nargs,
|
|||
{
|
||||
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
|
||||
_PyArg_ParseStack(). */
|
||||
|
||||
if (PyFunction_Check(func)) {
|
||||
return _PyFunction_FastCallKeywords(func, stack, nargs, kwnames);
|
||||
}
|
||||
|
||||
if (PyCFunction_Check(func)) {
|
||||
return _PyCFunction_FastCallKeywords(func, stack, nargs, kwnames);
|
||||
}
|
||||
|
||||
if (nkwargs > 0) {
|
||||
kwdict = _PyStack_AsDict(stack + nargs, kwnames);
|
||||
if (kwdict == NULL) {
|
||||
|
@ -2515,7 +2496,6 @@ _PyObject_FastCallKeywords(PyObject *func, PyObject **stack, Py_ssize_t nargs,
|
|||
else {
|
||||
kwdict = NULL;
|
||||
}
|
||||
|
||||
result = _PyObject_FastCallDict(func, stack, nargs, kwdict);
|
||||
Py_XDECREF(kwdict);
|
||||
return result;
|
||||
|
@ -2525,16 +2505,13 @@ static PyObject*
|
|||
call_function_tail(PyObject *callable, PyObject *args)
|
||||
{
|
||||
PyObject *result;
|
||||
|
||||
assert(args != NULL);
|
||||
|
||||
if (!PyTuple_Check(args)) {
|
||||
result = _PyObject_CallArg1(callable, args);
|
||||
}
|
||||
else {
|
||||
result = PyObject_Call(callable, args, NULL);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2543,22 +2520,18 @@ 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);
|
||||
}
|
||||
|
||||
va_start(va, format);
|
||||
args = Py_VaBuildValue(format, va);
|
||||
va_end(va);
|
||||
if (args == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = call_function_tail(callable, args);
|
||||
Py_DECREF(args);
|
||||
return result;
|
||||
|
@ -2569,22 +2542,18 @@ _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);
|
||||
}
|
||||
|
||||
va_start(va, format);
|
||||
args = _Py_VaBuildValue_SizeT(format, va);
|
||||
va_end(va);
|
||||
if (args == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = call_function_tail(callable, args);
|
||||
Py_DECREF(args);
|
||||
return result;
|
||||
|
@ -2594,18 +2563,14 @@ static PyObject*
|
|||
callmethod(PyObject* func, const char *format, va_list va, int is_size_t)
|
||||
{
|
||||
PyObject *args, *result;
|
||||
|
||||
assert(func != 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);
|
||||
}
|
||||
|
@ -2615,7 +2580,6 @@ callmethod(PyObject* func, const char *format, va_list va, int is_size_t)
|
|||
if (args == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = call_function_tail(func, args);
|
||||
Py_DECREF(args);
|
||||
return result;
|
||||
|
@ -2627,15 +2591,12 @@ PyObject_CallMethod(PyObject *o, const char *name, const char *format, ...)
|
|||
va_list va;
|
||||
PyObject *func = NULL;
|
||||
PyObject *retval = NULL;
|
||||
|
||||
if (o == NULL || name == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
func = PyObject_GetAttrString(o, name);
|
||||
if (func == NULL)
|
||||
return NULL;
|
||||
|
||||
va_start(va, format);
|
||||
retval = callmethod(func, format, va, 0);
|
||||
va_end(va);
|
||||
|
@ -2650,15 +2611,12 @@ _PyObject_CallMethodId(PyObject *o, _Py_Identifier *name,
|
|||
va_list va;
|
||||
PyObject *func = NULL;
|
||||
PyObject *retval = NULL;
|
||||
|
||||
if (o == NULL || name == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
func = _PyObject_GetAttrId(o, name);
|
||||
if (func == NULL)
|
||||
return NULL;
|
||||
|
||||
va_start(va, format);
|
||||
retval = callmethod(func, format, va, 0);
|
||||
va_end(va);
|
||||
|
@ -2673,11 +2631,9 @@ _PyObject_CallMethod_SizeT(PyObject *o, const char *name,
|
|||
va_list va;
|
||||
PyObject *func = NULL;
|
||||
PyObject *retval;
|
||||
|
||||
if (o == NULL || name == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
func = PyObject_GetAttrString(o, name);
|
||||
if (func == NULL)
|
||||
return NULL;
|
||||
|
@ -2695,11 +2651,9 @@ _PyObject_CallMethodId_SizeT(PyObject *o, _Py_Identifier *name,
|
|||
va_list va;
|
||||
PyObject *func = NULL;
|
||||
PyObject *retval;
|
||||
|
||||
if (o == NULL || name == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
func = _PyObject_GetAttrId(o, name);
|
||||
if (func == NULL) {
|
||||
return NULL;
|
||||
|
@ -2718,10 +2672,8 @@ objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size,
|
|||
Py_ssize_t i, n;
|
||||
va_list countva;
|
||||
PyObject **stack;
|
||||
|
||||
/* Count the number of arguments */
|
||||
va_copy(countva, va);
|
||||
|
||||
n = 0;
|
||||
while (1) {
|
||||
PyObject *arg = va_arg(countva, PyObject *);
|
||||
|
@ -2731,7 +2683,6 @@ objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size,
|
|||
n++;
|
||||
}
|
||||
*p_nargs = n;
|
||||
|
||||
/* Copy arguments */
|
||||
if (n <= small_stack_size) {
|
||||
stack = small_stack;
|
||||
|
@ -2744,7 +2695,6 @@ objargs_mkstack(PyObject **small_stack, Py_ssize_t small_stack_size,
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n; ++i) {
|
||||
stack[i] = va_arg(va, PyObject *);
|
||||
}
|
||||
|
@ -2760,15 +2710,12 @@ PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
|
|||
Py_ssize_t nargs;
|
||||
PyObject *result;
|
||||
va_list vargs;
|
||||
|
||||
if (callable == NULL || name == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
callable = PyObject_GetAttr(callable, name);
|
||||
if (callable == NULL)
|
||||
return NULL;
|
||||
|
||||
/* count the args */
|
||||
va_start(vargs, name);
|
||||
stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
|
||||
|
@ -2778,34 +2725,29 @@ PyObject_CallMethodObjArgs(PyObject *callable, PyObject *name, ...)
|
|||
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, ...)
|
||||
struct _Py_Identifier *name, ...)
|
||||
{
|
||||
PyObject *small_stack[5];
|
||||
PyObject **stack;
|
||||
Py_ssize_t nargs;
|
||||
PyObject *result;
|
||||
va_list vargs;
|
||||
|
||||
if (callable == NULL || name == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
callable = _PyObject_GetAttrId(callable, name);
|
||||
if (callable == NULL)
|
||||
return NULL;
|
||||
|
||||
/* count the args */
|
||||
va_start(vargs, name);
|
||||
stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
|
||||
|
@ -2815,13 +2757,11 @@ _PyObject_CallMethodIdObjArgs(PyObject *callable,
|
|||
Py_DECREF(callable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = _PyObject_FastCall(callable, stack, nargs);
|
||||
Py_DECREF(callable);
|
||||
if (stack != small_stack) {
|
||||
PyMem_Free(stack);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -2833,11 +2773,9 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...)
|
|||
Py_ssize_t nargs;
|
||||
PyObject *result;
|
||||
va_list vargs;
|
||||
|
||||
if (callable == NULL) {
|
||||
return null_error();
|
||||
}
|
||||
|
||||
/* count the args */
|
||||
va_start(vargs, callable);
|
||||
stack = objargs_mkstack(small_stack, Py_ARRAY_LENGTH(small_stack),
|
||||
|
@ -2846,18 +2784,13 @@ PyObject_CallFunctionObjArgs(PyObject *callable, ...)
|
|||
if (stack == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
result = _PyObject_FastCall(callable, stack, nargs);
|
||||
if (stack != small_stack) {
|
||||
PyMem_Free(stack);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* isinstance(), issubclass() */
|
||||
|
||||
/* abstract_get_bases() has logically 4 return states:
|
||||
*
|
||||
* 1. getattr(cls, '__bases__') could raise an AttributeError
|
||||
|
@ -2887,7 +2820,6 @@ abstract_get_bases(PyObject *cls)
|
|||
{
|
||||
_Py_IDENTIFIER(__bases__);
|
||||
PyObject *bases;
|
||||
|
||||
Py_ALLOW_RECURSION
|
||||
bases = _PyObject_GetAttrId(cls, &PyId___bases__);
|
||||
Py_END_ALLOW_RECURSION
|
||||
|
@ -2903,14 +2835,12 @@ abstract_get_bases(PyObject *cls)
|
|||
return bases;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
abstract_issubclass(PyObject *derived, PyObject *cls)
|
||||
{
|
||||
PyObject *bases = NULL;
|
||||
Py_ssize_t i, n;
|
||||
int r = 0;
|
||||
|
||||
while (1) {
|
||||
if (derived == cls)
|
||||
return 1;
|
||||
|
@ -2961,7 +2891,6 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
|
|||
PyObject *icls;
|
||||
int retval = 0;
|
||||
_Py_IDENTIFIER(__class__);
|
||||
|
||||
if (PyType_Check(cls)) {
|
||||
retval = PyObject_TypeCheck(inst, (PyTypeObject *)cls);
|
||||
if (retval == 0) {
|
||||
|
@ -2998,7 +2927,6 @@ recursive_isinstance(PyObject *inst, PyObject *cls)
|
|||
Py_DECREF(icls);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
@ -3007,21 +2935,17 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
|
|||
{
|
||||
_Py_IDENTIFIER(__instancecheck__);
|
||||
PyObject *checker;
|
||||
|
||||
/* Quick test for an exact match */
|
||||
if (Py_TYPE(inst) == (PyTypeObject *)cls)
|
||||
return 1;
|
||||
|
||||
/* We know what type's __instancecheck__ does. */
|
||||
if (PyType_CheckExact(cls)) {
|
||||
return recursive_isinstance(inst, cls);
|
||||
}
|
||||
|
||||
if (PyTuple_Check(cls)) {
|
||||
Py_ssize_t i;
|
||||
Py_ssize_t n;
|
||||
int r = 0;
|
||||
|
||||
if (Py_EnterRecursiveCall(" in __instancecheck__"))
|
||||
return -1;
|
||||
n = PyTuple_GET_SIZE(cls);
|
||||
|
@ -3035,7 +2959,6 @@ PyObject_IsInstance(PyObject *inst, PyObject *cls)
|
|||
Py_LeaveRecursiveCall();
|
||||
return r;
|
||||
}
|
||||
|
||||
checker = _PyObject_LookupSpecial(cls, &PyId___instancecheck__);
|
||||
if (checker != NULL) {
|
||||
PyObject *res;
|
||||
|
@ -3073,7 +2996,6 @@ recursive_issubclass(PyObject *derived, PyObject *cls)
|
|||
"issubclass() arg 2 must be a class"
|
||||
" or tuple of classes"))
|
||||
return -1;
|
||||
|
||||
return abstract_issubclass(derived, cls);
|
||||
}
|
||||
|
||||
|
@ -3082,7 +3004,6 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
|
|||
{
|
||||
_Py_IDENTIFIER(__subclasscheck__);
|
||||
PyObject *checker;
|
||||
|
||||
/* We know what type's __subclasscheck__ does. */
|
||||
if (PyType_CheckExact(cls)) {
|
||||
/* Quick test for an exact match */
|
||||
|
@ -3090,12 +3011,10 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
|
|||
return 1;
|
||||
return recursive_issubclass(derived, cls);
|
||||
}
|
||||
|
||||
if (PyTuple_Check(cls)) {
|
||||
Py_ssize_t i;
|
||||
Py_ssize_t n;
|
||||
int r = 0;
|
||||
|
||||
if (Py_EnterRecursiveCall(" in __subclasscheck__"))
|
||||
return -1;
|
||||
n = PyTuple_GET_SIZE(cls);
|
||||
|
@ -3109,7 +3028,6 @@ PyObject_IsSubclass(PyObject *derived, PyObject *cls)
|
|||
Py_LeaveRecursiveCall();
|
||||
return r;
|
||||
}
|
||||
|
||||
checker = _PyObject_LookupSpecial(cls, &PyId___subclasscheck__);
|
||||
if (checker != NULL) {
|
||||
PyObject *res;
|
||||
|
@ -3145,7 +3063,6 @@ _PyObject_RealIsSubclass(PyObject *derived, PyObject *cls)
|
|||
return recursive_issubclass(derived, cls);
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
PyObject_GetIter(PyObject *o)
|
||||
{
|
||||
|
@ -3190,7 +3107,6 @@ PyIter_Next(PyObject *iter)
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Flatten a sequence of bytes() objects into a C array of
|
||||
* NULL terminated string pointers with a NULL char* terminating the array.
|
||||
|
@ -3206,18 +3122,14 @@ _PySequence_BytesToCharpArray(PyObject* self)
|
|||
Py_ssize_t i, argc;
|
||||
PyObject *item = NULL;
|
||||
Py_ssize_t size;
|
||||
|
||||
argc = PySequence_Size(self);
|
||||
if (argc == -1)
|
||||
return NULL;
|
||||
|
||||
assert(argc >= 0);
|
||||
|
||||
if ((size_t)argc > (PY_SSIZE_T_MAX-sizeof(char *)) / sizeof(char *)) {
|
||||
PyErr_NoMemory();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
array = PyMem_Malloc((argc + 1) * sizeof(char *));
|
||||
if (array == NULL) {
|
||||
PyErr_NoMemory();
|
||||
|
@ -3247,16 +3159,13 @@ _PySequence_BytesToCharpArray(PyObject* self)
|
|||
Py_DECREF(item);
|
||||
}
|
||||
array[argc] = NULL;
|
||||
|
||||
return array;
|
||||
|
||||
fail:
|
||||
Py_XDECREF(item);
|
||||
_Py_FreeCharPArray(array);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Free's a NULL terminated char** array of C strings. */
|
||||
void
|
||||
_Py_FreeCharPArray(char *const array[])
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue