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

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

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

View file

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

View file

@ -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,
};

View file

@ -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 */

View file

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

View file

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

View file

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

View file

@ -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,

View file

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

View file

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

View file

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

View file

@ -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 *

View file

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

View file

@ -6,12 +6,8 @@
*/
/* clang-format off */
#ifndef PLATFORM
#define PLATFORM "unknown"
#endif
const char *
Py_GetPlatform(void)
{
return PLATFORM;
return "cosmo";
}

View file

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

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

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

View file

@ -328,7 +328,6 @@ safe_power(PyObject *v, PyObject *w)
return NULL;
}
}
return PyNumber_Power(v, w, Py_None);
}

View file

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

View file

@ -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 */

View file

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

View file

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

View file

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

View file

@ -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,