| ... | @@ -17952,19 +17952,40 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label | ... | @@ -17952,19 +17952,40 @@ fn ensurePostHoc(sema: *Sema, block: *Block, dest_block: Zir.Inst.Index) !*Label |
| 17952 | /// break from an inline loop. In such case we must convert it to | 17952 | /// break from an inline loop. In such case we must convert it to |
| 17953 | /// a runtime break. | 17953 | /// a runtime break. |
| 17954 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void { | 17954 | fn addRuntimeBreak(sema: *Sema, child_block: *Block, block_inst: Zir.Inst.Index, break_operand: Zir.Inst.Ref) !void { |
| | 17955 | const operand = sema.resolveInst(break_operand); |
| | 17956 | |
| | 17957 | var target_block: ?*Block = child_block; |
| | 17958 | while (target_block) |candidate| : (target_block = candidate.parent) { |
| | 17959 | const label = candidate.label orelse continue; |
| | 17960 | if (label.zir_block != block_inst) continue; |
| | 17961 | switch (sema.code.instructions.items(.tag)[@backingInt(label.zir_block)]) { |
| | 17962 | .block_inline, .block_comptime => continue, |
| | 17963 | else => {}, |
| | 17964 | } |
| | 17965 | return sema.addRuntimeBreakToBlock(child_block, candidate, label, operand); |
| | 17966 | } |
| | 17967 | |
| 17955 | const labeled_block = try sema.ensurePostHoc(child_block, block_inst); | 17968 | const labeled_block = try sema.ensurePostHoc(child_block, block_inst); |
| | 17969 | return sema.addRuntimeBreakToBlock(child_block, &labeled_block.block, &labeled_block.label, operand); |
| | 17970 | } |
| 17956 | | 17971 | |
| 17957 | const operand = sema.resolveInst(break_operand); | 17972 | fn addRuntimeBreakToBlock( |
| 17958 | const br_ref = try child_block.addBr(labeled_block.label.merges.block_inst, operand); | 17973 | sema: *Sema, |
| | 17974 | child_block: *Block, |
| | 17975 | target_block: *Block, |
| | 17976 | label: *Block.Label, |
| | 17977 | operand: Air.Inst.Ref, |
| | 17978 | ) !void { |
| | 17979 | const br_ref = try child_block.addBr(label.merges.block_inst, operand); |
| 17959 | | 17980 | |
| 17960 | try labeled_block.label.merges.results.append(sema.gpa, operand); | 17981 | try label.merges.results.append(sema.gpa, operand); |
| 17961 | try labeled_block.label.merges.br_list.append(sema.gpa, br_ref.toIndex().?); | 17982 | try label.merges.br_list.append(sema.gpa, br_ref.toIndex().?); |
| 17962 | try labeled_block.label.merges.src_locs.append(sema.gpa, null); | 17983 | try label.merges.src_locs.append(sema.gpa, null); |
| 17963 | | 17984 | |
| 17964 | labeled_block.block.runtime_index.increment(); | 17985 | target_block.runtime_index.increment(); |
| 17965 | if (labeled_block.block.runtime_cond == null and labeled_block.block.runtime_loop == null) { | 17986 | if (target_block.runtime_cond == null and target_block.runtime_loop == null) { |
| 17966 | labeled_block.block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop; | 17987 | target_block.runtime_cond = child_block.runtime_cond orelse child_block.runtime_loop; |
| 17967 | labeled_block.block.runtime_loop = child_block.runtime_loop; | 17988 | target_block.runtime_loop = child_block.runtime_loop; |
| 17968 | } | 17989 | } |
| 17969 | } | 17990 | } |
| 17970 | | 17991 | |