Closed jimy-byerley closed 3 years ago
Instr.stack_effect()
only look at the instruction impact on the stack and ignore the rest of the code. To compute the actual stacksize required by a bytecode object use Bytecode.compute_stacksize
.
This computation is carried on the control flow graph and is fairly involved which explains why your approach do not give the right value.
Feel free to reopen is an issue remains.
But compute_stacksize()
returns the complete stacksize needed to execute the code,
How can I get the current stacksize at each instruction ?
I guess to trunc the code until the desired instruction and the call compute_stacksize
would be very inefficient
Out of curiosity what is your use case for this ?
There is currently no way to achieve what you are trying to do out of the box. In particular I am not sure how you would deal with instructions that can lead to a jump, which value would you then report ?
I'm dealing with opcodes like MAP_ADD
MAP_ADD takes a stack position as argument to find the dict to add into. As I'm using it in a complex code sequence, I wanted to know the stack size at the location of this operation (my MAP is the bottom of the stack)
how you would deal with instructions that can lead to a jump, which value would you then report ?
I thought the problem couldn't happend: most of the time if the stack isn't empty when reaching the new block (jumping to it or not), then this stack values are important and have a role to play.
I admit Python specifications never said that it was always the case ...
The issue you are seeing is that FOR_ITER has a different stack effect when jumping and when not jumping. When not jumping (ie running the loop) it has a stack effect of 1 since it pushes the next value on the stack, when jumping however it removes the iterable from the stack and hence cancel the impact of GET_ITER. To accurately compute the state of the stack at any given instruction you need to be careful of that kind of effect. It may be possible to get it always right and that would be an interesting project (we could consider printing the state of the stack next to the instruction, which what I usually do in comment next to my bytecode manipulation). However I won't have time to look at it in the near future. If you want to experiment I will be happy to provide feedback and review a PR.
Hi there, In a program where I process a bytecode sequence, I'm using
Instr.stack_effect()
to determine the current stack size at a bytecode instruction. Ths is working well when I'm using simple statements and any kind of expressions, But it fails when I use loops. Here is a sample without loop:We can see that the stack is empty at start if the call to
boudou
If we uncomment the lines of the for loop, the stack size is bad after the loop, at the start of the call:
Can you fix that, or is there already a better way than
stack_effect
to do that ?