diff options
author | Mark Shannon <mark@hotpy.org> | 2022-07-01 13:01:14 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-01 13:01:14 (GMT) |
commit | be80db14c432c621e44920f8fd95a3f3191aca9b (patch) | |
tree | 15f11323e442796d0c92d96763dea288fae32db6 /Objects/frameobject.c | |
parent | 022800253f254ba681a9f1093501a9fd1c15bed7 (diff) | |
download | cpython-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.c | 56 |
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: |