mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-01-31 19:43:32 +00:00
47a53e143b
The APE_NO_MODIFY_SELF loader payload has been moved out of the examples folder and improved so that it works on BSD systems, and permits general elf program headers. This brings its quality up enough that it should be acceptable to use by default for many programs, e.g. Python, Lua, SQLite and Python. It's the responsibility of the user to define an appropriate TMPDIR if /tmp is considered an adversarial environment. Mac OS shall be supported by APE_NO_MODIFY_SELF soon. Fixes and improvements have been made to program_executable_name as it's now the one true way to get the absolute path of the executing image. This change fixes a memory leak in linenoise history loading, introduced by performance optimizations in51904e2687
This change fixes a longstanding regression with Mach system calls, that23ae9dfceb
back in February which impacted our sched_yield() implementation, which is why no one noticed until now. The Blinkenlights PC emulator has been improved. We now fix rendering on XNU and BSD by not making the assumption that the kernel terminal driver understands UTF8 since that seems to break its internal modeling of \r\n which is now being addressed by using \e[𝑦H instead. The paneling is now more compact in real mode so you won't need to make your font as tiny if you're only emulating an 8086 program. The CLMUL ISA is now emulated too This change also makes improvement to time. CLOCK_MONOTONIC now does the right thing on Windows NT. The nanosecond time module functions added in Python 3.7 have been backported. This change doubles the performance of Argon2 password stretching simply by not using its copy_block and xor_block helper functions, as they were trivial to inline thus resulting in us needing to iterate over each 1024 byte block four fewer times. This change makes code size improvements. _PyUnicode_ToNumeric() was 64k in size and now it's 10k. The CJK codec lookup tables now use lazy delta zigzag deflate (δzd) encoding which reduces their size from 600k to 200k plus the code bloat caused by macro abuse in _decimal.c is now addressed so our fully-loaded statically-linked hermetically-sealed Python virtual interpreter container is now 9.4 megs in the default build mode and 5.5m in MODE=tiny which leaves plenty of room for chibicc. The pydoc web server now accommodates the use case of people who work by SSH'ing into a different machine w/ python.com -m pydoc -p8080 -h0.0.0.0 Finally Python Capsulae delenda est and won't be supported in the future
214 lines
7.9 KiB
C
214 lines
7.9 KiB
C
#ifndef Py_LONGOBJECT_H
|
|
#define Py_LONGOBJECT_H
|
|
#include "third_party/python/Include/bytesobject.h"
|
|
#include "third_party/python/Include/object.h"
|
|
#include "third_party/python/Include/unicodeobject.h"
|
|
COSMOPOLITAN_C_START_
|
|
/* clang-format off */
|
|
|
|
/* Long (arbitrary precision) integer object interface */
|
|
|
|
typedef struct _longobject PyLongObject; /* Revealed in longintrepr.h */
|
|
|
|
extern PyTypeObject PyLong_Type;
|
|
|
|
#define PyLong_Check(op) \
|
|
PyType_FastSubclass(Py_TYPE(op), Py_TPFLAGS_LONG_SUBCLASS)
|
|
#define PyLong_CheckExact(op) (Py_TYPE(op) == &PyLong_Type)
|
|
|
|
PyObject * PyLong_FromLong(long);
|
|
PyObject * PyLong_FromUnsignedLong(unsigned long);
|
|
PyObject * PyLong_FromSize_t(size_t);
|
|
PyObject * PyLong_FromSsize_t(Py_ssize_t);
|
|
PyObject * PyLong_FromDouble(double);
|
|
long PyLong_AsLong(PyObject *);
|
|
long PyLong_AsLongAndOverflow(PyObject *, int *);
|
|
Py_ssize_t PyLong_AsSsize_t(PyObject *);
|
|
size_t PyLong_AsSize_t(PyObject *);
|
|
unsigned long PyLong_AsUnsignedLong(PyObject *);
|
|
unsigned long PyLong_AsUnsignedLongMask(PyObject *);
|
|
#ifndef Py_LIMITED_API
|
|
int _PyLong_AsInt(PyObject *);
|
|
#endif
|
|
PyObject * PyLong_GetInfo(void);
|
|
|
|
/* It may be useful in the future. I've added it in the PyInt -> PyLong
|
|
cleanup to keep the extra information. [CH] */
|
|
#define PyLong_AS_LONG(op) PyLong_AsLong(op)
|
|
|
|
/* Issue #1983: pid_t can be longer than a C long on some systems */
|
|
#if !defined(SIZEOF_PID_T) || SIZEOF_PID_T == SIZEOF_INT
|
|
#define _Py_PARSE_PID "i"
|
|
#define PyLong_FromPid PyLong_FromLong
|
|
#define PyLong_AsPid PyLong_AsLong
|
|
#elif SIZEOF_PID_T == SIZEOF_LONG
|
|
#define _Py_PARSE_PID "l"
|
|
#define PyLong_FromPid PyLong_FromLong
|
|
#define PyLong_AsPid PyLong_AsLong
|
|
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_PID_T == SIZEOF_LONG_LONG
|
|
#define _Py_PARSE_PID "L"
|
|
#define PyLong_FromPid PyLong_FromLongLong
|
|
#define PyLong_AsPid PyLong_AsLongLong
|
|
#else
|
|
#error "sizeof(pid_t) is neither sizeof(int), sizeof(long) or sizeof(long long)"
|
|
#endif /* SIZEOF_PID_T */
|
|
|
|
#if SIZEOF_VOID_P == SIZEOF_INT
|
|
# define _Py_PARSE_INTPTR "i"
|
|
# define _Py_PARSE_UINTPTR "I"
|
|
#elif SIZEOF_VOID_P == SIZEOF_LONG
|
|
# define _Py_PARSE_INTPTR "l"
|
|
# define _Py_PARSE_UINTPTR "k"
|
|
#elif defined(SIZEOF_LONG_LONG) && SIZEOF_VOID_P == SIZEOF_LONG_LONG
|
|
# define _Py_PARSE_INTPTR "L"
|
|
# define _Py_PARSE_UINTPTR "K"
|
|
#else
|
|
# error "void* different in size from int, long and long long"
|
|
#endif /* SIZEOF_VOID_P */
|
|
|
|
/* Used by Python/mystrtoul.c, _PyBytes_FromHex(),
|
|
_PyBytes_DecodeEscapeRecode(), etc. */
|
|
#ifndef Py_LIMITED_API
|
|
extern const unsigned char _PyLong_DigitValue[256];
|
|
#endif
|
|
|
|
/* _PyLong_Frexp returns a double x and an exponent e such that the
|
|
true value is approximately equal to x * 2**e. e is >= 0. x is
|
|
0.0 if and only if the input is 0 (in which case, e and x are both
|
|
zeroes); otherwise, 0.5 <= abs(x) < 1.0. On overflow, which is
|
|
possible if the number of bits doesn't fit into a Py_ssize_t, sets
|
|
OverflowError and returns -1.0 for x, 0 for e. */
|
|
#ifndef Py_LIMITED_API
|
|
double _PyLong_Frexp(PyLongObject *a, Py_ssize_t *e);
|
|
#endif
|
|
|
|
double PyLong_AsDouble(PyObject *);
|
|
PyObject * PyLong_FromVoidPtr(void *);
|
|
void * PyLong_AsVoidPtr(PyObject *);
|
|
|
|
PyObject * PyLong_FromLongLong(long long);
|
|
PyObject * PyLong_FromUnsignedLongLong(unsigned long long);
|
|
long long PyLong_AsLongLong(PyObject *);
|
|
unsigned long long PyLong_AsUnsignedLongLong(PyObject *);
|
|
unsigned long long PyLong_AsUnsignedLongLongMask(PyObject *);
|
|
long long PyLong_AsLongLongAndOverflow(PyObject *, int *);
|
|
|
|
PyObject * PyLong_FromString(const char *, char **, int);
|
|
#ifndef Py_LIMITED_API
|
|
PyObject * PyLong_FromUnicode(Py_UNICODE*, Py_ssize_t, int);
|
|
PyObject * PyLong_FromUnicodeObject(PyObject *u, int base);
|
|
PyObject * _PyLong_FromBytes(const char *, Py_ssize_t, int);
|
|
#endif
|
|
|
|
#ifndef Py_LIMITED_API
|
|
/* _PyLong_Sign. Return 0 if v is 0, -1 if v < 0, +1 if v > 0.
|
|
v must not be NULL, and must be a normalized long.
|
|
There are no error cases.
|
|
*/
|
|
int _PyLong_Sign(PyObject *v);
|
|
|
|
|
|
/* _PyLong_NumBits. Return the number of bits needed to represent the
|
|
absolute value of a long. For example, this returns 1 for 1 and -1, 2
|
|
for 2 and -2, and 2 for 3 and -3. It returns 0 for 0.
|
|
v must not be NULL, and must be a normalized long.
|
|
(size_t)-1 is returned and OverflowError set if the true result doesn't
|
|
fit in a size_t.
|
|
*/
|
|
size_t _PyLong_NumBits(PyObject *v);
|
|
|
|
/* _PyLong_DivmodNear. Given integers a and b, compute the nearest
|
|
integer q to the exact quotient a / b, rounding to the nearest even integer
|
|
in the case of a tie. Return (q, r), where r = a - q*b. The remainder r
|
|
will satisfy abs(r) <= abs(b)/2, with equality possible only if q is
|
|
even.
|
|
*/
|
|
PyObject * _PyLong_DivmodNear(PyObject *, PyObject *);
|
|
|
|
/* _PyLong_FromByteArray: View the n unsigned bytes as a binary integer in
|
|
base 256, and return a Python int with the same numeric value.
|
|
If n is 0, the integer is 0. Else:
|
|
If little_endian is 1/true, bytes[n-1] is the MSB and bytes[0] the LSB;
|
|
else (little_endian is 0/false) bytes[0] is the MSB and bytes[n-1] the
|
|
LSB.
|
|
If is_signed is 0/false, view the bytes as a non-negative integer.
|
|
If is_signed is 1/true, view the bytes as a 2's-complement integer,
|
|
non-negative if bit 0x80 of the MSB is clear, negative if set.
|
|
Error returns:
|
|
+ Return NULL with the appropriate exception set if there's not
|
|
enough memory to create the Python int.
|
|
*/
|
|
PyObject * _PyLong_FromByteArray(
|
|
const unsigned char* bytes, size_t n,
|
|
int little_endian, int is_signed);
|
|
|
|
/* _PyLong_AsByteArray: Convert the least-significant 8*n bits of long
|
|
v to a base-256 integer, stored in array bytes. Normally return 0,
|
|
return -1 on error.
|
|
If little_endian is 1/true, store the MSB at bytes[n-1] and the LSB at
|
|
bytes[0]; else (little_endian is 0/false) store the MSB at bytes[0] and
|
|
the LSB at bytes[n-1].
|
|
If is_signed is 0/false, it's an error if v < 0; else (v >= 0) n bytes
|
|
are filled and there's nothing special about bit 0x80 of the MSB.
|
|
If is_signed is 1/true, bytes is filled with the 2's-complement
|
|
representation of v's value. Bit 0x80 of the MSB is the sign bit.
|
|
Error returns (-1):
|
|
+ is_signed is 0 and v < 0. TypeError is set in this case, and bytes
|
|
isn't altered.
|
|
+ n isn't big enough to hold the full mathematical value of v. For
|
|
example, if is_signed is 0 and there are more digits in the v than
|
|
fit in n; or if is_signed is 1, v < 0, and n is just 1 bit shy of
|
|
being large enough to hold a sign bit. OverflowError is set in this
|
|
case, but bytes holds the least-significant n bytes of the true value.
|
|
*/
|
|
int _PyLong_AsByteArray(PyLongObject* v,
|
|
unsigned char* bytes, size_t n,
|
|
int little_endian, int is_signed);
|
|
|
|
/* _PyLong_FromNbInt: Convert the given object to a PyLongObject
|
|
using the nb_int slot, if available. Raise TypeError if either the
|
|
nb_int slot is not available or the result of the call to nb_int
|
|
returns something not of type int.
|
|
*/
|
|
PyLongObject *_PyLong_FromNbInt(PyObject *);
|
|
|
|
/* _PyLong_Format: Convert the long to a string object with given base,
|
|
appending a base prefix of 0[box] if base is 2, 8 or 16. */
|
|
PyObject * _PyLong_Format(PyObject *obj, int base);
|
|
|
|
int _PyLong_FormatWriter(
|
|
_PyUnicodeWriter *writer,
|
|
PyObject *obj,
|
|
int base,
|
|
int alternate);
|
|
|
|
char* _PyLong_FormatBytesWriter(
|
|
_PyBytesWriter *writer,
|
|
char *str,
|
|
PyObject *obj,
|
|
int base,
|
|
int alternate);
|
|
|
|
/* Format the object based on the format_spec, as defined in PEP 3101
|
|
(Advanced String Formatting). */
|
|
int _PyLong_FormatAdvancedWriter(
|
|
_PyUnicodeWriter *writer,
|
|
PyObject *obj,
|
|
PyObject *format_spec,
|
|
Py_ssize_t start,
|
|
Py_ssize_t end);
|
|
#endif /* Py_LIMITED_API */
|
|
|
|
/* These aren't really part of the int object, but they're handy. The
|
|
functions are in Python/mystrtoul.c.
|
|
*/
|
|
unsigned long PyOS_strtoul(const char *, char **, int);
|
|
long PyOS_strtol(const char *, char **, int);
|
|
|
|
#ifndef Py_LIMITED_API
|
|
/* For use by the gcd function in mathmodule.c */
|
|
PyObject * _PyLong_GCD(PyObject *, PyObject *);
|
|
#endif /* !Py_LIMITED_API */
|
|
|
|
COSMOPOLITAN_C_END_
|
|
#endif /* !Py_LONGOBJECT_H */
|