Find the last in the block from start to end. is any python bytecode instruction or a list of opcodes If is an opcode with a target (like a jump), a target destination can be specified which must match precisely if exact is True, or if
(
self, start: int, end: int, instr, target=None, exact=True
)
| 370 | return result_offset |
| 371 | |
| 372 | def last_instr( |
| 373 | self, start: int, end: int, instr, target=None, exact=True |
| 374 | ) -> Optional[int]: |
| 375 | """ |
| 376 | Find the last <instr> in the block from start to end. |
| 377 | <instr> is any python bytecode instruction or a list of opcodes |
| 378 | If <instr> is an opcode with a target (like a jump), a target |
| 379 | destination can be specified which must match precisely if exact |
| 380 | is True, or if exact is False, the instruction which has a target |
| 381 | closest to <target> will be returned. |
| 382 | |
| 383 | Return index to it or None if not found. |
| 384 | """ |
| 385 | |
| 386 | code = self.code |
| 387 | # Make sure requested positions do not go out of |
| 388 | # code bounds |
| 389 | if not (start >= 0 and end <= len(code)): |
| 390 | return None |
| 391 | |
| 392 | if not isinstance(instr, list): |
| 393 | instr = [instr] |
| 394 | |
| 395 | result_offset = None |
| 396 | current_distance = self.insts[-1].offset - self.insts[0].offset |
| 397 | extended_arg = 0 |
| 398 | # FIXME: use self.insts rather than code[] |
| 399 | for offset in self.op_range(start, end): |
| 400 | op = code[offset] |
| 401 | |
| 402 | if op == self.opc.EXTENDED_ARG: |
| 403 | arg = code2num(code, offset + 1) | extended_arg |
| 404 | extended_arg = extended_arg_val(self.opc, arg) |
| 405 | continue |
| 406 | |
| 407 | if op in instr: |
| 408 | if target is None: |
| 409 | result_offset = offset |
| 410 | else: |
| 411 | dest = self.get_target(offset, extended_arg) |
| 412 | if dest == target: |
| 413 | current_distance = 0 |
| 414 | result_offset = offset |
| 415 | elif not exact: |
| 416 | new_distance = abs(target - dest) |
| 417 | if new_distance <= current_distance: |
| 418 | current_distance = new_distance |
| 419 | result_offset = offset |
| 420 | pass |
| 421 | pass |
| 422 | pass |
| 423 | pass |
| 424 | extended_arg = 0 |
| 425 | pass |
| 426 | return result_offset |
| 427 | |
| 428 | def inst_matches(self, start, end, instr, target=None, include_beyond_target=False): |
| 429 | """ |
no test coverage detected