diff options
author | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-19 16:10:54 +0000 |
---|---|---|
committer | nobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2007-12-19 16:10:54 +0000 |
commit | a927483326e54e6a4e9387009af0b57f38636497 (patch) | |
tree | eb38d3722b555b480f00303979429b20ef2f2a41 /compile.c | |
parent | 5e8e08d74e9ed8f6805e0f86c643900770b1564d (diff) |
* compile.c (iseq_compile_each): should handle upper level eval iseq
from break/next, and COMPILE_ERROR() breaks only one block.
[ruby-dev:31372]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@14339 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'compile.c')
-rw-r--r-- | compile.c | 13 |
1 files changed, 11 insertions, 2 deletions
@@ -2942,11 +2942,12 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) INT2FIX(level | 0x02) /* TAG_BREAK */ ); } else if (iseq->type == ISEQ_TYPE_EVAL) { + break_in_eval: COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with break")); } else { rb_iseq_t *ip = iseq->parent_iseq; - while (ip && ip->compile_data) { + while (ip) { level++; if (ip->compile_data->redo_label != 0) { level = 0x8000; @@ -2960,6 +2961,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) level <<= 16; goto break_by_insn; } + else if (ip->type == ISEQ_TYPE_EVAL) { + goto break_in_eval; + } ip = ip->parent_iseq; } COMPILE_ERROR((ERROR_ARGS "Illegal break")); @@ -2985,6 +2989,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) iseq->compile_data->end_label); } else if (iseq->type == ISEQ_TYPE_EVAL) { + next_in_eval: COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with next")); } else { @@ -3001,6 +3006,9 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) level |= 0x4000; break; } + else if (ip->type == ISEQ_TYPE_EVAL) { + goto next_in_eval; + } ip = ip->parent_iseq; } if (ip != 0) { @@ -3034,6 +3042,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) #endif } else if (iseq->type == ISEQ_TYPE_EVAL) { + redo_in_eval: COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo")); } else if (iseq->compile_data->start_label) { @@ -3059,7 +3068,7 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped) break; } else if (ip->type == ISEQ_TYPE_EVAL) { - COMPILE_ERROR((ERROR_ARGS "Can't escape from eval with redo")); + goto redo_in_eval; } ip = ip->parent_iseq; } |