From: Yusuke ENDOH Date: 2007-12-30T03:40:16+09:00 Subject: [ruby-dev:32901] Re: then clause needs pop for stack consistency 遠藤です。 何度もすみません。 07/12/30 に Yusuke ENDOH さんは書きました: > NODE_CASE にも同様の問題がありますが、それぞれの body の最初に pop が > 挿入されるため、覗き穴最適化が働かず、発症する例は見つけられていません。 > でもすごくバグの元なので、以下のパッチでは NODE_CASE も対処してあります。 NODE_CASE の対応が間違っていました上に抜けがありました。すみません。 NODE_CASE の NODE_WHEN たちはそれぞれが pop するので、その最後には putnil を 足さないといけませんでした。 今のところ発症はしないので放っておくのも手かもしれません。 Index: compile.c =================================================================== --- compile.c (revision 14785) +++ compile.c (working copy) @@ -2634,6 +2634,7 @@ ADD_LABEL(ret, then_label); ADD_SEQ(ret, then_seq); ADD_INSNL(ret, nd_line(node), jump, end_label); + if (!poped) ADD_INSN(ret, nd_line(node), pop); ADD_LABEL(ret, else_label); ADD_SEQ(ret, else_seq); @@ -2680,6 +2681,7 @@ ADD_INSN(body_seq, nd_line(node), pop); COMPILE_(body_seq, "when body", node->nd_body, poped); ADD_INSNL(body_seq, nd_line(node), jump, endlabel); + if (poped) ADD_INSN(body_seq, nd_line(node), putnil); vals = node->nd_head; if (vals) { @@ -2723,6 +2725,7 @@ ADD_INSN(cond_seq, nd_line(node), pop); COMPILE_(cond_seq, "else", node, poped); ADD_INSNL(cond_seq, nd_line(node), jump, endlabel); + if (poped) ADD_INSN(cond_seq, nd_line(node), putnil); } else { debugs("== else (implicit)\n"); @@ -2732,6 +2735,7 @@ ADD_INSN(cond_seq, nd_line(tempnode), putnil); } ADD_INSNL(cond_seq, nd_line(tempnode), jump, endlabel); + if (poped) ADD_INSN(cond_seq, nd_line(tempnode), putnil); } if (special_literals) { @@ -2761,6 +2765,7 @@ ADD_LABEL(body_seq, l1); COMPILE_(body_seq, "when", node->nd_body, poped); ADD_INSNL(body_seq, nd_line(node), jump, endlabel); + if (!poped) ADD_INSN(body_seq, nd_line(node), pop); vals = node->nd_head; if (vals && nd_type(vals) == NODE_ARRAY) { @@ -2803,6 +2808,7 @@ /* else */ COMPILE_(ret, "else", node, poped); ADD_INSNL(ret, nd_line(orig_node), jump, endlabel); + if (!poped) ADD_INSN(ret, nd_line(orig_node), pop); ADD_SEQ(ret, body_seq); ADD_LABEL(ret, endlabel); -- Yusuke ENDOH