break and continue in loops
This commit is contained in:
+15
-6
@@ -652,12 +652,18 @@ emit_instruction_stream :: proc(
|
||||
sret_name := "",
|
||||
) -> ir.Instruction_Id {
|
||||
return_value := ir.INVALID_INSTRUCTION
|
||||
after_return := false
|
||||
// Set after any terminator (`ret`, `br`, conditional `br`). Code reachable
|
||||
// only by falling off a terminator is dead; it needs a fresh label to form a
|
||||
// well-formed basic block — unless the next instruction is already a `.Label`,
|
||||
// which opens its own block (the normal terminator-then-label sequence).
|
||||
after_terminator := false
|
||||
for instruction, instruction_index in instructions {
|
||||
instruction_id := ir.instruction_id(instruction_index)
|
||||
if after_return {
|
||||
fmt.sbprintf(&emitter.builder, "recover_after_return_%d:\n", instruction_index)
|
||||
after_return = false
|
||||
if after_terminator {
|
||||
if instruction.op != .Label {
|
||||
fmt.sbprintf(&emitter.builder, "recover_after_return_%d:\n", instruction_index)
|
||||
}
|
||||
after_terminator = false
|
||||
}
|
||||
switch instruction.op {
|
||||
case .Param, .Const:
|
||||
@@ -1662,14 +1668,17 @@ emit_instruction_stream :: proc(
|
||||
fmt.sbprintf(&emitter.builder, "bro_block_%d:\n", instruction.integer)
|
||||
case .Br:
|
||||
fmt.sbprintf(&emitter.builder, " br label %%bro_block_%d\n", instruction.integer)
|
||||
after_terminator = true
|
||||
case .Cond_Br:
|
||||
if !valid_value(instructions, instruction.a, types.BOOL, &emitter.module.types) {
|
||||
fmt.sbprintf(&emitter.builder, " br label %%bro_block_%d\n", u32(instruction.target))
|
||||
after_terminator = true
|
||||
continue
|
||||
}
|
||||
strings.write_string(&emitter.builder, " br i1 ")
|
||||
write_operand(&emitter.builder, instructions, instruction.a, types.BOOL, &emitter.module.types)
|
||||
fmt.sbprintf(&emitter.builder, ", label %%bro_block_%d, label %%bro_block_%d\n", instruction.integer, u32(instruction.target))
|
||||
after_terminator = true
|
||||
case .Trap:
|
||||
message := diagnostic_message(emitter, instruction.diagnostic, instruction.span, "invalid recovered source")
|
||||
emit_trap_call(emitter, message)
|
||||
@@ -1703,7 +1712,7 @@ emit_instruction_stream :: proc(
|
||||
write_operand(&emitter.builder, instructions, instruction.a, function.result, &emitter.module.types)
|
||||
strings.write_string(&emitter.builder, "\n")
|
||||
}
|
||||
after_return = true
|
||||
after_terminator = true
|
||||
case .Return_Void:
|
||||
if global_initializer {
|
||||
continue
|
||||
@@ -1713,7 +1722,7 @@ emit_instruction_stream :: proc(
|
||||
} else {
|
||||
strings.write_string(&emitter.builder, " ret void\n")
|
||||
}
|
||||
after_return = true
|
||||
after_terminator = true
|
||||
}
|
||||
}
|
||||
return return_value
|
||||
|
||||
Reference in New Issue
Block a user