From: wanabe Date: 2008-04-16T20:47:24+09:00 Subject: [ruby-dev:34429] Re: patch for [ruby-core:14537] ワナベです。 08/04/10 に Nobuyoshi Nakada さんは書きました: > [ruby-core:14537]や rescue Interrupt, *x のような例ならそれでい > いんですが、 rescue *x, Interrupt ような例ではうまくいきません。 なるほど、NODE_ARGSPUSH が何なのかやっとわかりました。 同様の式を case〜when 文で試したところ上手くいかなかったので そちらも併せてパッチにしてみました。 Index: compile.c =================================================================== --- compile.c (revision 15984) +++ compile.c (working copy) @@ -2747,18 +2747,11 @@ else if (nd_type(vals) == NODE_SPLAT || nd_type(vals) == NODE_ARGSCAT || nd_type(vals) == NODE_ARGSPUSH) { - NODE *val = vals->nd_head; special_literals = 0; - if (nd_type(vals) == NODE_ARGSCAT || - nd_type(vals) == NODE_ARGSPUSH) { - when_vals(iseq, cond_seq, vals->nd_head, l1, 0); - val = vals->nd_body; - } - - COMPILE(cond_seq, "when/cond splat", val); - ADD_INSN1(cond_seq, nd_line(val), checkincludearray, Qtrue); - ADD_INSNL(cond_seq, nd_line(val), branchif, l1); + COMPILE(cond_seq, "when/cond splat", vals); + ADD_INSN1(cond_seq, nd_line(vals), checkincludearray, Qtrue); + ADD_INSNL(cond_seq, nd_line(vals), branchif, l1); } else { rb_bug("NODE_CASE: unknown node (%s)", @@ -3212,15 +3205,33 @@ label_hit = NEW_LABEL(nd_line(node)); narg = resq->nd_args; - while (narg) { - COMPILE(ret, "rescue arg", narg->nd_head); - ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), - INT2FIX(0)); - ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1)); - ADD_INSNL(ret, nd_line(node), branchif, label_hit); - narg = narg->nd_next; + if (narg) { + if (nd_type(narg) == NODE_ARRAY) { + while (narg) { + COMPILE(ret, "rescue arg", narg->nd_head); + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), + INT2FIX(0)); + ADD_SEND(ret, nd_line(node), ID2SYM(idEqq), INT2FIX(1)); + ADD_INSNL(ret, nd_line(node), branchif, label_hit); + narg = narg->nd_next; + } + } + else if (nd_type(narg) == NODE_SPLAT || + nd_type(narg) == NODE_ARGSCAT || + nd_type(narg) == NODE_ARGSPUSH) { + ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), + INT2FIX(0)); + COMPILE(ret, "rescue/cond splat", narg); + ADD_INSN1(ret, nd_line(node), checkincludearray, Qtrue); + ADD_INSN(ret, nd_line(node), swap); + ADD_INSN(ret, nd_line(node), pop); + ADD_INSNL(ret, nd_line(node), branchif, label_hit); + } else { + rb_bug("NODE_RESBODY: unknown node (%s)", + ruby_node_name(nd_type(narg))); + } } - if (resq->nd_args == 0) { + else { ADD_INSN1(ret, nd_line(node), putobject, rb_eStandardError); ADD_INSN2(ret, nd_line(node), getdynamic, INT2FIX(1), -- ワナベ