Python-checkins
Threads by month
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
February 2023
- 1 participants
- 411 discussions
28 Feb '23
https://github.com/python/cpython/commit/360ef843d8fc03aad38ed84f9f45026ab0…
commit: 360ef843d8fc03aad38ed84f9f45026ab08ca4f4
branch: main
author: Anthony Sottile <asottile(a)umich.edu>
committer: erlend-aasland <erlend.aasland(a)protonmail.com>
date: 2023-02-28T22:34:06+01:00
summary:
gh-99108: Add missing md5/sha1 defines to Modules/Setup (#102308)
files:
M Modules/Setup
diff --git a/Modules/Setup b/Modules/Setup
index ff432e2929ec..1c6f2f7ea518 100644
--- a/Modules/Setup
+++ b/Modules/Setup
@@ -163,8 +163,8 @@ PYTHONPATH=$(COREPYTHONPATH)
# hashing builtins
#_blake2 _blake2/blake2module.c _blake2/blake2b_impl.c _blake2/blake2s_impl.c
-#_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c
-#_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c
+#_md5 md5module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_MD5.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
+#_sha1 sha1module.c -I$(srcdir)/Modules/_hacl/include _hacl/Hacl_Hash_SHA1.c -D_BSD_SOURCE -D_DEFAULT_SOURCE
#_sha2 sha2module.c -I$(srcdir)/Modules/_hacl/include Modules/_hacl/libHacl_Streaming_SHA2.a
#_sha3 _sha3/sha3module.c
1
0
28 Feb '23
https://github.com/python/cpython/commit/880437d4ec65ef35d505eeaff9dad5c665…
commit: 880437d4ec65ef35d505eeaff9dad5c6654dbc1a
branch: main
author: Eric Snow <ericsnowcurrently(a)gmail.com>
committer: ericsnowcurrently <ericsnowcurrently(a)gmail.com>
date: 2023-02-28T14:16:39-07:00
summary:
gh-100227: Move _str_replace_inf to PyInterpreterState (gh-102333)
https://github.com/python/cpython/issues/100227
files:
M Include/internal/pycore_global_objects.h
M Parser/asdl_c.py
M Python/Python-ast.c
M Python/ast_unparse.c
diff --git a/Include/internal/pycore_global_objects.h b/Include/internal/pycore_global_objects.h
index d0461fa7e82e..30c7c4e3bbd0 100644
--- a/Include/internal/pycore_global_objects.h
+++ b/Include/internal/pycore_global_objects.h
@@ -27,8 +27,6 @@ extern "C" {
_PyRuntime.cached_objects.NAME
struct _Py_cached_objects {
- PyObject *str_replace_inf;
-
PyObject *interned_strings;
};
@@ -67,11 +65,14 @@ struct _Py_static_objects {
(interp)->cached_objects.NAME
struct _Py_interp_cached_objects {
- int _not_set;
+ /* AST */
+ PyObject *str_replace_inf;
+
/* object.__reduce__ */
PyObject *objreduce;
PyObject *type_slots_pname;
pytype_slotdef *type_slots_ptrs[MAX_EQUIV];
+
};
#define _Py_INTERP_STATIC_OBJECT(interp, NAME) \
diff --git a/Parser/asdl_c.py b/Parser/asdl_c.py
index db0e597b7a5a..b44e303ac259 100755
--- a/Parser/asdl_c.py
+++ b/Parser/asdl_c.py
@@ -1484,9 +1484,7 @@ def generate_ast_fini(module_state, f):
for s in module_state:
f.write(" Py_CLEAR(state->" + s + ');\n')
f.write(textwrap.dedent("""
- if (_PyInterpreterState_Get() == _PyInterpreterState_Main()) {
- Py_CLEAR(_Py_CACHED_OBJECT(str_replace_inf));
- }
+ Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf));
#if !defined(NDEBUG)
state->initialized = -1;
diff --git a/Python/Python-ast.c b/Python/Python-ast.c
index d113c47b9539..6c878474afb1 100644
--- a/Python/Python-ast.c
+++ b/Python/Python-ast.c
@@ -263,9 +263,7 @@ void _PyAST_Fini(PyInterpreterState *interp)
Py_CLEAR(state->vararg);
Py_CLEAR(state->withitem_type);
- if (_PyInterpreterState_Get() == _PyInterpreterState_Main()) {
- Py_CLEAR(_Py_CACHED_OBJECT(str_replace_inf));
- }
+ Py_CLEAR(_Py_INTERP_CACHED_OBJECT(interp, str_replace_inf));
#if !defined(NDEBUG)
state->initialized = -1;
diff --git a/Python/ast_unparse.c b/Python/ast_unparse.c
index 79b2e2f15ba2..8aff045101cc 100644
--- a/Python/ast_unparse.c
+++ b/Python/ast_unparse.c
@@ -1,5 +1,6 @@
#include "Python.h"
#include "pycore_ast.h" // expr_ty
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_runtime.h" // _Py_ID()
#include <float.h> // DBL_MAX_10_EXP
#include <stdbool.h>
@@ -13,7 +14,10 @@ _Py_DECLARE_STR(open_br, "{");
_Py_DECLARE_STR(dbl_open_br, "{{");
_Py_DECLARE_STR(close_br, "}");
_Py_DECLARE_STR(dbl_close_br, "}}");
-#define _str_replace_inf _Py_CACHED_OBJECT(str_replace_inf)
+
+/* We would statically initialize this if doing so were simple enough. */
+#define _str_replace_inf(interp) \
+ _Py_INTERP_CACHED_OBJECT(interp, str_replace_inf)
/* Forward declarations for recursion via helper functions. */
static PyObject *
@@ -78,10 +82,11 @@ append_repr(_PyUnicodeWriter *writer, PyObject *obj)
if ((PyFloat_CheckExact(obj) && Py_IS_INFINITY(PyFloat_AS_DOUBLE(obj))) ||
PyComplex_CheckExact(obj))
{
+ PyInterpreterState *interp = _PyInterpreterState_GET();
PyObject *new_repr = PyUnicode_Replace(
repr,
&_Py_ID(inf),
- _str_replace_inf,
+ _str_replace_inf(interp),
-1
);
Py_DECREF(repr);
@@ -916,9 +921,13 @@ append_ast_expr(_PyUnicodeWriter *writer, expr_ty e, int level)
static int
maybe_init_static_strings(void)
{
- if (!_str_replace_inf &&
- !(_str_replace_inf = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP))) {
- return -1;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ if (_str_replace_inf(interp) == NULL) {
+ PyObject *tmp = PyUnicode_FromFormat("1e%d", 1 + DBL_MAX_10_EXP);
+ if (tmp == NULL) {
+ return -1;
+ }
+ _str_replace_inf(interp) = tmp;
}
return 0;
}
1
0
28 Feb '23
https://github.com/python/cpython/commit/f300a1fa4c121f7807cbda4fc8bb26240c…
commit: f300a1fa4c121f7807cbda4fc8bb26240c69ea74
branch: main
author: Eric Snow <ericsnowcurrently(a)gmail.com>
committer: ericsnowcurrently <ericsnowcurrently(a)gmail.com>
date: 2023-02-28T13:14:40-07:00
summary:
gh-100227: Move the dtoa State to PyInterpreterState (gh-102331)
https://github.com/python/cpython/issues/100227
files:
M Include/internal/pycore_dtoa.h
M Include/internal/pycore_interp.h
M Include/internal/pycore_runtime.h
M Include/internal/pycore_runtime_init.h
M Python/dtoa.c
M Python/pystate.c
diff --git a/Include/internal/pycore_dtoa.h b/Include/internal/pycore_dtoa.h
index 67189cf0ade6..fb524770efed 100644
--- a/Include/internal/pycore_dtoa.h
+++ b/Include/internal/pycore_dtoa.h
@@ -24,10 +24,11 @@ Bigint {
#ifdef Py_USING_MEMORY_DEBUGGER
-struct _dtoa_runtime_state {
+struct _dtoa_state {
int _not_used;
};
-#define _dtoa_runtime_state_INIT {0}
+#define _dtoa_interp_state_INIT(INTERP) \
+ {0}
#else // !Py_USING_MEMORY_DEBUGGER
@@ -40,7 +41,7 @@ struct _dtoa_runtime_state {
#define Bigint_PREALLOC_SIZE \
((PRIVATE_MEM+sizeof(double)-1)/sizeof(double))
-struct _dtoa_runtime_state {
+struct _dtoa_state {
/* p5s is a linked list of powers of 5 of the form 5**(2**i), i >= 2 */
// XXX This should be freed during runtime fini.
struct Bigint *p5s;
@@ -48,9 +49,9 @@ struct _dtoa_runtime_state {
double preallocated[Bigint_PREALLOC_SIZE];
double *preallocated_next;
};
-#define _dtoa_runtime_state_INIT(runtime) \
+#define _dtoa_state_INIT(INTERP) \
{ \
- .preallocated_next = runtime.dtoa.preallocated, \
+ .preallocated_next = (INTERP)->dtoa.preallocated, \
}
#endif // !Py_USING_MEMORY_DEBUGGER
diff --git a/Include/internal/pycore_interp.h b/Include/internal/pycore_interp.h
index 60de31b336f6..7ef9c40153e4 100644
--- a/Include/internal/pycore_interp.h
+++ b/Include/internal/pycore_interp.h
@@ -16,6 +16,7 @@ extern "C" {
#include "pycore_code.h" // struct callable_cache
#include "pycore_context.h" // struct _Py_context_state
#include "pycore_dict_state.h" // struct _Py_dict_state
+#include "pycore_dtoa.h" // struct _dtoa_state
#include "pycore_exceptions.h" // struct _Py_exc_state
#include "pycore_floatobject.h" // struct _Py_float_state
#include "pycore_function.h" // FUNC_MAX_WATCHERS
@@ -139,6 +140,7 @@ struct _is {
struct _Py_unicode_state unicode;
struct _Py_float_state float_state;
struct _Py_long_state long_state;
+ struct _dtoa_state dtoa;
/* Using a cache is very effective since typically only a single slice is
created and then deleted again. */
PySliceObject *slice_cache;
diff --git a/Include/internal/pycore_runtime.h b/Include/internal/pycore_runtime.h
index 9ef270791576..2350eaab5976 100644
--- a/Include/internal/pycore_runtime.h
+++ b/Include/internal/pycore_runtime.h
@@ -11,7 +11,6 @@ extern "C" {
#include "pycore_atomic.h" /* _Py_atomic_address */
#include "pycore_ceval_state.h" // struct _ceval_runtime_state
#include "pycore_dict_state.h" // struct _Py_dict_runtime_state
-#include "pycore_dtoa.h" // struct _dtoa_runtime_state
#include "pycore_floatobject.h" // struct _Py_float_runtime_state
#include "pycore_faulthandler.h" // struct _faulthandler_runtime_state
#include "pycore_function.h" // struct _func_runtime_state
@@ -141,7 +140,6 @@ typedef struct pyruntimestate {
struct _ceval_runtime_state ceval;
struct _gilstate_runtime_state gilstate;
struct _getargs_runtime_state getargs;
- struct _dtoa_runtime_state dtoa;
struct _fileutils_state fileutils;
struct _faulthandler_runtime_state faulthandler;
struct _tracemalloc_runtime_state tracemalloc;
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index a8d5953ff98b..b54adf04761d 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -53,7 +53,6 @@ extern "C" {
.gilstate = { \
.check_enabled = 1, \
}, \
- .dtoa = _dtoa_runtime_state_INIT(runtime), \
.fileutils = { \
.force_ascii = -1, \
}, \
@@ -94,10 +93,10 @@ extern "C" {
}, \
}, \
}, \
- ._main_interpreter = _PyInterpreterState_INIT, \
+ ._main_interpreter = _PyInterpreterState_INIT(runtime._main_interpreter), \
}
-#define _PyInterpreterState_INIT \
+#define _PyInterpreterState_INIT(INTERP) \
{ \
.id_refcount = -1, \
.imports = IMPORTS_INIT, \
@@ -113,6 +112,7 @@ extern "C" {
{ .threshold = 10, }, \
}, \
}, \
+ .dtoa = _dtoa_state_INIT(&(INTERP)), \
.static_objects = { \
.singletons = { \
._not_used = 1, \
diff --git a/Python/dtoa.c b/Python/dtoa.c
index cff5f1b0658e..6ea60ac9946e 100644
--- a/Python/dtoa.c
+++ b/Python/dtoa.c
@@ -119,7 +119,7 @@
#include "Python.h"
#include "pycore_dtoa.h" // _PY_SHORT_FLOAT_REPR
-#include "pycore_runtime.h" // _PyRuntime
+#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include <stdlib.h> // exit()
/* if _PY_SHORT_FLOAT_REPR == 0, then don't even try to compile
@@ -339,9 +339,9 @@ typedef struct Bigint Bigint;
Bfree to PyMem_Free. Investigate whether this has any significant
performance on impact. */
-#define freelist _PyRuntime.dtoa.freelist
-#define private_mem _PyRuntime.dtoa.preallocated
-#define pmem_next _PyRuntime.dtoa.preallocated_next
+#define freelist interp->dtoa.freelist
+#define private_mem interp->dtoa.preallocated
+#define pmem_next interp->dtoa.preallocated_next
/* Allocate space for a Bigint with up to 1<<k digits */
@@ -351,6 +351,7 @@ Balloc(int k)
int x;
Bigint *rv;
unsigned int len;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
if (k <= Bigint_Kmax && (rv = freelist[k]))
freelist[k] = rv->next;
@@ -385,6 +386,7 @@ Bfree(Bigint *v)
if (v->k > Bigint_Kmax)
FREE((void*)v);
else {
+ PyInterpreterState *interp = _PyInterpreterState_GET();
v->next = freelist[v->k];
freelist[v->k] = v;
}
@@ -692,7 +694,8 @@ pow5mult(Bigint *b, int k)
if (!(k >>= 2))
return b;
- p5 = _PyRuntime.dtoa.p5s;
+ PyInterpreterState *interp = _PyInterpreterState_GET();
+ p5 = interp->dtoa.p5s;
if (!p5) {
/* first time */
p5 = i2b(625);
@@ -700,7 +703,7 @@ pow5mult(Bigint *b, int k)
Bfree(b);
return NULL;
}
- _PyRuntime.dtoa.p5s = p5;
+ interp->dtoa.p5s = p5;
p5->next = 0;
}
for(;;) {
diff --git a/Python/pystate.c b/Python/pystate.c
index 3c655bf38958..28606e4f32f7 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -3,7 +3,8 @@
#include "Python.h"
#include "pycore_ceval.h"
-#include "pycore_code.h" // stats
+#include "pycore_code.h" // stats
+#include "pycore_dtoa.h" // _dtoa_state_INIT()
#include "pycore_frame.h"
#include "pycore_initconfig.h"
#include "pycore_object.h" // _PyType_InitCache()
@@ -618,6 +619,18 @@ free_interpreter(PyInterpreterState *interp)
e.g. by PyMem_RawCalloc() or memset(), or otherwise pre-initialized.
The runtime state is not manipulated. Instead it is assumed that
the interpreter is getting added to the runtime.
+
+ Note that the main interpreter was statically initialized as part
+ of the runtime and most state is already set properly. That leaves
+ a small number of fields to initialize dynamically, as well as some
+ that are initialized lazily.
+
+ For subinterpreters we memcpy() the main interpreter in
+ PyInterpreterState_New(), leaving it in the same mostly-initialized
+ state. The only difference is that the interpreter has some
+ self-referential state that is statically initializexd to the
+ main interpreter. We fix those fields here, in addition
+ to the other dynamically initialized fields.
*/
static void
@@ -645,6 +658,11 @@ init_interpreter(PyInterpreterState *interp,
PyConfig_InitPythonConfig(&interp->config);
_PyType_InitCache(interp);
+ if (interp != &runtime->_main_interpreter) {
+ /* Fix the self-referential, statically initialized fields. */
+ interp->dtoa = (struct _dtoa_state)_dtoa_state_INIT(interp);
+ }
+
interp->_initialized = 1;
}
1
0
https://github.com/python/cpython/commit/b5ff38243355c06d665ba8245d461a0d82…
commit: b5ff38243355c06d665ba8245d461a0d82504581
branch: main
author: Guido van Rossum <guido(a)python.org>
committer: gvanrossum <gvanrossum(a)gmail.com>
date: 2023-02-28T08:49:35-08:00
summary:
GH-102305: Expand some macros in generated_cases.c.h (#102309)
* Emit straight stack_pointer[-i] instead of PEEK(i), POKE(i, ...)
* Expand JUMPBY() and NEXTOPARG(), and fix a perf bug
files:
M Python/generated_cases.c.h
M Tools/cases_generator/generate_cases.py
diff --git a/Python/generated_cases.c.h b/Python/generated_cases.c.h
index 271ba26f4895..f59f7c17451c 100644
--- a/Python/generated_cases.c.h
+++ b/Python/generated_cases.c.h
@@ -22,7 +22,7 @@
if (value == NULL) goto unbound_local_error;
Py_INCREF(value);
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
@@ -32,7 +32,7 @@
if (value == NULL) goto unbound_local_error;
Py_INCREF(value);
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
@@ -42,7 +42,7 @@
assert(value != NULL);
Py_INCREF(value);
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
@@ -52,12 +52,12 @@
value = GETITEM(consts, oparg);
Py_INCREF(value);
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
TARGET(STORE_FAST) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
SETLOCAL(oparg, value);
STACK_SHRINK(1);
DISPATCH();
@@ -73,8 +73,7 @@
Py_INCREF(value);
_tmp_2 = value;
}
- NEXTOPARG();
- JUMPBY(1);
+ oparg = (next_instr++)->op.arg;
{
PyObject *value;
value = GETLOCAL(oparg);
@@ -83,8 +82,8 @@
_tmp_1 = value;
}
STACK_GROW(2);
- POKE(1, _tmp_1);
- POKE(2, _tmp_2);
+ stack_pointer[-1] = _tmp_1;
+ stack_pointer[-2] = _tmp_2;
DISPATCH();
}
@@ -98,8 +97,7 @@
Py_INCREF(value);
_tmp_2 = value;
}
- NEXTOPARG();
- JUMPBY(1);
+ oparg = (next_instr++)->op.arg;
{
PyObject *value;
value = GETITEM(consts, oparg);
@@ -107,19 +105,18 @@
_tmp_1 = value;
}
STACK_GROW(2);
- POKE(1, _tmp_1);
- POKE(2, _tmp_2);
+ stack_pointer[-1] = _tmp_1;
+ stack_pointer[-2] = _tmp_2;
DISPATCH();
}
TARGET(STORE_FAST__LOAD_FAST) {
- PyObject *_tmp_1 = PEEK(1);
+ PyObject *_tmp_1 = stack_pointer[-1];
{
PyObject *value = _tmp_1;
SETLOCAL(oparg, value);
}
- NEXTOPARG();
- JUMPBY(1);
+ oparg = (next_instr++)->op.arg;
{
PyObject *value;
value = GETLOCAL(oparg);
@@ -127,19 +124,18 @@
Py_INCREF(value);
_tmp_1 = value;
}
- POKE(1, _tmp_1);
+ stack_pointer[-1] = _tmp_1;
DISPATCH();
}
TARGET(STORE_FAST__STORE_FAST) {
- PyObject *_tmp_1 = PEEK(1);
- PyObject *_tmp_2 = PEEK(2);
+ PyObject *_tmp_1 = stack_pointer[-1];
+ PyObject *_tmp_2 = stack_pointer[-2];
{
PyObject *value = _tmp_1;
SETLOCAL(oparg, value);
}
- NEXTOPARG();
- JUMPBY(1);
+ oparg = (next_instr++)->op.arg;
{
PyObject *value = _tmp_2;
SETLOCAL(oparg, value);
@@ -157,8 +153,7 @@
Py_INCREF(value);
_tmp_2 = value;
}
- NEXTOPARG();
- JUMPBY(1);
+ oparg = (next_instr++)->op.arg;
{
PyObject *value;
value = GETLOCAL(oparg);
@@ -167,13 +162,13 @@
_tmp_1 = value;
}
STACK_GROW(2);
- POKE(1, _tmp_1);
- POKE(2, _tmp_2);
+ stack_pointer[-1] = _tmp_1;
+ stack_pointer[-2] = _tmp_2;
DISPATCH();
}
TARGET(POP_TOP) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
Py_DECREF(value);
STACK_SHRINK(1);
DISPATCH();
@@ -183,13 +178,13 @@
PyObject *res;
res = NULL;
STACK_GROW(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(END_FOR) {
- PyObject *_tmp_1 = PEEK(1);
- PyObject *_tmp_2 = PEEK(2);
+ PyObject *_tmp_1 = stack_pointer[-1];
+ PyObject *_tmp_2 = stack_pointer[-2];
{
PyObject *value = _tmp_1;
Py_DECREF(value);
@@ -203,17 +198,17 @@
}
TARGET(UNARY_NEGATIVE) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
PyObject *res;
res = PyNumber_Negative(value);
Py_DECREF(value);
if (res == NULL) goto pop_1_error;
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(UNARY_NOT) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
PyObject *res;
int err = PyObject_IsTrue(value);
Py_DECREF(value);
@@ -225,23 +220,23 @@
res = Py_False;
}
Py_INCREF(res);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(UNARY_INVERT) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
PyObject *res;
res = PyNumber_Invert(value);
Py_DECREF(value);
if (res == NULL) goto pop_1_error;
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(BINARY_OP_MULTIPLY_INT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *prod;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
@@ -252,14 +247,14 @@
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
if (prod == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, prod);
- JUMPBY(1);
+ stack_pointer[-1] = prod;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_MULTIPLY_FLOAT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *prod;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
@@ -272,14 +267,14 @@
_Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
if (prod == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, prod);
- JUMPBY(1);
+ stack_pointer[-1] = prod;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_SUBTRACT_INT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *sub;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
@@ -290,14 +285,14 @@
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
if (sub == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, sub);
- JUMPBY(1);
+ stack_pointer[-1] = sub;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_SUBTRACT_FLOAT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *sub;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
@@ -309,14 +304,14 @@
_Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
if (sub == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, sub);
- JUMPBY(1);
+ stack_pointer[-1] = sub;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_ADD_UNICODE) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *res;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
@@ -327,14 +322,14 @@
_Py_DECREF_SPECIALIZED(right, _PyUnicode_ExactDealloc);
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(1);
+ stack_pointer[-1] = res;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_INPLACE_ADD_UNICODE) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyUnicode_CheckExact(left), BINARY_OP);
DEOPT_IF(Py_TYPE(right) != Py_TYPE(left), BINARY_OP);
@@ -367,8 +362,8 @@
}
TARGET(BINARY_OP_ADD_FLOAT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *sum;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyFloat_CheckExact(left), BINARY_OP);
@@ -381,14 +376,14 @@
_Py_DECREF_SPECIALIZED(left, _PyFloat_ExactDealloc);
if (sum == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, sum);
- JUMPBY(1);
+ stack_pointer[-1] = sum;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_OP_ADD_INT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *sum;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(left), BINARY_OP);
@@ -399,16 +394,16 @@
_Py_DECREF_SPECIALIZED(left, (destructor)PyObject_Free);
if (sum == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, sum);
- JUMPBY(1);
+ stack_pointer[-1] = sum;
+ next_instr += 1;
DISPATCH();
}
TARGET(BINARY_SUBSCR) {
PREDICTED(BINARY_SUBSCR);
static_assert(INLINE_CACHE_ENTRIES_BINARY_SUBSCR == 4, "incorrect cache size");
- PyObject *sub = PEEK(1);
- PyObject *container = PEEK(2);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *container = stack_pointer[-2];
PyObject *res;
#if ENABLE_SPECIALIZATION
_PyBinarySubscrCache *cache = (_PyBinarySubscrCache *)next_instr;
@@ -426,15 +421,15 @@
Py_DECREF(sub);
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(BINARY_SLICE) {
- PyObject *stop = PEEK(1);
- PyObject *start = PEEK(2);
- PyObject *container = PEEK(3);
+ PyObject *stop = stack_pointer[-1];
+ PyObject *start = stack_pointer[-2];
+ PyObject *container = stack_pointer[-3];
PyObject *res;
PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop);
// Can't use ERROR_IF() here, because we haven't
@@ -449,15 +444,15 @@
Py_DECREF(container);
if (res == NULL) goto pop_3_error;
STACK_SHRINK(2);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(STORE_SLICE) {
- PyObject *stop = PEEK(1);
- PyObject *start = PEEK(2);
- PyObject *container = PEEK(3);
- PyObject *v = PEEK(4);
+ PyObject *stop = stack_pointer[-1];
+ PyObject *start = stack_pointer[-2];
+ PyObject *container = stack_pointer[-3];
+ PyObject *v = stack_pointer[-4];
PyObject *slice = _PyBuildSlice_ConsumeRefs(start, stop);
int err;
if (slice == NULL) {
@@ -475,8 +470,8 @@
}
TARGET(BINARY_SUBSCR_LIST_INT) {
- PyObject *sub = PEEK(1);
- PyObject *list = PEEK(2);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *list = stack_pointer[-2];
PyObject *res;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
@@ -494,14 +489,14 @@
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
Py_DECREF(list);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(BINARY_SUBSCR_TUPLE_INT) {
- PyObject *sub = PEEK(1);
- PyObject *tuple = PEEK(2);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *tuple = stack_pointer[-2];
PyObject *res;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(sub), BINARY_SUBSCR);
@@ -519,14 +514,14 @@
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
Py_DECREF(tuple);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(BINARY_SUBSCR_DICT) {
- PyObject *sub = PEEK(1);
- PyObject *dict = PEEK(2);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *dict = stack_pointer[-2];
PyObject *res;
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(dict), BINARY_SUBSCR);
@@ -544,14 +539,14 @@
Py_DECREF(dict);
Py_DECREF(sub);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(BINARY_SUBSCR_GETITEM) {
- PyObject *sub = PEEK(1);
- PyObject *container = PEEK(2);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *container = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t func_version = read_u16(&next_instr[3].cache);
PyTypeObject *tp = Py_TYPE(container);
@@ -575,8 +570,8 @@
}
TARGET(LIST_APPEND) {
- PyObject *v = PEEK(1);
- PyObject *list = PEEK(2 + (oparg-1));
+ PyObject *v = stack_pointer[-1];
+ PyObject *list = stack_pointer[-(2 + (oparg-1))];
if (_PyList_AppendTakeRef((PyListObject *)list, v) < 0) goto pop_1_error;
STACK_SHRINK(1);
PREDICT(JUMP_BACKWARD);
@@ -584,8 +579,8 @@
}
TARGET(SET_ADD) {
- PyObject *v = PEEK(1);
- PyObject *set = PEEK(2 + (oparg-1));
+ PyObject *v = stack_pointer[-1];
+ PyObject *set = stack_pointer[-(2 + (oparg-1))];
int err = PySet_Add(set, v);
Py_DECREF(v);
if (err) goto pop_1_error;
@@ -597,9 +592,9 @@
TARGET(STORE_SUBSCR) {
PREDICTED(STORE_SUBSCR);
static_assert(INLINE_CACHE_ENTRIES_STORE_SUBSCR == 1, "incorrect cache size");
- PyObject *sub = PEEK(1);
- PyObject *container = PEEK(2);
- PyObject *v = PEEK(3);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *container = stack_pointer[-2];
+ PyObject *v = stack_pointer[-3];
uint16_t counter = read_u16(&next_instr[0].cache);
#if ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
@@ -621,14 +616,14 @@
Py_DECREF(sub);
if (err) goto pop_3_error;
STACK_SHRINK(3);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(STORE_SUBSCR_LIST_INT) {
- PyObject *sub = PEEK(1);
- PyObject *list = PEEK(2);
- PyObject *value = PEEK(3);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *list = stack_pointer[-2];
+ PyObject *value = stack_pointer[-3];
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(sub), STORE_SUBSCR);
DEOPT_IF(!PyList_CheckExact(list), STORE_SUBSCR);
@@ -647,14 +642,14 @@
_Py_DECREF_SPECIALIZED(sub, (destructor)PyObject_Free);
Py_DECREF(list);
STACK_SHRINK(3);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(STORE_SUBSCR_DICT) {
- PyObject *sub = PEEK(1);
- PyObject *dict = PEEK(2);
- PyObject *value = PEEK(3);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *dict = stack_pointer[-2];
+ PyObject *value = stack_pointer[-3];
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyDict_CheckExact(dict), STORE_SUBSCR);
STAT_INC(STORE_SUBSCR, hit);
@@ -662,13 +657,13 @@
Py_DECREF(dict);
if (err) goto pop_3_error;
STACK_SHRINK(3);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(DELETE_SUBSCR) {
- PyObject *sub = PEEK(1);
- PyObject *container = PEEK(2);
+ PyObject *sub = stack_pointer[-1];
+ PyObject *container = stack_pointer[-2];
/* del container[sub] */
int err = PyObject_DelItem(container, sub);
Py_DECREF(container);
@@ -679,19 +674,19 @@
}
TARGET(CALL_INTRINSIC_1) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
PyObject *res;
assert(oparg <= MAX_INTRINSIC_1);
res = _PyIntrinsics_UnaryFunctions[oparg](tstate, value);
Py_DECREF(value);
if (res == NULL) goto pop_1_error;
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(CALL_INTRINSIC_2) {
- PyObject *value1 = PEEK(1);
- PyObject *value2 = PEEK(2);
+ PyObject *value1 = stack_pointer[-1];
+ PyObject *value2 = stack_pointer[-2];
PyObject *res;
assert(oparg <= MAX_INTRINSIC_2);
res = _PyIntrinsics_BinaryFunctions[oparg](tstate, value2, value1);
@@ -699,12 +694,12 @@
Py_DECREF(value1);
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(RAISE_VARARGS) {
- PyObject **args = &PEEK(oparg);
+ PyObject **args = (stack_pointer - oparg);
PyObject *cause = NULL, *exc = NULL;
switch (oparg) {
case 2:
@@ -725,7 +720,7 @@
}
TARGET(INTERPRETER_EXIT) {
- PyObject *retval = PEEK(1);
+ PyObject *retval = stack_pointer[-1];
assert(frame == &entry_frame);
assert(_PyFrame_IsIncomplete(frame));
STACK_SHRINK(1); // Since we're not going to DISPATCH()
@@ -740,7 +735,7 @@
}
TARGET(RETURN_VALUE) {
- PyObject *retval = PEEK(1);
+ PyObject *retval = stack_pointer[-1];
STACK_SHRINK(1);
assert(EMPTY());
_PyFrame_SetStackPointer(frame, stack_pointer);
@@ -774,7 +769,7 @@
}
TARGET(GET_AITER) {
- PyObject *obj = PEEK(1);
+ PyObject *obj = stack_pointer[-1];
PyObject *iter;
unaryfunc getter = NULL;
PyTypeObject *type = Py_TYPE(obj);
@@ -806,12 +801,12 @@
Py_DECREF(iter);
if (true) goto pop_1_error;
}
- POKE(1, iter);
+ stack_pointer[-1] = iter;
DISPATCH();
}
TARGET(GET_ANEXT) {
- PyObject *aiter = PEEK(1);
+ PyObject *aiter = stack_pointer[-1];
PyObject *awaitable;
unaryfunc getter = NULL;
PyObject *next_iter = NULL;
@@ -857,14 +852,14 @@
}
STACK_GROW(1);
- POKE(1, awaitable);
+ stack_pointer[-1] = awaitable;
PREDICT(LOAD_CONST);
DISPATCH();
}
TARGET(GET_AWAITABLE) {
PREDICTED(GET_AWAITABLE);
- PyObject *iterable = PEEK(1);
+ PyObject *iterable = stack_pointer[-1];
PyObject *iter;
iter = _PyCoro_GetAwaitableIter(iterable);
@@ -890,15 +885,15 @@
if (iter == NULL) goto pop_1_error;
- POKE(1, iter);
+ stack_pointer[-1] = iter;
PREDICT(LOAD_CONST);
DISPATCH();
}
TARGET(SEND) {
PREDICTED(SEND);
- PyObject *v = PEEK(1);
- PyObject *receiver = PEEK(2);
+ PyObject *v = stack_pointer[-1];
+ PyObject *receiver = stack_pointer[-2];
PyObject *retval;
#if ENABLE_SPECIALIZATION
_PySendCache *cache = (_PySendCache *)next_instr;
@@ -935,14 +930,14 @@
assert(retval != NULL);
}
Py_DECREF(v);
- POKE(1, retval);
- JUMPBY(1);
+ stack_pointer[-1] = retval;
+ next_instr += 1;
DISPATCH();
}
TARGET(SEND_GEN) {
- PyObject *v = PEEK(1);
- PyObject *receiver = PEEK(2);
+ PyObject *v = stack_pointer[-1];
+ PyObject *receiver = stack_pointer[-2];
assert(cframe.use_tracing == 0);
PyGenObject *gen = (PyGenObject *)receiver;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type &&
@@ -961,7 +956,7 @@
}
TARGET(YIELD_VALUE) {
- PyObject *retval = PEEK(1);
+ PyObject *retval = stack_pointer[-1];
// NOTE: It's important that YIELD_VALUE never raises an exception!
// The compiler treats any exception raised here as a failed close()
// or throw() call.
@@ -983,7 +978,7 @@
}
TARGET(POP_EXCEPT) {
- PyObject *exc_value = PEEK(1);
+ PyObject *exc_value = stack_pointer[-1];
_PyErr_StackItem *exc_info = tstate->exc_info;
Py_XSETREF(exc_info->exc_value, exc_value);
STACK_SHRINK(1);
@@ -991,8 +986,8 @@
}
TARGET(RERAISE) {
- PyObject *exc = PEEK(1);
- PyObject **values = &PEEK(1 + oparg);
+ PyObject *exc = stack_pointer[-1];
+ PyObject **values = (stack_pointer - (1 + oparg));
assert(oparg >= 0 && oparg <= 2);
if (oparg) {
PyObject *lasti = values[0];
@@ -1015,8 +1010,8 @@
}
TARGET(END_ASYNC_FOR) {
- PyObject *exc = PEEK(1);
- PyObject *awaitable = PEEK(2);
+ PyObject *exc = stack_pointer[-1];
+ PyObject *awaitable = stack_pointer[-2];
assert(exc && PyExceptionInstance_Check(exc));
if (PyErr_GivenExceptionMatches(exc, PyExc_StopAsyncIteration)) {
Py_DECREF(awaitable);
@@ -1034,9 +1029,9 @@
}
TARGET(CLEANUP_THROW) {
- PyObject *exc_value = PEEK(1);
- PyObject *last_sent_val = PEEK(2);
- PyObject *sub_iter = PEEK(3);
+ PyObject *exc_value = stack_pointer[-1];
+ PyObject *last_sent_val = stack_pointer[-2];
+ PyObject *sub_iter = stack_pointer[-3];
PyObject *none;
PyObject *value;
assert(throwflag);
@@ -1053,8 +1048,8 @@
goto exception_unwind;
}
STACK_SHRINK(1);
- POKE(1, value);
- POKE(2, none);
+ stack_pointer[-1] = value;
+ stack_pointer[-2] = none;
DISPATCH();
}
@@ -1062,7 +1057,7 @@
PyObject *value;
value = Py_NewRef(PyExc_AssertionError);
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
@@ -1090,12 +1085,12 @@
}
}
STACK_GROW(1);
- POKE(1, bc);
+ stack_pointer[-1] = bc;
DISPATCH();
}
TARGET(STORE_NAME) {
- PyObject *v = PEEK(1);
+ PyObject *v = stack_pointer[-1];
PyObject *name = GETITEM(names, oparg);
PyObject *ns = LOCALS();
int err;
@@ -1138,7 +1133,7 @@
TARGET(UNPACK_SEQUENCE) {
PREDICTED(UNPACK_SEQUENCE);
static_assert(INLINE_CACHE_ENTRIES_UNPACK_SEQUENCE == 1, "incorrect cache size");
- PyObject *seq = PEEK(1);
+ PyObject *seq = stack_pointer[-1];
#if ENABLE_SPECIALIZATION
_PyUnpackSequenceCache *cache = (_PyUnpackSequenceCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -1156,12 +1151,12 @@
if (res == 0) goto pop_1_error;
STACK_SHRINK(1);
STACK_GROW(oparg);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_SEQUENCE_TWO_TUPLE) {
- PyObject *seq = PEEK(1);
+ PyObject *seq = stack_pointer[-1];
PyObject **values = stack_pointer - (1);
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyTuple_GET_SIZE(seq) != 2, UNPACK_SEQUENCE);
@@ -1172,12 +1167,12 @@
Py_DECREF(seq);
STACK_SHRINK(1);
STACK_GROW(oparg);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_SEQUENCE_TUPLE) {
- PyObject *seq = PEEK(1);
+ PyObject *seq = stack_pointer[-1];
PyObject **values = stack_pointer - (1);
DEOPT_IF(!PyTuple_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyTuple_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE);
@@ -1189,12 +1184,12 @@
Py_DECREF(seq);
STACK_SHRINK(1);
STACK_GROW(oparg);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_SEQUENCE_LIST) {
- PyObject *seq = PEEK(1);
+ PyObject *seq = stack_pointer[-1];
PyObject **values = stack_pointer - (1);
DEOPT_IF(!PyList_CheckExact(seq), UNPACK_SEQUENCE);
DEOPT_IF(PyList_GET_SIZE(seq) != oparg, UNPACK_SEQUENCE);
@@ -1206,12 +1201,12 @@
Py_DECREF(seq);
STACK_SHRINK(1);
STACK_GROW(oparg);
- JUMPBY(1);
+ next_instr += 1;
DISPATCH();
}
TARGET(UNPACK_EX) {
- PyObject *seq = PEEK(1);
+ PyObject *seq = stack_pointer[-1];
int totalargs = 1 + (oparg & 0xFF) + (oparg >> 8);
PyObject **top = stack_pointer + totalargs - 1;
int res = unpack_iterable(tstate, seq, oparg & 0xFF, oparg >> 8, top);
@@ -1224,8 +1219,8 @@
TARGET(STORE_ATTR) {
PREDICTED(STORE_ATTR);
static_assert(INLINE_CACHE_ENTRIES_STORE_ATTR == 4, "incorrect cache size");
- PyObject *owner = PEEK(1);
- PyObject *v = PEEK(2);
+ PyObject *owner = stack_pointer[-1];
+ PyObject *v = stack_pointer[-2];
uint16_t counter = read_u16(&next_instr[0].cache);
#if ENABLE_SPECIALIZATION
if (ADAPTIVE_COUNTER_IS_ZERO(counter)) {
@@ -1247,12 +1242,12 @@
Py_DECREF(owner);
if (err) goto pop_2_error;
STACK_SHRINK(2);
- JUMPBY(4);
+ next_instr += 4;
DISPATCH();
}
TARGET(DELETE_ATTR) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
PyObject *name = GETITEM(names, oparg);
int err = PyObject_SetAttr(owner, name, (PyObject *)NULL);
Py_DECREF(owner);
@@ -1262,7 +1257,7 @@
}
TARGET(STORE_GLOBAL) {
- PyObject *v = PEEK(1);
+ PyObject *v = stack_pointer[-1];
PyObject *name = GETITEM(names, oparg);
int err = PyDict_SetItem(GLOBALS(), name, v);
Py_DECREF(v);
@@ -1347,7 +1342,7 @@
}
}
STACK_GROW(1);
- POKE(1, v);
+ stack_pointer[-1] = v;
DISPATCH();
}
@@ -1410,9 +1405,9 @@
null = NULL;
STACK_GROW(1);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, v);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), null); }
- JUMPBY(5);
+ stack_pointer[-1] = v;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; }
+ next_instr += 5;
DISPATCH();
}
@@ -1434,9 +1429,9 @@
null = NULL;
STACK_GROW(1);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), null); }
- JUMPBY(5);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; }
+ next_instr += 5;
DISPATCH();
}
@@ -1462,9 +1457,9 @@
null = NULL;
STACK_GROW(1);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), null); }
- JUMPBY(5);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = null; }
+ next_instr += 5;
DISPATCH();
}
@@ -1535,7 +1530,7 @@
Py_INCREF(value);
}
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
@@ -1549,12 +1544,12 @@
}
Py_INCREF(value);
STACK_GROW(1);
- POKE(1, value);
+ stack_pointer[-1] = value;
DISPATCH();
}
TARGET(STORE_DEREF) {
- PyObject *v = PEEK(1);
+ PyObject *v = stack_pointer[-1];
PyObject *cell = GETLOCAL(oparg);
PyObject *oldobj = PyCell_GET(cell);
PyCell_SET(cell, v);
@@ -1578,7 +1573,7 @@
}
TARGET(BUILD_STRING) {
- PyObject **pieces = &PEEK(oparg);
+ PyObject **pieces = (stack_pointer - oparg);
PyObject *str;
str = _PyUnicode_JoinArray(&_Py_STR(empty), pieces, oparg);
for (int i = 0; i < oparg; i++) {
@@ -1587,35 +1582,35 @@
if (str == NULL) { STACK_SHRINK(oparg); goto error; }
STACK_SHRINK(oparg);
STACK_GROW(1);
- POKE(1, str);
+ stack_pointer[-1] = str;
DISPATCH();
}
TARGET(BUILD_TUPLE) {
- PyObject **values = &PEEK(oparg);
+ PyObject **values = (stack_pointer - oparg);
PyObject *tup;
tup = _PyTuple_FromArraySteal(values, oparg);
if (tup == NULL) { STACK_SHRINK(oparg); goto error; }
STACK_SHRINK(oparg);
STACK_GROW(1);
- POKE(1, tup);
+ stack_pointer[-1] = tup;
DISPATCH();
}
TARGET(BUILD_LIST) {
- PyObject **values = &PEEK(oparg);
+ PyObject **values = (stack_pointer - oparg);
PyObject *list;
list = _PyList_FromArraySteal(values, oparg);
if (list == NULL) { STACK_SHRINK(oparg); goto error; }
STACK_SHRINK(oparg);
STACK_GROW(1);
- POKE(1, list);
+ stack_pointer[-1] = list;
DISPATCH();
}
TARGET(LIST_EXTEND) {
- PyObject *iterable = PEEK(1);
- PyObject *list = PEEK(2 + (oparg-1));
+ PyObject *iterable = stack_pointer[-1];
+ PyObject *list = stack_pointer[-(2 + (oparg-1))];
PyObject *none_val = _PyList_Extend((PyListObject *)list, iterable);
if (none_val == NULL) {
if (_PyErr_ExceptionMatches(tstate, PyExc_TypeError) &&
@@ -1636,8 +1631,8 @@
}
TARGET(SET_UPDATE) {
- PyObject *iterable = PEEK(1);
- PyObject *set = PEEK(2 + (oparg-1));
+ PyObject *iterable = stack_pointer[-1];
+ PyObject *set = stack_pointer[-(2 + (oparg-1))];
int err = _PySet_Update(set, iterable);
Py_DECREF(iterable);
if (err < 0) goto pop_1_error;
@@ -1646,7 +1641,7 @@
}
TARGET(BUILD_SET) {
- PyObject **values = &PEEK(oparg);
+ PyObject **values = (stack_pointer - oparg);
PyObject *set;
set = PySet_New(NULL);
if (set == NULL)
@@ -1664,12 +1659,12 @@
}
STACK_SHRINK(oparg);
STACK_GROW(1);
- POKE(1, set);
+ stack_pointer[-1] = set;
DISPATCH();
}
TARGET(BUILD_MAP) {
- PyObject **values = &PEEK(oparg*2);
+ PyObject **values = (stack_pointer - oparg*2);
PyObject *map;
map = _PyDict_FromItems(
values, 2,
@@ -1685,7 +1680,7 @@
if (map == NULL) { STACK_SHRINK(oparg*2); goto error; }
STACK_SHRINK(oparg*2);
STACK_GROW(1);
- POKE(1, map);
+ stack_pointer[-1] = map;
DISPATCH();
}
@@ -1733,8 +1728,8 @@
}
TARGET(BUILD_CONST_KEY_MAP) {
- PyObject *keys = PEEK(1);
- PyObject **values = &PEEK(1 + oparg);
+ PyObject *keys = stack_pointer[-1];
+ PyObject **values = (stack_pointer - (1 + oparg));
PyObject *map;
if (!PyTuple_CheckExact(keys) ||
PyTuple_GET_SIZE(keys) != (Py_ssize_t)oparg) {
@@ -1751,12 +1746,12 @@
}
if (map == NULL) { STACK_SHRINK(oparg); goto pop_1_error; }
STACK_SHRINK(oparg);
- POKE(1, map);
+ stack_pointer[-1] = map;
DISPATCH();
}
TARGET(DICT_UPDATE) {
- PyObject *update = PEEK(1);
+ PyObject *update = stack_pointer[-1];
PyObject *dict = PEEK(oparg + 1); // update is still on the stack
if (PyDict_Update(dict, update) < 0) {
if (_PyErr_ExceptionMatches(tstate, PyExc_AttributeError)) {
@@ -1773,7 +1768,7 @@
}
TARGET(DICT_MERGE) {
- PyObject *update = PEEK(1);
+ PyObject *update = stack_pointer[-1];
PyObject *dict = PEEK(oparg + 1); // update is still on the stack
if (_PyDict_MergeEx(dict, update, 2) < 0) {
@@ -1788,8 +1783,8 @@
}
TARGET(MAP_ADD) {
- PyObject *value = PEEK(1);
- PyObject *key = PEEK(2);
+ PyObject *value = stack_pointer[-1];
+ PyObject *key = stack_pointer[-2];
PyObject *dict = PEEK(oparg + 2); // key, value are still on the stack
assert(PyDict_CheckExact(dict));
/* dict[key] = value */
@@ -1803,7 +1798,7 @@
TARGET(LOAD_ATTR) {
PREDICTED(LOAD_ATTR);
static_assert(INLINE_CACHE_ENTRIES_LOAD_ATTR == 9, "incorrect cache size");
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
#if ENABLE_SPECIALIZATION
@@ -1853,14 +1848,14 @@
if (res == NULL) goto pop_1_error;
}
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_INSTANCE_VALUE) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -1880,14 +1875,14 @@
res2 = NULL;
Py_DECREF(owner);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_MODULE) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -1907,14 +1902,14 @@
res2 = NULL;
Py_DECREF(owner);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_WITH_HINT) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -1948,14 +1943,14 @@
res2 = NULL;
Py_DECREF(owner);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_SLOT) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -1972,14 +1967,14 @@
res2 = NULL;
Py_DECREF(owner);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_CLASS) {
- PyObject *cls = PEEK(1);
+ PyObject *cls = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -1998,14 +1993,14 @@
Py_INCREF(res);
Py_DECREF(cls);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_PROPERTY) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint32_t func_version = read_u32(&next_instr[3].cache);
PyObject *fget = read_obj(&next_instr[5].cache);
@@ -2035,7 +2030,7 @@
}
TARGET(LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN) {
- PyObject *owner = PEEK(1);
+ PyObject *owner = stack_pointer[-1];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint32_t func_version = read_u32(&next_instr[3].cache);
PyObject *getattribute = read_obj(&next_instr[5].cache);
@@ -2067,8 +2062,8 @@
}
TARGET(STORE_ATTR_INSTANCE_VALUE) {
- PyObject *owner = PEEK(1);
- PyObject *value = PEEK(2);
+ PyObject *owner = stack_pointer[-1];
+ PyObject *value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
assert(cframe.use_tracing == 0);
@@ -2090,13 +2085,13 @@
}
Py_DECREF(owner);
STACK_SHRINK(2);
- JUMPBY(4);
+ next_instr += 4;
DISPATCH();
}
TARGET(STORE_ATTR_WITH_HINT) {
- PyObject *owner = PEEK(1);
- PyObject *value = PEEK(2);
+ PyObject *owner = stack_pointer[-1];
+ PyObject *value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t hint = read_u16(&next_instr[3].cache);
assert(cframe.use_tracing == 0);
@@ -2139,13 +2134,13 @@
dict->ma_version_tag = new_version;
Py_DECREF(owner);
STACK_SHRINK(2);
- JUMPBY(4);
+ next_instr += 4;
DISPATCH();
}
TARGET(STORE_ATTR_SLOT) {
- PyObject *owner = PEEK(1);
- PyObject *value = PEEK(2);
+ PyObject *owner = stack_pointer[-1];
+ PyObject *value = stack_pointer[-2];
uint32_t type_version = read_u32(&next_instr[1].cache);
uint16_t index = read_u16(&next_instr[3].cache);
assert(cframe.use_tracing == 0);
@@ -2159,13 +2154,13 @@
Py_XDECREF(old_value);
Py_DECREF(owner);
STACK_SHRINK(2);
- JUMPBY(4);
+ next_instr += 4;
DISPATCH();
}
TARGET(COMPARE_OP) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *res;
STAT_INC(COMPARE_OP, deferred);
assert((oparg >> 4) <= Py_GE);
@@ -2174,15 +2169,15 @@
Py_DECREF(right);
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(1);
+ stack_pointer[-1] = res;
+ next_instr += 1;
DISPATCH();
}
TARGET(COMPARE_AND_BRANCH) {
PREDICTED(COMPARE_AND_BRANCH);
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
#if ENABLE_SPECIALIZATION
_PyCompareOpCache *cache = (_PyCompareOpCache *)next_instr;
if (ADAPTIVE_COUNTER_IS_ZERO(cache->counter)) {
@@ -2210,13 +2205,13 @@
JUMPBY(offset);
}
STACK_SHRINK(2);
- JUMPBY(2);
+ next_instr += 2;
DISPATCH();
}
TARGET(COMPARE_AND_BRANCH_FLOAT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyFloat_CheckExact(left), COMPARE_AND_BRANCH);
DEOPT_IF(!PyFloat_CheckExact(right), COMPARE_AND_BRANCH);
@@ -2232,13 +2227,13 @@
JUMPBY(offset);
}
STACK_SHRINK(2);
- JUMPBY(2);
+ next_instr += 2;
DISPATCH();
}
TARGET(COMPARE_AND_BRANCH_INT) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyLong_CheckExact(left), COMPARE_AND_BRANCH);
DEOPT_IF(!PyLong_CheckExact(right), COMPARE_AND_BRANCH);
@@ -2257,13 +2252,13 @@
JUMPBY(offset);
}
STACK_SHRINK(2);
- JUMPBY(2);
+ next_instr += 2;
DISPATCH();
}
TARGET(COMPARE_AND_BRANCH_STR) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
assert(cframe.use_tracing == 0);
DEOPT_IF(!PyUnicode_CheckExact(left), COMPARE_AND_BRANCH);
DEOPT_IF(!PyUnicode_CheckExact(right), COMPARE_AND_BRANCH);
@@ -2280,26 +2275,26 @@
JUMPBY(offset);
}
STACK_SHRINK(2);
- JUMPBY(2);
+ next_instr += 2;
DISPATCH();
}
TARGET(IS_OP) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *b;
int res = Py_Is(left, right) ^ oparg;
Py_DECREF(left);
Py_DECREF(right);
b = Py_NewRef(res ? Py_True : Py_False);
STACK_SHRINK(1);
- POKE(1, b);
+ stack_pointer[-1] = b;
DISPATCH();
}
TARGET(CONTAINS_OP) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *b;
int res = PySequence_Contains(right, left);
Py_DECREF(left);
@@ -2307,13 +2302,13 @@
if (res < 0) goto pop_2_error;
b = Py_NewRef((res^oparg) ? Py_True : Py_False);
STACK_SHRINK(1);
- POKE(1, b);
+ stack_pointer[-1] = b;
DISPATCH();
}
TARGET(CHECK_EG_MATCH) {
- PyObject *match_type = PEEK(1);
- PyObject *exc_value = PEEK(2);
+ PyObject *match_type = stack_pointer[-1];
+ PyObject *exc_value = stack_pointer[-2];
PyObject *rest;
PyObject *match;
if (check_except_star_type_valid(tstate, match_type) < 0) {
@@ -2336,14 +2331,14 @@
if (!Py_IsNone(match)) {
PyErr_SetExcInfo(NULL, Py_NewRef(match), NULL);
}
- POKE(1, match);
- POKE(2, rest);
+ stack_pointer[-1] = match;
+ stack_pointer[-2] = rest;
DISPATCH();
}
TARGET(CHECK_EXC_MATCH) {
- PyObject *right = PEEK(1);
- PyObject *left = PEEK(2);
+ PyObject *right = stack_pointer[-1];
+ PyObject *left = stack_pointer[-2];
PyObject *b;
assert(PyExceptionInstance_Check(left));
if (check_except_type_valid(tstate, right) < 0) {
@@ -2354,13 +2349,13 @@
int res = PyErr_GivenExceptionMatches(left, right);
Py_DECREF(right);
b = Py_NewRef(res ? Py_True : Py_False);
- POKE(1, b);
+ stack_pointer[-1] = b;
DISPATCH();
}
TARGET(IMPORT_NAME) {
- PyObject *fromlist = PEEK(1);
- PyObject *level = PEEK(2);
+ PyObject *fromlist = stack_pointer[-1];
+ PyObject *level = stack_pointer[-2];
PyObject *res;
PyObject *name = GETITEM(names, oparg);
res = import_name(tstate, frame, name, fromlist, level);
@@ -2368,18 +2363,18 @@
Py_DECREF(fromlist);
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(IMPORT_FROM) {
- PyObject *from = PEEK(1);
+ PyObject *from = stack_pointer[-1];
PyObject *res;
PyObject *name = GETITEM(names, oparg);
res = import_from(tstate, from, name);
if (res == NULL) goto error;
STACK_GROW(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
@@ -2398,7 +2393,7 @@
TARGET(POP_JUMP_IF_FALSE) {
PREDICTED(POP_JUMP_IF_FALSE);
- PyObject *cond = PEEK(1);
+ PyObject *cond = stack_pointer[-1];
if (Py_IsTrue(cond)) {
_Py_DECREF_NO_DEALLOC(cond);
}
@@ -2421,7 +2416,7 @@
}
TARGET(POP_JUMP_IF_TRUE) {
- PyObject *cond = PEEK(1);
+ PyObject *cond = stack_pointer[-1];
if (Py_IsFalse(cond)) {
_Py_DECREF_NO_DEALLOC(cond);
}
@@ -2444,7 +2439,7 @@
}
TARGET(POP_JUMP_IF_NOT_NONE) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
if (!Py_IsNone(value)) {
Py_DECREF(value);
JUMPBY(oparg);
@@ -2457,7 +2452,7 @@
}
TARGET(POP_JUMP_IF_NONE) {
- PyObject *value = PEEK(1);
+ PyObject *value = stack_pointer[-1];
if (Py_IsNone(value)) {
_Py_DECREF_NO_DEALLOC(value);
JUMPBY(oparg);
@@ -2470,7 +2465,7 @@
}
TARGET(JUMP_IF_FALSE_OR_POP) {
- PyObject *cond = PEEK(1);
+ PyObject *cond = stack_pointer[-1];
bool jump = false;
int err;
if (Py_IsTrue(cond)) {
@@ -2499,7 +2494,7 @@
}
TARGET(JUMP_IF_TRUE_OR_POP) {
- PyObject *cond = PEEK(1);
+ PyObject *cond = stack_pointer[-1];
bool jump = false;
int err;
if (Py_IsFalse(cond)) {
@@ -2538,7 +2533,7 @@
}
TARGET(GET_LEN) {
- PyObject *obj = PEEK(1);
+ PyObject *obj = stack_pointer[-1];
PyObject *len_o;
// PUSH(len(TOS))
Py_ssize_t len_i = PyObject_Length(obj);
@@ -2546,14 +2541,14 @@
len_o = PyLong_FromSsize_t(len_i);
if (len_o == NULL) goto error;
STACK_GROW(1);
- POKE(1, len_o);
+ stack_pointer[-1] = len_o;
DISPATCH();
}
TARGET(MATCH_CLASS) {
- PyObject *names = PEEK(1);
- PyObject *type = PEEK(2);
- PyObject *subject = PEEK(3);
+ PyObject *names = stack_pointer[-1];
+ PyObject *type = stack_pointer[-2];
+ PyObject *subject = stack_pointer[-3];
PyObject *attrs;
// Pop TOS and TOS1. Set TOS to a tuple of attributes on success, or
// None on failure.
@@ -2570,57 +2565,57 @@
attrs = Py_NewRef(Py_None); // Failure!
}
STACK_SHRINK(2);
- POKE(1, attrs);
+ stack_pointer[-1] = attrs;
DISPATCH();
}
TARGET(MATCH_MAPPING) {
- PyObject *subject = PEEK(1);
+ PyObject *subject = stack_pointer[-1];
PyObject *res;
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_MAPPING;
res = Py_NewRef(match ? Py_True : Py_False);
STACK_GROW(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
PREDICT(POP_JUMP_IF_FALSE);
DISPATCH();
}
TARGET(MATCH_SEQUENCE) {
- PyObject *subject = PEEK(1);
+ PyObject *subject = stack_pointer[-1];
PyObject *res;
int match = Py_TYPE(subject)->tp_flags & Py_TPFLAGS_SEQUENCE;
res = Py_NewRef(match ? Py_True : Py_False);
STACK_GROW(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
PREDICT(POP_JUMP_IF_FALSE);
DISPATCH();
}
TARGET(MATCH_KEYS) {
- PyObject *keys = PEEK(1);
- PyObject *subject = PEEK(2);
+ PyObject *keys = stack_pointer[-1];
+ PyObject *subject = stack_pointer[-2];
PyObject *values_or_none;
// On successful match, PUSH(values). Otherwise, PUSH(None).
values_or_none = match_keys(tstate, subject, keys);
if (values_or_none == NULL) goto error;
STACK_GROW(1);
- POKE(1, values_or_none);
+ stack_pointer[-1] = values_or_none;
DISPATCH();
}
TARGET(GET_ITER) {
- PyObject *iterable = PEEK(1);
+ PyObject *iterable = stack_pointer[-1];
PyObject *iter;
/* before: [obj]; after [getiter(obj)] */
iter = PyObject_GetIter(iterable);
Py_DECREF(iterable);
if (iter == NULL) goto pop_1_error;
- POKE(1, iter);
+ stack_pointer[-1] = iter;
DISPATCH();
}
TARGET(GET_YIELD_FROM_ITER) {
- PyObject *iterable = PEEK(1);
+ PyObject *iterable = stack_pointer[-1];
PyObject *iter;
/* before: [obj]; after [getiter(obj)] */
if (PyCoro_CheckExact(iterable)) {
@@ -2646,7 +2641,7 @@
}
Py_DECREF(iterable);
}
- POKE(1, iter);
+ stack_pointer[-1] = iter;
PREDICT(LOAD_CONST);
DISPATCH();
}
@@ -2654,7 +2649,7 @@
TARGET(FOR_ITER) {
PREDICTED(FOR_ITER);
static_assert(INLINE_CACHE_ENTRIES_FOR_ITER == 1, "incorrect cache size");
- PyObject *iter = PEEK(1);
+ PyObject *iter = stack_pointer[-1];
PyObject *next;
#if ENABLE_SPECIALIZATION
_PyForIterCache *cache = (_PyForIterCache *)next_instr;
@@ -2689,13 +2684,13 @@
}
// Common case: no jump, leave it to the code generator
STACK_GROW(1);
- POKE(1, next);
- JUMPBY(1);
+ stack_pointer[-1] = next;
+ next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_LIST) {
- PyObject *iter = PEEK(1);
+ PyObject *iter = stack_pointer[-1];
PyObject *next;
assert(cframe.use_tracing == 0);
DEOPT_IF(Py_TYPE(iter) != &PyListIter_Type, FOR_ITER);
@@ -2718,13 +2713,13 @@
end_for_iter_list:
// Common case: no jump, leave it to the code generator
STACK_GROW(1);
- POKE(1, next);
- JUMPBY(1);
+ stack_pointer[-1] = next;
+ next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_TUPLE) {
- PyObject *iter = PEEK(1);
+ PyObject *iter = stack_pointer[-1];
PyObject *next;
assert(cframe.use_tracing == 0);
_PyTupleIterObject *it = (_PyTupleIterObject *)iter;
@@ -2747,13 +2742,13 @@
end_for_iter_tuple:
// Common case: no jump, leave it to the code generator
STACK_GROW(1);
- POKE(1, next);
- JUMPBY(1);
+ stack_pointer[-1] = next;
+ next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_RANGE) {
- PyObject *iter = PEEK(1);
+ PyObject *iter = stack_pointer[-1];
PyObject *next;
assert(cframe.use_tracing == 0);
_PyRangeIterObject *r = (_PyRangeIterObject *)iter;
@@ -2774,13 +2769,13 @@
goto error;
}
STACK_GROW(1);
- POKE(1, next);
- JUMPBY(1);
+ stack_pointer[-1] = next;
+ next_instr += 1;
DISPATCH();
}
TARGET(FOR_ITER_GEN) {
- PyObject *iter = PEEK(1);
+ PyObject *iter = stack_pointer[-1];
assert(cframe.use_tracing == 0);
PyGenObject *gen = (PyGenObject *)iter;
DEOPT_IF(Py_TYPE(gen) != &PyGen_Type, FOR_ITER);
@@ -2798,7 +2793,7 @@
}
TARGET(BEFORE_ASYNC_WITH) {
- PyObject *mgr = PEEK(1);
+ PyObject *mgr = stack_pointer[-1];
PyObject *exit;
PyObject *res;
PyObject *enter = _PyObject_LookupSpecial(mgr, &_Py_ID(__aenter__));
@@ -2831,14 +2826,14 @@
if (true) goto pop_1_error;
}
STACK_GROW(1);
- POKE(1, res);
- POKE(2, exit);
+ stack_pointer[-1] = res;
+ stack_pointer[-2] = exit;
PREDICT(GET_AWAITABLE);
DISPATCH();
}
TARGET(BEFORE_WITH) {
- PyObject *mgr = PEEK(1);
+ PyObject *mgr = stack_pointer[-1];
PyObject *exit;
PyObject *res;
/* pop the context manager, push its __exit__ and the
@@ -2874,15 +2869,15 @@
if (true) goto pop_1_error;
}
STACK_GROW(1);
- POKE(1, res);
- POKE(2, exit);
+ stack_pointer[-1] = res;
+ stack_pointer[-2] = exit;
DISPATCH();
}
TARGET(WITH_EXCEPT_START) {
- PyObject *val = PEEK(1);
- PyObject *lasti = PEEK(3);
- PyObject *exit_func = PEEK(4);
+ PyObject *val = stack_pointer[-1];
+ PyObject *lasti = stack_pointer[-3];
+ PyObject *exit_func = stack_pointer[-4];
PyObject *res;
/* At the top of the stack are 4 values:
- val: TOP = exc_info()
@@ -2905,12 +2900,12 @@
3 | PY_VECTORCALL_ARGUMENTS_OFFSET, NULL);
if (res == NULL) goto error;
STACK_GROW(1);
- POKE(1, res);
+ stack_pointer[-1] = res;
DISPATCH();
}
TARGET(PUSH_EXC_INFO) {
- PyObject *new_exc = PEEK(1);
+ PyObject *new_exc = stack_pointer[-1];
PyObject *prev_exc;
_PyErr_StackItem *exc_info = tstate->exc_info;
if (exc_info->exc_value != NULL) {
@@ -2922,13 +2917,13 @@
assert(PyExceptionInstance_Check(new_exc));
exc_info->exc_value = Py_NewRef(new_exc);
STACK_GROW(1);
- POKE(1, new_exc);
- POKE(2, prev_exc);
+ stack_pointer[-1] = new_exc;
+ stack_pointer[-2] = prev_exc;
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_WITH_VALUES) {
- PyObject *self = PEEK(1);
+ PyObject *self = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -2952,14 +2947,14 @@
res = self;
assert(oparg & 1);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_NO_DICT) {
- PyObject *self = PEEK(1);
+ PyObject *self = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -2975,14 +2970,14 @@
res = self;
assert(oparg & 1);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
TARGET(LOAD_ATTR_METHOD_LAZY_DICT) {
- PyObject *self = PEEK(1);
+ PyObject *self = stack_pointer[-1];
PyObject *res2 = NULL;
PyObject *res;
uint32_t type_version = read_u32(&next_instr[1].cache);
@@ -3002,9 +2997,9 @@
res = self;
assert(oparg & 1);
STACK_GROW(((oparg & 1) ? 1 : 0));
- POKE(1, res);
- if (oparg & 1) { POKE(1 + ((oparg & 1) ? 1 : 0), res2); }
- JUMPBY(9);
+ stack_pointer[-1] = res;
+ if (oparg & 1) { stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))] = res2; }
+ next_instr += 9;
DISPATCH();
}
@@ -3018,9 +3013,9 @@
TARGET(CALL) {
PREDICTED(CALL);
static_assert(INLINE_CACHE_ENTRIES_CALL == 4, "incorrect cache size");
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
int is_meth = method != NULL;
int total_args = oparg;
@@ -3095,15 +3090,15 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BOUND_METHOD_EXACT_ARGS) {
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
DEOPT_IF(method != NULL, CALL);
DEOPT_IF(Py_TYPE(callable) != &PyMethod_Type, CALL);
STAT_INC(CALL, hit);
@@ -3117,9 +3112,9 @@
TARGET(CALL_PY_EXACT_ARGS) {
PREDICTED(CALL_PY_EXACT_ARGS);
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
uint32_t func_version = read_u32(&next_instr[1].cache);
assert(kwnames == NULL);
DEOPT_IF(tstate->interp->eval_frame, CALL);
@@ -3148,9 +3143,9 @@
}
TARGET(CALL_PY_WITH_DEFAULTS) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
uint32_t func_version = read_u32(&next_instr[1].cache);
uint16_t min_args = read_u16(&next_instr[3].cache);
assert(kwnames == NULL);
@@ -3185,9 +3180,9 @@
}
TARGET(CALL_NO_KW_TYPE_1) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *null = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *null = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(kwnames == NULL);
assert(cframe.use_tracing == 0);
@@ -3201,15 +3196,15 @@
Py_DECREF(&PyType_Type); // I.e., callable
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(CALL_NO_KW_STR_1) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *null = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *null = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(kwnames == NULL);
assert(cframe.use_tracing == 0);
@@ -3224,16 +3219,16 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_NO_KW_TUPLE_1) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *null = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *null = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(kwnames == NULL);
assert(oparg == 1);
@@ -3247,16 +3242,16 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BUILTIN_CLASS) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
int is_meth = method != NULL;
int total_args = oparg;
@@ -3281,16 +3276,16 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_NO_KW_BUILTIN_O) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(cframe.use_tracing == 0);
/* Builtin METH_O functions */
@@ -3322,16 +3317,16 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_NO_KW_BUILTIN_FAST) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(cframe.use_tracing == 0);
/* Builtin METH_FASTCALL functions, without keywords */
@@ -3367,16 +3362,16 @@
*/
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_BUILTIN_FAST_WITH_KEYWORDS) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(cframe.use_tracing == 0);
/* Builtin METH_FASTCALL | METH_KEYWORDS functions */
@@ -3412,16 +3407,16 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_NO_KW_LEN) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(cframe.use_tracing == 0);
assert(kwnames == NULL);
@@ -3450,15 +3445,15 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(CALL_NO_KW_ISINSTANCE) {
- PyObject **args = &PEEK(oparg);
- PyObject *callable = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *callable = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(cframe.use_tracing == 0);
assert(kwnames == NULL);
@@ -3489,15 +3484,15 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
DISPATCH();
}
TARGET(CALL_NO_KW_LIST_APPEND) {
- PyObject **args = &PEEK(oparg);
- PyObject *self = PEEK(1 + oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *self = stack_pointer[-(1 + oparg)];
+ PyObject *method = stack_pointer[-(2 + oparg)];
assert(cframe.use_tracing == 0);
assert(kwnames == NULL);
assert(oparg == 1);
@@ -3519,8 +3514,8 @@
}
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_O) {
- PyObject **args = &PEEK(oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(kwnames == NULL);
int is_meth = method != NULL;
@@ -3554,15 +3549,15 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS) {
- PyObject **args = &PEEK(oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
int is_meth = method != NULL;
int total_args = oparg;
@@ -3594,15 +3589,15 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_NOARGS) {
- PyObject **args = &PEEK(oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(kwnames == NULL);
assert(oparg == 0 || oparg == 1);
@@ -3634,15 +3629,15 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_NO_KW_METHOD_DESCRIPTOR_FAST) {
- PyObject **args = &PEEK(oparg);
- PyObject *method = PEEK(2 + oparg);
+ PyObject **args = (stack_pointer - oparg);
+ PyObject *method = stack_pointer[-(2 + oparg)];
PyObject *res;
assert(kwnames == NULL);
int is_meth = method != NULL;
@@ -3673,17 +3668,17 @@
if (res == NULL) { STACK_SHRINK(oparg); goto pop_2_error; }
STACK_SHRINK(oparg);
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(4);
+ stack_pointer[-1] = res;
+ next_instr += 4;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(CALL_FUNCTION_EX) {
PREDICTED(CALL_FUNCTION_EX);
- PyObject *kwargs = (oparg & 1) ? PEEK(((oparg & 1) ? 1 : 0)) : NULL;
- PyObject *callargs = PEEK(1 + ((oparg & 1) ? 1 : 0));
- PyObject *func = PEEK(2 + ((oparg & 1) ? 1 : 0));
+ PyObject *kwargs = (oparg & 1) ? stack_pointer[-(((oparg & 1) ? 1 : 0))] : NULL;
+ PyObject *callargs = stack_pointer[-(1 + ((oparg & 1) ? 1 : 0))];
+ PyObject *func = stack_pointer[-(2 + ((oparg & 1) ? 1 : 0))];
PyObject *result;
if (oparg & 1) {
// DICT_MERGE is called before this opcode if there are kwargs.
@@ -3711,17 +3706,17 @@
if (result == NULL) { STACK_SHRINK(((oparg & 1) ? 1 : 0)); goto pop_3_error; }
STACK_SHRINK(((oparg & 1) ? 1 : 0));
STACK_SHRINK(2);
- POKE(1, result);
+ stack_pointer[-1] = result;
CHECK_EVAL_BREAKER();
DISPATCH();
}
TARGET(MAKE_FUNCTION) {
- PyObject *codeobj = PEEK(1);
- PyObject *closure = (oparg & 0x08) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0)) : NULL;
- PyObject *annotations = (oparg & 0x04) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0)) : NULL;
- PyObject *kwdefaults = (oparg & 0x02) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0)) : NULL;
- PyObject *defaults = (oparg & 0x01) ? PEEK(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0)) : NULL;
+ PyObject *codeobj = stack_pointer[-1];
+ PyObject *closure = (oparg & 0x08) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0))] : NULL;
+ PyObject *annotations = (oparg & 0x04) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0))] : NULL;
+ PyObject *kwdefaults = (oparg & 0x02) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0))] : NULL;
+ PyObject *defaults = (oparg & 0x01) ? stack_pointer[-(1 + ((oparg & 0x08) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x01) ? 1 : 0))] : NULL;
PyObject *func;
PyFunctionObject *func_obj = (PyFunctionObject *)
@@ -3752,7 +3747,7 @@
func_obj->func_version = ((PyCodeObject *)codeobj)->co_version;
func = (PyObject *)func_obj;
STACK_SHRINK(((oparg & 0x01) ? 1 : 0) + ((oparg & 0x02) ? 1 : 0) + ((oparg & 0x04) ? 1 : 0) + ((oparg & 0x08) ? 1 : 0));
- POKE(1, func);
+ stack_pointer[-1] = func;
DISPATCH();
}
@@ -3780,9 +3775,9 @@
}
TARGET(BUILD_SLICE) {
- PyObject *step = (oparg == 3) ? PEEK(((oparg == 3) ? 1 : 0)) : NULL;
- PyObject *stop = PEEK(1 + ((oparg == 3) ? 1 : 0));
- PyObject *start = PEEK(2 + ((oparg == 3) ? 1 : 0));
+ PyObject *step = (oparg == 3) ? stack_pointer[-(((oparg == 3) ? 1 : 0))] : NULL;
+ PyObject *stop = stack_pointer[-(1 + ((oparg == 3) ? 1 : 0))];
+ PyObject *start = stack_pointer[-(2 + ((oparg == 3) ? 1 : 0))];
PyObject *slice;
slice = PySlice_New(start, stop, step);
Py_DECREF(start);
@@ -3791,13 +3786,13 @@
if (slice == NULL) { STACK_SHRINK(((oparg == 3) ? 1 : 0)); goto pop_2_error; }
STACK_SHRINK(((oparg == 3) ? 1 : 0));
STACK_SHRINK(1);
- POKE(1, slice);
+ stack_pointer[-1] = slice;
DISPATCH();
}
TARGET(FORMAT_VALUE) {
- PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? PEEK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)) : NULL;
- PyObject *value = PEEK(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0));
+ PyObject *fmt_spec = ((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? stack_pointer[-((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))] : NULL;
+ PyObject *value = stack_pointer[-(1 + (((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0))];
PyObject *result;
/* Handles f-string value formatting. */
PyObject *(*conv_fn)(PyObject *);
@@ -3845,25 +3840,25 @@
if (result == NULL) { STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0)); goto pop_1_error; }
}
STACK_SHRINK((((oparg & FVS_MASK) == FVS_HAVE_SPEC) ? 1 : 0));
- POKE(1, result);
+ stack_pointer[-1] = result;
DISPATCH();
}
TARGET(COPY) {
- PyObject *bottom = PEEK(1 + (oparg-1));
+ PyObject *bottom = stack_pointer[-(1 + (oparg-1))];
PyObject *top;
assert(oparg > 0);
top = Py_NewRef(bottom);
STACK_GROW(1);
- POKE(1, top);
+ stack_pointer[-1] = top;
DISPATCH();
}
TARGET(BINARY_OP) {
PREDICTED(BINARY_OP);
static_assert(INLINE_CACHE_ENTRIES_BINARY_OP == 1, "incorrect cache size");
- PyObject *rhs = PEEK(1);
- PyObject *lhs = PEEK(2);
+ PyObject *rhs = stack_pointer[-1];
+ PyObject *lhs = stack_pointer[-2];
PyObject *res;
#if ENABLE_SPECIALIZATION
_PyBinaryOpCache *cache = (_PyBinaryOpCache *)next_instr;
@@ -3884,17 +3879,17 @@
Py_DECREF(rhs);
if (res == NULL) goto pop_2_error;
STACK_SHRINK(1);
- POKE(1, res);
- JUMPBY(1);
+ stack_pointer[-1] = res;
+ next_instr += 1;
DISPATCH();
}
TARGET(SWAP) {
- PyObject *top = PEEK(1);
- PyObject *bottom = PEEK(2 + (oparg-2));
+ PyObject *top = stack_pointer[-1];
+ PyObject *bottom = stack_pointer[-(2 + (oparg-2))];
assert(oparg >= 2);
- POKE(1, bottom);
- POKE(2 + (oparg-2), top);
+ stack_pointer[-1] = bottom;
+ stack_pointer[-(2 + (oparg-2))] = top;
DISPATCH();
}
diff --git a/Tools/cases_generator/generate_cases.py b/Tools/cases_generator/generate_cases.py
index c7f52b55a5eb..b760172974c8 100644
--- a/Tools/cases_generator/generate_cases.py
+++ b/Tools/cases_generator/generate_cases.py
@@ -171,19 +171,17 @@ def declare(self, dst: StackEffect, src: StackEffect | None):
def assign(self, dst: StackEffect, src: StackEffect):
if src.name == UNUSED:
return
+ if src.size:
+ # Don't write sized arrays -- it's up to the user code.
+ return
cast = self.cast(dst, src)
- if m := re.match(r"^PEEK\((.*)\)$", dst.name):
- stmt = f"POKE({m.group(1)}, {cast}{src.name});"
+ if re.match(r"^REG\(oparg(\d+)\)$", dst.name):
+ self.emit(f"Py_XSETREF({dst.name}, {cast}{src.name});")
+ else:
+ stmt = f"{dst.name} = {cast}{src.name};"
if src.cond:
stmt = f"if ({src.cond}) {{ {stmt} }}"
self.emit(stmt)
- elif m := re.match(r"^&PEEK\(.*\)$", dst.name):
- # The user code is responsible for writing to the output array.
- pass
- elif m := re.match(r"^REG\(oparg(\d+)\)$", dst.name):
- self.emit(f"Py_XSETREF({dst.name}, {cast}{src.name});")
- else:
- self.emit(f"{dst.name} = {cast}{src.name};")
def cast(self, dst: StackEffect, src: StackEffect) -> str:
return f"({dst.type or 'PyObject *'})" if src.type != dst.type else ""
@@ -292,11 +290,11 @@ def write(self, out: Formatter) -> None:
list_effect_size([ieff for ieff in ieffects[: i + 1]])
)
if ieffect.size:
- src = StackEffect(f"&PEEK({isize})", "PyObject **")
+ src = StackEffect(f"(stack_pointer - {maybe_parenthesize(isize)})", "PyObject **")
elif ieffect.cond:
- src = StackEffect(f"({ieffect.cond}) ? PEEK({isize}) : NULL", "")
+ src = StackEffect(f"({ieffect.cond}) ? stack_pointer[-{maybe_parenthesize(isize)}] : NULL", "")
else:
- src = StackEffect(f"PEEK({isize})", "")
+ src = StackEffect(f"stack_pointer[-{maybe_parenthesize(isize)}]", "")
out.declare(ieffect, src)
else:
# Write input register variable declarations and initializations
@@ -324,7 +322,7 @@ def write(self, out: Formatter) -> None:
else:
out.declare(oeffect, None)
- # out.emit(f"JUMPBY(OPSIZE({self.inst.name}) - 1);")
+ # out.emit(f"next_instr += OPSIZE({self.inst.name}) - 1;")
self.write_body(out, 0)
@@ -349,9 +347,9 @@ def write(self, out: Formatter) -> None:
list_effect_size([oeff for oeff in oeffects[: i + 1]])
)
if oeffect.size:
- dst = StackEffect(f"&PEEK({osize})", "PyObject **")
+ dst = StackEffect(f"stack_pointer - {maybe_parenthesize(osize)}", "PyObject **")
else:
- dst = StackEffect(f"PEEK({osize})", "")
+ dst = StackEffect(f"stack_pointer[-{maybe_parenthesize(osize)}]", "")
out.assign(dst, oeffect)
else:
# Write output register assignments
@@ -361,7 +359,7 @@ def write(self, out: Formatter) -> None:
# Write cache effect
if self.cache_offset:
- out.emit(f"JUMPBY({self.cache_offset});")
+ out.emit(f"next_instr += {self.cache_offset};")
def write_body(self, out: Formatter, dedent: int, cache_adjust: int = 0) -> None:
"""Write the instruction body."""
@@ -1060,17 +1058,13 @@ def write_super(self, sup: SuperInstruction) -> None:
with self.wrap_super_or_macro(sup):
first = True
for comp in sup.parts:
- if first:
- pass
- # self.out.emit("JUMPBY(OPSIZE(opcode) - 1);")
- else:
- self.out.emit("NEXTOPARG();")
- self.out.emit("JUMPBY(1);")
- # self.out.emit("JUMPBY(OPSIZE(opcode));")
+ if not first:
+ self.out.emit("oparg = (next_instr++)->op.arg;")
+ # self.out.emit("next_instr += OPSIZE(opcode) - 1;")
first = False
comp.write_body(self.out, 0)
if comp.instr.cache_offset:
- self.out.emit(f"JUMPBY({comp.instr.cache_offset});")
+ self.out.emit(f"next_instr += {comp.instr.cache_offset};")
def write_macro(self, mac: MacroInstruction) -> None:
"""Write code for a macro instruction."""
@@ -1087,7 +1081,7 @@ def write_macro(self, mac: MacroInstruction) -> None:
cache_adjust += comp.instr.cache_offset
if cache_adjust:
- self.out.emit(f"JUMPBY({cache_adjust});")
+ self.out.emit(f"next_instr += {cache_adjust};")
if (
last_instr
@@ -1113,7 +1107,7 @@ def wrap_super_or_macro(self, up: SuperOrMacroInstruction):
for i, var in reversed(list(enumerate(up.stack))):
src = None
if i < up.initial_sp:
- src = StackEffect(f"PEEK({up.initial_sp - i})", "")
+ src = StackEffect(f"stack_pointer[-{up.initial_sp - i}]", "")
self.out.declare(var, src)
yield
@@ -1122,7 +1116,7 @@ def wrap_super_or_macro(self, up: SuperOrMacroInstruction):
self.out.stack_adjust(up.final_sp - up.initial_sp, [], [])
for i, var in enumerate(reversed(up.stack[: up.final_sp]), 1):
- dst = StackEffect(f"PEEK({i})", "")
+ dst = StackEffect(f"stack_pointer[-{i}]", "")
self.out.assign(dst, var)
self.out.emit(f"DISPATCH();")
1
0
https://github.com/python/cpython/commit/e1a90ec75cd0f5cab21b467a73404081ea…
commit: e1a90ec75cd0f5cab21b467a73404081eaa1077f
branch: main
author: Ee Durbin <ewdurbin(a)gmail.com>
committer: ewdurbin <ewdurbin(a)gmail.com>
date: 2023-02-28T08:23:39-05:00
summary:
Migrate to new PSF mailgun account (#102284)
Our legacy mailgun account is associated with a parent rackspace account that I am trying to decomission.
The necessary secret has been added to the GitHub Actions Secrets already, so this is ready to go on approval.
files:
M .github/workflows/new-bugs-announce-notifier.yml
diff --git a/.github/workflows/new-bugs-announce-notifier.yml b/.github/workflows/new-bugs-announce-notifier.yml
index b2b63472d834..b2a76ef7d361 100644
--- a/.github/workflows/new-bugs-announce-notifier.yml
+++ b/.github/workflows/new-bugs-announce-notifier.yml
@@ -19,13 +19,13 @@ jobs:
- name: Send notification
uses: actions/github-script@v6
env:
- MAILGUN_API_KEY: ${{ secrets.PSF_MAILGUN_KEY }}
+ MAILGUN_API_KEY: ${{ secrets.MAILGUN_PYTHON_ORG_MAILGUN_KEY }}
with:
script: |
const Mailgun = require("mailgun.js");
const formData = require('form-data');
const mailgun = new Mailgun(formData);
- const DOMAIN = "mg.python.org";
+ const DOMAIN = "mailgun.python.org";
const mg = mailgun.client({username: 'api', key: process.env.MAILGUN_API_KEY});
github.rest.issues.get({
issue_number: context.issue.number,
@@ -44,7 +44,7 @@ jobs:
};
const data = {
- from: "CPython Issues <github(a)mg.python.org>",
+ from: "CPython Issues <github(a)mailgun.python.org>",
to: "new-bugs-announce(a)python.org",
subject: `[Issue ${issue.data.number}] ${issue.data.title}`,
template: "new-github-issue",
1
0
gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Python/) (#102193)
by iritkatriel 28 Feb '23
by iritkatriel 28 Feb '23
28 Feb '23
https://github.com/python/cpython/commit/4c87537efb5fd28b4e4ee9631076ed5953…
commit: 4c87537efb5fd28b4e4ee9631076ed5953720156
branch: main
author: Irit Katriel <1055913+iritkatriel(a)users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel(a)users.noreply.github.com>
date: 2023-02-28T11:50:52Z
summary:
gh-102192: Replace PyErr_Fetch/Restore etc by more efficient alternatives (in Python/) (#102193)
files:
M Python/bytecodes.c
M Python/ceval.c
M Python/ceval_gil.c
M Python/compile.c
M Python/frame.c
M Python/initconfig.c
M Python/modsupport.c
M Python/sysmodule.c
diff --git a/Python/bytecodes.c b/Python/bytecodes.c
index 7e9b36f69721..63dbecad3b45 100644
--- a/Python/bytecodes.c
+++ b/Python/bytecodes.c
@@ -17,7 +17,7 @@
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_moduleobject.h" // PyModuleObject
#include "pycore_opcode.h" // EXTRA_CASES
-#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_range.h" // _PyRangeIterObject
diff --git a/Python/ceval.c b/Python/ceval.c
index 5540c93d5e3d..b422d0ed34ed 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -13,7 +13,7 @@
#include "pycore_object.h" // _PyObject_GC_TRACK()
#include "pycore_moduleobject.h" // PyModuleObject
#include "pycore_opcode.h" // EXTRA_CASES
-#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pyerrors.h" // _PyErr_Fetch(), _PyErr_GetRaisedException()
#include "pycore_pymem.h" // _PyMem_IsPtrFreed()
#include "pycore_pystate.h" // _PyInterpreterState_GET()
#include "pycore_range.h" // _PyRangeIterObject
@@ -105,8 +105,7 @@ static void
dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer)
{
PyObject **stack_base = _PyFrame_Stackbase(frame);
- PyObject *type, *value, *traceback;
- PyErr_Fetch(&type, &value, &traceback);
+ PyObject *exc = PyErr_GetRaisedException();
printf(" stack=[");
for (PyObject **ptr = stack_base; ptr < stack_pointer; ptr++) {
if (ptr != stack_base) {
@@ -120,7 +119,7 @@ dump_stack(_PyInterpreterFrame *frame, PyObject **stack_pointer)
}
printf("]\n");
fflush(stdout);
- PyErr_Restore(type, value, traceback);
+ PyErr_SetRaisedException(exc);
}
static void
@@ -157,8 +156,7 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
return;
}
PyFunctionObject *f = (PyFunctionObject *)fobj;
- PyObject *type, *value, *traceback;
- PyErr_Fetch(&type, &value, &traceback);
+ PyObject *exc = PyErr_GetRaisedException();
PyObject *name = f->func_qualname;
if (name == NULL) {
name = f->func_name;
@@ -178,7 +176,7 @@ lltrace_resume_frame(_PyInterpreterFrame *frame)
}
printf("\n");
fflush(stdout);
- PyErr_Restore(type, value, traceback);
+ PyErr_SetRaisedException(exc);
}
#endif
static int call_trace(Py_tracefunc, PyObject *,
@@ -1032,7 +1030,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
PyObject *v = POP();
Py_XDECREF(v);
}
- PyObject *exc, *val, *tb;
if (lasti) {
int frame_lasti = _PyInterpreterFrame_LASTI(frame);
PyObject *lasti = PyLong_FromLong(frame_lasti);
@@ -1041,19 +1038,12 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
}
PUSH(lasti);
}
- _PyErr_Fetch(tstate, &exc, &val, &tb);
+
/* Make the raw exception data
available to the handler,
so a program can emulate the
Python main loop. */
- _PyErr_NormalizeException(tstate, &exc, &val, &tb);
- if (tb != NULL)
- PyException_SetTraceback(val, tb);
- else
- PyException_SetTraceback(val, Py_None);
- Py_XDECREF(tb);
- Py_XDECREF(exc);
- PUSH(val);
+ PUSH(_PyErr_GetRaisedException(tstate));
JUMPTO(handler);
/* Resume normal execution */
DISPATCH();
@@ -2075,19 +2065,15 @@ call_trace_protected(Py_tracefunc func, PyObject *obj,
PyThreadState *tstate, _PyInterpreterFrame *frame,
int what, PyObject *arg)
{
- PyObject *type, *value, *traceback;
- int err;
- _PyErr_Fetch(tstate, &type, &value, &traceback);
- err = call_trace(func, obj, tstate, frame, what, arg);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
+ int err = call_trace(func, obj, tstate, frame, what, arg);
if (err == 0)
{
- _PyErr_Restore(tstate, type, value, traceback);
+ _PyErr_SetRaisedException(tstate, exc);
return 0;
}
else {
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(traceback);
+ Py_XDECREF(exc);
return -1;
}
}
@@ -2935,18 +2921,15 @@ format_exc_check_arg(PyThreadState *tstate, PyObject *exc,
if (exc == PyExc_NameError) {
// Include the name in the NameError exceptions to offer suggestions later.
- PyObject *type, *value, *traceback;
- PyErr_Fetch(&type, &value, &traceback);
- PyErr_NormalizeException(&type, &value, &traceback);
- if (PyErr_GivenExceptionMatches(value, PyExc_NameError)) {
- PyNameErrorObject* exc = (PyNameErrorObject*) value;
- if (exc->name == NULL) {
+ PyObject *exc = PyErr_GetRaisedException();
+ if (PyErr_GivenExceptionMatches(exc, PyExc_NameError)) {
+ if (((PyNameErrorObject*)exc)->name == NULL) {
// We do not care if this fails because we are going to restore the
// NameError anyway.
- (void)PyObject_SetAttr(value, &_Py_ID(name), obj);
+ (void)PyObject_SetAttr(exc, &_Py_ID(name), obj);
}
}
- PyErr_Restore(type, value, traceback);
+ PyErr_SetRaisedException(exc);
}
}
diff --git a/Python/ceval_gil.c b/Python/ceval_gil.c
index 1bf223348d28..749d8144bf7a 100644
--- a/Python/ceval_gil.c
+++ b/Python/ceval_gil.c
@@ -2,7 +2,7 @@
#include "Python.h"
#include "pycore_atomic.h" // _Py_atomic_int
#include "pycore_ceval.h" // _PyEval_SignalReceived()
-#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pylifecycle.h" // _PyErr_Print()
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_interp.h" // _Py_RunGC()
@@ -870,10 +870,9 @@ _Py_FinishPendingCalls(PyThreadState *tstate)
}
if (make_pending_calls(tstate->interp) < 0) {
- PyObject *exc, *val, *tb;
- _PyErr_Fetch(tstate, &exc, &val, &tb);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
PyErr_BadInternalCall();
- _PyErr_ChainExceptions(exc, val, tb);
+ _PyErr_ChainExceptions1(exc);
_PyErr_Print(tstate);
}
}
diff --git a/Python/compile.c b/Python/compile.c
index 2f1130e62ee1..b14c637210ff 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -1633,8 +1633,7 @@ static void
compiler_exit_scope(struct compiler *c)
{
// Don't call PySequence_DelItem() with an exception raised
- PyObject *exc_type, *exc_val, *exc_tb;
- PyErr_Fetch(&exc_type, &exc_val, &exc_tb);
+ PyObject *exc = PyErr_GetRaisedException();
c->c_nestlevel--;
compiler_unit_free(c->u);
@@ -1655,7 +1654,7 @@ compiler_exit_scope(struct compiler *c)
c->u = NULL;
}
- PyErr_Restore(exc_type, exc_val, exc_tb);
+ PyErr_SetRaisedException(exc);
}
/* Search if variable annotations are present statically in a block. */
diff --git a/Python/frame.c b/Python/frame.c
index b562709ce10f..c2c0be301139 100644
--- a/Python/frame.c
+++ b/Python/frame.c
@@ -29,17 +29,14 @@ PyFrameObject *
_PyFrame_MakeAndSetFrameObject(_PyInterpreterFrame *frame)
{
assert(frame->frame_obj == NULL);
- PyObject *error_type, *error_value, *error_traceback;
- PyErr_Fetch(&error_type, &error_value, &error_traceback);
+ PyObject *exc = PyErr_GetRaisedException();
PyFrameObject *f = _PyFrame_New_NoTrack(frame->f_code);
if (f == NULL) {
- Py_XDECREF(error_type);
- Py_XDECREF(error_value);
- Py_XDECREF(error_traceback);
+ Py_XDECREF(exc);
return NULL;
}
- PyErr_Restore(error_type, error_value, error_traceback);
+ PyErr_SetRaisedException(exc);
if (frame->frame_obj) {
// GH-97002: How did we get into this horrible situation? Most likely,
// allocating f triggered a GC collection, which ran some code that
diff --git a/Python/initconfig.c b/Python/initconfig.c
index deec805a6b1c..db7f11e17d66 100644
--- a/Python/initconfig.c
+++ b/Python/initconfig.c
@@ -5,7 +5,7 @@
#include "pycore_interp.h" // _PyInterpreterState.runtime
#include "pycore_long.h" // _PY_LONG_MAX_STR_DIGITS_THRESHOLD
#include "pycore_pathconfig.h" // _Py_path_config
-#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pylifecycle.h" // _Py_PreInitializeFromConfig()
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
#include "pycore_pystate.h" // _PyThreadState_GET()
diff --git a/Python/modsupport.c b/Python/modsupport.c
index b9a10dc157e7..75698455c881 100644
--- a/Python/modsupport.c
+++ b/Python/modsupport.c
@@ -93,16 +93,12 @@ static PyObject *do_mkvalue(const char**, va_list *, int);
static void
do_ignore(const char **p_format, va_list *p_va, char endchar, Py_ssize_t n, int flags)
{
- PyObject *v;
- Py_ssize_t i;
assert(PyErr_Occurred());
- v = PyTuple_New(n);
- for (i = 0; i < n; i++) {
- PyObject *exception, *value, *tb, *w;
-
- PyErr_Fetch(&exception, &value, &tb);
- w = do_mkvalue(p_format, p_va, flags);
- PyErr_Restore(exception, value, tb);
+ PyObject *v = PyTuple_New(n);
+ for (Py_ssize_t i = 0; i < n; i++) {
+ PyObject *exc = PyErr_GetRaisedException();
+ PyObject *w = do_mkvalue(p_format, p_va, flags);
+ PyErr_SetRaisedException(exc);
if (w != NULL) {
if (v != NULL) {
PyTuple_SET_ITEM(v, i, w);
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index b69b80356092..207abb964bca 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -23,7 +23,7 @@ Data members:
#include "pycore_namespace.h" // _PyNamespace_New()
#include "pycore_object.h" // _PyObject_IS_GC()
#include "pycore_pathconfig.h" // _PyPathConfig_ComputeSysPath0()
-#include "pycore_pyerrors.h" // _PyErr_Fetch()
+#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pylifecycle.h" // _PyErr_WriteUnraisableDefaultHook()
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
#include "pycore_pymem.h" // _PyMem_SetDefaultAllocator()
@@ -89,12 +89,11 @@ PySys_GetObject(const char *name)
{
PyThreadState *tstate = _PyThreadState_GET();
- PyObject *exc_type, *exc_value, *exc_tb;
- _PyErr_Fetch(tstate, &exc_type, &exc_value, &exc_tb);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
PyObject *value = _PySys_GetObject(tstate->interp, name);
/* XXX Suppress a new exception if it was raised and restore
* the old one. */
- _PyErr_Restore(tstate, exc_type, exc_value, exc_tb);
+ _PyErr_SetRaisedException(tstate, exc);
return value;
}
@@ -203,8 +202,8 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
int dtrace = PyDTrace_AUDIT_ENABLED();
- PyObject *exc_type, *exc_value, *exc_tb;
- _PyErr_Fetch(ts, &exc_type, &exc_value, &exc_tb);
+
+ PyObject *exc = _PyErr_GetRaisedException(ts);
/* Initialize event args now */
if (argFormat && argFormat[0]) {
@@ -287,13 +286,11 @@ sys_audit_tstate(PyThreadState *ts, const char *event,
Py_XDECREF(eventArgs);
if (!res) {
- _PyErr_Restore(ts, exc_type, exc_value, exc_tb);
+ _PyErr_SetRaisedException(ts, exc);
}
else {
assert(_PyErr_Occurred(ts));
- Py_XDECREF(exc_type);
- Py_XDECREF(exc_value);
- Py_XDECREF(exc_tb);
+ Py_XDECREF(exc);
}
return res;
@@ -3661,12 +3658,11 @@ static void
sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
{
PyObject *file;
- PyObject *error_type, *error_value, *error_traceback;
char buffer[1001];
int written;
PyThreadState *tstate = _PyThreadState_GET();
- _PyErr_Fetch(tstate, &error_type, &error_value, &error_traceback);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
file = _PySys_GetAttr(tstate, key);
written = PyOS_vsnprintf(buffer, sizeof(buffer), format, va);
if (sys_pyfile_write(buffer, file) != 0) {
@@ -3678,7 +3674,7 @@ sys_write(PyObject *key, FILE *fp, const char *format, va_list va)
if (sys_pyfile_write(truncated, file) != 0)
fputs(truncated, fp);
}
- _PyErr_Restore(tstate, error_type, error_value, error_traceback);
+ _PyErr_SetRaisedException(tstate, exc);
}
void
@@ -3708,7 +3704,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
const char *utf8;
PyThreadState *tstate = _PyThreadState_GET();
- PyObject *error = _PyErr_GetRaisedException(tstate);
+ PyObject *exc = _PyErr_GetRaisedException(tstate);
file = _PySys_GetAttr(tstate, key);
message = PyUnicode_FromFormatV(format, va);
if (message != NULL) {
@@ -3720,7 +3716,7 @@ sys_format(PyObject *key, FILE *fp, const char *format, va_list va)
}
Py_DECREF(message);
}
- _PyErr_SetRaisedException(tstate, error);
+ _PyErr_SetRaisedException(tstate, exc);
}
void
1
0
https://github.com/python/cpython/commit/85b1fc1fc5a2e49d521382eaf5e7793175…
commit: 85b1fc1fc5a2e49d521382eaf5e7793175d00371
branch: main
author: Furkan Onder <furkanonder(a)protonmail.com>
committer: hugovk <hugovk(a)users.noreply.github.com>
date: 2023-02-28T13:43:00+02:00
summary:
GH-90744: Fix erroneous doc links in the sys module (#101319)
Co-authored-by: Hugo van Kemenade <hugovk(a)users.noreply.github.com>
files:
M Doc/library/sys.rst
diff --git a/Doc/library/sys.rst b/Doc/library/sys.rst
index 605e2c9a6710..23c5bbed0c6f 100644
--- a/Doc/library/sys.rst
+++ b/Doc/library/sys.rst
@@ -568,55 +568,55 @@ always available.
.. tabularcolumns:: |l|l|L|
- +---------------------+----------------+--------------------------------------------------+
- | attribute | float.h macro | explanation |
- +=====================+================+==================================================+
- | :const:`epsilon` | DBL_EPSILON | difference between 1.0 and the least value |
- | | | greater than 1.0 that is representable as a float|
- | | | |
- | | | See also :func:`math.ulp`. |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`dig` | DBL_DIG | maximum number of decimal digits that can be |
- | | | faithfully represented in a float; see below |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`mant_dig` | DBL_MANT_DIG | float precision: the number of base-``radix`` |
- | | | digits in the significand of a float |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`max` | DBL_MAX | maximum representable positive finite float |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`max_exp` | DBL_MAX_EXP | maximum integer *e* such that ``radix**(e-1)`` is|
- | | | a representable finite float |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`max_10_exp` | DBL_MAX_10_EXP | maximum integer *e* such that ``10**e`` is in the|
- | | | range of representable finite floats |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`min` | DBL_MIN | minimum representable positive *normalized* float|
- | | | |
- | | | Use :func:`math.ulp(0.0) <math.ulp>` to get the |
- | | | smallest positive *denormalized* representable |
- | | | float. |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`min_exp` | DBL_MIN_EXP | minimum integer *e* such that ``radix**(e-1)`` is|
- | | | a normalized float |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`min_10_exp` | DBL_MIN_10_EXP | minimum integer *e* such that ``10**e`` is a |
- | | | normalized float |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`radix` | FLT_RADIX | radix of exponent representation |
- +---------------------+----------------+--------------------------------------------------+
- | :const:`rounds` | FLT_ROUNDS | integer representing the rounding mode for |
- | | | floating-point arithmetic. This reflects the |
- | | | value of the system FLT_ROUNDS macro at |
- | | | interpreter startup time: |
- | | | ``-1`` indeterminable, |
- | | | ``0`` toward zero, |
- | | | ``1`` to nearest, |
- | | | ``2`` toward positive infinity, |
- | | | ``3`` toward negative infinity |
- | | | |
- | | | All other values for FLT_ROUNDS characterize |
- | | | implementation-defined rounding behavior. |
- +---------------------+----------------+--------------------------------------------------+
+ +---------------------+---------------------+--------------------------------------------------+
+ | attribute | float.h macro | explanation |
+ +=====================+=====================+==================================================+
+ | ``epsilon`` | ``DBL_EPSILON`` | difference between 1.0 and the least value |
+ | | | greater than 1.0 that is representable as a float|
+ | | | |
+ | | | See also :func:`math.ulp`. |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``dig`` | ``DBL_DIG`` | maximum number of decimal digits that can be |
+ | | | faithfully represented in a float; see below |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``mant_dig`` | ``DBL_MANT_DIG`` | float precision: the number of base-``radix`` |
+ | | | digits in the significand of a float |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``max`` | ``DBL_MAX`` | maximum representable positive finite float |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``max_exp`` | ``DBL_MAX_EXP`` | maximum integer *e* such that ``radix**(e-1)`` is|
+ | | | a representable finite float |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``max_10_exp`` | ``DBL_MAX_10_EXP`` | maximum integer *e* such that ``10**e`` is in the|
+ | | | range of representable finite floats |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``min`` | ``DBL_MIN`` | minimum representable positive *normalized* float|
+ | | | |
+ | | | Use :func:`math.ulp(0.0) <math.ulp>` to get the |
+ | | | smallest positive *denormalized* representable |
+ | | | float. |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``min_exp`` | ``DBL_MIN_EXP`` | minimum integer *e* such that ``radix**(e-1)`` is|
+ | | | a normalized float |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``min_10_exp`` | ``DBL_MIN_10_EXP`` | minimum integer *e* such that ``10**e`` is a |
+ | | | normalized float |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``radix`` | ``FLT_RADIX`` | radix of exponent representation |
+ +---------------------+---------------------+--------------------------------------------------+
+ | ``rounds`` | ``FLT_ROUNDS`` | integer representing the rounding mode for |
+ | | | floating-point arithmetic. This reflects the |
+ | | | value of the system ``FLT_ROUNDS`` macro at |
+ | | | interpreter startup time: |
+ | | | ``-1`` indeterminable, |
+ | | | ``0`` toward zero, |
+ | | | ``1`` to nearest, |
+ | | | ``2`` toward positive infinity, |
+ | | | ``3`` toward negative infinity |
+ | | | |
+ | | | All other values for ``FLT_ROUNDS`` characterize |
+ | | | implementation-defined rounding behavior. |
+ +---------------------+---------------------+--------------------------------------------------+
The attribute :attr:`sys.float_info.dig` needs further explanation. If
``s`` is any string representing a decimal number with at most
1
0
gh-87092: Make jump target label equal to the offset of the target in the instructions sequence (#102093)
by iritkatriel 28 Feb '23
by iritkatriel 28 Feb '23
28 Feb '23
https://github.com/python/cpython/commit/9f799ab0200f07d762eb8fe822c606e1b4…
commit: 9f799ab0200f07d762eb8fe822c606e1b4b4866e
branch: main
author: Irit Katriel <1055913+iritkatriel(a)users.noreply.github.com>
committer: iritkatriel <1055913+iritkatriel(a)users.noreply.github.com>
date: 2023-02-28T11:29:32Z
summary:
gh-87092: Make jump target label equal to the offset of the target in the instructions sequence (#102093)
files:
M Lib/test/support/bytecode_helper.py
M Lib/test/test_compiler_codegen.py
M Lib/test/test_peepholer.py
M Python/compile.c
diff --git a/Lib/test/support/bytecode_helper.py b/Lib/test/support/bytecode_helper.py
index 65ae7a227baa..190fe8723b1f 100644
--- a/Lib/test/support/bytecode_helper.py
+++ b/Lib/test/support/bytecode_helper.py
@@ -50,18 +50,13 @@ class CompilationStepTestCase(unittest.TestCase):
HAS_TARGET = set(dis.hasjrel + dis.hasjabs + dis.hasexc)
HAS_ARG_OR_TARGET = HAS_ARG.union(HAS_TARGET)
- def setUp(self):
- self.last_label = 0
-
- def Label(self):
- self.last_label += 1
- return self.last_label
+ class Label:
+ pass
def assertInstructionsMatch(self, actual_, expected_):
# get two lists where each entry is a label or
- # an instruction tuple. Compare them, while mapping
- # each actual label to a corresponding expected label
- # based on their locations.
+ # an instruction tuple. Normalize the labels to the
+ # instruction count of the target, and compare the lists.
self.assertIsInstance(actual_, list)
self.assertIsInstance(expected_, list)
@@ -82,39 +77,35 @@ def assertInstructionsMatch(self, actual_, expected_):
act = act[:len(exp)]
self.assertEqual(exp, act)
+ def resolveAndRemoveLabels(self, insts):
+ idx = 0
+ res = []
+ for item in insts:
+ assert isinstance(item, (self.Label, tuple))
+ if isinstance(item, self.Label):
+ item.value = idx
+ else:
+ idx += 1
+ res.append(item)
+
+ return res
+
def normalize_insts(self, insts):
""" Map labels to instruction index.
- Remove labels which are not used as jump targets.
Map opcodes to opnames.
"""
- labels_map = {}
- targets = set()
- idx = 1
- for item in insts:
- assert isinstance(item, (int, tuple))
- if isinstance(item, tuple):
- opcode, oparg, *_ = item
- if dis.opmap.get(opcode, opcode) in self.HAS_TARGET:
- targets.add(oparg)
- idx += 1
- elif isinstance(item, int):
- assert item not in labels_map, "label reused"
- labels_map[item] = idx
-
+ insts = self.resolveAndRemoveLabels(insts)
res = []
for item in insts:
- if isinstance(item, int) and item in targets:
- if not res or labels_map[item] != res[-1]:
- res.append(labels_map[item])
- elif isinstance(item, tuple):
- opcode, oparg, *loc = item
- opcode = dis.opmap.get(opcode, opcode)
- if opcode in self.HAS_TARGET:
- arg = labels_map[oparg]
- else:
- arg = oparg if opcode in self.HAS_TARGET else None
- opcode = dis.opname[opcode]
- res.append((opcode, arg, *loc))
+ assert isinstance(item, tuple)
+ opcode, oparg, *loc = item
+ opcode = dis.opmap.get(opcode, opcode)
+ if isinstance(oparg, self.Label):
+ arg = oparg.value
+ else:
+ arg = oparg if opcode in self.HAS_ARG else None
+ opcode = dis.opname[opcode]
+ res.append((opcode, arg, *loc))
return res
@@ -129,20 +120,18 @@ class CfgOptimizationTestCase(CompilationStepTestCase):
def complete_insts_info(self, insts):
# fill in omitted fields in location, and oparg 0 for ops with no arg.
- instructions = []
+ res = []
for item in insts:
- if isinstance(item, int):
- instructions.append(item)
- else:
- assert isinstance(item, tuple)
- inst = list(reversed(item))
- opcode = dis.opmap[inst.pop()]
- oparg = inst.pop() if opcode in self.HAS_ARG_OR_TARGET else 0
- loc = inst + [-1] * (4 - len(inst))
- instructions.append((opcode, oparg, *loc))
- return instructions
+ assert isinstance(item, tuple)
+ inst = list(reversed(item))
+ opcode = dis.opmap[inst.pop()]
+ oparg = inst.pop() if opcode in self.HAS_ARG_OR_TARGET else 0
+ loc = inst + [-1] * (4 - len(inst))
+ res.append((opcode, oparg, *loc))
+ return res
def get_optimized(self, insts, consts):
+ insts = self.normalize_insts(insts)
insts = self.complete_insts_info(insts)
insts = optimize_cfg(insts, consts)
return insts, consts
diff --git a/Lib/test/test_compiler_codegen.py b/Lib/test/test_compiler_codegen.py
index f2e14c1e628c..022753e0c994 100644
--- a/Lib/test/test_compiler_codegen.py
+++ b/Lib/test/test_compiler_codegen.py
@@ -37,11 +37,11 @@ def test_for_loop(self):
('GET_ITER', None, 1),
loop_lbl := self.Label(),
('FOR_ITER', exit_lbl := self.Label(), 1),
- ('STORE_NAME', None, 1),
+ ('STORE_NAME', 1, 1),
('PUSH_NULL', None, 2),
- ('LOAD_NAME', None, 2),
- ('LOAD_NAME', None, 2),
- ('CALL', None, 2),
+ ('LOAD_NAME', 2, 2),
+ ('LOAD_NAME', 1, 2),
+ ('CALL', 1, 2),
('POP_TOP', None),
('JUMP', loop_lbl),
exit_lbl,
diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py
index 707ff821b31a..aea234e38705 100644
--- a/Lib/test/test_peepholer.py
+++ b/Lib/test/test_peepholer.py
@@ -984,6 +984,7 @@ def cfg_optimization_test(self, insts, expected_insts,
if expected_consts is None:
expected_consts = consts
opt_insts, opt_consts = self.get_optimized(insts, consts)
+ expected_insts = self.normalize_insts(expected_insts)
self.assertInstructionsMatch(opt_insts, expected_insts)
self.assertEqual(opt_consts, expected_consts)
@@ -996,11 +997,11 @@ def test_conditional_jump_forward_non_const_condition(self):
('LOAD_CONST', 3, 14),
]
expected = [
- ('LOAD_NAME', '1', 11),
+ ('LOAD_NAME', 1, 11),
('POP_JUMP_IF_TRUE', lbl := self.Label(), 12),
- ('LOAD_CONST', '2', 13),
+ ('LOAD_CONST', 2, 13),
lbl,
- ('LOAD_CONST', '3', 14)
+ ('LOAD_CONST', 3, 14)
]
self.cfg_optimization_test(insts, expected, consts=list(range(5)))
@@ -1018,7 +1019,7 @@ def test_conditional_jump_forward_const_condition(self):
expected = [
('NOP', None, 11),
('NOP', None, 12),
- ('LOAD_CONST', '3', 14)
+ ('LOAD_CONST', 3, 14)
]
self.cfg_optimization_test(insts, expected, consts=list(range(5)))
@@ -1031,9 +1032,9 @@ def test_conditional_jump_backward_non_const_condition(self):
]
expected = [
lbl := self.Label(),
- ('LOAD_NAME', '1', 11),
+ ('LOAD_NAME', 1, 11),
('POP_JUMP_IF_TRUE', lbl, 12),
- ('LOAD_CONST', '2', 13)
+ ('LOAD_CONST', 2, 13)
]
self.cfg_optimization_test(insts, expected, consts=list(range(5)))
diff --git a/Python/compile.c b/Python/compile.c
index 3f620beb0d02..2f1130e62ee1 100644
--- a/Python/compile.c
+++ b/Python/compile.c
@@ -9704,56 +9704,77 @@ instructions_to_cfg(PyObject *instructions, cfg_builder *g)
{
assert(PyList_Check(instructions));
- Py_ssize_t instr_size = PyList_GET_SIZE(instructions);
- for (Py_ssize_t i = 0; i < instr_size; i++) {
+ Py_ssize_t num_insts = PyList_GET_SIZE(instructions);
+ bool *is_target = PyMem_Calloc(num_insts, sizeof(bool));
+ if (is_target == NULL) {
+ return ERROR;
+ }
+ for (Py_ssize_t i = 0; i < num_insts; i++) {
PyObject *item = PyList_GET_ITEM(instructions, i);
- if (PyLong_Check(item)) {
- int lbl_id = PyLong_AsLong(item);
+ if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
+ PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
+ goto error;
+ }
+ int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ if (HAS_TARGET(opcode)) {
+ int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
if (PyErr_Occurred()) {
- return ERROR;
+ goto error;
}
- if (lbl_id <= 0 || lbl_id > instr_size) {
- /* expect label in a reasonable range */
+ if (oparg < 0 || oparg >= num_insts) {
PyErr_SetString(PyExc_ValueError, "label out of range");
- return ERROR;
+ goto error;
}
- jump_target_label lbl = {lbl_id};
+ is_target[oparg] = true;
+ }
+ }
+
+ for (int i = 0; i < num_insts; i++) {
+ if (is_target[i]) {
+ jump_target_label lbl = {i};
RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
}
- else {
- if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
- PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
- return ERROR;
- }
- int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- location loc;
- loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
- if (PyErr_Occurred()) {
- return ERROR;
- }
- RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
+ PyObject *item = PyList_GET_ITEM(instructions, i);
+ if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
+ PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
+ goto error;
+ }
+ int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ location loc;
+ loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
+ if (PyErr_Occurred()) {
+ goto error;
}
+ loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
+ if (PyErr_Occurred()) {
+ goto error;
+ }
+ RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
}
+
+ PyMem_Free(is_target);
return SUCCESS;
+error:
+ PyMem_Free(is_target);
+ return ERROR;
}
static PyObject *
@@ -9763,20 +9784,12 @@ cfg_to_instructions(cfg_builder *g)
if (instructions == NULL) {
return NULL;
}
- int lbl = 1;
+ int lbl = 0;
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
- b->b_label = lbl++;
+ b->b_label = lbl;
+ lbl += b->b_iused;
}
for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
- PyObject *lbl = PyLong_FromLong(b->b_label);
- if (lbl == NULL) {
- goto error;
- }
- if (PyList_Append(instructions, lbl) != 0) {
- Py_DECREF(lbl);
- goto error;
- }
- Py_DECREF(lbl);
for (int i = 0; i < b->b_iused; i++) {
struct instr *instr = &b->b_instr[i];
location loc = instr->i_loc;
1
0
https://github.com/python/cpython/commit/6b2d7c0ddb4d2afe298ee7c8f6a23c400f…
commit: 6b2d7c0ddb4d2afe298ee7c8f6a23c400f1465fd
branch: main
author: Petr Viktorin <encukou(a)gmail.com>
committer: encukou <encukou(a)gmail.com>
date: 2023-02-28T09:31:01+01:00
summary:
gh-101101: Unstable C API tier (PEP 689) (GH-101102)
files:
A Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst
A Modules/_testcapi/code.c
M Doc/c-api/code.rst
M Doc/c-api/stable.rst
M Doc/tools/extensions/c_annotations.py
M Doc/whatsnew/3.12.rst
M Include/README.rst
M Include/cpython/ceval.h
M Include/cpython/code.h
M Include/pyport.h
M Lib/test/test_code.py
M Modules/Setup.stdlib.in
M Modules/_testcapi/parts.h
M Modules/_testcapimodule.c
M Objects/codeobject.c
M PCbuild/_testcapi.vcxproj
M PCbuild/_testcapi.vcxproj.filters
M Python/ceval.c
diff --git a/Doc/c-api/code.rst b/Doc/c-api/code.rst
index ae75d68901d7..062ef3a1fea9 100644
--- a/Doc/c-api/code.rst
+++ b/Doc/c-api/code.rst
@@ -33,28 +33,47 @@ bound into a function.
Return the number of free variables in *co*.
-.. c:function:: PyCodeObject* PyCode_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
+.. c:function:: PyCodeObject* PyUnstable_Code_New(int argcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Return a new code object. If you need a dummy code object to create a frame,
- use :c:func:`PyCode_NewEmpty` instead. Calling :c:func:`PyCode_New` directly
- will bind you to a precise Python version since the definition of the bytecode
- changes often. The many arguments of this function are inter-dependent in complex
+ use :c:func:`PyCode_NewEmpty` instead.
+
+ Since the definition of the bytecode changes often, calling
+ :c:func:`PyCode_New` directly can bind you to a precise Python version.
+
+ The many arguments of this function are inter-dependent in complex
ways, meaning that subtle changes to values are likely to result in incorrect
execution or VM crashes. Use this function only with extreme care.
.. versionchanged:: 3.11
Added ``exceptiontable`` parameter.
-.. c:function:: PyCodeObject* PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
+ .. index:: single: PyCode_New
+
+ .. versionchanged:: 3.12
+
+ Renamed from ``PyCode_New`` as part of :ref:`unstable-c-api`.
+ The old name is deprecated, but will remain available until the
+ signature changes again.
+
+.. c:function:: PyCodeObject* PyUnstable_Code_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount, int nlocals, int stacksize, int flags, PyObject *code, PyObject *consts, PyObject *names, PyObject *varnames, PyObject *freevars, PyObject *cellvars, PyObject *filename, PyObject *name, int firstlineno, PyObject *linetable, PyObject *exceptiontable)
Similar to :c:func:`PyCode_New`, but with an extra "posonlyargcount" for positional-only arguments.
The same caveats that apply to ``PyCode_New`` also apply to this function.
- .. versionadded:: 3.8
+ .. index:: single: PyCode_NewWithPosOnlyArgs
+
+ .. versionadded:: 3.8 as ``PyCode_NewWithPosOnlyArgs``
.. versionchanged:: 3.11
Added ``exceptiontable`` parameter.
+ .. versionchanged:: 3.12
+
+ Renamed to ``PyUnstable_Code_NewWithPosOnlyArgs``.
+ The old name is deprecated, but will remain available until the
+ signature changes again.
+
.. c:function:: PyCodeObject* PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno)
Return a new empty code object with the specified filename,
@@ -165,3 +184,70 @@ bound into a function.
:c:func:`PyErr_WriteUnraisable`. Otherwise it should return ``0``.
.. versionadded:: 3.12
+
+
+Extra information
+-----------------
+
+To support low-level extensions to frame evaluation, such as external
+just-in-time compilers, it is possible to attach arbitrary extra data to
+code objects.
+
+These functions are part of the unstable C API tier:
+this functionality is a CPython implementation detail, and the API
+may change without deprecation warnings.
+
+.. c:function:: Py_ssize_t PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
+
+ Return a new an opaque index value used to adding data to code objects.
+
+ You generally call this function once (per interpreter) and use the result
+ with ``PyCode_GetExtra`` and ``PyCode_SetExtra`` to manipulate
+ data on individual code objects.
+
+ If *free* is not ``NULL``: when a code object is deallocated,
+ *free* will be called on non-``NULL`` data stored under the new index.
+ Use :c:func:`Py_DecRef` when storing :c:type:`PyObject`.
+
+ .. index:: single: _PyEval_RequestCodeExtraIndex
+
+ .. versionadded:: 3.6 as ``_PyEval_RequestCodeExtraIndex``
+
+ .. versionchanged:: 3.12
+
+ Renamed to ``PyUnstable_Eval_RequestCodeExtraIndex``.
+ The old private name is deprecated, but will be available until the API
+ changes.
+
+.. c:function:: int PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
+
+ Set *extra* to the extra data stored under the given index.
+ Return 0 on success. Set an exception and return -1 on failure.
+
+ If no data was set under the index, set *extra* to ``NULL`` and return
+ 0 without setting an exception.
+
+ .. index:: single: _PyCode_GetExtra
+
+ .. versionadded:: 3.6 as ``_PyCode_GetExtra``
+
+ .. versionchanged:: 3.12
+
+ Renamed to ``PyUnstable_Code_GetExtra``.
+ The old private name is deprecated, but will be available until the API
+ changes.
+
+.. c:function:: int PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
+
+ Set the extra data stored under the given index to *extra*.
+ Return 0 on success. Set an exception and return -1 on failure.
+
+ .. index:: single: _PyCode_SetExtra
+
+ .. versionadded:: 3.6 as ``_PyCode_SetExtra``
+
+ .. versionchanged:: 3.12
+
+ Renamed to ``PyUnstable_Code_SetExtra``.
+ The old private name is deprecated, but will be available until the API
+ changes.
diff --git a/Doc/c-api/stable.rst b/Doc/c-api/stable.rst
index 4ae20e93e367..3721fc0697f5 100644
--- a/Doc/c-api/stable.rst
+++ b/Doc/c-api/stable.rst
@@ -6,9 +6,9 @@
C API Stability
***************
-Python's C API is covered by the Backwards Compatibility Policy, :pep:`387`.
-While the C API will change with every minor release (e.g. from 3.9 to 3.10),
-most changes will be source-compatible, typically by only adding new API.
+Unless documented otherwise, Python's C API is covered by the Backwards
+Compatibility Policy, :pep:`387`.
+Most changes to it are source-compatible (typically by only adding new API).
Changing existing API or removing API is only done after a deprecation period
or to fix serious issues.
@@ -18,8 +18,38 @@ way; see :ref:`stable-abi-platform` below).
So, code compiled for Python 3.10.0 will work on 3.10.8 and vice versa,
but will need to be compiled separately for 3.9.x and 3.10.x.
+There are two tiers of C API with different stability exepectations:
+
+- *Unstable API*, may change in minor versions without a deprecation period.
+ It is marked by the ``PyUnstable`` prefix in names.
+- *Limited API*, is compatible across several minor releases.
+ When :c:macro:`Py_LIMITED_API` is defined, only this subset is exposed
+ from ``Python.h``.
+
+These are discussed in more detail below.
+
Names prefixed by an underscore, such as ``_Py_InternalState``,
are private API that can change without notice even in patch releases.
+If you need to use this API, consider reaching out to
+`CPython developers <https://discuss.python.org/c/core-dev/c-api/30>`_
+to discuss adding public API for your use case.
+
+.. _unstable-c-api:
+
+Unstable C API
+==============
+
+.. index:: single: PyUnstable
+
+Any API named with the ``PyUnstable`` prefix exposes CPython implementation
+details, and may change in every minor release (e.g. from 3.9 to 3.10) without
+any deprecation warnings.
+However, it will not change in a bugfix release (e.g. from 3.10.0 to 3.10.1).
+
+It is generally intended for specialized, low-level tools like debuggers.
+
+Projects that use this API are expected to follow
+CPython development and spend extra effort adjusting to changes.
Stable Application Binary Interface
diff --git a/Doc/tools/extensions/c_annotations.py b/Doc/tools/extensions/c_annotations.py
index 9defb24a0331..e5dc82cf0dc2 100644
--- a/Doc/tools/extensions/c_annotations.py
+++ b/Doc/tools/extensions/c_annotations.py
@@ -143,6 +143,22 @@ def add_annotations(self, app, doctree):
' (Only some members are part of the stable ABI.)')
node.insert(0, emph_node)
+ # Unstable API annotation.
+ if name.startswith('PyUnstable'):
+ warn_node = nodes.admonition(
+ classes=['unstable-c-api', 'warning'])
+ message = 'This is '
+ emph_node = nodes.emphasis(message, message)
+ ref_node = addnodes.pending_xref(
+ 'Unstable API', refdomain="std",
+ reftarget='unstable-c-api',
+ reftype='ref', refexplicit="False")
+ ref_node += nodes.Text('Unstable API')
+ emph_node += ref_node
+ emph_node += nodes.Text('. It may change without warning in minor releases.')
+ warn_node += emph_node
+ node.insert(0, warn_node)
+
# Return value annotation
if objtype != 'function':
continue
diff --git a/Doc/whatsnew/3.12.rst b/Doc/whatsnew/3.12.rst
index 1a25ec6b7061..c0c021c67914 100644
--- a/Doc/whatsnew/3.12.rst
+++ b/Doc/whatsnew/3.12.rst
@@ -810,6 +810,29 @@ C API Changes
New Features
------------
+
+* :pep:`697`: Introduced the :ref:`Unstable C API tier <unstable-c-api>`,
+ intended for low-level tools like debuggers and JIT compilers.
+ This API may change in each minor release of CPython without deprecation
+ warnings.
+ Its contents are marked by the ``PyUnstable_`` prefix in names.
+
+ Code object constructors:
+
+ - ``PyUnstable_Code_New()`` (renamed from ``PyCode_New``)
+ - ``PyUnstable_Code_NewWithPosOnlyArgs()`` (renamed from ``PyCode_NewWithPosOnlyArgs``)
+
+ Extra storage for code objects (:pep:`523`):
+
+ - ``PyUnstable_Eval_RequestCodeExtraIndex()`` (renamed from ``_PyEval_RequestCodeExtraIndex``)
+ - ``PyUnstable_Code_GetExtra()`` (renamed from ``_PyCode_GetExtra``)
+ - ``PyUnstable_Code_SetExtra()`` (renamed from ``_PyCode_SetExtra``)
+
+ The original names will continue to be available until the respective
+ API changes.
+
+ (Contributed by Petr Viktorin in :gh:`101101`.)
+
* Added the new limited C API function :c:func:`PyType_FromMetaclass`,
which generalizes the existing :c:func:`PyType_FromModuleAndSpec` using
an additional metaclass argument.
diff --git a/Include/README.rst b/Include/README.rst
index f52e690eac9a..531f09692f78 100644
--- a/Include/README.rst
+++ b/Include/README.rst
@@ -1,11 +1,13 @@
The Python C API
================
-The C API is divided into three sections:
+The C API is divided into these sections:
1. ``Include/``: Limited API
2. ``Include/cpython/``: CPython implementation details
-3. ``Include/internal/``: The internal API
+3. ``Include/cpython/``, names with the ``PyUnstable_`` prefix: API that can
+ change between minor releases
+4. ``Include/internal/``, and any name with ``_`` prefix: The internal API
Information on changing the C API is available `in the developer guide`_
diff --git a/Include/cpython/ceval.h b/Include/cpython/ceval.h
index 74665c9fa105..0fbbee10c2ed 100644
--- a/Include/cpython/ceval.h
+++ b/Include/cpython/ceval.h
@@ -22,7 +22,12 @@ PyAPI_FUNC(PyObject *) _PyEval_EvalFrameDefault(PyThreadState *tstate, struct _P
PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds);
PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void);
-PyAPI_FUNC(Py_ssize_t) _PyEval_RequestCodeExtraIndex(freefunc);
+PyAPI_FUNC(Py_ssize_t) PyUnstable_Eval_RequestCodeExtraIndex(freefunc);
+// Old name -- remove when this API changes:
+_Py_DEPRECATED_EXTERNALLY(3.12) static inline Py_ssize_t
+_PyEval_RequestCodeExtraIndex(freefunc f) {
+ return PyUnstable_Eval_RequestCodeExtraIndex(f);
+}
PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *);
PyAPI_FUNC(int) _PyEval_SliceIndexNotNone(PyObject *, Py_ssize_t *);
diff --git a/Include/cpython/code.h b/Include/cpython/code.h
index fba9296aedc9..0e4bd8a58c16 100644
--- a/Include/cpython/code.h
+++ b/Include/cpython/code.h
@@ -178,19 +178,40 @@ static inline int PyCode_GetFirstFree(PyCodeObject *op) {
#define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
#define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
-/* Public interface */
-PyAPI_FUNC(PyCodeObject *) PyCode_New(
+/* Unstable public interface */
+PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New(
int, int, int, int, int, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, int, PyObject *,
PyObject *);
-PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs(
+PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs(
int, int, int, int, int, int, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, PyObject *,
PyObject *, PyObject *, PyObject *, int, PyObject *,
PyObject *);
/* same as struct above */
+// Old names -- remove when this API changes:
+_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
+PyCode_New(
+ int a, int b, int c, int d, int e, PyObject *f, PyObject *g,
+ PyObject *h, PyObject *i, PyObject *j, PyObject *k,
+ PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
+ PyObject *q)
+{
+ return PyUnstable_Code_New(
+ a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
+}
+_Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
+PyCode_NewWithPosOnlyArgs(
+ int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g,
+ PyObject *h, PyObject *i, PyObject *j, PyObject *k,
+ PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
+ PyObject *q)
+{
+ return PyUnstable_Code_NewWithPosOnlyArgs(
+ a, poac, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
+}
/* Creates a new empty code object with the specified source location. */
PyAPI_FUNC(PyCodeObject *)
@@ -269,11 +290,21 @@ PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
PyObject *names, PyObject *lnotab);
-
-PyAPI_FUNC(int) _PyCode_GetExtra(PyObject *code, Py_ssize_t index,
- void **extra);
-PyAPI_FUNC(int) _PyCode_SetExtra(PyObject *code, Py_ssize_t index,
- void *extra);
+PyAPI_FUNC(int) PyUnstable_Code_GetExtra(
+ PyObject *code, Py_ssize_t index, void **extra);
+PyAPI_FUNC(int) PyUnstable_Code_SetExtra(
+ PyObject *code, Py_ssize_t index, void *extra);
+// Old names -- remove when this API changes:
+_Py_DEPRECATED_EXTERNALLY(3.12) static inline int
+_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
+{
+ return PyUnstable_Code_GetExtra(code, index, extra);
+}
+_Py_DEPRECATED_EXTERNALLY(3.12) static inline int
+_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
+{
+ return PyUnstable_Code_SetExtra(code, index, extra);
+}
/* Equivalent to getattr(code, 'co_code') in Python.
Returns a strong reference to a bytes object. */
diff --git a/Include/pyport.h b/Include/pyport.h
index 40092c2f81ad..eef0fe1bfd71 100644
--- a/Include/pyport.h
+++ b/Include/pyport.h
@@ -323,6 +323,15 @@ extern "C" {
#define Py_DEPRECATED(VERSION_UNUSED)
#endif
+// _Py_DEPRECATED_EXTERNALLY(version)
+// Deprecated outside CPython core.
+#ifdef Py_BUILD_CORE
+#define _Py_DEPRECATED_EXTERNALLY(VERSION_UNUSED)
+#else
+#define _Py_DEPRECATED_EXTERNALLY(version) Py_DEPRECATED(version)
+#endif
+
+
#if defined(__clang__)
#define _Py_COMP_DIAG_PUSH _Pragma("clang diagnostic push")
#define _Py_COMP_DIAG_IGNORE_DEPR_DECLS \
diff --git a/Lib/test/test_code.py b/Lib/test/test_code.py
index 9c2ac83e1b69..0cd1fb3f9728 100644
--- a/Lib/test/test_code.py
+++ b/Lib/test/test_code.py
@@ -752,15 +752,15 @@ def f():
py = ctypes.pythonapi
freefunc = ctypes.CFUNCTYPE(None,ctypes.c_voidp)
- RequestCodeExtraIndex = py._PyEval_RequestCodeExtraIndex
+ RequestCodeExtraIndex = py.PyUnstable_Eval_RequestCodeExtraIndex
RequestCodeExtraIndex.argtypes = (freefunc,)
RequestCodeExtraIndex.restype = ctypes.c_ssize_t
- SetExtra = py._PyCode_SetExtra
+ SetExtra = py.PyUnstable_Code_SetExtra
SetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t, ctypes.c_voidp)
SetExtra.restype = ctypes.c_int
- GetExtra = py._PyCode_GetExtra
+ GetExtra = py.PyUnstable_Code_GetExtra
GetExtra.argtypes = (ctypes.py_object, ctypes.c_ssize_t,
ctypes.POINTER(ctypes.c_voidp))
GetExtra.restype = ctypes.c_int
diff --git a/Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst b/Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst
new file mode 100644
index 000000000000..20db25ddd0c1
--- /dev/null
+++ b/Misc/NEWS.d/next/C API/2022-04-21-17-25-22.gh-issue-91744.FgvaMi.rst
@@ -0,0 +1,3 @@
+Introduced the *Unstable C API tier*, marking APi that is allowed to change
+in minor releases without a deprecation period.
+See :pep:`689` for details.
diff --git a/Modules/Setup.stdlib.in b/Modules/Setup.stdlib.in
index 7551e5b34943..b12290d436cb 100644
--- a/Modules/Setup.stdlib.in
+++ b/Modules/Setup.stdlib.in
@@ -169,7 +169,7 @@
@MODULE__XXTESTFUZZ_TRUE@_xxtestfuzz _xxtestfuzz/_xxtestfuzz.c _xxtestfuzz/fuzzer.c
@MODULE__TESTBUFFER_TRUE@_testbuffer _testbuffer.c
@MODULE__TESTINTERNALCAPI_TRUE@_testinternalcapi _testinternalcapi.c
-@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c
+@MODULE__TESTCAPI_TRUE@_testcapi _testcapimodule.c _testcapi/vectorcall.c _testcapi/vectorcall_limited.c _testcapi/heaptype.c _testcapi/unicode.c _testcapi/getargs.c _testcapi/pytime.c _testcapi/datetime.c _testcapi/docstring.c _testcapi/mem.c _testcapi/watchers.c _testcapi/long.c _testcapi/float.c _testcapi/structmember.c _testcapi/exceptions.c _testcapi/code.c
@MODULE__TESTCLINIC_TRUE@_testclinic _testclinic.c
# Some testing modules MUST be built as shared libraries.
diff --git a/Modules/_testcapi/code.c b/Modules/_testcapi/code.c
new file mode 100644
index 000000000000..588dc67971ea
--- /dev/null
+++ b/Modules/_testcapi/code.c
@@ -0,0 +1,115 @@
+#include "parts.h"
+
+static Py_ssize_t
+get_code_extra_index(PyInterpreterState* interp) {
+ Py_ssize_t result = -1;
+
+ static const char *key = "_testcapi.frame_evaluation.code_index";
+
+ PyObject *interp_dict = PyInterpreterState_GetDict(interp); // borrowed
+ assert(interp_dict); // real users would handle missing dict... somehow
+
+ PyObject *index_obj = PyDict_GetItemString(interp_dict, key); // borrowed
+ Py_ssize_t index = 0;
+ if (!index_obj) {
+ if (PyErr_Occurred()) {
+ goto finally;
+ }
+ index = PyUnstable_Eval_RequestCodeExtraIndex(NULL);
+ if (index < 0 || PyErr_Occurred()) {
+ goto finally;
+ }
+ index_obj = PyLong_FromSsize_t(index); // strong ref
+ if (!index_obj) {
+ goto finally;
+ }
+ int res = PyDict_SetItemString(interp_dict, key, index_obj);
+ Py_DECREF(index_obj);
+ if (res < 0) {
+ goto finally;
+ }
+ }
+ else {
+ index = PyLong_AsSsize_t(index_obj);
+ if (index == -1 && PyErr_Occurred()) {
+ goto finally;
+ }
+ }
+
+ result = index;
+finally:
+ return result;
+}
+
+static PyObject *
+test_code_extra(PyObject* self, PyObject *Py_UNUSED(callable))
+{
+ PyObject *result = NULL;
+ PyObject *test_module = NULL;
+ PyObject *test_func = NULL;
+
+ // Get or initialize interpreter-specific code object storage index
+ PyInterpreterState *interp = PyInterpreterState_Get();
+ if (!interp) {
+ return NULL;
+ }
+ Py_ssize_t code_extra_index = get_code_extra_index(interp);
+ if (PyErr_Occurred()) {
+ goto finally;
+ }
+
+ // Get a function to test with
+ // This can be any Python function. Use `test.test_misc.testfunction`.
+ test_module = PyImport_ImportModule("test.test_capi.test_misc");
+ if (!test_module) {
+ goto finally;
+ }
+ test_func = PyObject_GetAttrString(test_module, "testfunction");
+ if (!test_func) {
+ goto finally;
+ }
+ PyObject *test_func_code = PyFunction_GetCode(test_func); // borrowed
+ if (!test_func_code) {
+ goto finally;
+ }
+
+ // Check the value is initially NULL
+ void *extra;
+ int res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
+ if (res < 0) {
+ goto finally;
+ }
+ assert (extra == NULL);
+
+ // Set another code extra value
+ res = PyUnstable_Code_SetExtra(test_func_code, code_extra_index, (void*)(uintptr_t)77);
+ if (res < 0) {
+ goto finally;
+ }
+ // Assert it was set correctly
+ res = PyUnstable_Code_GetExtra(test_func_code, code_extra_index, &extra);
+ if (res < 0) {
+ goto finally;
+ }
+ assert ((uintptr_t)extra == 77);
+
+ result = Py_NewRef(Py_None);
+finally:
+ Py_XDECREF(test_module);
+ Py_XDECREF(test_func);
+ return result;
+}
+
+static PyMethodDef TestMethods[] = {
+ {"test_code_extra", test_code_extra, METH_NOARGS},
+ {NULL},
+};
+
+int
+_PyTestCapi_Init_Code(PyObject *m) {
+ if (PyModule_AddFunctions(m, TestMethods) < 0) {
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/Modules/_testcapi/parts.h b/Modules/_testcapi/parts.h
index 1689f186b833..c8f31dc8e39f 100644
--- a/Modules/_testcapi/parts.h
+++ b/Modules/_testcapi/parts.h
@@ -37,6 +37,7 @@ int _PyTestCapi_Init_Long(PyObject *module);
int _PyTestCapi_Init_Float(PyObject *module);
int _PyTestCapi_Init_Structmember(PyObject *module);
int _PyTestCapi_Init_Exceptions(PyObject *module);
+int _PyTestCapi_Init_Code(PyObject *module);
#ifdef LIMITED_API_AVAILABLE
int _PyTestCapi_Init_VectorcallLimited(PyObject *module);
diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c
index fc716a3564d3..10e507d6b481 100644
--- a/Modules/_testcapimodule.c
+++ b/Modules/_testcapimodule.c
@@ -4083,6 +4083,9 @@ PyInit__testcapi(void)
if (_PyTestCapi_Init_Exceptions(m) < 0) {
return NULL;
}
+ if (_PyTestCapi_Init_Code(m) < 0) {
+ return NULL;
+ }
#ifndef LIMITED_API_AVAILABLE
PyModule_AddObjectRef(m, "LIMITED_API_AVAILABLE", Py_False);
diff --git a/Objects/codeobject.c b/Objects/codeobject.c
index a03b14edea8d..175bd57568f8 100644
--- a/Objects/codeobject.c
+++ b/Objects/codeobject.c
@@ -567,7 +567,8 @@ _PyCode_New(struct _PyCodeConstructor *con)
******************/
PyCodeObject *
-PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
+PyUnstable_Code_NewWithPosOnlyArgs(
+ int argcount, int posonlyargcount, int kwonlyargcount,
int nlocals, int stacksize, int flags,
PyObject *code, PyObject *consts, PyObject *names,
PyObject *varnames, PyObject *freevars, PyObject *cellvars,
@@ -691,7 +692,7 @@ PyCode_NewWithPosOnlyArgs(int argcount, int posonlyargcount, int kwonlyargcount,
}
PyCodeObject *
-PyCode_New(int argcount, int kwonlyargcount,
+PyUnstable_Code_New(int argcount, int kwonlyargcount,
int nlocals, int stacksize, int flags,
PyObject *code, PyObject *consts, PyObject *names,
PyObject *varnames, PyObject *freevars, PyObject *cellvars,
@@ -1371,7 +1372,7 @@ typedef struct {
int
-_PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
+PyUnstable_Code_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
{
if (!PyCode_Check(code)) {
PyErr_BadInternalCall();
@@ -1392,7 +1393,7 @@ _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
int
-_PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
+PyUnstable_Code_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
diff --git a/PCbuild/_testcapi.vcxproj b/PCbuild/_testcapi.vcxproj
index 742eb3ed2d90..4cc184bfc1ac 100644
--- a/PCbuild/_testcapi.vcxproj
+++ b/PCbuild/_testcapi.vcxproj
@@ -108,6 +108,7 @@
<ClCompile Include="..\Modules\_testcapi\long.c" />
<ClCompile Include="..\Modules\_testcapi\structmember.c" />
<ClCompile Include="..\Modules\_testcapi\exceptions.c" />
+ <ClCompile Include="..\Modules\_testcapi\code.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc" />
diff --git a/PCbuild/_testcapi.vcxproj.filters b/PCbuild/_testcapi.vcxproj.filters
index ab5afc150c32..fbdaf04ce37c 100644
--- a/PCbuild/_testcapi.vcxproj.filters
+++ b/PCbuild/_testcapi.vcxproj.filters
@@ -54,6 +54,9 @@
<ClCompile Include="..\Modules\_testcapi\exceptions.c">
<Filter>Source Files</Filter>
</ClCompile>
+ <ClCompile Include="..\Modules\_testcapi\code.c">
+ <Filter>Source Files</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\PC\python_nt.rc">
diff --git a/Python/ceval.c b/Python/ceval.c
index b382d2109b93..5540c93d5e3d 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -2988,7 +2988,7 @@ format_awaitable_error(PyThreadState *tstate, PyTypeObject *type, int oparg)
Py_ssize_t
-_PyEval_RequestCodeExtraIndex(freefunc free)
+PyUnstable_Eval_RequestCodeExtraIndex(freefunc free)
{
PyInterpreterState *interp = _PyInterpreterState_GET();
Py_ssize_t new_index;
1
0
https://github.com/python/cpython/commit/d01cf5072be5511595b6d0c35ace6c1b07…
commit: d01cf5072be5511595b6d0c35ace6c1b07716f8d
branch: 3.11
author: Miss Islington (bot) <31488909+miss-islington(a)users.noreply.github.com>
committer: miss-islington <31488909+miss-islington(a)users.noreply.github.com>
date: 2023-02-27T22:41:20-08:00
summary:
IDLE: Simplify DynOptionsMenu __init__code (GH-101371)
Refactor DynOptionMenu's initializer to not copy kwargs dict and use subscripting;
improve its htest.
(cherry picked from commit c41af812c948ec3cb07b2ef7a46a238f5cab3dc2)
Co-authored-by: JosephSBoyle <48555120+JosephSBoyle(a)users.noreply.github.com>
Co-authored-by: Terry Jan Reedy <tjreedy(a)udel.edu>
files:
M Lib/idlelib/dynoption.py
diff --git a/Lib/idlelib/dynoption.py b/Lib/idlelib/dynoption.py
index 9c6ffa435a10..d5dfc3eda13f 100644
--- a/Lib/idlelib/dynoption.py
+++ b/Lib/idlelib/dynoption.py
@@ -2,24 +2,19 @@
OptionMenu widget modified to allow dynamic menu reconfiguration
and setting of highlightthickness
"""
-import copy
-
from tkinter import OptionMenu, _setit, StringVar, Button
class DynOptionMenu(OptionMenu):
- """
- unlike OptionMenu, our kwargs can include highlightthickness
+ """Add SetMenu and highlightthickness to OptionMenu.
+
+ Highlightthickness adds space around menu button.
"""
def __init__(self, master, variable, value, *values, **kwargs):
- # TODO copy value instead of whole dict
- kwargsCopy=copy.copy(kwargs)
- if 'highlightthickness' in list(kwargs.keys()):
- del(kwargs['highlightthickness'])
+ highlightthickness = kwargs.pop('highlightthickness', None)
OptionMenu.__init__(self, master, variable, value, *values, **kwargs)
- self.config(highlightthickness=kwargsCopy.get('highlightthickness'))
- #self.menu=self['menu']
- self.variable=variable
- self.command=kwargs.get('command')
+ self['highlightthickness'] = highlightthickness
+ self.variable = variable
+ self.command = kwargs.get('command')
def SetMenu(self,valueList,value=None):
"""
@@ -38,14 +33,15 @@ def _dyn_option_menu(parent): # htest #
from tkinter import Toplevel # + StringVar, Button
top = Toplevel(parent)
- top.title("Tets dynamic option menu")
+ top.title("Test dynamic option menu")
x, y = map(int, parent.geometry().split('+')[1:])
top.geometry("200x100+%d+%d" % (x + 250, y + 175))
top.focus_set()
var = StringVar(top)
var.set("Old option set") #Set the default value
- dyn = DynOptionMenu(top,var, "old1","old2","old3","old4")
+ dyn = DynOptionMenu(top, var, "old1","old2","old3","old4",
+ highlightthickness=5)
dyn.pack()
def update():
@@ -54,5 +50,6 @@ def update():
button.pack()
if __name__ == '__main__':
+ # Only module without unittests because of intention to replace.
from idlelib.idle_test.htest import run
run(_dyn_option_menu)
1
0