compile_break: do not goto into a branch

I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
This commit is contained in:
卜部昌平 2020-06-11 15:18:42 +09:00
parent 1f90690a1d
commit cc1e9b8e11
Notes: git 2020-06-29 11:07:11 +09:00

View File

@ -6579,22 +6579,8 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
ADD_INSN(ret, line, putnil);
}
}
else if (iseq->body->type == ISEQ_TYPE_BLOCK) {
break_by_insn:
/* escape from block */
CHECK(COMPILE(ret, "break val (block)", node->nd_stts));
ADD_INSN1(ret, line, throw, INT2FIX(throw_flag | TAG_BREAK));
if (popped) {
ADD_INSN(ret, line, pop);
}
}
else if (iseq->body->type == ISEQ_TYPE_EVAL) {
break_in_eval:
COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with break");
return COMPILE_NG;
}
else {
const rb_iseq_t *ip = iseq->body->parent_iseq;
const rb_iseq_t *ip = iseq;
while (ip) {
if (!ISEQ_COMPILE_DATA(ip)) {
@ -6604,16 +6590,26 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i
if (ISEQ_COMPILE_DATA(ip)->redo_label != 0) {
throw_flag = VM_THROW_NO_ESCAPE_FLAG;
goto break_by_insn;
}
else if (ip->body->type == ISEQ_TYPE_BLOCK) {
goto break_by_insn;
throw_flag = 0;
}
else if (ip->body->type == ISEQ_TYPE_EVAL) {
goto break_in_eval;
COMPILE_ERROR(ERROR_ARGS "Can't escape from eval with break");
return COMPILE_NG;
}
else {
ip = ip->body->parent_iseq;
continue;
}
ip = ip->body->parent_iseq;
/* escape from block */
CHECK(COMPILE(ret, "break val (block)", node->nd_stts));
ADD_INSN1(ret, line, throw, INT2FIX(throw_flag | TAG_BREAK));
if (popped) {
ADD_INSN(ret, line, pop);
}
return COMPILE_OK;
}
COMPILE_ERROR(ERROR_ARGS "Invalid break");
return COMPILE_NG;