mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-05-22 21:32:31 +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
62
third_party/python/Python/ast.c
vendored
62
third_party/python/Python/ast.c
vendored
|
@ -30,6 +30,7 @@
|
|||
#include "third_party/python/Include/token.h"
|
||||
#include "third_party/python/Include/tupleobject.h"
|
||||
#include "third_party/python/Include/warnings.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
|
||||
static int validate_stmts(asdl_seq *);
|
||||
|
@ -157,7 +158,6 @@ validate_constant(PyObject *value)
|
|||
{
|
||||
if (value == Py_None || value == Py_Ellipsis)
|
||||
return 1;
|
||||
|
||||
if (PyLong_CheckExact(value)
|
||||
|| PyFloat_CheckExact(value)
|
||||
|| PyComplex_CheckExact(value)
|
||||
|
@ -165,14 +165,11 @@ validate_constant(PyObject *value)
|
|||
|| PyUnicode_CheckExact(value)
|
||||
|| PyBytes_CheckExact(value))
|
||||
return 1;
|
||||
|
||||
if (PyTuple_CheckExact(value) || PyFrozenSet_CheckExact(value)) {
|
||||
PyObject *it;
|
||||
|
||||
it = PyObject_GetIter(value);
|
||||
if (it == NULL)
|
||||
return 0;
|
||||
|
||||
while (1) {
|
||||
PyObject *item = PyIter_Next(it);
|
||||
if (item == NULL) {
|
||||
|
@ -182,7 +179,6 @@ validate_constant(PyObject *value)
|
|||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (!validate_constant(item)) {
|
||||
Py_DECREF(it);
|
||||
Py_DECREF(item);
|
||||
|
@ -190,11 +186,9 @@ validate_constant(PyObject *value)
|
|||
}
|
||||
Py_DECREF(item);
|
||||
}
|
||||
|
||||
Py_DECREF(it);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -203,7 +197,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
|||
{
|
||||
int check_ctx = 1;
|
||||
expr_context_ty actual_ctx;
|
||||
|
||||
/* First check expression context. */
|
||||
switch (exp->kind) {
|
||||
case Attribute_kind:
|
||||
|
@ -239,7 +232,6 @@ validate_expr(expr_ty exp, expr_context_ty ctx)
|
|||
expr_context_name(ctx), expr_context_name(actual_ctx));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Now validate expression. */
|
||||
switch (exp->kind) {
|
||||
case BoolOp_kind:
|
||||
|
@ -577,7 +569,6 @@ int
|
|||
PyAST_Validate(mod_ty mod)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
switch (mod->kind) {
|
||||
case Module_kind:
|
||||
res = validate_stmts(mod->v.Module.body);
|
||||
|
@ -600,7 +591,6 @@ PyAST_Validate(mod_ty mod)
|
|||
}
|
||||
|
||||
/* This is done here, so defines like "test" don't interfere with AST use above. */
|
||||
/* WHAT */
|
||||
#include "third_party/python/Include/grammar.h"
|
||||
#include "third_party/python/Include/parsetok.h"
|
||||
#include "third_party/python/Include/graminit.h"
|
||||
|
@ -609,7 +599,6 @@ PyAST_Validate(mod_ty mod)
|
|||
struct compiling {
|
||||
PyArena *c_arena; /* Arena for allocating memory. */
|
||||
PyObject *c_filename; /* filename */
|
||||
PyObject *c_normalize; /* Normalization function from unicodedata. */
|
||||
};
|
||||
|
||||
static asdl_seq *seq_for_testlist(struct compiling *, const node *);
|
||||
|
@ -634,50 +623,25 @@ static expr_ty parsestrplus(struct compiling *, const node *n);
|
|||
#define COMP_LISTCOMP 1
|
||||
#define COMP_SETCOMP 2
|
||||
|
||||
static int
|
||||
init_normalization(struct compiling *c)
|
||||
{
|
||||
PyObject *m = PyImport_ImportModuleNoBlock("unicodedata");
|
||||
if (!m)
|
||||
return 0;
|
||||
c->c_normalize = PyObject_GetAttrString(m, "normalize");
|
||||
Py_DECREF(m);
|
||||
if (!c->c_normalize)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static identifier
|
||||
new_identifier(const char *n, struct compiling *c)
|
||||
{
|
||||
PyObject *id = PyUnicode_DecodeUTF8(n, strlen(n), NULL);
|
||||
if (!id)
|
||||
PyObject *id, *id2;
|
||||
if (!(id = PyUnicode_DecodeUTF8(n, strlen(n), NULL)))
|
||||
return NULL;
|
||||
/* PyUnicode_DecodeUTF8 should always return a ready string. */
|
||||
assert(PyUnicode_IS_READY(id));
|
||||
/* Check whether there are non-ASCII characters in the
|
||||
identifier; if so, normalize to NFKC. */
|
||||
if (!PyUnicode_IS_ASCII(id)) {
|
||||
PyObject *id2;
|
||||
_Py_IDENTIFIER(NFKC);
|
||||
if (!c->c_normalize && !init_normalization(c)) {
|
||||
Py_DECREF(id);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *form = _PyUnicode_FromId(&PyId_NFKC);
|
||||
if (form == NULL) {
|
||||
Py_DECREF(id);
|
||||
return NULL;
|
||||
}
|
||||
PyObject *args[2] = {form, id};
|
||||
id2 = _PyObject_FastCall(c->c_normalize, args, 2);
|
||||
if (!PyUnicode_IS_ASCII(id) && !_PyUnicode_IsNormalized(0, id, 1, 1)) {
|
||||
id2 = _PyUnicode_NfcNfkc(0, id, 1);
|
||||
Py_DECREF(id);
|
||||
if (!id2)
|
||||
return NULL;
|
||||
if (!PyUnicode_Check(id2)) {
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
"unicodedata.normalize() must return a string, not "
|
||||
"%.200s",
|
||||
"unicodedata.normalize() must return "
|
||||
" a string, not %.200s",
|
||||
Py_TYPE(id2)->tp_name);
|
||||
Py_DECREF(id2);
|
||||
return NULL;
|
||||
|
@ -741,7 +705,6 @@ num_stmts(const node *n)
|
|||
{
|
||||
int i, l;
|
||||
node *ch;
|
||||
|
||||
switch (TYPE(n)) {
|
||||
case single_input:
|
||||
if (TYPE(CHILD(n, 0)) == NEWLINE)
|
||||
|
@ -773,14 +736,12 @@ num_stmts(const node *n)
|
|||
}
|
||||
default: {
|
||||
char buf[128];
|
||||
|
||||
sprintf(buf, "Non-statement found: %d %d",
|
||||
TYPE(n), NCH(n));
|
||||
Py_FatalError(buf);
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return 0;
|
||||
unreachable;
|
||||
}
|
||||
|
||||
/* Transform the CST rooted at node * to the appropriate AST
|
||||
|
@ -796,15 +757,11 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
|||
node *ch;
|
||||
struct compiling c;
|
||||
mod_ty res = NULL;
|
||||
|
||||
c.c_arena = arena;
|
||||
/* borrowed reference */
|
||||
c.c_filename = filename;
|
||||
c.c_normalize = NULL;
|
||||
|
||||
if (TYPE(n) == encoding_decl)
|
||||
n = CHILD(n, 0);
|
||||
|
||||
k = 0;
|
||||
switch (TYPE(n)) {
|
||||
case file_input:
|
||||
|
@ -891,9 +848,6 @@ PyAST_FromNodeObject(const node *n, PyCompilerFlags *flags,
|
|||
goto out;
|
||||
}
|
||||
out:
|
||||
if (c.c_normalize) {
|
||||
Py_DECREF(c.c_normalize);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
|
101
third_party/python/Python/ceval.c
vendored
101
third_party/python/Python/ceval.c
vendored
|
@ -5,6 +5,7 @@
|
|||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#define PY_LOCAL_AGGRESSIVE
|
||||
#include "libc/bits/likely.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
|
@ -51,41 +52,32 @@
|
|||
|
||||
typedef PyObject *(*callproc)(PyObject *, PyObject *, PyObject *);
|
||||
|
||||
/* Forward declarations */
|
||||
static PyObject * call_function(PyObject ***, Py_ssize_t, PyObject *);
|
||||
static PyObject * fast_function(PyObject *, PyObject **, Py_ssize_t, PyObject *);
|
||||
static PyObject * do_call_core(PyObject *, PyObject *, PyObject *);
|
||||
|
||||
#ifdef LLTRACE
|
||||
static int lltrace;
|
||||
static int prtrace(PyObject *, const char *);
|
||||
#endif
|
||||
static int call_trace(Py_tracefunc, PyObject *,
|
||||
PyThreadState *, PyFrameObject *,
|
||||
int, PyObject *);
|
||||
static int call_trace_protected(Py_tracefunc, PyObject *,
|
||||
PyThreadState *, PyFrameObject *,
|
||||
int, PyObject *);
|
||||
static void call_exc_trace(Py_tracefunc, PyObject *,
|
||||
PyThreadState *, PyFrameObject *);
|
||||
static int maybe_call_line_trace(Py_tracefunc, PyObject *,
|
||||
PyThreadState *, PyFrameObject *, int *, int *, int *);
|
||||
static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *);
|
||||
|
||||
static PyObject *call_function(PyObject ***, Py_ssize_t, PyObject *);
|
||||
static PyObject *cmp_outcome(int, PyObject *, PyObject *);
|
||||
static PyObject *do_call_core(PyObject *, PyObject *, PyObject *);
|
||||
static PyObject *fast_function(PyObject *, PyObject **, Py_ssize_t, PyObject *);
|
||||
static PyObject *import_from(PyObject *, PyObject *);
|
||||
static PyObject *import_name(PyFrameObject *, PyObject *, PyObject *, PyObject *);
|
||||
static PyObject *special_lookup(PyObject *, _Py_Identifier *);
|
||||
static PyObject *unicode_concatenate(PyObject *, PyObject *, PyFrameObject *, const _Py_CODEUNIT *);
|
||||
static int call_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, int, PyObject *);
|
||||
static int call_trace_protected(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, int, PyObject *);
|
||||
static int check_args_iterable(PyObject *, PyObject *);
|
||||
static int import_all_from(PyObject *, PyObject *);
|
||||
static int maybe_call_line_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *, int *, int *, int *);
|
||||
static void call_exc_trace(Py_tracefunc, PyObject *, PyThreadState *, PyFrameObject *);
|
||||
static void dtrace_function_entry(PyFrameObject *);
|
||||
static void dtrace_function_return(PyFrameObject *);
|
||||
|
||||
static PyObject * cmp_outcome(int, PyObject *, PyObject *);
|
||||
static PyObject * import_name(PyFrameObject *, PyObject *, PyObject *, PyObject *);
|
||||
static PyObject * import_from(PyObject *, PyObject *);
|
||||
static int import_all_from(PyObject *, PyObject *);
|
||||
static void format_exc_check_arg(PyObject *, const char *, PyObject *);
|
||||
static void format_exc_unbound(PyCodeObject *co, int oparg);
|
||||
static PyObject * unicode_concatenate(PyObject *, PyObject *,
|
||||
PyFrameObject *, const _Py_CODEUNIT *);
|
||||
static PyObject * special_lookup(PyObject *, _Py_Identifier *);
|
||||
static int check_args_iterable(PyObject *func, PyObject *vararg);
|
||||
static void format_kwargs_mapping_error(PyObject *func, PyObject *kwargs);
|
||||
static void format_awaitable_error(PyTypeObject *, int);
|
||||
static void format_exc_check_arg(PyObject *, const char *, PyObject *);
|
||||
static void format_exc_unbound(PyCodeObject *, int);
|
||||
static void format_kwargs_mapping_error(PyObject *, PyObject *);
|
||||
static void maybe_dtrace_line(PyFrameObject *, int *, int *, int *);
|
||||
|
||||
#define NAME_ERROR_MSG \
|
||||
"name '%.200s' is not defined"
|
||||
|
@ -764,7 +756,7 @@ PyEval_EvalFrame(PyFrameObject *f) {
|
|||
}
|
||||
|
||||
PyObject *
|
||||
PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
|
||||
(PyEval_EvalFrameEx)(PyFrameObject *f, int throwflag)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
return tstate->interp->eval_frame(f, throwflag);
|
||||
|
@ -835,11 +827,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
We disable the optimization if DYNAMIC_EXECUTION_PROFILE is defined,
|
||||
because it would render the measurements invalid.
|
||||
|
||||
|
||||
NOTE: care must be taken that the compiler doesn't try to "optimize" the
|
||||
indirect jumps by sharing them between all opcodes. Such optimizations
|
||||
can be disabled on gcc by using the -fno-gcse flag (or possibly
|
||||
-fno-crossjumping).
|
||||
NOTE: Care must be taken that the compiler doesn't try to "optimize"
|
||||
the indirect jumps by sharing them between all opcodes. Such
|
||||
optimizations can be disabled on gcc by using the -fno-gcse
|
||||
flag (or possibly -fno-crossjumping).
|
||||
*/
|
||||
|
||||
#ifdef DYNAMIC_EXECUTION_PROFILE
|
||||
|
@ -863,10 +854,23 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
/* Import the static jump table */
|
||||
#include "third_party/python/Python/opcode_targets.inc"
|
||||
|
||||
#if __GNUC__ + 0 >= 9
|
||||
#define HOT_LABEL __attribute__((__hot__))
|
||||
#define COLD_LABEL __attribute__((__hot__))
|
||||
#else
|
||||
#define HOT_LABEL
|
||||
#define COLD_LABEL
|
||||
#endif
|
||||
|
||||
#define TARGET(op) \
|
||||
TARGET_##op: \
|
||||
case op:
|
||||
|
||||
#define LIKELY_TARGET(op) \
|
||||
TARGET_##op: \
|
||||
HOT_LABEL; \
|
||||
case op:
|
||||
|
||||
#define DISPATCH() \
|
||||
{ \
|
||||
if (!_Py_atomic_load_relaxed(&eval_breaker)) { \
|
||||
|
@ -898,9 +902,8 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
#endif
|
||||
|
||||
#else
|
||||
#define TARGET(op) \
|
||||
case op:
|
||||
|
||||
#define TARGET(op) case op:
|
||||
#define LIKELY_TARGET(op) case op:
|
||||
#define DISPATCH() continue
|
||||
#define FAST_DISPATCH() goto fast_next_opcode
|
||||
#endif
|
||||
|
@ -1057,7 +1060,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
|
||||
tstate->frame = f;
|
||||
|
||||
if (tstate->use_tracing) {
|
||||
if (UNLIKELY(tstate->use_tracing)) {
|
||||
if (tstate->c_tracefunc != NULL) {
|
||||
/* tstate->c_tracefunc, if defined, is a
|
||||
function that will be called on *every* entry
|
||||
|
@ -1220,7 +1223,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
}
|
||||
#endif
|
||||
/* Check for asynchronous exceptions. */
|
||||
if (tstate->async_exc != NULL) {
|
||||
if (UNLIKELY(tstate->async_exc != NULL)) {
|
||||
PyObject *exc = tstate->async_exc;
|
||||
tstate->async_exc = NULL;
|
||||
UNSIGNAL_ASYNC_EXC();
|
||||
|
@ -1297,9 +1300,9 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
TARGET(NOP)
|
||||
FAST_DISPATCH();
|
||||
|
||||
TARGET(LOAD_FAST) {
|
||||
LIKELY_TARGET(LOAD_FAST) {
|
||||
PyObject *value = GETLOCAL(oparg);
|
||||
if (value == NULL) {
|
||||
if (UNLIKELY(value == NULL)) {
|
||||
format_exc_check_arg(PyExc_UnboundLocalError,
|
||||
UNBOUNDLOCAL_ERROR_MSG,
|
||||
PyTuple_GetItem(co->co_varnames, oparg));
|
||||
|
@ -2444,7 +2447,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
}
|
||||
else {
|
||||
/* Slow-path if globals or builtins is not a dict */
|
||||
|
||||
/* namespace 1: globals */
|
||||
v = PyObject_GetItem(f->f_globals, name);
|
||||
if (v == NULL) {
|
||||
|
@ -2820,7 +2822,6 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
PyObject *sum = PyDict_New();
|
||||
if (sum == NULL)
|
||||
goto error;
|
||||
|
||||
for (i = oparg; i > 0; i--) {
|
||||
PyObject *arg = PEEK(i);
|
||||
if (_PyDict_MergeEx(sum, arg, 2) < 0) {
|
||||
|
@ -3548,6 +3549,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
|
||||
#if USE_COMPUTED_GOTOS
|
||||
_unknown_opcode:
|
||||
COLD_LABEL;
|
||||
#endif
|
||||
default:
|
||||
fprintf(stderr,
|
||||
|
@ -3565,10 +3567,10 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
|
|||
|
||||
/* This should never be reached. Every opcode should end with DISPATCH()
|
||||
or goto error. */
|
||||
assert(0);
|
||||
unreachable;
|
||||
|
||||
error:
|
||||
|
||||
COLD_LABEL;
|
||||
assert(why == WHY_NOT);
|
||||
why = WHY_EXCEPTION;
|
||||
|
||||
|
@ -3592,7 +3594,7 @@ fast_block_end:
|
|||
assert(why != WHY_NOT);
|
||||
|
||||
/* Unwind stacks if a (pseudo) exception occurred */
|
||||
while (why != WHY_NOT && f->f_iblock > 0) {
|
||||
while (UNLIKELY(why != WHY_NOT && f->f_iblock > 0)) {
|
||||
/* Peek at the current block. */
|
||||
PyTryBlock *b = &f->f_blockstack[f->f_iblock - 1];
|
||||
|
||||
|
@ -3712,7 +3714,7 @@ fast_yield:
|
|||
swap_exc_state(tstate, f);
|
||||
}
|
||||
|
||||
if (tstate->use_tracing) {
|
||||
if (UNLIKELY(tstate->use_tracing)) {
|
||||
if (tstate->c_tracefunc) {
|
||||
if (why == WHY_RETURN || why == WHY_YIELD) {
|
||||
if (call_trace(tstate->c_tracefunc, tstate->c_traceobj,
|
||||
|
@ -4275,10 +4277,9 @@ restore_and_clear_exc_state(PyThreadState *tstate, PyFrameObject *f)
|
|||
Py_XDECREF(tb);
|
||||
}
|
||||
|
||||
|
||||
/* Logic for the raise statement (too complicated for inlining).
|
||||
This *consumes* a reference count to each of its arguments. */
|
||||
static int
|
||||
static noinline int
|
||||
do_raise(PyObject *exc, PyObject *cause)
|
||||
{
|
||||
PyObject *type = NULL, *value = NULL;
|
||||
|
@ -4461,7 +4462,6 @@ Error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef LLTRACE
|
||||
static int
|
||||
prtrace(PyObject *v, const char *str)
|
||||
|
@ -4549,7 +4549,6 @@ _PyEval_CallTracing(PyObject *func, PyObject *args)
|
|||
int save_tracing = tstate->tracing;
|
||||
int save_use_tracing = tstate->use_tracing;
|
||||
PyObject *result;
|
||||
|
||||
tstate->tracing = 0;
|
||||
tstate->use_tracing = ((tstate->c_tracefunc != NULL)
|
||||
|| (tstate->c_profilefunc != NULL));
|
||||
|
|
21
third_party/python/Python/codecs.c
vendored
21
third_party/python/Python/codecs.c
vendored
|
@ -4,6 +4,7 @@
|
|||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/bits/weaken.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/bytesobject.h"
|
||||
|
@ -20,6 +21,7 @@
|
|||
#include "third_party/python/Include/pystate.h"
|
||||
#include "third_party/python/Include/tupleobject.h"
|
||||
#include "third_party/python/Include/ucnhash.h"
|
||||
#include "third_party/python/Modules/unicodedata.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* ------------------------------------------------------------------------
|
||||
|
@ -985,8 +987,6 @@ PyObject *PyCodec_BackslashReplaceErrors(PyObject *exc)
|
|||
return Py_BuildValue("(Nn)", res, end);
|
||||
}
|
||||
|
||||
static _PyUnicode_Name_CAPI *ucnhash_CAPI = NULL;
|
||||
|
||||
PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
|
||||
{
|
||||
if (PyObject_TypeCheck(exc, (PyTypeObject *)PyExc_UnicodeEncodeError)) {
|
||||
|
@ -1007,17 +1007,16 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
|
|||
return NULL;
|
||||
if (!(object = PyUnicodeEncodeError_GetObject(exc)))
|
||||
return NULL;
|
||||
if (!ucnhash_CAPI) {
|
||||
/* load the unicode data module */
|
||||
ucnhash_CAPI = (_PyUnicode_Name_CAPI *)PyCapsule_Import(
|
||||
PyUnicodeData_CAPSULE_NAME, 1);
|
||||
if (!ucnhash_CAPI)
|
||||
return NULL;
|
||||
}
|
||||
for (i = start, ressize = 0; i < end; ++i) {
|
||||
/* object is guaranteed to be "ready" */
|
||||
if (!weaken(_PyUnicode_GetUcName)) {
|
||||
PyErr_SetString(
|
||||
PyExc_UnicodeError,
|
||||
"_PyUnicode_GetUcName() not available");
|
||||
return NULL;
|
||||
}
|
||||
c = PyUnicode_READ_CHAR(object, i);
|
||||
if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
|
||||
if (weaken(_PyUnicode_GetUcName)(NULL, c, buffer, sizeof(buffer), 1)) {
|
||||
replsize = 1+1+1+(int)strlen(buffer)+1;
|
||||
}
|
||||
else if (c >= 0x10000) {
|
||||
|
@ -1040,7 +1039,7 @@ PyObject *PyCodec_NameReplaceErrors(PyObject *exc)
|
|||
i < end; ++i) {
|
||||
c = PyUnicode_READ_CHAR(object, i);
|
||||
*outp++ = '\\';
|
||||
if (ucnhash_CAPI->getname(NULL, c, buffer, sizeof(buffer), 1)) {
|
||||
if (_PyUnicode_GetUcName(NULL, c, buffer, sizeof(buffer), 1)) {
|
||||
*outp++ = 'N';
|
||||
*outp++ = '{';
|
||||
strcpy((char *)outp, buffer);
|
||||
|
|
357
third_party/python/Python/cosmomodule.c
vendored
357
third_party/python/Python/cosmomodule.c
vendored
|
@ -1,105 +1,316 @@
|
|||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
|
||||
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:4;tab-width:8;coding:utf-8 -*-│
|
||||
│vi: set net ft=c ts=4 sts=4 sw=4 fenc=utf-8 :vi│
|
||||
╞══════════════════════════════════════════════════════════════════════════════╡
|
||||
│ This is free and unencumbered software released into the public domain. │
|
||||
│ Copyright 2021 Justine Alexandra Roberts Tunney │
|
||||
│ │
|
||||
│ Anyone is free to copy, modify, publish, use, compile, sell, or │
|
||||
│ distribute this software, either in source code form or as a compiled │
|
||||
│ binary, for any purpose, commercial or non-commercial, and by any │
|
||||
│ means. │
|
||||
│ Permission to use, copy, modify, and/or distribute this software for │
|
||||
│ any purpose with or without fee is hereby granted, provided that the │
|
||||
│ above copyright notice and this permission notice appear in all copies. │
|
||||
│ │
|
||||
│ In jurisdictions that recognize copyright laws, the author or authors │
|
||||
│ of this software dedicate any and all copyright interest in the │
|
||||
│ software to the public domain. We make this dedication for the benefit │
|
||||
│ of the public at large and to the detriment of our heirs and │
|
||||
│ successors. We intend this dedication to be an overt act of │
|
||||
│ relinquishment in perpetuity of all present and future rights to this │
|
||||
│ software under copyright law. │
|
||||
│ │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, │
|
||||
│ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF │
|
||||
│ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. │
|
||||
│ IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR │
|
||||
│ OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, │
|
||||
│ ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR │
|
||||
│ OTHER DEALINGS IN THE SOFTWARE. │
|
||||
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
|
||||
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
|
||||
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
|
||||
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
|
||||
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
|
||||
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
|
||||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/Python-ast.h"
|
||||
#define PY_SSIZE_T_CLEAN
|
||||
#include "dsp/scale/cdecimate2xuint8x8.h"
|
||||
#include "libc/bits/popcnt.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nexgen32e/crc32.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/nexgen32e/rdtscp.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/ceval.h"
|
||||
#include "third_party/python/Include/code.h"
|
||||
#include "third_party/python/Include/cosmo.h"
|
||||
#include "third_party/python/Include/dictobject.h"
|
||||
#include "third_party/python/Include/errcode.h"
|
||||
#include "third_party/python/Include/eval.h"
|
||||
#include "third_party/python/Include/fileutils.h"
|
||||
#include "third_party/python/Include/frameobject.h"
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Include/listobject.h"
|
||||
#include "third_party/python/Include/longobject.h"
|
||||
#include "third_party/python/Include/marshal.h"
|
||||
#include "third_party/python/Include/methodobject.h"
|
||||
#include "third_party/python/Include/modsupport.h"
|
||||
#include "third_party/python/Include/objimpl.h"
|
||||
#include "third_party/python/Include/osdefs.h"
|
||||
#include "third_party/python/Include/pgenheaders.h"
|
||||
#include "third_party/python/Include/pydebug.h"
|
||||
#include "third_party/python/Include/moduleobject.h"
|
||||
#include "third_party/python/Include/pyerrors.h"
|
||||
#include "third_party/python/Include/pylifecycle.h"
|
||||
#include "third_party/python/Include/pymacro.h"
|
||||
#include "third_party/python/Include/pythonrun.h"
|
||||
#include "third_party/python/Include/sysmodule.h"
|
||||
#include "third_party/python/Include/traceback.h"
|
||||
#include "third_party/python/Include/tupleobject.h"
|
||||
#include "third_party/python/Include/warnings.h"
|
||||
#include "third_party/python/Include/weakrefobject.h"
|
||||
#include "third_party/python/Include/yoink.h"
|
||||
#include "third_party/python/Python/importdl.h"
|
||||
#include "third_party/xed/x86.h"
|
||||
/* clang-format off */
|
||||
|
||||
PYTHON_PROVIDE("_cosmo");
|
||||
PYTHON_PROVIDE("cosmo");
|
||||
|
||||
static int cosmo_constants(PyObject *m)
|
||||
PyDoc_STRVAR(cosmo_doc,
|
||||
"Cosmopolitan Libc Module\n\
|
||||
\n\
|
||||
This module exposes low-level utilities from the Cosmopolitan library.\n\
|
||||
\n\
|
||||
Static objects:\n\
|
||||
\n\
|
||||
MODE -- make build mode, e.g. \"\", \"tiny\", \"opt\", \"rel\", etc.\n\
|
||||
IMAGE_BASE_VIRTUAL -- base address of actually portable executable image\n\
|
||||
kernel -- o/s platform, e.g. \"linux\", \"xnu\", \"metal\", \"nt\", etc.\n\
|
||||
kStartTsc -- the rdtsc() value at process creation.");
|
||||
|
||||
PyDoc_STRVAR(syscount_doc,
|
||||
"syscount($module)\n\
|
||||
--\n\n\
|
||||
Returns number of SYSCALL instructions issued to kernel by C library.\n\
|
||||
\n\
|
||||
Context switching from userspace to kernelspace is expensive! So it is\n\
|
||||
useful to be able to know how many times that's happening in your app.\n\
|
||||
\n\
|
||||
This value currently isn't meaningful on Windows NT, where it currently\n\
|
||||
tracks the number of POSIX calls that were attempted, but have not been\n\
|
||||
polyfilled yet.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_syscount(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
if(PyModule_AddStringMacro(m, MODE)) return -1;
|
||||
return 0;
|
||||
return PyLong_FromSize_t(g_syscount);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(rdtsc_doc,
|
||||
"rdtsc($module)\n\
|
||||
--\n\n\
|
||||
Returns CPU timestamp counter.");
|
||||
|
||||
PyDoc_STRVAR(doc_cosmo,
|
||||
"additional information and special functions provided by Cosmopolitan Libc.");
|
||||
static PyObject *
|
||||
cosmo_rdtsc(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyLong_FromUnsignedLong(rdtsc());
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(getcpucore_doc,
|
||||
"getcpucore($module)\n\
|
||||
--\n\n\
|
||||
Returns 0-indexed CPU core on which process is currently scheduled.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_getcpucore(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyLong_FromUnsignedLong(TSC_AUX_CORE(rdpid()));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(getcpunode_doc,
|
||||
"getcpunode($module)\n\
|
||||
--\n\n\
|
||||
Returns 0-indexed NUMA node on which process is currently scheduled.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_getcpunode(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
return PyLong_FromUnsignedLong(TSC_AUX_NODE(rdpid()));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(ftrace_doc,
|
||||
"ftrace($module)\n\
|
||||
--\n\n\
|
||||
Enables logging of C function calls to stderr, e.g.\n\
|
||||
\n\
|
||||
cosmo.ftrace()\n\
|
||||
WeirdFunction()\n\
|
||||
os._exit(1)\n\
|
||||
\n\
|
||||
Please be warned this prints massive amount of text. In order for it\n\
|
||||
to work, the concomitant .com.dbg binary needs to be present.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_ftrace(PyObject *self, PyObject *noargs)
|
||||
{
|
||||
ftrace_install();
|
||||
return Py_None;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(crc32c_doc,
|
||||
"crc32c($module, bytes, init=0)\n\
|
||||
--\n\n\
|
||||
Computes 32-bit Castagnoli Cyclic Redundancy Check.\n\
|
||||
\n\
|
||||
Used by ISCSI, TensorFlow, etc.\n\
|
||||
Similar to zlib.crc32().");
|
||||
|
||||
static PyObject *
|
||||
cosmo_crc32c(PyObject *self, PyObject *args)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
Py_buffer data;
|
||||
unsigned crc, init = 0;
|
||||
if (!PyArg_ParseTuple(args, "y*|I:crc32c", &data, &init)) return 0;
|
||||
crc = crc32c(init, data.buf, data.len);
|
||||
PyBuffer_Release(&data);
|
||||
return PyLong_FromUnsignedLong(crc);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(decimate_doc,
|
||||
"decimate($module, bytes)\n\
|
||||
--\n\n\
|
||||
Shrinks byte buffer in half using John Costella's magic kernel.\n\
|
||||
\n\
|
||||
This downscales data 2x using an eight-tap convolution, e.g.\n\
|
||||
\n\
|
||||
>>> cosmo.decimate(b'\\xff\\xff\\x00\\x00\\xff\\xff\\x00\\x00\\xff\\xff\\x00\\x00')\n\
|
||||
b'\\xff\\x00\\xff\\x00\\xff\\x00'\n\
|
||||
\n\
|
||||
This is very fast if SSSE3 is available (Intel 2004+ / AMD 2011+).");
|
||||
|
||||
static PyObject *
|
||||
cosmo_decimate(PyObject *self, PyObject *args)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
PyObject *buf;
|
||||
Py_buffer data;
|
||||
if (!PyArg_ParseTuple(args, "y*:decimate", &data)) return 0;
|
||||
if ((buf = PyBytes_FromStringAndSize(0, (n = ROUNDUP(data.len, 16))))) {
|
||||
memcpy(PyBytes_AS_STRING(buf), data.buf, data.len);
|
||||
memset(PyBytes_AS_STRING(buf) + data.len, 0, n - data.len);
|
||||
cDecimate2xUint8x8(n, (void *)PyBytes_AS_STRING(buf),
|
||||
(signed char[8]){-1, -3, 3, 17, 17, 3, -3, -1});
|
||||
_PyBytes_Resize(&buf, (data.len + 1) >> 1);
|
||||
}
|
||||
PyBuffer_Release(&data);
|
||||
return buf;
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(ild_doc,
|
||||
"ild($module, bytes)\n\
|
||||
--\n\n\
|
||||
Decodes byte-length of first machine instruction in byte sequence.\n\
|
||||
\n\
|
||||
This function makes it possible to tokenize raw x86 binary instructions.\n\
|
||||
Return value is negative on error, where -1 is defined as buffer being\n\
|
||||
too short, and lower numbers represent other errors.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_ild(PyObject *self, PyObject *args)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
const char *p;
|
||||
enum XedError e;
|
||||
struct XedDecodedInst xedd;
|
||||
if (!PyArg_ParseTuple(args, "y#:ild", &p, &n)) return 0;
|
||||
xed_decoded_inst_zero_set_mode(&xedd, XED_MACHINE_MODE_LONG_64);
|
||||
e = xed_instruction_length_decode(&xedd, p, n);
|
||||
return PyLong_FromUnsignedLong(e ? -e : xedd.length);
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(popcount_doc,
|
||||
"popcount($module, bytes)\n\
|
||||
--\n\n\
|
||||
Returns population count of byte sequence, e.g.\n\
|
||||
\n\
|
||||
>>> cosmo.popcount(b'\\xff\\x00\\xff')\n\
|
||||
16\n\
|
||||
\n\
|
||||
The population count is the number of bits that are set to one.\n\
|
||||
It does the same thing as `Long.bit_count()` but for data buffers.\n\
|
||||
This goes 30gbps on Nehalem (Intel 2008+) so it's quite fast.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_popcount(PyObject *self, PyObject *args)
|
||||
{
|
||||
Py_ssize_t n;
|
||||
const char *p;
|
||||
if (!PyArg_ParseTuple(args, "y#:popcount", &p, &n)) return 0;
|
||||
return PyLong_FromSize_t(_countbits(p, n));
|
||||
}
|
||||
|
||||
PyDoc_STRVAR(rgb2xterm256_doc,
|
||||
"rgb2xterm256($module, r, g, b)\n\
|
||||
--\n\n\
|
||||
Quantizes RGB to color to XTERM256 ANSI terminal code.\n\
|
||||
\n\
|
||||
This helps you print colors in the terminal faster. For example:\n\
|
||||
\n\
|
||||
print(\"\\x1b[38;5;%dmhello\\x1b[0m\" % (cosmo.rgb2xterm256(255,0,0)))\n\
|
||||
\n\
|
||||
Will print red text to the terminal.");
|
||||
|
||||
static PyObject *
|
||||
cosmo_rgb2xterm256(PyObject *self, PyObject *args)
|
||||
{
|
||||
unsigned char r, g, b;
|
||||
int res, cerr, gerr, ir, ig, ib, gray, grai, cr, cg, cb, gv;
|
||||
const unsigned char kXtermCube[6] = {0, 0137, 0207, 0257, 0327, 0377};
|
||||
if (!PyArg_ParseTuple(args, "BBB:rgb2xterm256", &r, &g, &b)) return 0;
|
||||
gray = round(r * .299 + g * .587 + b * .114);
|
||||
grai = gray > 238 ? 23 : (gray - 3) / 10;
|
||||
ir = r < 48 ? 0 : r < 115 ? 1 : (r - 35) / 40;
|
||||
ig = g < 48 ? 0 : g < 115 ? 1 : (g - 35) / 40;
|
||||
ib = b < 48 ? 0 : b < 115 ? 1 : (b - 35) / 40;
|
||||
cr = kXtermCube[ir];
|
||||
cg = kXtermCube[ig];
|
||||
cb = kXtermCube[ib];
|
||||
gv = 8 + 10 * grai;
|
||||
cerr = (cr-r)*(cr-r) + (cg-g)*(cg-g) + (cb-b)*(cb-b);
|
||||
gerr = (gv-r)*(gv-r) + (gv-g)*(gv-g) + (gv-b)*(gv-b);
|
||||
if (cerr <= gerr) {
|
||||
res = 16 + 36 * ir + 6 * ig + ib;
|
||||
} else {
|
||||
res = 232 + grai;
|
||||
}
|
||||
return PyLong_FromUnsignedLong(res);
|
||||
}
|
||||
|
||||
static PyMethodDef cosmo_methods[] = {
|
||||
{NULL, NULL} /* sentinel */
|
||||
{"ild", cosmo_ild, METH_VARARGS, ild_doc},
|
||||
{"rdtsc", cosmo_rdtsc, METH_NOARGS, rdtsc_doc},
|
||||
{"crc32c", cosmo_crc32c, METH_VARARGS, crc32c_doc},
|
||||
{"syscount", cosmo_syscount, METH_NOARGS, syscount_doc},
|
||||
{"popcount", cosmo_popcount, METH_VARARGS, popcount_doc},
|
||||
{"decimate", cosmo_decimate, METH_VARARGS, decimate_doc},
|
||||
{"getcpucore", cosmo_getcpucore, METH_NOARGS, getcpucore_doc},
|
||||
{"getcpunode", cosmo_getcpunode, METH_NOARGS, getcpunode_doc},
|
||||
{"rgb2xterm256", cosmo_rgb2xterm256, METH_VARARGS, rgb2xterm256_doc},
|
||||
#ifdef __PG__
|
||||
{"ftrace", cosmo_ftrace, METH_NOARGS, ftrace_doc},
|
||||
#endif
|
||||
{0},
|
||||
};
|
||||
|
||||
|
||||
static struct PyModuleDef cosmomodule = {
|
||||
PyModuleDef_HEAD_INIT,
|
||||
"_cosmo",
|
||||
doc_cosmo,
|
||||
"cosmo",
|
||||
cosmo_doc,
|
||||
-1,
|
||||
cosmo_methods,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const char *
|
||||
GetKernelName(void) {
|
||||
if (IsLinux()) {
|
||||
return "linux";
|
||||
} else if (IsXnu()) {
|
||||
return "xnu";
|
||||
} else if (IsMetal()) {
|
||||
return "metal";
|
||||
} else if (IsWindows()) {
|
||||
return "nt";
|
||||
} else if (IsFreebsd()) {
|
||||
return "freebsd";
|
||||
} else if (IsOpenbsd()) {
|
||||
return "openbsd";
|
||||
} else if (IsNetbsd()) {
|
||||
return "netbsd";
|
||||
} else {
|
||||
return "wut";
|
||||
}
|
||||
}
|
||||
|
||||
PyMODINIT_FUNC
|
||||
PyInit_cosmo(void)
|
||||
{
|
||||
PyObject *m, *d;
|
||||
|
||||
m = PyModule_Create(&cosmomodule);
|
||||
if (m == NULL)
|
||||
goto failure;
|
||||
|
||||
if(cosmo_constants(m))
|
||||
goto failure;
|
||||
|
||||
return m;
|
||||
failure:
|
||||
Py_XDECREF(m);
|
||||
return NULL;
|
||||
PyObject *m;
|
||||
if (!(m = PyModule_Create(&cosmomodule))) return 0;
|
||||
PyModule_AddStringConstant(m, "MODE", MODE);
|
||||
PyModule_AddIntConstant(m, "IMAGE_BASE_VIRTUAL", IMAGE_BASE_VIRTUAL);
|
||||
PyModule_AddStringConstant(m, "kernel", GetKernelName());
|
||||
PyModule_AddIntConstant(m, "kStartTsc", kStartTsc);
|
||||
return !PyErr_Occurred() ? m : 0;
|
||||
}
|
||||
|
||||
_Section(".rodata.pytab.1") const struct _inittab _PyImport_Inittab_cosmo = {
|
||||
"cosmo",
|
||||
PyInit_cosmo,
|
||||
};
|
||||
|
|
65
third_party/python/Python/dtoa.c
vendored
65
third_party/python/Python/dtoa.c
vendored
|
@ -528,7 +528,33 @@ s2b(const char *s, int nd0, int nd, ULong y9)
|
|||
static inline int
|
||||
hi0bits(ULong x)
|
||||
{
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
return x ? __builtin_clz(x) : 32;
|
||||
#else
|
||||
int k = 0;
|
||||
if (!(x & 0xffff0000)) {
|
||||
k = 16;
|
||||
x <<= 16;
|
||||
}
|
||||
if (!(x & 0xff000000)) {
|
||||
k += 8;
|
||||
x <<= 8;
|
||||
}
|
||||
if (!(x & 0xf0000000)) {
|
||||
k += 4;
|
||||
x <<= 4;
|
||||
}
|
||||
if (!(x & 0xc0000000)) {
|
||||
k += 2;
|
||||
x <<= 2;
|
||||
}
|
||||
if (!(x & 0x80000000)) {
|
||||
k++;
|
||||
if (!(x & 0x40000000))
|
||||
return 32;
|
||||
}
|
||||
return k;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* count trailing 0 bits in the 32-bit integer y, and shift y right by that
|
||||
|
@ -538,6 +564,7 @@ static inline int
|
|||
lo0bits(ULong *y)
|
||||
{
|
||||
int k;
|
||||
#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
|
||||
if (*y) {
|
||||
k = __builtin_ctz(*y);
|
||||
*y >>= k;
|
||||
|
@ -545,6 +572,44 @@ lo0bits(ULong *y)
|
|||
} else {
|
||||
return 32;
|
||||
}
|
||||
#else
|
||||
ULong x = *y;
|
||||
if (x & 7) {
|
||||
if (x & 1)
|
||||
return 0;
|
||||
if (x & 2) {
|
||||
*y = x >> 1;
|
||||
return 1;
|
||||
}
|
||||
*y = x >> 2;
|
||||
return 2;
|
||||
}
|
||||
k = 0;
|
||||
if (!(x & 0xffff)) {
|
||||
k = 16;
|
||||
x >>= 16;
|
||||
}
|
||||
if (!(x & 0xff)) {
|
||||
k += 8;
|
||||
x >>= 8;
|
||||
}
|
||||
if (!(x & 0xf)) {
|
||||
k += 4;
|
||||
x >>= 4;
|
||||
}
|
||||
if (!(x & 0x3)) {
|
||||
k += 2;
|
||||
x >>= 2;
|
||||
}
|
||||
if (!(x & 1)) {
|
||||
k++;
|
||||
x >>= 1;
|
||||
if (!x)
|
||||
return 32;
|
||||
}
|
||||
*y = x;
|
||||
return k;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* convert a small nonnegative integer to a Bigint */
|
||||
|
|
2
third_party/python/Python/dynload_dl.c
vendored
2
third_party/python/Python/dynload_dl.c
vendored
|
@ -14,13 +14,11 @@ extern char *Py_GetProgramName(void);
|
|||
|
||||
const char *_PyImport_DynLoadFiletab[] = {".o", NULL};
|
||||
|
||||
|
||||
dl_funcptr _PyImport_FindSharedFuncptr(const char *prefix,
|
||||
const char *shortname,
|
||||
const char *pathname, FILE *fp)
|
||||
{
|
||||
char funcname[258];
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname), "%.20s_%.200s", prefix, shortname);
|
||||
return dl_loadmod(Py_GetProgramName(), pathname, funcname);
|
||||
}
|
||||
|
|
6
third_party/python/Python/dynload_shlib.c
vendored
6
third_party/python/Python/dynload_shlib.c
vendored
|
@ -54,16 +54,13 @@ _PyImport_FindSharedFuncptr(const char *prefix,
|
|||
char funcname[258];
|
||||
char pathbuf[260];
|
||||
int dlopenflags=0;
|
||||
|
||||
if (strchr(pathname, '/') == NULL) {
|
||||
/* Prefix bare filename with "./" */
|
||||
PyOS_snprintf(pathbuf, sizeof(pathbuf), "./%-.255s", pathname);
|
||||
pathname = pathbuf;
|
||||
}
|
||||
|
||||
PyOS_snprintf(funcname, sizeof(funcname),
|
||||
LEAD_UNDERSCORE "%.20s_%.200s", prefix, shortname);
|
||||
|
||||
if (fp != NULL) {
|
||||
int i;
|
||||
struct _Py_stat_struct status;
|
||||
|
@ -82,11 +79,8 @@ _PyImport_FindSharedFuncptr(const char *prefix,
|
|||
handles[nhandles].ino = status.st_ino;
|
||||
}
|
||||
}
|
||||
|
||||
dlopenflags = PyThreadState_GET()->interp->dlopenflags;
|
||||
|
||||
handle = dlopen(pathname, dlopenflags);
|
||||
|
||||
if (handle == NULL) {
|
||||
PyObject *mod_name;
|
||||
PyObject *path;
|
||||
|
|
2
third_party/python/Python/dynload_win.c
vendored
2
third_party/python/Python/dynload_win.c
vendored
|
@ -92,7 +92,7 @@ static char *GetPythonImport (HINSTANCE hModule)
|
|||
pe_offset = DWORD_AT(dllbase + 0x3C);
|
||||
|
||||
/* The PE signature must be "PE\0\0" */
|
||||
if (memcmp(dllbase+pe_offset,"PE\0\0",4)) {
|
||||
if (bcmp(dllbase+pe_offset,"PE\0\0",4)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
101
third_party/python/Python/errors.c
vendored
101
third_party/python/Python/errors.c
vendored
|
@ -5,6 +5,12 @@
|
|||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/errno.h"
|
||||
#include "libc/nt/enum/formatmessageflags.h"
|
||||
#include "libc/nt/enum/lang.h"
|
||||
#include "libc/nt/memory.h"
|
||||
#include "libc/nt/process.h"
|
||||
#include "libc/nt/runtime.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/dictobject.h"
|
||||
#include "third_party/python/Include/fileobject.h"
|
||||
|
@ -17,6 +23,7 @@
|
|||
#include "third_party/python/Include/sysmodule.h"
|
||||
#include "third_party/python/Include/traceback.h"
|
||||
#include "third_party/python/Include/tupleobject.h"
|
||||
#include "third_party/python/Include/unicodeobject.h"
|
||||
/* clang-format off */
|
||||
|
||||
_Py_IDENTIFIER(builtins);
|
||||
|
@ -27,24 +34,20 @@ PyErr_Restore(PyObject *type, PyObject *value, PyObject *traceback)
|
|||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
PyObject *oldtype, *oldvalue, *oldtraceback;
|
||||
|
||||
if (traceback != NULL && !PyTraceBack_Check(traceback)) {
|
||||
/* XXX Should never happen -- fatal error instead? */
|
||||
/* Well, it could be None. */
|
||||
Py_DECREF(traceback);
|
||||
traceback = NULL;
|
||||
}
|
||||
|
||||
/* Save these in locals to safeguard against recursive
|
||||
invocation through Py_XDECREF */
|
||||
oldtype = tstate->curexc_type;
|
||||
oldvalue = tstate->curexc_value;
|
||||
oldtraceback = tstate->curexc_traceback;
|
||||
|
||||
tstate->curexc_type = type;
|
||||
tstate->curexc_value = value;
|
||||
tstate->curexc_traceback = traceback;
|
||||
|
||||
Py_XDECREF(oldtype);
|
||||
Py_XDECREF(oldvalue);
|
||||
Py_XDECREF(oldtraceback);
|
||||
|
@ -70,7 +73,6 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
|
|||
PyThreadState *tstate = PyThreadState_GET();
|
||||
PyObject *exc_value;
|
||||
PyObject *tb = NULL;
|
||||
|
||||
if (exception != NULL &&
|
||||
!PyExceptionClass_Check(exception)) {
|
||||
PyErr_Format(PyExc_SystemError,
|
||||
|
@ -78,7 +80,6 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
|
|||
exception);
|
||||
return;
|
||||
}
|
||||
|
||||
Py_XINCREF(value);
|
||||
exc_value = tstate->exc_value;
|
||||
if (exc_value != NULL && exc_value != Py_None) {
|
||||
|
@ -87,21 +88,17 @@ PyErr_SetObject(PyObject *exception, PyObject *value)
|
|||
if (value == NULL || !PyExceptionInstance_Check(value)) {
|
||||
/* We must normalize the value right now */
|
||||
PyObject *fixed_value;
|
||||
|
||||
/* Issue #23571: functions must not be called with an
|
||||
exception set */
|
||||
PyErr_Clear();
|
||||
|
||||
fixed_value = _PyErr_CreateException(exception, value);
|
||||
Py_XDECREF(value);
|
||||
if (fixed_value == NULL) {
|
||||
Py_DECREF(exc_value);
|
||||
return;
|
||||
}
|
||||
|
||||
value = fixed_value;
|
||||
}
|
||||
|
||||
/* Avoid reference cycles through the context chain.
|
||||
This is O(chain length) but context chains are
|
||||
usually very short. Sensitive readers may try
|
||||
|
@ -156,7 +153,6 @@ PyErr_SetString(PyObject *exception, const char *string)
|
|||
Py_XDECREF(value);
|
||||
}
|
||||
|
||||
|
||||
PyObject *
|
||||
PyErr_Occurred(void)
|
||||
{
|
||||
|
@ -164,7 +160,6 @@ PyErr_Occurred(void)
|
|||
return tstate == NULL ? NULL : tstate->curexc_type;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
|
||||
{
|
||||
|
@ -188,7 +183,6 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
|
|||
/* err might be an instance, so check its class. */
|
||||
if (PyExceptionInstance_Check(err))
|
||||
err = PyExceptionInstance_Class(err);
|
||||
|
||||
if (PyExceptionClass_Check(err) && PyExceptionClass_Check(exc)) {
|
||||
int res = 0;
|
||||
PyObject *exception, *value, *tb;
|
||||
|
@ -204,18 +198,15 @@ PyErr_GivenExceptionMatches(PyObject *err, PyObject *exc)
|
|||
PyErr_Restore(exception, value, tb);
|
||||
return res;
|
||||
}
|
||||
|
||||
return err == exc;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyErr_ExceptionMatches(PyObject *exc)
|
||||
{
|
||||
return PyErr_GivenExceptionMatches(PyErr_Occurred(), exc);
|
||||
}
|
||||
|
||||
|
||||
#ifndef Py_NORMALIZE_RECURSION_LIMIT
|
||||
#define Py_NORMALIZE_RECURSION_LIMIT 32
|
||||
#endif
|
||||
|
@ -234,12 +225,10 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
|
|||
PyObject *value = *val;
|
||||
PyObject *inclass = NULL;
|
||||
PyObject *initial_tb = NULL;
|
||||
|
||||
if (type == NULL) {
|
||||
/* There was no exception, so nothing to do. */
|
||||
return;
|
||||
}
|
||||
|
||||
/* If PyErr_SetNone() was used, the value will have been actually
|
||||
set to NULL.
|
||||
*/
|
||||
|
@ -247,10 +236,8 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
|
|||
value = Py_None;
|
||||
Py_INCREF(value);
|
||||
}
|
||||
|
||||
if (PyExceptionInstance_Check(value))
|
||||
inclass = PyExceptionInstance_Class(value);
|
||||
|
||||
/* Normalize the exception so that if the type is a class, the
|
||||
value will be an instance.
|
||||
*/
|
||||
|
@ -263,7 +250,6 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
|
|||
}
|
||||
else
|
||||
is_subclass = 0;
|
||||
|
||||
/* if the value was not an instance, or is not an instance
|
||||
whose class is (or is derived from) type, then use the
|
||||
value as an argument to instantiation of the type
|
||||
|
@ -271,12 +257,10 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
|
|||
*/
|
||||
if (!inclass || !is_subclass) {
|
||||
PyObject *fixed_value;
|
||||
|
||||
fixed_value = _PyErr_CreateException(type, value);
|
||||
if (fixed_value == NULL) {
|
||||
goto finally;
|
||||
}
|
||||
|
||||
Py_DECREF(value);
|
||||
value = fixed_value;
|
||||
}
|
||||
|
@ -338,11 +322,9 @@ void
|
|||
PyErr_Fetch(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
|
||||
*p_type = tstate->curexc_type;
|
||||
*p_value = tstate->curexc_value;
|
||||
*p_traceback = tstate->curexc_traceback;
|
||||
|
||||
tstate->curexc_type = NULL;
|
||||
tstate->curexc_value = NULL;
|
||||
tstate->curexc_traceback = NULL;
|
||||
|
@ -358,11 +340,9 @@ void
|
|||
PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
|
||||
{
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
|
||||
*p_type = tstate->exc_type;
|
||||
*p_value = tstate->exc_value;
|
||||
*p_traceback = tstate->exc_traceback;
|
||||
|
||||
Py_XINCREF(*p_type);
|
||||
Py_XINCREF(*p_value);
|
||||
Py_XINCREF(*p_traceback);
|
||||
|
@ -373,15 +353,12 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
|
|||
{
|
||||
PyObject *oldtype, *oldvalue, *oldtraceback;
|
||||
PyThreadState *tstate = PyThreadState_GET();
|
||||
|
||||
oldtype = tstate->exc_type;
|
||||
oldvalue = tstate->exc_value;
|
||||
oldtraceback = tstate->exc_traceback;
|
||||
|
||||
tstate->exc_type = p_type;
|
||||
tstate->exc_value = p_value;
|
||||
tstate->exc_traceback = p_traceback;
|
||||
|
||||
Py_XDECREF(oldtype);
|
||||
Py_XDECREF(oldvalue);
|
||||
Py_XDECREF(oldtraceback);
|
||||
|
@ -395,7 +372,6 @@ _PyErr_ChainExceptions(PyObject *exc, PyObject *val, PyObject *tb)
|
|||
{
|
||||
if (exc == NULL)
|
||||
return;
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
PyObject *exc2, *val2, *tb2;
|
||||
PyErr_Fetch(&exc2, &val2, &tb2);
|
||||
|
@ -418,7 +394,6 @@ static PyObject *
|
|||
_PyErr_FormatVFromCause(PyObject *exception, const char *format, va_list vargs)
|
||||
{
|
||||
PyObject *exc, *val, *val2, *tb;
|
||||
|
||||
assert(PyErr_Occurred());
|
||||
PyErr_Fetch(&exc, &val, &tb);
|
||||
PyErr_NormalizeException(&exc, &val, &tb);
|
||||
|
@ -428,16 +403,13 @@ _PyErr_FormatVFromCause(PyObject *exception, const char *format, va_list vargs)
|
|||
}
|
||||
Py_DECREF(exc);
|
||||
assert(!PyErr_Occurred());
|
||||
|
||||
PyErr_FormatV(exception, format, vargs);
|
||||
|
||||
PyErr_Fetch(&exc, &val2, &tb);
|
||||
PyErr_NormalizeException(&exc, &val2, &tb);
|
||||
Py_INCREF(val);
|
||||
PyException_SetCause(val2, val);
|
||||
PyException_SetContext(val2, val);
|
||||
PyErr_Restore(exc, val2, tb);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -493,12 +465,10 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P
|
|||
#ifdef MS_WINDOWS
|
||||
WCHAR *s_buf = NULL;
|
||||
#endif /* Unix/Windows */
|
||||
|
||||
#ifdef EINTR
|
||||
if (i == EINTR && PyErr_CheckSignals())
|
||||
return NULL;
|
||||
#endif
|
||||
|
||||
#ifndef MS_WINDOWS
|
||||
if (i != 0) {
|
||||
char *s = strerror(i);
|
||||
|
@ -548,7 +518,6 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P
|
|||
}
|
||||
}
|
||||
#endif /* Unix/Windows */
|
||||
|
||||
if (message == NULL)
|
||||
{
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -556,7 +525,6 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P
|
|||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filenameObject != NULL) {
|
||||
if (filenameObject2 != NULL)
|
||||
args = Py_BuildValue("(iOOiO)", i, message, filenameObject, 0, filenameObject2);
|
||||
|
@ -567,7 +535,6 @@ PyErr_SetFromErrnoWithFilenameObjects(PyObject *exc, PyObject *filenameObject, P
|
|||
args = Py_BuildValue("(iO)", i, message);
|
||||
}
|
||||
Py_DECREF(message);
|
||||
|
||||
if (args != NULL) {
|
||||
v = PyObject_Call(exc, args, NULL);
|
||||
Py_DECREF(args);
|
||||
|
@ -591,7 +558,6 @@ PyErr_SetFromErrnoWithFilename(PyObject *exc, const char *filename)
|
|||
return result;
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
PyObject *
|
||||
PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
|
||||
{
|
||||
|
@ -602,7 +568,6 @@ PyErr_SetFromErrnoWithUnicodeFilename(PyObject *exc, const Py_UNICODE *filename)
|
|||
Py_XDECREF(name);
|
||||
return result;
|
||||
}
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
PyObject *
|
||||
PyErr_SetFromErrno(PyObject *exc)
|
||||
|
@ -610,17 +575,6 @@ PyErr_SetFromErrno(PyObject *exc)
|
|||
return PyErr_SetFromErrnoWithFilenameObjects(exc, NULL, NULL);
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
/* Windows specific error code handling */
|
||||
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||
PyObject *exc,
|
||||
int ierr,
|
||||
PyObject *filenameObject)
|
||||
{
|
||||
return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr,
|
||||
filenameObject, NULL);
|
||||
}
|
||||
|
||||
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
|
||||
PyObject *exc,
|
||||
int ierr,
|
||||
|
@ -628,21 +582,22 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
|
|||
PyObject *filenameObject2)
|
||||
{
|
||||
int len;
|
||||
WCHAR *s_buf = NULL; /* Free via LocalFree */
|
||||
size_t buf32z;
|
||||
wchar_t *buf32;
|
||||
char16_t *s_buf = NULL; /* Free via LocalFree */
|
||||
PyObject *message;
|
||||
PyObject *args, *v;
|
||||
DWORD err = (DWORD)ierr;
|
||||
uint32_t err = (uint32_t)ierr;
|
||||
if (err==0) err = GetLastError();
|
||||
len = FormatMessageW(
|
||||
len = FormatMessage(
|
||||
/* Error API error */
|
||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
kNtFormatMessageAllocateBuffer |
|
||||
kNtFormatMessageFromSystem |
|
||||
kNtFormatMessageIgnoreInserts,
|
||||
NULL, /* no message source */
|
||||
err,
|
||||
MAKELANGID(LANG_NEUTRAL,
|
||||
SUBLANG_DEFAULT), /* Default language */
|
||||
(LPWSTR) &s_buf,
|
||||
MAKELANGID(kNtLangNeutral, kNtSublangDefault),
|
||||
(char16_t *)&s_buf,
|
||||
0, /* size not used */
|
||||
NULL); /* no args */
|
||||
if (len==0) {
|
||||
|
@ -653,15 +608,15 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
|
|||
/* remove trailing cr/lf and dots */
|
||||
while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
|
||||
s_buf[--len] = L'\0';
|
||||
message = PyUnicode_FromWideChar(s_buf, len);
|
||||
buf32 = utf16to32(s_buf, len, &buf32z);
|
||||
message = PyUnicode_FromWideChar(buf32, buf32z);
|
||||
free(buf32);
|
||||
|
||||
}
|
||||
|
||||
if (message == NULL)
|
||||
{
|
||||
if (message == NULL) {
|
||||
LocalFree(s_buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (filenameObject == NULL) {
|
||||
assert(filenameObject2 == NULL);
|
||||
filenameObject = filenameObject2 = Py_None;
|
||||
|
@ -672,7 +627,6 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
|
|||
The POSIX translation will be figured out by the constructor. */
|
||||
args = Py_BuildValue("(iOOiO)", 0, message, filenameObject, err, filenameObject2);
|
||||
Py_DECREF(message);
|
||||
|
||||
if (args != NULL) {
|
||||
v = PyObject_Call(exc, args, NULL);
|
||||
Py_DECREF(args);
|
||||
|
@ -685,6 +639,16 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObjects(
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Windows specific error code handling */
|
||||
PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||
PyObject *exc,
|
||||
int ierr,
|
||||
PyObject *filenameObject)
|
||||
{
|
||||
return PyErr_SetExcFromWindowsErrWithFilenameObjects(exc, ierr,
|
||||
filenameObject, NULL);
|
||||
}
|
||||
|
||||
PyObject *PyErr_SetExcFromWindowsErrWithFilename(
|
||||
PyObject *exc,
|
||||
int ierr,
|
||||
|
@ -751,7 +715,6 @@ PyObject *PyErr_SetFromWindowsErrWithUnicodeFilename(
|
|||
Py_XDECREF(name);
|
||||
return result;
|
||||
}
|
||||
#endif /* MS_WINDOWS */
|
||||
|
||||
PyObject *
|
||||
PyErr_SetImportErrorSubclass(PyObject *exception, PyObject *msg,
|
||||
|
|
5
third_party/python/Python/frozen.c
vendored
5
third_party/python/Python/frozen.c
vendored
|
@ -5,10 +5,11 @@
|
|||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "third_party/python/Include/import.h"
|
||||
#include "third_party/python/Python/importlib.inc"
|
||||
#include "third_party/python/Python/importlib_external.inc"
|
||||
/* clang-format off */
|
||||
|
||||
#include "o//third_party/python/Python/importlib.inc"
|
||||
#include "o//third_party/python/Python/importlib_external.inc"
|
||||
|
||||
/* Dummy frozen modules initializer */
|
||||
|
||||
/* In order to test the support for frozen modules, by default we
|
||||
|
|
16
third_party/python/Python/future.c
vendored
16
third_party/python/Python/future.c
vendored
|
@ -24,9 +24,7 @@ future_check_features(PyFutureFeatures *ff, stmt_ty s, PyObject *filename)
|
|||
{
|
||||
int i;
|
||||
asdl_seq *names;
|
||||
|
||||
assert(s->kind == ImportFrom_kind);
|
||||
|
||||
names = s->v.ImportFrom.names;
|
||||
for (i = 0; i < asdl_seq_LEN(names); i++) {
|
||||
alias_ty name = (alias_ty)asdl_seq_GET(names, i);
|
||||
|
@ -71,13 +69,10 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
|||
{
|
||||
int i, done = 0, prev_line = 0;
|
||||
stmt_ty first;
|
||||
|
||||
if (!(mod->kind == Module_kind || mod->kind == Interactive_kind))
|
||||
return 1;
|
||||
|
||||
if (asdl_seq_LEN(mod->v.Module.body) == 0)
|
||||
return 1;
|
||||
|
||||
/* A subsequent pass will detect future imports that don't
|
||||
appear at the beginning of the file. There's one case,
|
||||
however, that is easier to handle here: A series of imports
|
||||
|
@ -85,7 +80,6 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
|||
statement but some subsequent import has the future form
|
||||
but is preceded by a regular import.
|
||||
*/
|
||||
|
||||
i = 0;
|
||||
first = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||
if (first->kind == Expr_kind
|
||||
|
@ -93,21 +87,16 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
|||
|| (first->v.Expr.value->kind == Constant_kind
|
||||
&& PyUnicode_CheckExact(first->v.Expr.value->v.Constant.value))))
|
||||
i++;
|
||||
|
||||
|
||||
for (; i < asdl_seq_LEN(mod->v.Module.body); i++) {
|
||||
stmt_ty s = (stmt_ty)asdl_seq_GET(mod->v.Module.body, i);
|
||||
|
||||
if (done && s->lineno > prev_line)
|
||||
return 1;
|
||||
prev_line = s->lineno;
|
||||
|
||||
/* The tests below will return from this function unless it is
|
||||
still possible to find a future statement. The only things
|
||||
that can precede a future statement are another future
|
||||
statement and a doc string.
|
||||
*/
|
||||
|
||||
if (s->kind == ImportFrom_kind) {
|
||||
identifier modname = s->v.ImportFrom.module;
|
||||
if (modname &&
|
||||
|
@ -133,12 +122,10 @@ future_parse(PyFutureFeatures *ff, mod_ty mod, PyObject *filename)
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
PyFutureFeatures *
|
||||
PyFuture_FromASTObject(mod_ty mod, PyObject *filename)
|
||||
{
|
||||
PyFutureFeatures *ff;
|
||||
|
||||
ff = (PyFutureFeatures *)PyObject_Malloc(sizeof(PyFutureFeatures));
|
||||
if (ff == NULL) {
|
||||
PyErr_NoMemory();
|
||||
|
@ -146,7 +133,6 @@ PyFuture_FromASTObject(mod_ty mod, PyObject *filename)
|
|||
}
|
||||
ff->ff_features = 0;
|
||||
ff->ff_lineno = -1;
|
||||
|
||||
if (!future_parse(ff, mod, filename)) {
|
||||
PyObject_Free(ff);
|
||||
return NULL;
|
||||
|
@ -154,13 +140,11 @@ PyFuture_FromASTObject(mod_ty mod, PyObject *filename)
|
|||
return ff;
|
||||
}
|
||||
|
||||
|
||||
PyFutureFeatures *
|
||||
PyFuture_FromAST(mod_ty mod, const char *filename_str)
|
||||
{
|
||||
PyFutureFeatures *ff;
|
||||
PyObject *filename;
|
||||
|
||||
filename = PyUnicode_DecodeFSDefault(filename_str);
|
||||
if (filename == NULL)
|
||||
return NULL;
|
||||
|
|
124
third_party/python/Python/getargs.c
vendored
124
third_party/python/Python/getargs.c
vendored
|
@ -20,47 +20,11 @@
|
|||
#include "third_party/python/Include/pymem.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* New getargs implementation */
|
||||
|
||||
int PyArg_Parse(PyObject *, const char *, ...);
|
||||
int PyArg_ParseTuple(PyObject *, const char *, ...);
|
||||
int PyArg_VaParse(PyObject *, const char *, va_list);
|
||||
|
||||
int PyArg_ParseTupleAndKeywords(PyObject *, PyObject *,
|
||||
const char *, char **, ...);
|
||||
int PyArg_VaParseTupleAndKeywords(PyObject *, PyObject *,
|
||||
const char *, char **, va_list);
|
||||
|
||||
int _PyArg_ParseTupleAndKeywordsFast(PyObject *, PyObject *,
|
||||
struct _PyArg_Parser *, ...);
|
||||
int _PyArg_VaParseTupleAndKeywordsFast(PyObject *, PyObject *,
|
||||
struct _PyArg_Parser *, va_list);
|
||||
|
||||
#ifdef HAVE_DECLSPEC_DLL
|
||||
/* Export functions */
|
||||
int _PyArg_Parse_SizeT(PyObject *, const char *, ...);
|
||||
int _PyArg_ParseStack_SizeT(PyObject **, Py_ssize_t , PyObject *,
|
||||
struct _PyArg_Parser *, ...);
|
||||
int _PyArg_ParseTuple_SizeT(PyObject *, const char *, ...);
|
||||
int _PyArg_ParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
|
||||
const char *, char **, ...);
|
||||
PyObject * _Py_BuildValue_SizeT(const char *, ...);
|
||||
int _PyArg_VaParse_SizeT(PyObject *, const char *, va_list);
|
||||
int _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *, PyObject *,
|
||||
const char *, char **, va_list);
|
||||
|
||||
int _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
|
||||
struct _PyArg_Parser *, ...);
|
||||
int _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *, PyObject *,
|
||||
struct _PyArg_Parser *, va_list);
|
||||
#endif
|
||||
|
||||
#define FLAG_COMPAT 1
|
||||
#define FLAG_SIZE_T 2
|
||||
|
||||
typedef int (*destr_t)(PyObject *, void *);
|
||||
|
||||
|
||||
/* Keep track of "objects" that have been allocated or initialized and
|
||||
which will need to be deallocated or cleaned up somehow if overall
|
||||
parsing fails.
|
||||
|
@ -78,7 +42,7 @@ typedef struct {
|
|||
|
||||
#define STATIC_FREELIST_ENTRIES 8
|
||||
|
||||
/* Forward */
|
||||
static const char *skipitem(const char **, va_list *, int);
|
||||
static int vgetargs1(PyObject *, const char *, va_list *, int);
|
||||
static void seterror(Py_ssize_t, const char *, int *, const char *, const char *);
|
||||
static const char *convertitem(PyObject *, const char **, va_list *, int, int *,
|
||||
|
@ -87,25 +51,22 @@ static const char *converttuple(PyObject *, const char **, va_list *, int,
|
|||
int *, char *, size_t, int, freelist_t *);
|
||||
static const char *convertsimple(PyObject *, const char **, va_list *, int,
|
||||
char *, size_t, freelist_t *);
|
||||
static Py_ssize_t convertbuffer(PyObject *, void **p, const char **);
|
||||
static Py_ssize_t convertbuffer(PyObject *, void **, const char **);
|
||||
static int getbuffer(PyObject *, Py_buffer *, const char**);
|
||||
|
||||
static int vgetargskeywords(PyObject *, PyObject *,
|
||||
const char *, char **, va_list *, int);
|
||||
static int vgetargskeywordsfast(PyObject *, PyObject *,
|
||||
struct _PyArg_Parser *, va_list *, int);
|
||||
static int vgetargskeywordsfast_impl(PyObject **args, Py_ssize_t nargs,
|
||||
PyObject *keywords, PyObject *kwnames,
|
||||
struct _PyArg_Parser *parser,
|
||||
va_list *p_va, int flags);
|
||||
static const char *skipitem(const char **, va_list *, int);
|
||||
struct _PyArg_Parser *, va_list *, int);
|
||||
static int vgetargskeywordsfast_impl(PyObject **, Py_ssize_t,
|
||||
PyObject *, PyObject *,
|
||||
struct _PyArg_Parser *,
|
||||
va_list *, int );
|
||||
|
||||
int
|
||||
PyArg_Parse(PyObject *args, const char *format, ...)
|
||||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
retval = vgetargs1(args, format, &va, FLAG_COMPAT);
|
||||
va_end(va);
|
||||
|
@ -117,20 +78,17 @@ _PyArg_Parse_SizeT(PyObject *args, const char *format, ...)
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
retval = vgetargs1(args, format, &va, FLAG_COMPAT|FLAG_SIZE_T);
|
||||
va_end(va);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyArg_ParseTuple(PyObject *args, const char *format, ...)
|
||||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
retval = vgetargs1(args, format, &va, 0);
|
||||
va_end(va);
|
||||
|
@ -142,22 +100,18 @@ _PyArg_ParseTuple_SizeT(PyObject *args, const char *format, ...)
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
retval = vgetargs1(args, format, &va, FLAG_SIZE_T);
|
||||
va_end(va);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyArg_VaParse(PyObject *args, const char *format, va_list va)
|
||||
{
|
||||
va_list lva;
|
||||
int retval;
|
||||
|
||||
va_copy(lva, va);
|
||||
|
||||
retval = vgetargs1(args, format, &lva, 0);
|
||||
va_end(lva);
|
||||
return retval;
|
||||
|
@ -168,17 +122,13 @@ _PyArg_VaParse_SizeT(PyObject *args, const char *format, va_list va)
|
|||
{
|
||||
va_list lva;
|
||||
int retval;
|
||||
|
||||
va_copy(lva, va);
|
||||
|
||||
retval = vgetargs1(args, format, &lva, FLAG_SIZE_T);
|
||||
va_end(lva);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* Handle cleanup of allocated memory in case of exception */
|
||||
|
||||
static int
|
||||
cleanup_ptr(PyObject *self, void *ptr)
|
||||
{
|
||||
|
@ -202,13 +152,10 @@ static int
|
|||
addcleanup(void *ptr, freelist_t *freelist, destr_t destructor)
|
||||
{
|
||||
int index;
|
||||
|
||||
index = freelist->first_available;
|
||||
freelist->first_available += 1;
|
||||
|
||||
freelist->entries[index].item = ptr;
|
||||
freelist->entries[index].destructor = destructor;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -216,7 +163,6 @@ static int
|
|||
cleanreturn(int retval, freelist_t *freelist)
|
||||
{
|
||||
int index;
|
||||
|
||||
if (retval == 0) {
|
||||
/* A failure occurred, therefore execute all of the cleanup
|
||||
functions.
|
||||
|
@ -231,7 +177,6 @@ cleanreturn(int retval, freelist_t *freelist)
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
||||
{
|
||||
|
@ -249,14 +194,11 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
int compat = flags & FLAG_COMPAT;
|
||||
freelistentry_t static_entries[STATIC_FREELIST_ENTRIES];
|
||||
freelist_t freelist;
|
||||
|
||||
freelist.entries = static_entries;
|
||||
freelist.first_available = 0;
|
||||
freelist.entries_malloced = 0;
|
||||
|
||||
assert(compat || (args != (PyObject*)NULL));
|
||||
flags = flags & ~FLAG_COMPAT;
|
||||
|
||||
while (endfmt == 0) {
|
||||
int c = *format++;
|
||||
switch (c) {
|
||||
|
@ -298,15 +240,11 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (level != 0)
|
||||
Py_FatalError(/* '(' */ "missing ')' in getargs format");
|
||||
|
||||
if (min < 0)
|
||||
min = max;
|
||||
|
||||
format = formatsave;
|
||||
|
||||
if (max > STATIC_FREELIST_ENTRIES) {
|
||||
freelist.entries = PyMem_NEW(freelistentry_t, max);
|
||||
if (freelist.entries == NULL) {
|
||||
|
@ -315,7 +253,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
}
|
||||
freelist.entries_malloced = 1;
|
||||
}
|
||||
|
||||
if (compat) {
|
||||
if (max == 0) {
|
||||
if (args == NULL)
|
||||
|
@ -347,15 +284,12 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
return cleanreturn(0, &freelist);
|
||||
}
|
||||
}
|
||||
|
||||
if (!PyTuple_Check(args)) {
|
||||
PyErr_SetString(PyExc_SystemError,
|
||||
"new style getargs format but argument is not a tuple");
|
||||
return cleanreturn(0, &freelist);
|
||||
}
|
||||
|
||||
len = PyTuple_GET_SIZE(args);
|
||||
|
||||
if (len < min || max < len) {
|
||||
if (message == NULL)
|
||||
PyErr_Format(PyExc_TypeError,
|
||||
|
@ -371,7 +305,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
PyErr_SetString(PyExc_TypeError, message);
|
||||
return cleanreturn(0, &freelist);
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (*format == '|')
|
||||
format++;
|
||||
|
@ -383,7 +316,6 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
return cleanreturn(0, &freelist);
|
||||
}
|
||||
}
|
||||
|
||||
if (*format != '\0' && !Py_ISALPHA(*format) &&
|
||||
*format != '(' &&
|
||||
*format != '|' && *format != ':' && *format != ';') {
|
||||
|
@ -391,12 +323,9 @@ vgetargs1(PyObject *args, const char *format, va_list *p_va, int flags)
|
|||
"bad format string: %.200s", formatsave);
|
||||
return cleanreturn(0, &freelist);
|
||||
}
|
||||
|
||||
return cleanreturn(1, &freelist);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
|
||||
const char *message)
|
||||
|
@ -404,7 +333,6 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
|
|||
char buf[512];
|
||||
int i;
|
||||
char *p = buf;
|
||||
|
||||
if (PyErr_Occurred())
|
||||
return;
|
||||
else if (message == NULL) {
|
||||
|
@ -439,7 +367,6 @@ seterror(Py_ssize_t iarg, const char *msg, int *levels, const char *fname,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* Convert a tuple argument.
|
||||
On entry, *p_format points to the character _after_ the opening '('.
|
||||
On successful exit, *p_format points to the closing ')'.
|
||||
|
@ -468,7 +395,6 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
const char *format = *p_format;
|
||||
int i;
|
||||
Py_ssize_t len;
|
||||
|
||||
for (;;) {
|
||||
int c = *format++;
|
||||
if (c == '(') {
|
||||
|
@ -486,7 +412,6 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
else if (level == 0 && Py_ISALPHA(c))
|
||||
n++;
|
||||
}
|
||||
|
||||
if (!PySequence_Check(arg) || PyBytes_Check(arg)) {
|
||||
levels[0] = 0;
|
||||
PyOS_snprintf(msgbuf, bufsize,
|
||||
|
@ -496,7 +421,6 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
arg == Py_None ? "None" : arg->ob_type->tp_name);
|
||||
return msgbuf;
|
||||
}
|
||||
|
||||
len = PySequence_Size(arg);
|
||||
if (len != n) {
|
||||
levels[0] = 0;
|
||||
|
@ -513,7 +437,6 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
}
|
||||
return msgbuf;
|
||||
}
|
||||
|
||||
format = *p_format;
|
||||
for (i = 0; i < n; i++) {
|
||||
const char *msg;
|
||||
|
@ -535,12 +458,10 @@ converttuple(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
*p_format = format;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Convert a single item. */
|
||||
|
||||
static const char *
|
||||
|
@ -549,7 +470,6 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
{
|
||||
const char *msg;
|
||||
const char *format = *p_format;
|
||||
|
||||
if (*format == '(' /* ')' */) {
|
||||
format++;
|
||||
msg = converttuple(arg, &format, p_va, flags, levels, msgbuf,
|
||||
|
@ -568,8 +488,6 @@ convertitem(PyObject *arg, const char **p_format, va_list *p_va, int flags,
|
|||
return msg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Format an error message generated by convertsimple(). */
|
||||
|
||||
static const char *
|
||||
|
@ -1385,7 +1303,6 @@ _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
format == NULL ||
|
||||
|
@ -1394,7 +1311,6 @@ _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(va, kwlist);
|
||||
retval = vgetargskeywords(args, keywords, format,
|
||||
kwlist, &va, FLAG_SIZE_T);
|
||||
|
@ -1402,7 +1318,6 @@ _PyArg_ParseTupleAndKeywords_SizeT(PyObject *args,
|
|||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PyArg_VaParseTupleAndKeywords(PyObject *args,
|
||||
PyObject *keywords,
|
||||
|
@ -1411,7 +1326,6 @@ PyArg_VaParseTupleAndKeywords(PyObject *args,
|
|||
{
|
||||
int retval;
|
||||
va_list lva;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
format == NULL ||
|
||||
|
@ -1420,9 +1334,7 @@ PyArg_VaParseTupleAndKeywords(PyObject *args,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_copy(lva, va);
|
||||
|
||||
retval = vgetargskeywords(args, keywords, format, kwlist, &lva, 0);
|
||||
va_end(lva);
|
||||
return retval;
|
||||
|
@ -1436,7 +1348,6 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
|
|||
{
|
||||
int retval;
|
||||
va_list lva;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
format == NULL ||
|
||||
|
@ -1445,9 +1356,7 @@ _PyArg_VaParseTupleAndKeywords_SizeT(PyObject *args,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_copy(lva, va);
|
||||
|
||||
retval = vgetargskeywords(args, keywords, format,
|
||||
kwlist, &lva, FLAG_SIZE_T);
|
||||
va_end(lva);
|
||||
|
@ -1460,7 +1369,6 @@ _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
parser == NULL)
|
||||
|
@ -1468,7 +1376,6 @@ _PyArg_ParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(va, parser);
|
||||
retval = vgetargskeywordsfast(args, keywords, parser, &va, 0);
|
||||
va_end(va);
|
||||
|
@ -1481,7 +1388,6 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
parser == NULL)
|
||||
|
@ -1489,7 +1395,6 @@ _PyArg_ParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(va, parser);
|
||||
retval = vgetargskeywordsfast(args, keywords, parser, &va, FLAG_SIZE_T);
|
||||
va_end(va);
|
||||
|
@ -1502,14 +1407,12 @@ _PyArg_ParseStack(PyObject **args, Py_ssize_t nargs, PyObject *kwnames,
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
if ((kwnames != NULL && !PyTuple_Check(kwnames)) ||
|
||||
parser == NULL)
|
||||
{
|
||||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(va, parser);
|
||||
retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, 0);
|
||||
va_end(va);
|
||||
|
@ -1522,28 +1425,24 @@ _PyArg_ParseStack_SizeT(PyObject **args, Py_ssize_t nargs, PyObject *kwnames,
|
|||
{
|
||||
int retval;
|
||||
va_list va;
|
||||
|
||||
if ((kwnames != NULL && !PyTuple_Check(kwnames)) ||
|
||||
parser == NULL)
|
||||
{
|
||||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_start(va, parser);
|
||||
retval = vgetargskeywordsfast_impl(args, nargs, NULL, kwnames, parser, &va, FLAG_SIZE_T);
|
||||
va_end(va);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
|
||||
struct _PyArg_Parser *parser, va_list va)
|
||||
{
|
||||
int retval;
|
||||
va_list lva;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
parser == NULL)
|
||||
|
@ -1551,9 +1450,7 @@ _PyArg_VaParseTupleAndKeywordsFast(PyObject *args, PyObject *keywords,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_copy(lva, va);
|
||||
|
||||
retval = vgetargskeywordsfast(args, keywords, parser, &lva, 0);
|
||||
va_end(lva);
|
||||
return retval;
|
||||
|
@ -1565,7 +1462,6 @@ _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
|
|||
{
|
||||
int retval;
|
||||
va_list lva;
|
||||
|
||||
if ((args == NULL || !PyTuple_Check(args)) ||
|
||||
(keywords != NULL && !PyDict_Check(keywords)) ||
|
||||
parser == NULL)
|
||||
|
@ -1573,9 +1469,7 @@ _PyArg_VaParseTupleAndKeywordsFast_SizeT(PyObject *args, PyObject *keywords,
|
|||
PyErr_BadInternalCall();
|
||||
return 0;
|
||||
}
|
||||
|
||||
va_copy(lva, va);
|
||||
|
||||
retval = vgetargskeywordsfast(args, keywords, parser, &lva, FLAG_SIZE_T);
|
||||
va_end(lva);
|
||||
return retval;
|
||||
|
@ -2416,7 +2310,6 @@ PyArg_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t m
|
|||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* For type constructors that don't take keyword args
|
||||
*
|
||||
* Sets a TypeError and returns 0 if the args/kwargs is
|
||||
|
@ -2433,13 +2326,11 @@ _PyArg_NoKeywords(const char *funcname, PyObject *kw)
|
|||
}
|
||||
if (PyDict_Size(kw) == 0)
|
||||
return 1;
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "%s does not take keyword arguments",
|
||||
funcname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
_PyArg_NoPositional(const char *funcname, PyObject *args)
|
||||
{
|
||||
|
@ -2451,7 +2342,6 @@ _PyArg_NoPositional(const char *funcname, PyObject *args)
|
|||
}
|
||||
if (PyTuple_GET_SIZE(args) == 0)
|
||||
return 1;
|
||||
|
||||
PyErr_Format(PyExc_TypeError, "%s does not take positional arguments",
|
||||
funcname);
|
||||
return 0;
|
||||
|
|
18
third_party/python/Python/getcompiler.c
vendored
18
third_party/python/Python/getcompiler.c
vendored
|
@ -7,24 +7,16 @@
|
|||
#include "third_party/python/Include/pylifecycle.h"
|
||||
/* clang-format off */
|
||||
|
||||
/* Return the compiler identification, if possible. */
|
||||
|
||||
#ifndef COMPILER
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define COMPILER "\n[GCC " __VERSION__ "]"
|
||||
#endif
|
||||
|
||||
#endif /* !COMPILER */
|
||||
|
||||
#ifndef COMPILER
|
||||
|
||||
#ifdef __cplusplus
|
||||
#ifdef __llvm__
|
||||
#define COMPILER "[LLVM " __VERSION__ "]"
|
||||
#elif defined(__GNUC__)
|
||||
#define COMPILER "[GCC " __VERSION__ "]"
|
||||
#elif defined(__cplusplus)
|
||||
#define COMPILER "[C++]"
|
||||
#else
|
||||
#define COMPILER "[C]"
|
||||
#endif
|
||||
|
||||
#endif /* !COMPILER */
|
||||
|
||||
const char *
|
||||
|
|
20
third_party/python/Python/getopt.c
vendored
20
third_party/python/Python/getopt.c
vendored
|
@ -9,6 +9,11 @@
|
|||
#include "third_party/python/Include/pygetopt.h"
|
||||
/* clang-format off */
|
||||
|
||||
asm(".ident\t\"\\n\\n\
|
||||
python getopt (isc license)\\n\
|
||||
Copyright 1992-1994 David Gottner\"");
|
||||
/* clang-format off */
|
||||
|
||||
/*---------------------------------------------------------------------------*
|
||||
* <RCS keywords>
|
||||
*
|
||||
|
@ -56,9 +61,7 @@ int _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring)
|
|||
{
|
||||
wchar_t *ptr;
|
||||
wchar_t option;
|
||||
|
||||
if (*opt_ptr == '\0') {
|
||||
|
||||
if (_PyOS_optind >= argc)
|
||||
return -1;
|
||||
#ifdef MS_WINDOWS
|
||||
|
@ -67,51 +70,40 @@ int _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring)
|
|||
return 'h';
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (argv[_PyOS_optind][0] != L'-' ||
|
||||
argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
|
||||
return -1;
|
||||
|
||||
else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
|
||||
++_PyOS_optind;
|
||||
return -1;
|
||||
}
|
||||
|
||||
else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'h';
|
||||
}
|
||||
|
||||
else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
|
||||
++_PyOS_optind;
|
||||
return 'V';
|
||||
}
|
||||
|
||||
|
||||
opt_ptr = &argv[_PyOS_optind++][1];
|
||||
}
|
||||
|
||||
if ((option = *opt_ptr++) == L'\0')
|
||||
return -1;
|
||||
|
||||
if (option == 'J') {
|
||||
if (_PyOS_opterr)
|
||||
fprintf(stderr, "-J is reserved for Jython\n");
|
||||
return '_';
|
||||
}
|
||||
|
||||
if ((ptr = wcschr(optstring, option)) == NULL) {
|
||||
if (_PyOS_opterr)
|
||||
fprintf(stderr, "Unknown option: -%c\n", (char)option);
|
||||
return '_';
|
||||
}
|
||||
|
||||
if (*(ptr + 1) == L':') {
|
||||
if (*opt_ptr != L'\0') {
|
||||
_PyOS_optarg = opt_ptr;
|
||||
opt_ptr = L"";
|
||||
}
|
||||
|
||||
else {
|
||||
if (_PyOS_optind >= argc) {
|
||||
if (_PyOS_opterr)
|
||||
|
@ -119,10 +111,8 @@ int _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring)
|
|||
"Argument expected for the -%c option\n", (char)option);
|
||||
return '_';
|
||||
}
|
||||
|
||||
_PyOS_optarg = argv[_PyOS_optind++];
|
||||
}
|
||||
}
|
||||
|
||||
return option;
|
||||
}
|
||||
|
|
6
third_party/python/Python/getplatform.c
vendored
6
third_party/python/Python/getplatform.c
vendored
|
@ -6,12 +6,8 @@
|
|||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
/* clang-format off */
|
||||
|
||||
#ifndef PLATFORM
|
||||
#define PLATFORM "unknown"
|
||||
#endif
|
||||
|
||||
const char *
|
||||
Py_GetPlatform(void)
|
||||
{
|
||||
return PLATFORM;
|
||||
return "cosmo";
|
||||
}
|
||||
|
|
7
third_party/python/Python/import.c
vendored
7
third_party/python/Python/import.c
vendored
|
@ -963,10 +963,8 @@ static PyObject *
|
|||
_imp__fix_co_filename_impl(PyObject *module, PyCodeObject *code,
|
||||
PyObject *path)
|
||||
/*[clinic end generated code: output=1d002f100235587d input=895ba50e78b82f05]*/
|
||||
|
||||
{
|
||||
update_compiled_module(code, path);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
}
|
||||
|
||||
|
@ -2169,11 +2167,8 @@ int
|
|||
PyImport_AppendInittab(const char *name, PyObject* (*initfunc)(void))
|
||||
{
|
||||
struct _inittab newtab[2];
|
||||
|
||||
memset(newtab, '\0', sizeof newtab);
|
||||
|
||||
bzero(newtab, sizeof newtab);
|
||||
newtab[0].name = name;
|
||||
newtab[0].initfunc = initfunc;
|
||||
|
||||
return PyImport_ExtendInittab(newtab);
|
||||
}
|
||||
|
|
1836
third_party/python/Python/importlib.inc
vendored
1836
third_party/python/Python/importlib.inc
vendored
File diff suppressed because it is too large
Load diff
2447
third_party/python/Python/importlib_external.inc
vendored
2447
third_party/python/Python/importlib_external.inc
vendored
File diff suppressed because it is too large
Load diff
12
third_party/python/Python/initimport.c
vendored
12
third_party/python/Python/initimport.c
vendored
|
@ -70,18 +70,6 @@ _Py_InitImport(PyInterpreterState *interp, PyObject *sysmod)
|
|||
Py_FatalError("Py_Initialize: can't save _imp to sys.modules");
|
||||
}
|
||||
|
||||
/* Import the _cosmo module */
|
||||
cosmomod = PyInit_cosmo();
|
||||
if (impmod == NULL) {
|
||||
Py_FatalError("Py_Initialize: can't import _cosmo");
|
||||
}
|
||||
else if (Py_VerboseFlag) {
|
||||
PySys_FormatStderr("import _cosmo # for bonus Cosmopolitan Libc features\n");
|
||||
}
|
||||
if (PyDict_SetItemString(sys_modules, "_cosmo", cosmomod) < 0) {
|
||||
Py_FatalError("Py_Initialize: can't save _cosmo to sys.modules");
|
||||
}
|
||||
|
||||
/* Install importlib as the implementation of import */
|
||||
value = PyObject_CallMethod(importlib, "_install", "OO", sysmod, impmod);
|
||||
if (value == NULL) {
|
||||
|
|
2
third_party/python/Python/initstdio.c
vendored
2
third_party/python/Python/initstdio.c
vendored
|
@ -45,7 +45,7 @@ is_valid_fd(int fd)
|
|||
fstat(1, &st) fails with EBADF. Prefer fstat() over dup() to detect
|
||||
such error. */
|
||||
struct stat st;
|
||||
return (fstat(fd, &st) == 0);
|
||||
return fstat(fd, &st) == 0;
|
||||
}
|
||||
int fd2;
|
||||
if (fd < 0)
|
||||
|
|
1
third_party/python/Python/mysnprintf.c
vendored
1
third_party/python/Python/mysnprintf.c
vendored
|
@ -51,7 +51,6 @@ PyOS_snprintf(char *str, size_t size, const char *format, ...)
|
|||
{
|
||||
int rc;
|
||||
va_list va;
|
||||
|
||||
va_start(va, format);
|
||||
rc = PyOS_vsnprintf(str, size, format, va);
|
||||
va_end(va);
|
||||
|
|
1
third_party/python/Python/peephole.c
vendored
1
third_party/python/Python/peephole.c
vendored
|
@ -328,7 +328,6 @@ safe_power(PyObject *v, PyObject *w)
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return PyNumber_Power(v, w, Py_None);
|
||||
}
|
||||
|
||||
|
|
20
third_party/python/Python/pystate.c
vendored
20
third_party/python/Python/pystate.c
vendored
|
@ -17,6 +17,10 @@
|
|||
#include "third_party/python/Include/pystate.h"
|
||||
/* clang-format off */
|
||||
|
||||
#if defined(__FSANITIZE_ADDRESS__) || defined(__FSANITIZE_UNDEFINED__)
|
||||
STATIC_YOINK("__die"); /* to guarantee backtraces */
|
||||
#endif
|
||||
|
||||
/* Thread and interpreter state structures and their interfaces */
|
||||
|
||||
#define ZERO(x) x = (typeof(x))pushpop(0L)
|
||||
|
@ -209,13 +213,10 @@ static PyThreadState *
|
|||
new_threadstate(PyInterpreterState *interp, int init)
|
||||
{
|
||||
PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState));
|
||||
|
||||
if (_PyThreadState_GetFrame == 0)
|
||||
_PyThreadState_GetFrame = threadstate_getframe;
|
||||
|
||||
if (tstate != 0) {
|
||||
tstate->interp = interp;
|
||||
|
||||
ZERO(tstate->frame);
|
||||
ZERO(tstate->recursion_depth);
|
||||
ZERO(tstate->overflowed);
|
||||
|
@ -229,46 +230,35 @@ new_threadstate(PyInterpreterState *interp, int init)
|
|||
#else
|
||||
ZERO(tstate->thread_id);
|
||||
#endif
|
||||
|
||||
ZERO(tstate->dict);
|
||||
|
||||
ZERO(tstate->curexc_type);
|
||||
ZERO(tstate->curexc_value);
|
||||
ZERO(tstate->curexc_traceback);
|
||||
|
||||
ZERO(tstate->exc_type);
|
||||
ZERO(tstate->exc_value);
|
||||
ZERO(tstate->exc_traceback);
|
||||
|
||||
ZERO(tstate->c_profilefunc);
|
||||
ZERO(tstate->c_tracefunc);
|
||||
ZERO(tstate->c_profileobj);
|
||||
ZERO(tstate->c_traceobj);
|
||||
|
||||
ZERO(tstate->trash_delete_nesting);
|
||||
ZERO(tstate->trash_delete_later);
|
||||
ZERO(tstate->on_delete);
|
||||
ZERO(tstate->on_delete_data);
|
||||
|
||||
ZERO(tstate->coroutine_wrapper);
|
||||
ZERO(tstate->in_coroutine_wrapper);
|
||||
|
||||
ZERO(tstate->async_gen_firstiter);
|
||||
ZERO(tstate->async_gen_finalizer);
|
||||
|
||||
if (init)
|
||||
_PyThreadState_Init(tstate);
|
||||
|
||||
HEAD_LOCK();
|
||||
ZERO(tstate->prev);
|
||||
|
||||
tstate->next = interp->tstate_head;
|
||||
if (tstate->next)
|
||||
tstate->next->prev = tstate;
|
||||
interp->tstate_head = tstate;
|
||||
HEAD_UNLOCK();
|
||||
}
|
||||
|
||||
return tstate;
|
||||
}
|
||||
|
||||
|
@ -535,7 +525,7 @@ _PyThreadState_DeleteExcept(PyThreadState *tstate)
|
|||
|
||||
|
||||
PyThreadState *
|
||||
_PyThreadState_UncheckedGet(void)
|
||||
(_PyThreadState_UncheckedGet)(void)
|
||||
{
|
||||
return GET_TSTATE();
|
||||
}
|
||||
|
|
1
third_party/python/Python/pythonrun.c
vendored
1
third_party/python/Python/pythonrun.c
vendored
|
@ -407,6 +407,7 @@ PyRun_SimpleFileExFlags(FILE *fp, const char *filename, int closeit,
|
|||
fclose(pyc_fp);
|
||||
goto done;
|
||||
}
|
||||
|
||||
v = run_pyc_file(pyc_fp, filename, d, d, flags);
|
||||
} else {
|
||||
/* When running from stdin, leave __main__.__loader__ alone */
|
||||
|
|
52
third_party/python/Python/random.c
vendored
52
third_party/python/Python/random.c
vendored
|
@ -4,11 +4,18 @@
|
|||
│ Python 3 │
|
||||
│ https://docs.python.org/3/license.html │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/assert.h"
|
||||
#include "libc/bits/bits.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/weirdtypes.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/macros.internal.h"
|
||||
#include "libc/nexgen32e/rdtsc.h"
|
||||
#include "libc/rand/rand.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/sysv/consts/auxv.h"
|
||||
#include "libc/sysv/consts/grnd.h"
|
||||
#include "libc/sysv/consts/o.h"
|
||||
#include "third_party/python/Include/ceval.h"
|
||||
|
@ -382,13 +389,40 @@ _PyOS_URandomNonblock(void *buffer, Py_ssize_t size)
|
|||
return pyurandom(buffer, size, 0, 1);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
getsome(void)
|
||||
{
|
||||
int i;
|
||||
char cf;
|
||||
uint64_t x;
|
||||
for (i = 0; i < 10; ++i) {
|
||||
asm volatile(CFLAG_ASM("rdrand\t%1")
|
||||
: CFLAG_CONSTRAINT(cf), "=r"(x)
|
||||
: /* no inputs */
|
||||
: "cc");
|
||||
if (cf) return x;
|
||||
asm volatile("pause");
|
||||
}
|
||||
while (getrandom(&x, sizeof(x), GRND_NONBLOCK) != sizeof(x)) {
|
||||
if (errno != EINTR) {
|
||||
x ^= rdtsc();
|
||||
x += getpid();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
void
|
||||
_PyRandom_Init(void)
|
||||
{
|
||||
char *env;
|
||||
uint64_t x;
|
||||
const unsigned char *auxrng;
|
||||
unsigned char *secret = (unsigned char *)&_Py_HashSecret.uc;
|
||||
Py_ssize_t secret_size = sizeof(_Py_HashSecret_t);
|
||||
Py_BUILD_ASSERT(sizeof(_Py_HashSecret_t) == sizeof(_Py_HashSecret.uc));
|
||||
_Static_assert(sizeof(_Py_HashSecret_t) == 24, "");
|
||||
|
||||
if (_Py_HashSecret_Initialized)
|
||||
return;
|
||||
|
@ -423,16 +457,30 @@ _PyRandom_Init(void)
|
|||
}
|
||||
else {
|
||||
int res;
|
||||
|
||||
/* _PyRandom_Init() is called very early in the Python initialization
|
||||
and so exceptions cannot be used (use raise=0).
|
||||
|
||||
_PyRandom_Init() must not block Python initialization: call
|
||||
pyurandom() is non-blocking mode (blocking=0): see the PEP 524. */
|
||||
#if 1
|
||||
/*
|
||||
* [jart] modified to be more efficient
|
||||
*/
|
||||
x = getsome();
|
||||
memcpy(secret, &x, 8);
|
||||
if ((auxrng = (const unsigned char *)getauxval(AT_RANDOM))) {
|
||||
memcpy(secret + 8, auxrng, 16);
|
||||
} else {
|
||||
x = getsome();
|
||||
memcpy(secret + 8, &x, 8);
|
||||
x = getsome();
|
||||
memcpy(secret + 16, &x, 8);
|
||||
}
|
||||
#else
|
||||
res = pyurandom(secret, secret_size, 0, 0);
|
||||
if (res < 0) {
|
||||
Py_FatalError("failed to get random numbers to initialize Python");
|
||||
}
|
||||
#endif
|
||||
Py_HashRandomizationFlag = 1;
|
||||
}
|
||||
}
|
||||
|
|
98
third_party/python/Python/sysmodule.c
vendored
98
third_party/python/Python/sysmodule.c
vendored
|
@ -7,11 +7,14 @@
|
|||
#include "libc/calls/calls.h"
|
||||
#include "libc/dce.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/nt/dll.h"
|
||||
#include "libc/nt/version.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
#include "libc/sysv/consts/exit.h"
|
||||
#include "libc/unicode/locale.h"
|
||||
#include "libc/x/x.h"
|
||||
#include "third_party/python/Include/abstract.h"
|
||||
#include "third_party/python/Include/boolobject.h"
|
||||
#include "third_party/python/Include/ceval.h"
|
||||
|
@ -790,8 +793,8 @@ A struct sequence providing information about asynhronous\n\
|
|||
generators hooks. The attributes are read only.");
|
||||
|
||||
static PyStructSequence_Field asyncgen_hooks_fields[] = {
|
||||
{"firstiter", "Hook to intercept first iteration"},
|
||||
{"finalizer", "Hook to intercept finalization"},
|
||||
{"firstiter", PyDoc_STR("Hook to intercept first iteration")},
|
||||
{"finalizer", PyDoc_STR("Hook to intercept finalization")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -897,17 +900,15 @@ A struct sequence providing parameters used for computing\n\
|
|||
hashes. The attributes are read only.");
|
||||
|
||||
static PyStructSequence_Field hash_info_fields[] = {
|
||||
{"width", "width of the type used for hashing, in bits"},
|
||||
{"modulus", "prime number giving the modulus on which the hash "
|
||||
"function is based"},
|
||||
{"inf", "value to be used for hash of a positive infinity"},
|
||||
{"nan", "value to be used for hash of a nan"},
|
||||
{"imag", "multiplier used for the imaginary part of a complex number"},
|
||||
{"algorithm", "name of the algorithm for hashing of str, bytes and "
|
||||
"memoryviews"},
|
||||
{"hash_bits", "internal output size of hash algorithm"},
|
||||
{"seed_bits", "seed size of hash algorithm"},
|
||||
{"cutoff", "small string optimization cutoff"},
|
||||
{"width", PyDoc_STR("width of the type used for hashing, in bits")},
|
||||
{"modulus", PyDoc_STR("prime number giving the modulus on which the hash function is based")},
|
||||
{"inf", PyDoc_STR("value to be used for hash of a positive infinity")},
|
||||
{"nan", PyDoc_STR("value to be used for hash of a nan")},
|
||||
{"imag", PyDoc_STR("multiplier used for the imaginary part of a complex number")},
|
||||
{"algorithm", PyDoc_STR("name of the algorithm for hashing of str, bytes and memoryviews")},
|
||||
{"hash_bits", PyDoc_STR("internal output size of hash algorithm")},
|
||||
{"seed_bits", PyDoc_STR("seed size of hash algorithm")},
|
||||
{"cutoff", PyDoc_STR("small string optimization cutoff")},
|
||||
{NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -977,7 +978,6 @@ of the Python interpreter stack. This limit prevents infinite\n\
|
|||
recursion from causing an overflow of the C stack and crashing Python."
|
||||
);
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
PyDoc_STRVAR(getwindowsversion_doc,
|
||||
"getwindowsversion()\n\
|
||||
\n\
|
||||
|
@ -992,19 +992,19 @@ server. Platform_version is a 3-tuple containing a version number that is\n\
|
|||
intended for identifying the OS rather than feature detection."
|
||||
);
|
||||
|
||||
static PyTypeObject WindowsVersionType = {0, 0, 0, 0, 0, 0};
|
||||
static PyTypeObject WindowsVersionType = {0};
|
||||
|
||||
static PyStructSequence_Field windows_version_fields[] = {
|
||||
{"major", "Major version number"},
|
||||
{"minor", "Minor version number"},
|
||||
{"build", "Build number"},
|
||||
{"platform", "Operating system platform"},
|
||||
{"service_pack", "Latest Service Pack installed on the system"},
|
||||
{"service_pack_major", "Service Pack major version number"},
|
||||
{"service_pack_minor", "Service Pack minor version number"},
|
||||
{"suite_mask", "Bit mask identifying available product suites"},
|
||||
{"product_type", "System product type"},
|
||||
{"platform_version", "Diagnostic version number"},
|
||||
{"major", PyDoc_STR("Major version number")},
|
||||
{"minor", PyDoc_STR("Minor version number")},
|
||||
{"build", PyDoc_STR("Build number")},
|
||||
{"platform", PyDoc_STR("Operating system platform")},
|
||||
{"service_pack", PyDoc_STR("Latest Service Pack installed on the system")},
|
||||
{"service_pack_major", PyDoc_STR("Service Pack major version number")},
|
||||
{"service_pack_minor", PyDoc_STR("Service Pack minor version number")},
|
||||
{"suite_mask", PyDoc_STR("Bit mask identifying available product suites")},
|
||||
{"product_type", PyDoc_STR("System product type")},
|
||||
{"platform_version", PyDoc_STR("Diagnostic version number")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -1017,26 +1017,20 @@ static PyStructSequence_Desc windows_version_desc = {
|
|||
via indexing, the rest are name only */
|
||||
};
|
||||
|
||||
/* Disable deprecation warnings about GetVersionEx as the result is
|
||||
being passed straight through to the caller, who is responsible for
|
||||
using it correctly. */
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
static PyObject *
|
||||
sys_getwindowsversion(PyObject *self)
|
||||
{
|
||||
PyObject *version;
|
||||
int pos = 0;
|
||||
OSVERSIONINFOEX ver;
|
||||
DWORD realMajor, realMinor, realBuild;
|
||||
HANDLE hKernel32;
|
||||
wchar_t kernel32_path[MAX_PATH];
|
||||
LPVOID verblock;
|
||||
DWORD verblock_size;
|
||||
PyObject *version;
|
||||
struct NtOsVersionInfo ver;
|
||||
uint32_t realMajor, realMinor, realBuild;
|
||||
int64_t hKernel32;
|
||||
wchar_t kernel32_path[PATH_MAX];
|
||||
void *verblock;
|
||||
uint32_t verblock_size;
|
||||
|
||||
ver.dwOSVersionInfoSize = sizeof(ver);
|
||||
if (!GetVersionEx((OSVERSIONINFO*) &ver))
|
||||
if (!GetVersionEx(&ver))
|
||||
return PyErr_SetFromWindowsErr(0);
|
||||
|
||||
version = PyStructSequence_New(&WindowsVersionType);
|
||||
|
@ -1047,7 +1041,7 @@ sys_getwindowsversion(PyObject *self)
|
|||
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwMinorVersion));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwBuildNumber));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.dwPlatformId));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromString(ver.szCSDVersion));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyUnicode_FromString(gc(utf16toutf8(ver.szCSDVersion,-1,0))));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMajor));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wServicePackMinor));
|
||||
PyStructSequence_SET_ITEM(version, pos++, PyLong_FromLong(ver.wSuiteMask));
|
||||
|
@ -1057,17 +1051,17 @@ sys_getwindowsversion(PyObject *self)
|
|||
realMinor = ver.dwMinorVersion;
|
||||
realBuild = ver.dwBuildNumber;
|
||||
|
||||
#if 0 // todo(jart): port me
|
||||
// GetVersion will lie if we are running in a compatibility mode.
|
||||
// We need to read the version info from a system file resource
|
||||
// to accurately identify the OS version. If we fail for any reason,
|
||||
// just return whatever GetVersion said.
|
||||
hKernel32 = GetModuleHandleW(L"kernel32.dll");
|
||||
hKernel32 = GetModuleHandle("kernel32.dll");
|
||||
if (hKernel32 && GetModuleFileNameW(hKernel32, kernel32_path, MAX_PATH) &&
|
||||
(verblock_size = GetFileVersionInfoSizeW(kernel32_path, NULL)) &&
|
||||
(verblock = PyMem_RawMalloc(verblock_size))) {
|
||||
VS_FIXEDFILEINFO *ffi;
|
||||
UINT ffi_len;
|
||||
|
||||
if (GetFileVersionInfoW(kernel32_path, 0, verblock_size, verblock) &&
|
||||
VerQueryValueW(verblock, L"", (LPVOID)&ffi, &ffi_len)) {
|
||||
realMajor = HIWORD(ffi->dwProductVersionMS);
|
||||
|
@ -1081,6 +1075,7 @@ sys_getwindowsversion(PyObject *self)
|
|||
realMinor,
|
||||
realBuild
|
||||
));
|
||||
#endif
|
||||
|
||||
if (PyErr_Occurred()) {
|
||||
Py_DECREF(version);
|
||||
|
@ -1090,6 +1085,8 @@ sys_getwindowsversion(PyObject *self)
|
|||
return version;
|
||||
}
|
||||
|
||||
#ifdef MS_WINDOWS
|
||||
|
||||
#pragma warning(pop)
|
||||
|
||||
PyDoc_STRVAR(enablelegacywindowsfsencoding_doc,
|
||||
|
@ -1482,9 +1479,9 @@ static PyMethodDef sys_methods[] = {
|
|||
{"getsizeof", (PyCFunction)sys_getsizeof,
|
||||
METH_VARARGS | METH_KEYWORDS, getsizeof_doc},
|
||||
{"_getframe", sys_getframe, METH_VARARGS, getframe_doc},
|
||||
#ifdef MS_WINDOWS
|
||||
{"getwindowsversion", (PyCFunction)sys_getwindowsversion, METH_NOARGS,
|
||||
getwindowsversion_doc},
|
||||
#ifdef MS_WINDOWS
|
||||
{"_enablelegacywindowsfsencoding", (PyCFunction)sys_enablelegacywindowsfsencoding,
|
||||
METH_NOARGS, enablelegacywindowsfsencoding_doc },
|
||||
#endif /* MS_WINDOWS */
|
||||
|
@ -1569,8 +1566,7 @@ PySys_AddWarnOptionUnicode(PyObject *unicode)
|
|||
{
|
||||
if (warnoptions == NULL || !PyList_Check(warnoptions)) {
|
||||
Py_XDECREF(warnoptions);
|
||||
warnoptions = PyList_New(0);
|
||||
if (warnoptions == NULL)
|
||||
warnoptions = PyList_New(0); if (warnoptions == NULL)
|
||||
return;
|
||||
}
|
||||
PyList_Append(warnoptions, unicode);
|
||||
|
@ -1826,11 +1822,11 @@ Version information as a named tuple.");
|
|||
static PyTypeObject VersionInfoType;
|
||||
|
||||
static PyStructSequence_Field version_info_fields[] = {
|
||||
{"major", "Major release number"},
|
||||
{"minor", "Minor release number"},
|
||||
{"micro", "Patch release number"},
|
||||
{"releaselevel", "'alpha', 'beta', 'candidate', or 'final'"},
|
||||
{"serial", "Serial release number"},
|
||||
{"major", PyDoc_STR("Major release number")},
|
||||
{"minor", PyDoc_STR("Minor release number")},
|
||||
{"micro", PyDoc_STR("Patch release number")},
|
||||
{"releaselevel", PyDoc_STR("'alpha', 'beta', 'candidate', or 'final'")},
|
||||
{"serial", PyDoc_STR("Serial release number")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
@ -2132,7 +2128,6 @@ _PySys_Init(void)
|
|||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
||||
PyErr_Clear();
|
||||
|
||||
#if defined(MS_WINDOWS)
|
||||
/* getwindowsversion */
|
||||
if (WindowsVersionType.tp_name == 0)
|
||||
if (PyStructSequence_InitType2(&WindowsVersionType,
|
||||
|
@ -2144,7 +2139,6 @@ _PySys_Init(void)
|
|||
res = PyDict_DelItemString(WindowsVersionType.tp_dict, "__new__");
|
||||
if (res < 0 && PyErr_ExceptionMatches(PyExc_KeyError))
|
||||
PyErr_Clear();
|
||||
#endif
|
||||
|
||||
/* float repr style: 0.03 (short) vs 0.029999999999999999 (legacy) */
|
||||
#ifndef PY_NO_SHORT_FLOAT_REPR
|
||||
|
|
6
third_party/python/Python/thread.c
vendored
6
third_party/python/Python/thread.c
vendored
|
@ -363,9 +363,9 @@ PyDoc_STRVAR(threadinfo__doc__,
|
|||
A struct sequence holding information about the thread implementation.");
|
||||
|
||||
static PyStructSequence_Field threadinfo_fields[] = {
|
||||
{"name", "name of the thread implementation"},
|
||||
{"lock", "name of the lock implementation"},
|
||||
{"version", "name and version of the thread library"},
|
||||
{"name", PyDoc_STR("name of the thread implementation")},
|
||||
{"lock", PyDoc_STR("name of the lock implementation")},
|
||||
{"version", PyDoc_STR("name and version of the thread library")},
|
||||
{0}
|
||||
};
|
||||
|
||||
|
|
2
third_party/python/Python/thread_pthread.inc
vendored
2
third_party/python/Python/thread_pthread.inc
vendored
|
@ -418,7 +418,7 @@ PyThread_allocate_lock(void)
|
|||
|
||||
lock = (pthread_lock *) PyMem_RawMalloc(sizeof(pthread_lock));
|
||||
if (lock) {
|
||||
memset((void *)lock, '\0', sizeof(pthread_lock));
|
||||
bzero((void *)lock, sizeof(pthread_lock));
|
||||
lock->locked = 0;
|
||||
|
||||
status = pthread_mutex_init(&lock->mut,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue