summaryrefslogtreecommitdiffstats
path: root/compile.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-20 05:44:47 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-04-20 05:44:47 +0000
commit855e5124fc24d62f3e47d133e3e8dc66f5789f8d (patch)
treeb9a391b9dd1a4ae7138c7f59e37c14a8710de538 /compile.c
parentb2e16548ef9253722272be11645b4a32a6d76032 (diff)
downloadruby-855e5124fc24d62f3e47d133e3e8dc66f5789f8d.tar.gz
ruby-855e5124fc24d62f3e47d133e3e8dc66f5789f8d.tar.xz
ruby-855e5124fc24d62f3e47d133e3e8dc66f5789f8d.zip
* compile.c (iseq_compile_each): fix for splat in when and rescue.
a patch from wanabe <s.wanabe AT gmail.com> in [ruby-dev:34429]. [ruby-core:14537] git-svn-id: http://svn.ruby-lang.org/repos/ruby/trunk@16093 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c65
1 files changed, 39 insertions, 26 deletions
diff --git a/compile.c b/compile.c
index 03e17ad05..002ea9f26 100644
--- a/compile.c
+++ b/compile.c
@@ -2779,26 +2779,19 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
vals = node->nd_head;
if (vals) {
- if (nd_type(vals) == NODE_ARRAY) {
+ switch (nd_type(vals)) {
+ case NODE_ARRAY:
special_literals = when_vals(iseq, cond_seq, vals, l1, special_literals);
- }
- else if (nd_type(vals) == NODE_SPLAT ||
- nd_type(vals) == NODE_ARGSCAT ||
- nd_type(vals) == NODE_ARGSPUSH) {
- NODE *val = vals->nd_head;
+ break;
+ case NODE_SPLAT:
+ case NODE_ARGSCAT:
+ case NODE_ARGSPUSH:
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);
- }
- else {
+ 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);
+ break;
+ default:
rb_bug("NODE_CASE: unknown node (%s)",
ruby_node_name(nd_type(vals)));
}
@@ -3248,15 +3241,35 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
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) {
+ switch (nd_type(narg)) {
+ case 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;
+ }
+ break;
+ case NODE_SPLAT:
+ case NODE_ARGSCAT:
+ case 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);
+ break;
+ default:
+ 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),