def _compute_stacksize(self):
<EOL>code = self.code<EOL>label_pos = { op : pos<EOL>for pos, (op, arg) in enumerate(code)<EOL>if isinstance(op, Label)<EOL>}<EOL>sf_targets = set( label_pos[arg]<EOL>for op, arg in code<EOL>if op == SETUP_FINALLY or op == SETUP_WITH<EOL>)<EOL>stacks = [None] * len(code)<EOL>def get_next_stacks(pos, curstack):<EOL><INDENT>"""<STR_LIT>"""<EOL>op, arg = code[pos]<EOL>if isinstance(op, Label):<EOL><INDENT>if pos in sf_targets:<EOL><INDENT>curstack = curstack[:-<NUM_LIT:1>] + (curstack[-<NUM_LIT:1>] + <NUM_LIT:2>,)<EOL><DEDENT>if stacks[pos] is None:<EOL><INDENT>stacks[pos] = curstack<EOL><DEDENT>else:<EOL><INDENT>if stacks[pos] != curstack:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return<EOL><DEDENT><DEDENT>def newstack(n):<EOL><INDENT>if curstack[-<NUM_LIT:1>] + n < <NUM_LIT:0>:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>return curstack[:-<NUM_LIT:1>] + (curstack[-<NUM_LIT:1>]+n,)<EOL><DEDENT>if not isopcode(op):<EOL><INDENT>yield pos+<NUM_LIT:1>, curstack<EOL><DEDENT>elif op in ( RETURN_VALUE, RAISE_VARARGS ):<EOL><INDENT>pass<EOL><DEDENT>elif op in (JUMP_FORWARD, JUMP_ABSOLUTE):<EOL><INDENT>yield label_pos[arg], curstack<EOL><DEDENT>elif op in (POP_JUMP_IF_FALSE, POP_JUMP_IF_TRUE):<EOL><INDENT>yield label_pos[arg], newstack(-<NUM_LIT:1>)<EOL>yield pos+<NUM_LIT:1>, newstack(-<NUM_LIT:1>)<EOL><DEDENT>elif op in (JUMP_IF_TRUE_OR_POP, JUMP_IF_FALSE_OR_POP):<EOL><INDENT>yield label_pos[arg], curstack<EOL>yield pos+<NUM_LIT:1>, newstack(-<NUM_LIT:1>)<EOL><DEDENT>elif op == FOR_ITER:<EOL><INDENT>yield label_pos[arg], newstack(-<NUM_LIT:1>)<EOL>yield pos+<NUM_LIT:1>, newstack(<NUM_LIT:1>)<EOL><DEDENT>elif op == BREAK_LOOP:<EOL><INDENT>pass<EOL><DEDENT>elif op == CONTINUE_LOOP:<EOL><INDENT>pass<EOL><DEDENT>elif op == SETUP_LOOP:<EOL><INDENT>yield label_pos[arg], curstack<EOL>yield pos+<NUM_LIT:1>, curstack + (<NUM_LIT:0>,)<EOL><DEDENT>elif op == SETUP_EXCEPT:<EOL><INDENT>yield label_pos[arg], newstack(<NUM_LIT:3>)<EOL>yield pos+<NUM_LIT:1>, curstack + (<NUM_LIT:0>,)<EOL><DEDENT>elif op == SETUP_FINALLY or op == SETUP_WITH :<EOL><INDENT>yield label_pos[arg], newstack(<NUM_LIT:1>)<EOL>yield pos+<NUM_LIT:1>, curstack + ( int(op == SETUP_WITH) ,)<EOL><DEDENT>elif op == POP_BLOCK:<EOL><INDENT>yield pos+<NUM_LIT:1>, curstack[:-<NUM_LIT:1>]<EOL><DEDENT>elif op == END_FINALLY :<EOL><INDENT>yield pos+<NUM_LIT:1>, newstack(-<NUM_LIT:3>)<EOL><DEDENT>elif op == _WITH_CLEANUP_OPCODE:<EOL><INDENT>yield pos+<NUM_LIT:1>, newstack(-<NUM_LIT:1>)<EOL><DEDENT>else:<EOL><INDENT>yield pos+<NUM_LIT:1>, newstack( stack_effect( op, arg ) )<EOL><DEDENT><DEDENT>maxsize = <NUM_LIT:0><EOL>open_positions = [(<NUM_LIT:0>, (<NUM_LIT:0>,))]<EOL>while open_positions:<EOL><INDENT>pos, curstack = open_positions.pop()<EOL>maxsize = max(maxsize, sum(curstack))<EOL>open_positions.extend(get_next_stacks(pos, curstack))<EOL><DEDENT>return maxsize<EOL>
Given this object's code list, compute its maximal stack usage.
This is done by scanning the code, and computing for each opcode
the stack state at the opcode.