diff options
Diffstat (limited to 'Modules')
-rw-r--r-- | Modules/_ctypes/_ctypes_test.c | 4 | ||||
-rw-r--r-- | Modules/_ctypes/cfield.c | 4 | ||||
-rw-r--r-- | Modules/_ctypes/ctypes.h | 2 | ||||
-rw-r--r-- | Modules/_interpchannelsmodule.c | 6 | ||||
-rw-r--r-- | Modules/_interpqueuesmodule.c | 6 | ||||
-rw-r--r-- | Modules/_interpretersmodule.c | 28 | ||||
-rw-r--r-- | Modules/_opcode.c | 2 | ||||
-rw-r--r-- | Modules/_remote_debugging_module.c | 83 | ||||
-rw-r--r-- | Modules/_stat.c | 4 | ||||
-rw-r--r-- | Modules/_testinternalcapi.c | 5 | ||||
-rw-r--r-- | Modules/blake2module.c | 74 | ||||
-rw-r--r-- | Modules/clinic/_remote_debugging_module.c.h | 40 | ||||
-rw-r--r-- | Modules/clinic/blake2module.c.h | 14 | ||||
-rw-r--r-- | Modules/clinic/mathmodule.c.h | 36 | ||||
-rw-r--r-- | Modules/clinic/sha3module.c.h | 14 | ||||
-rw-r--r-- | Modules/hmacmodule.c | 21 | ||||
-rw-r--r-- | Modules/mathmodule.c | 20 | ||||
-rw-r--r-- | Modules/posixmodule.c | 3 | ||||
-rw-r--r-- | Modules/sha3module.c | 9 |
19 files changed, 253 insertions, 122 deletions
diff --git a/Modules/_ctypes/_ctypes_test.c b/Modules/_ctypes/_ctypes_test.c index d28e5708b44..66338805007 100644 --- a/Modules/_ctypes/_ctypes_test.c +++ b/Modules/_ctypes/_ctypes_test.c @@ -23,7 +23,7 @@ # define _Py_thread_local __thread #endif -#if defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(_Py_FFI_SUPPORT_C_COMPLEX) # include <complex.h> // csqrt() # undef I // for _ctypes_test_generated.c.h #endif @@ -457,7 +457,7 @@ EXPORT(double) my_sqrt(double a) return sqrt(a); } -#if defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(_Py_FFI_SUPPORT_C_COMPLEX) EXPORT(double complex) my_csqrt(double complex a) { return csqrt(a); diff --git a/Modules/_ctypes/cfield.c b/Modules/_ctypes/cfield.c index 163b9264261..547e2471a1c 100644 --- a/Modules/_ctypes/cfield.c +++ b/Modules/_ctypes/cfield.c @@ -759,7 +759,7 @@ d_get(void *ptr, Py_ssize_t size) return PyFloat_FromDouble(val); } -#if defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(_Py_FFI_SUPPORT_C_COMPLEX) /* We don't use _Complex types here, using arrays instead, as the C11+ standard says: "Each complex type has the same representation and alignment @@ -1599,7 +1599,7 @@ for base_code, base_c_type in [ /////////////////////////////////////////////////////////////////////////// TABLE_ENTRY_SW(d, &ffi_type_double); -#if defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(_Py_FFI_SUPPORT_C_COMPLEX) if (Py_FFI_COMPLEX_AVAILABLE) { TABLE_ENTRY(D, &ffi_type_complex_double); TABLE_ENTRY(F, &ffi_type_complex_float); diff --git a/Modules/_ctypes/ctypes.h b/Modules/_ctypes/ctypes.h index 6a45c11e61a..5b4f97d43b8 100644 --- a/Modules/_ctypes/ctypes.h +++ b/Modules/_ctypes/ctypes.h @@ -23,7 +23,7 @@ // Do we support C99 complex types in ffi? // For Apple's libffi, this must be determined at runtime (see gh-128156). -#if defined(Py_FFI_SUPPORT_C_COMPLEX) +#if defined(_Py_FFI_SUPPORT_C_COMPLEX) # if USING_APPLE_OS_LIBFFI && defined(__has_builtin) # if __has_builtin(__builtin_available) # define Py_FFI_COMPLEX_AVAILABLE __builtin_available(macOS 10.15, *) diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index ee5e2b005e0..9c1f8615161 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -3614,8 +3614,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg) { module_state *state = get_module_state(mod); assert(state != NULL); - (void)traverse_module_state(state, visit, arg); - return 0; + return traverse_module_state(state, visit, arg); } static int @@ -3625,8 +3624,7 @@ module_clear(PyObject *mod) assert(state != NULL); // Now we clear the module state. - (void)clear_module_state(state); - return 0; + return clear_module_state(state); } static void diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index de06b8b41fe..e5afe746f90 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1952,8 +1952,7 @@ static int module_traverse(PyObject *mod, visitproc visit, void *arg) { module_state *state = get_module_state(mod); - (void)traverse_module_state(state, visit, arg); - return 0; + return traverse_module_state(state, visit, arg); } static int @@ -1962,8 +1961,7 @@ module_clear(PyObject *mod) module_state *state = get_module_state(mod); // Now we clear the module state. - (void)clear_module_state(state); - return 0; + return clear_module_state(state); } static void diff --git a/Modules/_interpretersmodule.c b/Modules/_interpretersmodule.c index e201ccd53da..e7feaa7f186 100644 --- a/Modules/_interpretersmodule.c +++ b/Modules/_interpretersmodule.c @@ -1039,8 +1039,8 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs) PyObject *id, *updates; int restricted = 0; if (!PyArg_ParseTupleAndKeywords(args, kwargs, - "OO|$p:" MODULE_NAME_STR ".set___main___attrs", - kwlist, &id, &updates, &restricted)) + "OO!|$p:" MODULE_NAME_STR ".set___main___attrs", + kwlist, &id, &PyDict_Type, &updates, &restricted)) { return NULL; } @@ -1054,16 +1054,14 @@ interp_set___main___attrs(PyObject *self, PyObject *args, PyObject *kwargs) } // Check the updates. - if (updates != Py_None) { - Py_ssize_t size = PyObject_Size(updates); - if (size < 0) { - return NULL; - } - if (size == 0) { - PyErr_SetString(PyExc_ValueError, - "arg 2 must be a non-empty mapping"); - return NULL; - } + Py_ssize_t size = PyDict_Size(updates); + if (size < 0) { + return NULL; + } + if (size == 0) { + PyErr_SetString(PyExc_ValueError, + "arg 2 must be a non-empty dict"); + return NULL; } _PyXI_session *session = _PyXI_NewSession(); @@ -1708,8 +1706,7 @@ module_traverse(PyObject *mod, visitproc visit, void *arg) { module_state *state = get_module_state(mod); assert(state != NULL); - (void)traverse_module_state(state, visit, arg); - return 0; + return traverse_module_state(state, visit, arg); } static int @@ -1717,8 +1714,7 @@ module_clear(PyObject *mod) { module_state *state = get_module_state(mod); assert(state != NULL); - (void)clear_module_state(state); - return 0; + return clear_module_state(state); } static void diff --git a/Modules/_opcode.c b/Modules/_opcode.c index c295f7b3152..ef271b6ef56 100644 --- a/Modules/_opcode.c +++ b/Modules/_opcode.c @@ -5,7 +5,7 @@ #include "Python.h" #include "compile.h" #include "opcode.h" -#include "pycore_ceval.h" +#include "pycore_ceval.h" // SPECIAL_MAX #include "pycore_code.h" #include "pycore_compile.h" #include "pycore_intrinsics.h" diff --git a/Modules/_remote_debugging_module.c b/Modules/_remote_debugging_module.c index c2421cac6bd..ce7189637c2 100644 --- a/Modules/_remote_debugging_module.c +++ b/Modules/_remote_debugging_module.c @@ -64,12 +64,14 @@ #endif #ifdef Py_GIL_DISABLED -#define INTERP_STATE_MIN_SIZE MAX(MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \ - offsetof(PyInterpreterState, tlbc_indices.tlbc_generation) + sizeof(uint32_t)), \ - offsetof(PyInterpreterState, threads.head) + sizeof(void*)) +#define INTERP_STATE_MIN_SIZE MAX(MAX(MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \ + offsetof(PyInterpreterState, tlbc_indices.tlbc_generation) + sizeof(uint32_t)), \ + offsetof(PyInterpreterState, threads.head) + sizeof(void*)), \ + offsetof(PyInterpreterState, _gil.last_holder) + sizeof(PyThreadState*)) #else -#define INTERP_STATE_MIN_SIZE MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \ - offsetof(PyInterpreterState, threads.head) + sizeof(void*)) +#define INTERP_STATE_MIN_SIZE MAX(MAX(offsetof(PyInterpreterState, _code_object_generation) + sizeof(uint64_t), \ + offsetof(PyInterpreterState, threads.head) + sizeof(void*)), \ + offsetof(PyInterpreterState, _gil.last_holder) + sizeof(PyThreadState*)) #endif #define INTERP_STATE_BUFFER_SIZE MAX(INTERP_STATE_MIN_SIZE, 256) @@ -206,6 +208,7 @@ typedef struct { uint64_t code_object_generation; _Py_hashtable_t *code_object_cache; int debug; + int only_active_thread; RemoteDebuggingState *cached_state; // Cached module state #ifdef Py_GIL_DISABLED // TLBC cache invalidation tracking @@ -2496,6 +2499,7 @@ _remote_debugging.RemoteUnwinder.__init__ pid: int * all_threads: bool = False + only_active_thread: bool = False debug: bool = False Initialize a new RemoteUnwinder object for debugging a remote Python process. @@ -2504,6 +2508,8 @@ Args: pid: Process ID of the target Python process to debug all_threads: If True, initialize state for all threads in the process. If False, only initialize for the main thread. + only_active_thread: If True, only sample the thread holding the GIL. + Cannot be used together with all_threads=True. debug: If True, chain exceptions to explain the sequence of events that lead to the exception. @@ -2514,15 +2520,33 @@ Raises: PermissionError: If access to the target process is denied OSError: If unable to attach to the target process or access its memory RuntimeError: If unable to read debug information from the target process + ValueError: If both all_threads and only_active_thread are True [clinic start generated code]*/ static int _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self, int pid, int all_threads, + int only_active_thread, int debug) -/*[clinic end generated code: output=3982f2a7eba49334 input=48a762566b828e91]*/ +/*[clinic end generated code: output=13ba77598ecdcbe1 input=8f8f12504e17da04]*/ { + // Validate that all_threads and only_active_thread are not both True + if (all_threads && only_active_thread) { + PyErr_SetString(PyExc_ValueError, + "all_threads and only_active_thread cannot both be True"); + return -1; + } + +#ifdef Py_GIL_DISABLED + if (only_active_thread) { + PyErr_SetString(PyExc_ValueError, + "only_active_thread is not supported when Py_GIL_DISABLED is not defined"); + return -1; + } +#endif + self->debug = debug; + self->only_active_thread = only_active_thread; self->cached_state = NULL; if (_Py_RemoteDebug_InitProcHandle(&self->handle, pid) < 0) { set_exception_cause(self, PyExc_RuntimeError, "Failed to initialize process handle"); @@ -2602,13 +2626,18 @@ _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self, @critical_section _remote_debugging.RemoteUnwinder.get_stack_trace -Returns a list of stack traces for all threads in the target process. +Returns a list of stack traces for threads in the target process. Each element in the returned list is a tuple of (thread_id, frame_list), where: - thread_id is the OS thread identifier - frame_list is a list of tuples (function_name, filename, line_number) representing the Python stack frames for that thread, ordered from most recent to oldest +The threads returned depend on the initialization parameters: +- If only_active_thread was True: returns only the thread holding the GIL +- If all_threads was True: returns all threads +- Otherwise: returns only the main thread + Example: [ (1234, [ @@ -2632,7 +2661,7 @@ Raises: static PyObject * _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self) -/*[clinic end generated code: output=666192b90c69d567 input=331dbe370578badf]*/ +/*[clinic end generated code: output=666192b90c69d567 input=f756f341206f9116]*/ { PyObject* result = NULL; // Read interpreter state into opaque buffer @@ -2655,6 +2684,28 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self _Py_hashtable_clear(self->code_object_cache); } + // If only_active_thread is true, we need to determine which thread holds the GIL + PyThreadState* gil_holder = NULL; + if (self->only_active_thread) { + // The GIL state is already in interp_state_buffer, just read from there + // Check if GIL is locked + int gil_locked = GET_MEMBER(int, interp_state_buffer, + self->debug_offsets.interpreter_state.gil_runtime_state_locked); + + if (gil_locked) { + // Get the last holder (current holder when GIL is locked) + gil_holder = GET_MEMBER(PyThreadState*, interp_state_buffer, + self->debug_offsets.interpreter_state.gil_runtime_state_holder); + } else { + // GIL is not locked, return empty list + result = PyList_New(0); + if (!result) { + set_exception_cause(self, PyExc_MemoryError, "Failed to create empty result list"); + } + goto exit; + } + } + #ifdef Py_GIL_DISABLED // Check TLBC generation and invalidate cache if needed uint32_t current_tlbc_generation = GET_MEMBER(uint32_t, interp_state_buffer, @@ -2666,7 +2717,10 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self #endif uintptr_t current_tstate; - if (self->tstate_addr == 0) { + if (self->only_active_thread && gil_holder != NULL) { + // We have the GIL holder, process only that thread + current_tstate = (uintptr_t)gil_holder; + } else if (self->tstate_addr == 0) { // Get threads head from buffer current_tstate = GET_MEMBER(uintptr_t, interp_state_buffer, self->debug_offsets.interpreter_state.threads_head); @@ -2700,10 +2754,14 @@ _remote_debugging_RemoteUnwinder_get_stack_trace_impl(RemoteUnwinderObject *self if (self->tstate_addr) { break; } + + // If we're only processing the GIL holder, we're done after one iteration + if (self->only_active_thread && gil_holder != NULL) { + break; + } } exit: - _Py_RemoteDebug_ClearCache(&self->handle); return result; } @@ -2827,11 +2885,9 @@ _remote_debugging_RemoteUnwinder_get_all_awaited_by_impl(RemoteUnwinderObject *s goto result_err; } - _Py_RemoteDebug_ClearCache(&self->handle); return result; result_err: - _Py_RemoteDebug_ClearCache(&self->handle); Py_XDECREF(result); return NULL; } @@ -2898,11 +2954,9 @@ _remote_debugging_RemoteUnwinder_get_async_stack_trace_impl(RemoteUnwinderObject goto cleanup; } - _Py_RemoteDebug_ClearCache(&self->handle); return result; cleanup: - _Py_RemoteDebug_ClearCache(&self->handle); Py_XDECREF(result); return NULL; } @@ -2928,7 +2982,6 @@ RemoteUnwinder_dealloc(PyObject *op) } #endif if (self->handle.pid != 0) { - _Py_RemoteDebug_ClearCache(&self->handle); _Py_RemoteDebug_CleanupProcHandle(&self->handle); } PyObject_Del(self); diff --git a/Modules/_stat.c b/Modules/_stat.c index f11ca7d23b4..1dabf2f6d5b 100644 --- a/Modules/_stat.c +++ b/Modules/_stat.c @@ -57,7 +57,7 @@ typedef unsigned short mode_t; * Only the names are defined by POSIX but not their value. All common file * types seems to have the same numeric value on all platforms, though. * - * pyport.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK + * fileutils.h guarantees S_IFMT, S_IFDIR, S_IFCHR, S_IFREG and S_IFLNK */ #ifndef S_IFBLK @@ -86,7 +86,7 @@ typedef unsigned short mode_t; /* S_ISXXX() - * pyport.h defines S_ISDIR(), S_ISREG() and S_ISCHR() + * fileutils.h defines S_ISDIR(), S_ISREG() and S_ISCHR() */ #ifndef S_ISBLK diff --git a/Modules/_testinternalcapi.c b/Modules/_testinternalcapi.c index 804cb4e4d1c..fdf22a0c994 100644 --- a/Modules/_testinternalcapi.c +++ b/Modules/_testinternalcapi.c @@ -21,6 +21,7 @@ #include "pycore_fileutils.h" // _Py_normpath() #include "pycore_flowgraph.h" // _PyCompile_OptimizeCfg() #include "pycore_frame.h" // _PyInterpreterFrame +#include "pycore_function.h" // _PyFunction_GET_BUILTINS #include "pycore_gc.h" // PyGC_Head #include "pycore_hashtable.h" // _Py_hashtable_new() #include "pycore_import.h" // _PyImport_ClearExtension() @@ -1022,7 +1023,7 @@ get_code_var_counts(PyObject *self, PyObject *_args, PyObject *_kwargs) globalsns = PyFunction_GET_GLOBALS(codearg); } if (builtinsns == NULL) { - builtinsns = PyFunction_GET_BUILTINS(codearg); + builtinsns = _PyFunction_GET_BUILTINS(codearg); } codearg = PyFunction_GET_CODE(codearg); } @@ -1190,7 +1191,7 @@ verify_stateless_code(PyObject *self, PyObject *args, PyObject *kwargs) globalsns = PyFunction_GET_GLOBALS(codearg); } if (builtinsns == NULL) { - builtinsns = PyFunction_GET_BUILTINS(codearg); + builtinsns = _PyFunction_GET_BUILTINS(codearg); } codearg = PyFunction_GET_CODE(codearg); } diff --git a/Modules/blake2module.c b/Modules/blake2module.c index 6c4349ac06b..163f238a426 100644 --- a/Modules/blake2module.c +++ b/Modules/blake2module.c @@ -43,25 +43,25 @@ // SIMD256 can't be compiled on macOS ARM64, and performance of SIMD128 isn't // great; but when compiling a universal2 binary, autoconf will set -// HACL_CAN_COMPILE_SIMD128 and HACL_CAN_COMPILE_SIMD256 because they *can* be -// compiled on x86_64. If we're on macOS ARM64, disable these preprocessor -// symbols. +// _Py_HACL_CAN_COMPILE_VEC{128,256} because they *can* be compiled on x86_64. +// If we're on macOS ARM64, we however disable these preprocessor symbols. #if defined(__APPLE__) && defined(__arm64__) -# undef HACL_CAN_COMPILE_SIMD128 -# undef HACL_CAN_COMPILE_SIMD256 +# undef _Py_HACL_CAN_COMPILE_VEC128 +# undef _Py_HACL_CAN_COMPILE_VEC256 #endif -// Small mismatch between the variable names Python defines as part of configure -// at the ones HACL* expects to be set in order to enable those headers. -#define HACL_CAN_COMPILE_VEC128 HACL_CAN_COMPILE_SIMD128 -#define HACL_CAN_COMPILE_VEC256 HACL_CAN_COMPILE_SIMD256 +// HACL* expects HACL_CAN_COMPILE_VEC* macros to be set in order to enable +// the corresponding SIMD instructions so we need to "forward" the values +// we just deduced above. +#define HACL_CAN_COMPILE_VEC128 _Py_HACL_CAN_COMPILE_VEC128 +#define HACL_CAN_COMPILE_VEC256 _Py_HACL_CAN_COMPILE_VEC256 #include "_hacl/Hacl_Hash_Blake2s.h" #include "_hacl/Hacl_Hash_Blake2b.h" -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 #include "_hacl/Hacl_Hash_Blake2s_Simd128.h" #endif -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 #include "_hacl/Hacl_Hash_Blake2b_Simd256.h" #endif @@ -88,7 +88,7 @@ blake2_get_state(PyObject *module) return (Blake2State *)state; } -#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256) +#if defined(_Py_HACL_CAN_COMPILE_VEC128) || defined(_Py_HACL_CAN_COMPILE_VEC256) static inline Blake2State * blake2_get_state_from_type(PyTypeObject *module) { @@ -181,7 +181,7 @@ blake2module_init_cpu_features(Blake2State *state) #undef ECX_SSE3 #undef EBX_AVX2 -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 // TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection state->can_run_simd128 = sse && sse2 && sse3 && sse41 && sse42 && cmov; #else @@ -191,7 +191,7 @@ blake2module_init_cpu_features(Blake2State *state) state->can_run_simd128 = false; #endif -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 // TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection state->can_run_simd256 = state->can_run_simd128 && avx && avx2; #else @@ -332,18 +332,18 @@ is_blake2s(blake2_impl impl) static inline blake2_impl type_to_impl(PyTypeObject *type) { -#if defined(HACL_CAN_COMPILE_SIMD128) || defined(HACL_CAN_COMPILE_SIMD256) +#if defined(_Py_HACL_CAN_COMPILE_VEC128) || defined(_Py_HACL_CAN_COMPILE_VEC256) Blake2State *st = blake2_get_state_from_type(type); #endif if (!strcmp(type->tp_name, blake2b_type_spec.name)) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 return st->can_run_simd256 ? Blake2b_256 : Blake2b; #else return Blake2b; #endif } else if (!strcmp(type->tp_name, blake2s_type_spec.name)) { -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 return st->can_run_simd128 ? Blake2s_128 : Blake2s; #else return Blake2s; @@ -357,10 +357,10 @@ typedef struct { union { Hacl_Hash_Blake2s_state_t *blake2s_state; Hacl_Hash_Blake2b_state_t *blake2b_state; -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 Hacl_Hash_Blake2s_Simd128_state_t *blake2s_128_state; #endif -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 Hacl_Hash_Blake2b_Simd256_state_t *blake2b_256_state; #endif }; @@ -429,13 +429,13 @@ blake2_update_unlocked(Blake2Object *self, uint8_t *buf, Py_ssize_t len) switch (self->impl) { // blake2b_256_state and blake2s_128_state must be if'd since // otherwise this results in an unresolved symbol at link-time. -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: HACL_UPDATE(Hacl_Hash_Blake2b_Simd256_update, self->blake2b_256_state, buf, len); return; #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: HACL_UPDATE(Hacl_Hash_Blake2s_Simd128_update, self->blake2s_128_state, buf, len); @@ -555,12 +555,12 @@ py_blake2_new(PyTypeObject *type, PyObject *data, int digest_size, // Ensure that the states are NULL-initialized in case of an error. // See: py_blake2_clear() for more details. switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: self->blake2b_256_state = NULL; break; #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: self->blake2s_128_state = NULL; break; @@ -623,12 +623,12 @@ py_blake2_new(PyTypeObject *type, PyObject *data, int digest_size, } while (0) switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: BLAKE2_MALLOC(Blake2b_Simd256, self->blake2b_256_state); break; #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: BLAKE2_MALLOC(Blake2s_Simd128, self->blake2s_128_state); break; @@ -756,12 +756,12 @@ blake2_blake2b_copy_unlocked(Blake2Object *self, Blake2Object *cpy) } while (0) switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: BLAKE2_COPY(Blake2b_Simd256, blake2b_256_state); break; #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: BLAKE2_COPY(Blake2s_Simd128, blake2s_128_state); break; @@ -787,17 +787,19 @@ error: /*[clinic input] _blake2.blake2b.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -_blake2_blake2b_copy_impl(Blake2Object *self) -/*[clinic end generated code: output=622d1c56b91c50d8 input=e383c2d199fd8a2e]*/ +_blake2_blake2b_copy_impl(Blake2Object *self, PyTypeObject *cls) +/*[clinic end generated code: output=5f8ea31c56c52287 input=f38f3475e9aec98d]*/ { int rc; Blake2Object *cpy; - if ((cpy = new_Blake2Object(Py_TYPE(self))) == NULL) { + if ((cpy = new_Blake2Object(cls)) == NULL) { return NULL; } @@ -838,12 +840,12 @@ static uint8_t blake2_blake2b_compute_digest(Blake2Object *self, uint8_t *digest) { switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: return Hacl_Hash_Blake2b_Simd256_digest( self->blake2b_256_state, digest); #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: return Hacl_Hash_Blake2s_Simd128_digest( self->blake2s_128_state, digest); @@ -921,11 +923,11 @@ static Hacl_Hash_Blake2b_index hacl_get_blake2_info(Blake2Object *self) { switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: return Hacl_Hash_Blake2b_Simd256_info(self->blake2b_256_state); #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: return Hacl_Hash_Blake2s_Simd128_info(self->blake2s_128_state); #endif @@ -973,12 +975,12 @@ py_blake2_clear(PyObject *op) } while (0) switch (self->impl) { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 case Blake2b_256: BLAKE2_FREE(Blake2b_Simd256, self->blake2b_256_state); break; #endif -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 case Blake2s_128: BLAKE2_FREE(Blake2s_Simd128, self->blake2s_128_state); break; diff --git a/Modules/clinic/_remote_debugging_module.c.h b/Modules/clinic/_remote_debugging_module.c.h index 5c313a2d664..e80b24b54c0 100644 --- a/Modules/clinic/_remote_debugging_module.c.h +++ b/Modules/clinic/_remote_debugging_module.c.h @@ -10,7 +10,8 @@ preserve #include "pycore_modsupport.h" // _PyArg_UnpackKeywords() PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__, -"RemoteUnwinder(pid, *, all_threads=False, debug=False)\n" +"RemoteUnwinder(pid, *, all_threads=False, only_active_thread=False,\n" +" debug=False)\n" "--\n" "\n" "Initialize a new RemoteUnwinder object for debugging a remote Python process.\n" @@ -19,6 +20,8 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__, " pid: Process ID of the target Python process to debug\n" " all_threads: If True, initialize state for all threads in the process.\n" " If False, only initialize for the main thread.\n" +" only_active_thread: If True, only sample the thread holding the GIL.\n" +" Cannot be used together with all_threads=True.\n" " debug: If True, chain exceptions to explain the sequence of events that\n" " lead to the exception.\n" "\n" @@ -28,11 +31,13 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder___init____doc__, "Raises:\n" " PermissionError: If access to the target process is denied\n" " OSError: If unable to attach to the target process or access its memory\n" -" RuntimeError: If unable to read debug information from the target process"); +" RuntimeError: If unable to read debug information from the target process\n" +" ValueError: If both all_threads and only_active_thread are True"); static int _remote_debugging_RemoteUnwinder___init___impl(RemoteUnwinderObject *self, int pid, int all_threads, + int only_active_thread, int debug); static int @@ -41,7 +46,7 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje int return_value = -1; #if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE) - #define NUM_KEYWORDS 3 + #define NUM_KEYWORDS 4 static struct { PyGC_Head _this_is_not_used; PyObject_VAR_HEAD @@ -50,7 +55,7 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje } _kwtuple = { .ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS) .ob_hash = -1, - .ob_item = { &_Py_ID(pid), &_Py_ID(all_threads), &_Py_ID(debug), }, + .ob_item = { &_Py_ID(pid), &_Py_ID(all_threads), &_Py_ID(only_active_thread), &_Py_ID(debug), }, }; #undef NUM_KEYWORDS #define KWTUPLE (&_kwtuple.ob_base.ob_base) @@ -59,19 +64,20 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje # define KWTUPLE NULL #endif // !Py_BUILD_CORE - static const char * const _keywords[] = {"pid", "all_threads", "debug", NULL}; + static const char * const _keywords[] = {"pid", "all_threads", "only_active_thread", "debug", NULL}; static _PyArg_Parser _parser = { .keywords = _keywords, .fname = "RemoteUnwinder", .kwtuple = KWTUPLE, }; #undef KWTUPLE - PyObject *argsbuf[3]; + PyObject *argsbuf[4]; PyObject * const *fastargs; Py_ssize_t nargs = PyTuple_GET_SIZE(args); Py_ssize_t noptargs = nargs + (kwargs ? PyDict_GET_SIZE(kwargs) : 0) - 1; int pid; int all_threads = 0; + int only_active_thread = 0; int debug = 0; fastargs = _PyArg_UnpackKeywords(_PyTuple_CAST(args)->ob_item, nargs, kwargs, NULL, &_parser, @@ -95,12 +101,21 @@ _remote_debugging_RemoteUnwinder___init__(PyObject *self, PyObject *args, PyObje goto skip_optional_kwonly; } } - debug = PyObject_IsTrue(fastargs[2]); + if (fastargs[2]) { + only_active_thread = PyObject_IsTrue(fastargs[2]); + if (only_active_thread < 0) { + goto exit; + } + if (!--noptargs) { + goto skip_optional_kwonly; + } + } + debug = PyObject_IsTrue(fastargs[3]); if (debug < 0) { goto exit; } skip_optional_kwonly: - return_value = _remote_debugging_RemoteUnwinder___init___impl((RemoteUnwinderObject *)self, pid, all_threads, debug); + return_value = _remote_debugging_RemoteUnwinder___init___impl((RemoteUnwinderObject *)self, pid, all_threads, only_active_thread, debug); exit: return return_value; @@ -110,13 +125,18 @@ PyDoc_STRVAR(_remote_debugging_RemoteUnwinder_get_stack_trace__doc__, "get_stack_trace($self, /)\n" "--\n" "\n" -"Returns a list of stack traces for all threads in the target process.\n" +"Returns a list of stack traces for threads in the target process.\n" "\n" "Each element in the returned list is a tuple of (thread_id, frame_list), where:\n" "- thread_id is the OS thread identifier\n" "- frame_list is a list of tuples (function_name, filename, line_number) representing\n" " the Python stack frames for that thread, ordered from most recent to oldest\n" "\n" +"The threads returned depend on the initialization parameters:\n" +"- If only_active_thread was True: returns only the thread holding the GIL\n" +"- If all_threads was True: returns all threads\n" +"- Otherwise: returns only the main thread\n" +"\n" "Example:\n" " [\n" " (1234, [\n" @@ -253,4 +273,4 @@ _remote_debugging_RemoteUnwinder_get_async_stack_trace(PyObject *self, PyObject return return_value; } -/*[clinic end generated code: output=774ec34aa653402d input=a9049054013a1b77]*/ +/*[clinic end generated code: output=a37ab223d5081b16 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/blake2module.c.h b/Modules/clinic/blake2module.c.h index 9e9cd56e569..97d010d03a4 100644 --- a/Modules/clinic/blake2module.c.h +++ b/Modules/clinic/blake2module.c.h @@ -434,15 +434,19 @@ PyDoc_STRVAR(_blake2_blake2b_copy__doc__, "Return a copy of the hash object."); #define _BLAKE2_BLAKE2B_COPY_METHODDEF \ - {"copy", (PyCFunction)_blake2_blake2b_copy, METH_NOARGS, _blake2_blake2b_copy__doc__}, + {"copy", _PyCFunction_CAST(_blake2_blake2b_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _blake2_blake2b_copy__doc__}, static PyObject * -_blake2_blake2b_copy_impl(Blake2Object *self); +_blake2_blake2b_copy_impl(Blake2Object *self, PyTypeObject *cls); static PyObject * -_blake2_blake2b_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) +_blake2_blake2b_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _blake2_blake2b_copy_impl((Blake2Object *)self); + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; + } + return _blake2_blake2b_copy_impl((Blake2Object *)self, cls); } PyDoc_STRVAR(_blake2_blake2b_update__doc__, @@ -502,4 +506,4 @@ _blake2_blake2b_hexdigest(PyObject *self, PyObject *Py_UNUSED(ignored)) { return _blake2_blake2b_hexdigest_impl((Blake2Object *)self); } -/*[clinic end generated code: output=eed18dcfaf6f7731 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=60a4abbcb8950fe5 input=a9049054013a1b77]*/ diff --git a/Modules/clinic/mathmodule.c.h b/Modules/clinic/mathmodule.c.h index fbb012fb6dd..a443c48faaa 100644 --- a/Modules/clinic/mathmodule.c.h +++ b/Modules/clinic/mathmodule.c.h @@ -84,6 +84,40 @@ PyDoc_STRVAR(math_floor__doc__, #define MATH_FLOOR_METHODDEF \ {"floor", (PyCFunction)math_floor, METH_O, math_floor__doc__}, +PyDoc_STRVAR(math_signbit__doc__, +"signbit($module, x, /)\n" +"--\n" +"\n" +"Return True if the sign of x is negative and False otherwise."); + +#define MATH_SIGNBIT_METHODDEF \ + {"signbit", (PyCFunction)math_signbit, METH_O, math_signbit__doc__}, + +static PyObject * +math_signbit_impl(PyObject *module, double x); + +static PyObject * +math_signbit(PyObject *module, PyObject *arg) +{ + PyObject *return_value = NULL; + double x; + + if (PyFloat_CheckExact(arg)) { + x = PyFloat_AS_DOUBLE(arg); + } + else + { + x = PyFloat_AsDouble(arg); + if (x == -1.0 && PyErr_Occurred()) { + goto exit; + } + } + return_value = math_signbit_impl(module, x); + +exit: + return return_value; +} + PyDoc_STRVAR(math_fsum__doc__, "fsum($module, seq, /)\n" "--\n" @@ -1178,4 +1212,4 @@ math_ulp(PyObject *module, PyObject *arg) exit: return return_value; } -/*[clinic end generated code: output=44bba3a0a052a364 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=4e3fa94d026f027b input=a9049054013a1b77]*/ diff --git a/Modules/clinic/sha3module.c.h b/Modules/clinic/sha3module.c.h index d6d44bf4c51..1f631ff406e 100644 --- a/Modules/clinic/sha3module.c.h +++ b/Modules/clinic/sha3module.c.h @@ -100,15 +100,19 @@ PyDoc_STRVAR(_sha3_sha3_224_copy__doc__, "Return a copy of the hash object."); #define _SHA3_SHA3_224_COPY_METHODDEF \ - {"copy", (PyCFunction)_sha3_sha3_224_copy, METH_NOARGS, _sha3_sha3_224_copy__doc__}, + {"copy", _PyCFunction_CAST(_sha3_sha3_224_copy), METH_METHOD|METH_FASTCALL|METH_KEYWORDS, _sha3_sha3_224_copy__doc__}, static PyObject * -_sha3_sha3_224_copy_impl(SHA3object *self); +_sha3_sha3_224_copy_impl(SHA3object *self, PyTypeObject *cls); static PyObject * -_sha3_sha3_224_copy(PyObject *self, PyObject *Py_UNUSED(ignored)) +_sha3_sha3_224_copy(PyObject *self, PyTypeObject *cls, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) { - return _sha3_sha3_224_copy_impl((SHA3object *)self); + if (nargs || (kwnames && PyTuple_GET_SIZE(kwnames))) { + PyErr_SetString(PyExc_TypeError, "copy() takes no arguments"); + return NULL; + } + return _sha3_sha3_224_copy_impl((SHA3object *)self, cls); } PyDoc_STRVAR(_sha3_sha3_224_digest__doc__, @@ -306,4 +310,4 @@ _sha3_shake_128_hexdigest(PyObject *self, PyObject *const *args, Py_ssize_t narg exit: return return_value; } -/*[clinic end generated code: output=c17e3ec670afe253 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=48be77f8a31e8a3e input=a9049054013a1b77]*/ diff --git a/Modules/hmacmodule.c b/Modules/hmacmodule.c index e7a5ccbb19b..95e400231bb 100644 --- a/Modules/hmacmodule.c +++ b/Modules/hmacmodule.c @@ -31,14 +31,15 @@ #endif #if defined(__APPLE__) && defined(__arm64__) -# undef HACL_CAN_COMPILE_SIMD128 -# undef HACL_CAN_COMPILE_SIMD256 +# undef _Py_HACL_CAN_COMPILE_VEC128 +# undef _Py_HACL_CAN_COMPILE_VEC256 #endif -// Small mismatch between the variable names Python defines as part of configure -// at the ones HACL* expects to be set in order to enable those headers. -#define HACL_CAN_COMPILE_VEC128 HACL_CAN_COMPILE_SIMD128 -#define HACL_CAN_COMPILE_VEC256 HACL_CAN_COMPILE_SIMD256 +// HACL* expects HACL_CAN_COMPILE_VEC* macros to be set in order to enable +// the corresponding SIMD instructions so we need to "forward" the values +// we just deduced above. +#define HACL_CAN_COMPILE_VEC128 _Py_HACL_CAN_COMPILE_VEC128 +#define HACL_CAN_COMPILE_VEC256 _Py_HACL_CAN_COMPILE_VEC256 #include "_hacl/Hacl_HMAC.h" #include "_hacl/Hacl_Streaming_HMAC.h" // Hacl_Agile_Hash_* identifiers @@ -361,7 +362,7 @@ narrow_hmac_hash_kind(hmacmodule_state *state, HMAC_Hash_Kind kind) { switch (kind) { case Py_hmac_kind_hmac_blake2s_32: { -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 if (state->can_run_simd128) { return Py_hmac_kind_hmac_vectorized_blake2s_32; } @@ -369,7 +370,7 @@ narrow_hmac_hash_kind(hmacmodule_state *state, HMAC_Hash_Kind kind) return kind; } case Py_hmac_kind_hmac_blake2b_32: { -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 if (state->can_run_simd256) { return Py_hmac_kind_hmac_vectorized_blake2b_32; } @@ -1601,7 +1602,7 @@ hmacmodule_init_cpu_features(hmacmodule_state *state) #undef ECX_SSE3 #undef EBX_AVX2 -#if HACL_CAN_COMPILE_SIMD128 +#if _Py_HACL_CAN_COMPILE_VEC128 // TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection state->can_run_simd128 = sse && sse2 && sse3 && sse41 && sse42 && cmov; #else @@ -1611,7 +1612,7 @@ hmacmodule_init_cpu_features(hmacmodule_state *state) state->can_run_simd128 = false; #endif -#if HACL_CAN_COMPILE_SIMD256 +#if _Py_HACL_CAN_COMPILE_VEC256 // TODO(picnixz): use py_cpuid_features (gh-125022) to improve detection state->can_run_simd256 = state->can_run_simd128 && avx && avx2; #else diff --git a/Modules/mathmodule.c b/Modules/mathmodule.c index bbbb4911568..033de0b2907 100644 --- a/Modules/mathmodule.c +++ b/Modules/mathmodule.c @@ -1233,6 +1233,23 @@ FUNC2(remainder, m_remainder, "Return x - n*y where n*y is the closest integer multiple of y.\n" "In the case where x is exactly halfway between two multiples of\n" "y, the nearest even value of n is used. The result is always exact.") + +/*[clinic input] +math.signbit + + x: double + / + +Return True if the sign of x is negative and False otherwise. +[clinic start generated code]*/ + +static PyObject * +math_signbit_impl(PyObject *module, double x) +/*[clinic end generated code: output=20c5f20156a9b871 input=3d3493fbcb5bdb3e]*/ +{ + return PyBool_FromLong(signbit(x)); +} + FUNC1D(sin, sin, 0, "sin($module, x, /)\n--\n\n" "Return the sine of x (measured in radians).", @@ -3148,7 +3165,7 @@ static PyObject * math_issubnormal_impl(PyObject *module, double x) /*[clinic end generated code: output=4e76ac98ddcae761 input=9a20aba7107d0d95]*/ { -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L +#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L return PyBool_FromLong(issubnormal(x)); #else return PyBool_FromLong(isfinite(x) && x && !isnormal(x)); @@ -4199,6 +4216,7 @@ static PyMethodDef math_methods[] = { MATH_POW_METHODDEF MATH_RADIANS_METHODDEF {"remainder", _PyCFunction_CAST(math_remainder), METH_FASTCALL, math_remainder_doc}, + MATH_SIGNBIT_METHODDEF {"sin", math_sin, METH_O, math_sin_doc}, {"sinh", math_sinh, METH_O, math_sinh_doc}, {"sqrt", math_sqrt, METH_O, math_sqrt_doc}, diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c index 7dc5ef39a56..b570f81b7cf 100644 --- a/Modules/posixmodule.c +++ b/Modules/posixmodule.c @@ -685,7 +685,8 @@ static void reset_remotedebug_data(PyThreadState *tstate) { tstate->remote_debugger_support.debugger_pending_call = 0; - memset(tstate->remote_debugger_support.debugger_script_path, 0, MAX_SCRIPT_PATH_SIZE); + memset(tstate->remote_debugger_support.debugger_script_path, 0, + Py_MAX_SCRIPT_PATH_SIZE); } diff --git a/Modules/sha3module.c b/Modules/sha3module.c index face90a6094..5764556bb68 100644 --- a/Modules/sha3module.c +++ b/Modules/sha3module.c @@ -239,16 +239,17 @@ SHA3_traverse(PyObject *self, visitproc visit, void *arg) /*[clinic input] _sha3.sha3_224.copy + cls: defining_class + Return a copy of the hash object. [clinic start generated code]*/ static PyObject * -_sha3_sha3_224_copy_impl(SHA3object *self) -/*[clinic end generated code: output=6c537411ecdcda4c input=93a44aaebea51ba8]*/ +_sha3_sha3_224_copy_impl(SHA3object *self, PyTypeObject *cls) +/*[clinic end generated code: output=13958b44c244013e input=7134b4dc0a2fbcac]*/ { SHA3object *newobj; - - if ((newobj = newSHA3object(Py_TYPE(self))) == NULL) { + if ((newobj = newSHA3object(cls)) == NULL) { return NULL; } HASHLIB_ACQUIRE_LOCK(self); |