(
blocks: list[BasicBlock],
default_error_handler: BasicBlock,
func_name: str | None,
strict_traceback_checks: bool,
)
| 64 | |
| 65 | |
| 66 | def split_blocks_at_errors( |
| 67 | blocks: list[BasicBlock], |
| 68 | default_error_handler: BasicBlock, |
| 69 | func_name: str | None, |
| 70 | strict_traceback_checks: bool, |
| 71 | ) -> list[BasicBlock]: |
| 72 | new_blocks: list[BasicBlock] = [] |
| 73 | |
| 74 | # First split blocks on ops that may raise. |
| 75 | for block in blocks: |
| 76 | ops = block.ops |
| 77 | block.ops = [] |
| 78 | cur_block = block |
| 79 | new_blocks.append(cur_block) |
| 80 | |
| 81 | # If the block has an error handler specified, use it. Otherwise |
| 82 | # fall back to the default. |
| 83 | error_label = block.error_handler or default_error_handler |
| 84 | block.error_handler = None |
| 85 | |
| 86 | for op in ops: |
| 87 | target: Value = op |
| 88 | cur_block.ops.append(op) |
| 89 | if isinstance(op, RegisterOp) and op.error_kind != ERR_NEVER: |
| 90 | # Split |
| 91 | new_block = BasicBlock() |
| 92 | new_blocks.append(new_block) |
| 93 | |
| 94 | if op.error_kind == ERR_MAGIC: |
| 95 | # Op returns an error value on error that depends on result RType. |
| 96 | variant = Branch.IS_ERROR |
| 97 | negated = False |
| 98 | elif op.error_kind == ERR_FALSE: |
| 99 | # Op returns a C false value on error. |
| 100 | variant = Branch.BOOL |
| 101 | negated = True |
| 102 | elif op.error_kind == ERR_ALWAYS: |
| 103 | variant = Branch.BOOL |
| 104 | negated = True |
| 105 | # this is a hack to represent the always fail |
| 106 | # semantics, using a temporary bool with value false |
| 107 | target = Integer(0, bool_rprimitive) |
| 108 | elif op.error_kind == ERR_MAGIC_OVERLAPPING: |
| 109 | comp = insert_overlapping_error_value_check(cur_block.ops, target) |
| 110 | new_block2 = BasicBlock() |
| 111 | new_blocks.append(new_block2) |
| 112 | branch = Branch( |
| 113 | comp, |
| 114 | true_label=new_block2, |
| 115 | false_label=new_block, |
| 116 | op=Branch.BOOL, |
| 117 | rare=True, |
| 118 | ) |
| 119 | cur_block.ops.append(branch) |
| 120 | cur_block = new_block2 |
| 121 | target = primitive_call(err_occurred_op, [], target.line) |
| 122 | cur_block.ops.append(target) |
| 123 | variant = Branch.IS_ERROR |
no test coverage detected
searching dependent graphs…