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:
Justine Tunney 2021-09-27 22:58:51 -07:00
parent fa7b4f5bd1
commit 39bf41f4eb
806 changed files with 77494 additions and 63859 deletions

View file

@ -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));