gh-119689: generate stack effect metadata for pseudo instructions (#119691)

This commit is contained in:
Irit Katriel 2024-05-29 10:47:56 +01:00 committed by GitHub
parent 7ca74a760a
commit c1e9647107
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
10 changed files with 112 additions and 73 deletions

View file

@ -213,7 +213,7 @@ dummy_func(
}
}
pseudo(LOAD_CLOSURE) = {
pseudo(LOAD_CLOSURE, (-- unused)) = {
LOAD_FAST,
};
@ -259,7 +259,7 @@ dummy_func(
SETLOCAL(oparg, value);
}
pseudo(STORE_FAST_MAYBE_NULL) = {
pseudo(STORE_FAST_MAYBE_NULL, (unused --)) = {
STORE_FAST,
};
@ -2393,12 +2393,12 @@ dummy_func(
#endif /* _Py_TIER2 */
}
pseudo(JUMP) = {
pseudo(JUMP, (--)) = {
JUMP_FORWARD,
JUMP_BACKWARD,
};
pseudo(JUMP_NO_INTERRUPT) = {
pseudo(JUMP_NO_INTERRUPT, (--)) = {
JUMP_FORWARD,
JUMP_BACKWARD_NO_INTERRUPT,
};
@ -2895,19 +2895,27 @@ dummy_func(
ERROR_IF(res == NULL, error);
}
pseudo(SETUP_FINALLY, (HAS_ARG)) = {
pseudo(SETUP_FINALLY, (-- unused), (HAS_ARG)) = {
/* If an exception is raised, restore the stack position
* and push one value before jumping to the handler.
*/
NOP,
};
pseudo(SETUP_CLEANUP, (HAS_ARG)) = {
pseudo(SETUP_CLEANUP, (-- unused, unused), (HAS_ARG)) = {
/* As SETUP_FINALLY, but push lasti as well */
NOP,
};
pseudo(SETUP_WITH, (HAS_ARG)) = {
pseudo(SETUP_WITH, (-- unused), (HAS_ARG)) = {
/* If an exception is raised, restore the stack position to the
* position before the result of __(a)enter__ and push 2 values
* before jumping to the handler.
*/
NOP,
};
pseudo(POP_BLOCK) = {
pseudo(POP_BLOCK, (--)) = {
NOP,
};

View file

@ -703,51 +703,22 @@ compiler_set_qualname(struct compiler *c)
static int
stack_effect(int opcode, int oparg, int jump)
{
if (0 <= opcode && opcode <= MAX_REAL_OPCODE) {
if (_PyOpcode_Deopt[opcode] != opcode) {
// Specialized instructions are not supported.
return PY_INVALID_STACK_EFFECT;
}
int popped = _PyOpcode_num_popped(opcode, oparg);
int pushed = _PyOpcode_num_pushed(opcode, oparg);
if (popped < 0 || pushed < 0) {
return PY_INVALID_STACK_EFFECT;
}
return pushed - popped;
if (opcode < 0) {
return PY_INVALID_STACK_EFFECT;
}
// Pseudo ops
switch (opcode) {
case POP_BLOCK:
case JUMP:
case JUMP_NO_INTERRUPT:
return 0;
/* Exception handling pseudo-instructions */
case SETUP_FINALLY:
/* 0 in the normal flow.
* Restore the stack position and push 1 value before jumping to
* the handler if an exception be raised. */
return jump ? 1 : 0;
case SETUP_CLEANUP:
/* As SETUP_FINALLY, but pushes lasti as well */
return jump ? 2 : 0;
case SETUP_WITH:
/* 0 in the normal flow.
* Restore the stack position to the position before the result
* of __(a)enter__ and push 2 values before jumping to the handler
* if an exception be raised. */
return jump ? 1 : 0;
case STORE_FAST_MAYBE_NULL:
return -1;
case LOAD_CLOSURE:
return 1;
default:
return PY_INVALID_STACK_EFFECT;
if ((opcode <= MAX_REAL_OPCODE) && (_PyOpcode_Deopt[opcode] != opcode)) {
// Specialized instructions are not supported.
return PY_INVALID_STACK_EFFECT;
}
return PY_INVALID_STACK_EFFECT; /* not reachable */
int popped = _PyOpcode_num_popped(opcode, oparg);
int pushed = _PyOpcode_num_pushed(opcode, oparg);
if (popped < 0 || pushed < 0) {
return PY_INVALID_STACK_EFFECT;
}
if (IS_BLOCK_PUSH_OPCODE(opcode) && !jump) {
return 0;
}
return pushed - popped;
}
int