ref: db710d46c1f43cf7e23ea8ed278454b772a2cea3
dir: /maxstack.inc/
static uint32_t compute_maxstack(uint8_t *code, size_t len) { uint8_t *ip = code+4, *end = code+len; uint8_t op; uint32_t i, n, sp = 0, maxsp = 0; while (1) { if ((int32_t)sp > (int32_t)maxsp) maxsp = sp; if (ip >= end) break; op = *ip++; switch (op) { case OP_ARGC: n = *ip++; USED(n); break; case OP_VARGC: n = *ip++; sp += (n+2); break; case OP_LARGC: SWAP_INT32(ip); n = GET_INT32(ip); ip+=4; USED(n); break; case OP_LVARGC: SWAP_INT32(ip); n = GET_INT32(ip); ip+=4; sp += (n+2); break; case OP_OPTARGS: SWAP_INT32(ip); i = GET_INT32(ip); ip+=4; SWAP_INT32(ip); n = abs(GET_INT32(ip)); ip+=4; sp += (n-i); break; case OP_KEYARGS: SWAP_INT32(ip); i = GET_INT32(ip); ip+=4; SWAP_INT32(ip); n = GET_INT32(ip); ip+=4; USED(n); SWAP_INT32(ip); n = abs(GET_INT32(ip)); ip+=4; sp += (n-i); break; case OP_BRBOUND: SWAP_INT32(ip); ip+=4; sp++; break; case OP_TCALL: case OP_CALL: n = *ip++; // nargs sp -= n; break; case OP_TCALLL: case OP_CALLL: SWAP_INT32(ip); n = GET_INT32(ip); ip+=4; sp -= n; break; case OP_JMP: SWAP_INT16(ip); ip += 2; break; case OP_JMPL: SWAP_INT32(ip); ip += 4; break; case OP_BRF: case OP_BRT: SWAP_INT16(ip); ip+=2; sp--; break; case OP_BRFL: case OP_BRTL: SWAP_INT32(ip); ip += 4; sp--; break; case OP_BRNE: SWAP_INT16(ip); ip += 2; sp -= 2; break; case OP_BRNEL: SWAP_INT32(ip); ip += 4; sp -= 2; break; case OP_BRNN: case OP_BRN: SWAP_INT16(ip); ip += 2; sp--; break; case OP_BRNNL: case OP_BRNL: SWAP_INT32(ip); ip += 4; sp--; break; case OP_RET: sp--; break; case OP_CONS: case OP_SETCAR: case OP_SETCDR: case OP_POP: case OP_EQ: case OP_EQV: case OP_EQUAL: case OP_ADD2: case OP_SUB2: case OP_IDIV: case OP_NUMEQ: case OP_LT: case OP_COMPARE: case OP_AREF: case OP_TRYCATCH: sp--; break; case OP_PAIRP: case OP_ATOMP: case OP_NOT: case OP_NULLP: case OP_BOOLEANP: case OP_SYMBOLP: case OP_NUMBERP: case OP_FIXNUMP: case OP_BOUNDP: case OP_BUILTINP: case OP_FUNCTIONP: case OP_VECTORP: case OP_NOP: case OP_CAR: case OP_CDR: case OP_NEG: case OP_CLOSURE: break; case OP_TAPPLY: case OP_APPLY: n = *ip++; sp -= (n-1); break; case OP_LIST: case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_VECTOR: n = *ip++; sp -= (n-1); break; case OP_ASET: sp -= 2; break; case OP_FOR: if (sp+2 > maxsp) maxsp = sp+2; sp -=2; break; case OP_LOADT: case OP_LOADF: case OP_LOADNIL: case OP_LOAD0: case OP_LOAD1: case OP_LOADA0: case OP_LOADA1: case OP_LOADC00: case OP_LOADC01: case OP_DUP: sp++; break; case OP_LOADI8: case OP_LOADV: case OP_LOADG: case OP_LOADA: ip++; sp++; break; case OP_LOADVL: case OP_LOADGL: case OP_LOADAL: SWAP_INT32(ip); ip+=4; sp++; break; case OP_SETG: case OP_SETA: ip++; break; case OP_SETGL: case OP_SETAL: SWAP_INT32(ip); ip+=4; break; case OP_LOADC: ip+=2; sp++; break; case OP_SETC: ip+=2; break; case OP_LOADCL: SWAP_INT32(ip); ip+=4; SWAP_INT32(ip); ip+=4; sp++; break; case OP_SETCL: SWAP_INT32(ip); ip+=4; SWAP_INT32(ip); ip+=4; break; } } return maxsp+5; }