diff options
-rw-r--r-- | ChangeLog | 8 | ||||
-rw-r--r-- | bootstraptest/test_eval.rb | 11 | ||||
-rwxr-xr-x | tool/instruction.rb | 20 |
3 files changed, 35 insertions, 4 deletions
@@ -1,3 +1,11 @@ +Wed Sep 23 11:28:06 2009 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * tool/instruction.rb (make_header_prepare_stack): check stack + overflow. [ruby-core:25714] + + * tool/instruction.rb (make_footer_stack_val): ditto. + + Wed Sep 23 05:03:36 2009 Marc-Andre Lafortune <ruby-core@marc-andre.ca> * proc.c (umethod_bind, rb_mod_define_method): Fix bug that diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb index 452ce43107..f63d995ffb 100644 --- a/bootstraptest/test_eval.rb +++ b/bootstraptest/test_eval.rb @@ -308,3 +308,14 @@ assert_equal "[:x]", %q{ binding end }, '[ruby-core:25125]' + +assert_normal_exit %q{ + hash = {} + ("aaaa".."matz").each_with_index do |s, i| + hash[s] = i + end + begin + eval "class C; @@h = #{hash.inspect}; end" + rescue SystemStackError + end +}, '[ruby-core:25714]' diff --git a/tool/instruction.rb b/tool/instruction.rb index 45d57c1890..a82ac2ccc0 100755 --- a/tool/instruction.rb +++ b/tool/instruction.rb @@ -684,6 +684,9 @@ class RubyVM push_ba = insn.pushsc raise "unsupport" if push_ba[0].size > 0 && push_ba[1].size > 0 + n = 0 + push_ba.each {|pushs| n += pushs.length} + commit " CHECK_STACK_OVERFLOW(REG_CFP, #{n});" if n > 0 push_ba.each{|pushs| pushs.each{|r| commit " PUSH(SCREG(#{r}));" @@ -816,13 +819,22 @@ class RubyVM commit " #define LABEL_IS_SC(lab) LABEL_##lab##_###{insn.sc.size == 0 ? 't' : 'f'}" end + def each_footer_stack_val insn + insn.rets.reverse_each{|v| + break if v[1] == '...' + yield v + } + end + def make_footer_stack_val insn comment " /* push stack val */" - insn.rets.reverse_each{|v| - if v[1] == '...' - break - end + n = 0 + each_footer_stack_val(insn){|v| + n += 1 unless v[2] + } + commit " CHECK_STACK_OVERFLOW(REG_CFP, #{n});" if n > 0 + each_footer_stack_val(insn){|v| if v[2] commit " SCREG(#{v[2]}) = #{v[1]};" else |