summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog8
-rw-r--r--bootstraptest/test_eval.rb11
-rwxr-xr-xtool/instruction.rb20
3 files changed, 35 insertions, 4 deletions
diff --git a/ChangeLog b/ChangeLog
index f0b7cdf089..abf2edafa1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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