| 315 | |
| 316 | |
| 317 | static Instruction symbexec (const Proto *pt, int lastpc, int reg) { |
| 318 | int pc; |
| 319 | int last; /* stores position of last instruction that changed `reg' */ |
| 320 | last = pt->sizecode-1; /* points to final return (a `neutral' instruction) */ |
| 321 | check(precheck(pt)); |
| 322 | for (pc = 0; pc < lastpc; pc++) { |
| 323 | Instruction i = pt->code[pc]; |
| 324 | OpCode op = GET_OPCODE(i); |
| 325 | int a = GETARG_A(i); |
| 326 | int b = 0; |
| 327 | int c = 0; |
| 328 | check(op < NUM_OPCODES); |
| 329 | checkreg(pt, a); |
| 330 | switch (getOpMode(op)) { |
| 331 | case iABC: { |
| 332 | b = GETARG_B(i); |
| 333 | c = GETARG_C(i); |
| 334 | check(checkArgMode(pt, b, getBMode(op))); |
| 335 | check(checkArgMode(pt, c, getCMode(op))); |
| 336 | break; |
| 337 | } |
| 338 | case iABx: { |
| 339 | b = GETARG_Bx(i); |
| 340 | if (getBMode(op) == OpArgK) check(b < pt->sizek); |
| 341 | break; |
| 342 | } |
| 343 | case iAsBx: { |
| 344 | b = GETARG_sBx(i); |
| 345 | if (getBMode(op) == OpArgR) { |
| 346 | int dest = pc+1+b; |
| 347 | check(0 <= dest && dest < pt->sizecode); |
| 348 | if (dest > 0) { |
| 349 | int j; |
| 350 | /* check that it does not jump to a setlist count; this |
| 351 | is tricky, because the count from a previous setlist may |
| 352 | have the same value of an invalid setlist; so, we must |
| 353 | go all the way back to the first of them (if any) */ |
| 354 | for (j = 0; j < dest; j++) { |
| 355 | Instruction d = pt->code[dest-1-j]; |
| 356 | if (!(GET_OPCODE(d) == OP_SETLIST && GETARG_C(d) == 0)) break; |
| 357 | } |
| 358 | /* if 'j' is even, previous value is not a setlist (even if |
| 359 | it looks like one) */ |
| 360 | check((j&1) == 0); |
| 361 | } |
| 362 | } |
| 363 | break; |
| 364 | } |
| 365 | } |
| 366 | if (testAMode(op)) { |
| 367 | if (a == reg) last = pc; /* change register `a' */ |
| 368 | } |
| 369 | if (testTMode(op)) { |
| 370 | check(pc+2 < pt->sizecode); /* check skip */ |
| 371 | check(GET_OPCODE(pt->code[pc+1]) == OP_JMP); |
| 372 | } |
| 373 | switch (op) { |
| 374 | case OP_LOADBOOL: { |
no test coverage detected