summaryrefslogtreecommitdiffstats
path: root/Objects/frameobject.c
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2022-07-01 13:01:14 (GMT)
committerGitHub <noreply@github.com>2022-07-01 13:01:14 (GMT)
commitbe80db14c432c621e44920f8fd95a3f3191aca9b (patch)
tree15f11323e442796d0c92d96763dea288fae32db6 /Objects/frameobject.c
parent022800253f254ba681a9f1093501a9fd1c15bed7 (diff)
downloadcpython-be80db14c432c621e44920f8fd95a3f3191aca9b.zip
cpython-be80db14c432c621e44920f8fd95a3f3191aca9b.tar.gz
cpython-be80db14c432c621e44920f8fd95a3f3191aca9b.tar.bz2
GH-94438: Account for NULLs on evaluation stack when jumping lines. (GH-94444)
Diffstat (limited to 'Objects/frameobject.c')
-rw-r--r--Objects/frameobject.c56
1 files changed, 43 insertions, 13 deletions
diff --git a/Objects/frameobject.c b/Objects/frameobject.c
index 44cc062..34a6c46 100644
--- a/Objects/frameobject.c
+++ b/Objects/frameobject.c
@@ -137,9 +137,24 @@ typedef enum kind {
Iterator = 1,
Except = 2,
Object = 3,
+ Null = 4,
} Kind;
-#define BITS_PER_BLOCK 2
+static int
+compatible_kind(Kind from, Kind to) {
+ if (to == 0) {
+ return 0;
+ }
+ if (to == Object) {
+ return from != Null;
+ }
+ if (to == Null) {
+ return 1;
+ }
+ return from == to;
+}
+
+#define BITS_PER_BLOCK 3
#define UNINITIALIZED -2
#define OVERFLOWED -1
@@ -298,6 +313,31 @@ mark_stacks(PyCodeObject *code_obj, int len)
case RERAISE:
/* End of block */
break;
+ case PUSH_NULL:
+ next_stack = push_value(next_stack, Null);
+ stacks[i+1] = next_stack;
+ break;
+ case LOAD_GLOBAL:
+ {
+ int j = get_arg(code, i);
+ if (j & 1) {
+ next_stack = push_value(next_stack, Null);
+ }
+ next_stack = push_value(next_stack, Object);
+ stacks[i+1] = next_stack;
+ break;
+ }
+ case LOAD_ATTR:
+ {
+ int j = get_arg(code, i);
+ if (j & 1) {
+ next_stack = pop_value(next_stack);
+ next_stack = push_value(next_stack, Null);
+ next_stack = push_value(next_stack, Object);
+ }
+ stacks[i+1] = next_stack;
+ break;
+ }
default:
{
int delta = PyCompile_OpcodeStackEffect(opcode, _Py_OPARG(code[i]));
@@ -319,17 +359,6 @@ mark_stacks(PyCodeObject *code_obj, int len)
}
static int
-compatible_kind(Kind from, Kind to) {
- if (to == 0) {
- return 0;
- }
- if (to == Object) {
- return 1;
- }
- return from == to;
-}
-
-static int
compatible_stack(int64_t from_stack, int64_t to_stack)
{
if (from_stack < 0 || to_stack < 0) {
@@ -365,7 +394,8 @@ explain_incompatible_stack(int64_t to_stack)
case Except:
return "can't jump into an 'except' block as there's no exception";
case Object:
- return "differing stack depth";
+ case Null:
+ return "incompatible stacks";
case Iterator:
return "can't jump into the body of a for loop";
default: