Description
If the abstract interpreter ever pushes bottom
(i.e., a contradition) to the stack, it might as well stop -- this indicates we're looking at unreachable code (e.g., after a deopt that always deopts, or a branch that always branches).
My original idea was to tweak the code generator to auto-generate such checks for the output stack effects (hand-waving a bit around array outputs, which are special anyways). But when I implemented that, I quickly found that most such pushes are freshly created symbols (e.g. sym_new_const()
or sym_new_undefined()
) that we already know cannot be bottom
.
Also, there's a category of stack writes that evades easy detection, e.g. when _GUARD_BOTH_INT
calls sym_set_type(left, &PyLong_Type)
(and ditto for right
), this is part of an opcode whose input and output stack effects are identical, and for such opcodes, the push operation is actually a write (without changing the stack pointer) that is generated on a different code path in the generator.
So no I'm considering to just hand-write bottom checks where they seem relevant. Perhaps we can change the sym_set_...()
functions to return a bool
result indicating whether they produced a bottom
value, and change the (hand-written) code that calls these to emit something like
if (sym_set_null(sym)) {
goto hit_bottom;
}
where hit_bottom
is a new error label that prints a different debug message.
I'm still weighing my options though...