diff options
author | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-12 01:33:34 +0000 |
---|---|---|
committer | ko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2012-04-12 01:33:34 +0000 |
commit | ee7f8d4805fb4a661b8e8328be49f32cbc3e606d (patch) | |
tree | 82f7f28bb49cb5c3c571a649a9b32b61eb7ce988 /vm.c | |
parent | 655738577ffd90df3796c73afd8be84cd89091f6 (diff) |
* compile.c (compile_array, compile_array_):
Divide big array (or hash) literals into several blocks and
concatetene them. There was a problem that a big array (hash)
literal causes SystemStackError exception (stack overflow)
because VM push all contents of the literal onto VM stack to
make an array (or hash). To solve this issue, we make several
arrays (hashes) and concatenate them to make a big array (hash)
object.
??
* compile.c (iseq_compile_each, setup_args): use modified
compile_array.
* vm.c (m_core_hash_from_ary, m_core_hash_merge_ary,
m_core_hash_merge_ptr): added for above change.
* id.c (Init_id), parse.y: add core method ids.
* bootstraptest/test_literal.rb: add simple tests.
* bootstraptest/test_eval.rb: remove rescue clause to catch
SystemStackError exception.
* test/ruby/test_literal.rb: add tests to check no stack overflow.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@35306 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'vm.c')
-rw-r--r-- | vm.c | 41 |
1 files changed, 41 insertions, 0 deletions
@@ -2030,6 +2030,44 @@ m_core_set_postexe(VALUE self, VALUE iseqval) return Qnil; } +static VALUE +m_core_hash_from_ary(VALUE self, VALUE ary) +{ + VALUE hash = rb_hash_new(); + int i; + + for (i=0; i<RARRAY_LEN(ary); i+=2) { + rb_hash_aset(hash, RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]); + } + + return hash; +} + +static VALUE +m_core_hash_merge_ary(VALUE self, VALUE hash, VALUE ary) +{ + int i; + + for (i=0; i<RARRAY_LEN(ary); i+=2) { + rb_hash_aset(hash, RARRAY_PTR(ary)[i], RARRAY_PTR(ary)[i+1]); + } + + return hash; +} + +static VALUE +m_core_hash_merge_ptr(int argc, VALUE *argv, VALUE recv) +{ + int i; + VALUE hash = argv[0]; + + for (i=1; i<argc; i+=2) { + rb_hash_aset(hash, argv[i], argv[i+1]); + } + + return hash; +} + extern VALUE *rb_gc_stack_start; extern size_t rb_gc_stack_maxsize; #ifdef __ia64 @@ -2093,6 +2131,9 @@ Init_VM(void) rb_define_method_id(klass, id_core_define_method, m_core_define_method, 3); rb_define_method_id(klass, id_core_define_singleton_method, m_core_define_singleton_method, 3); rb_define_method_id(klass, id_core_set_postexe, m_core_set_postexe, 1); + rb_define_method_id(klass, id_core_hash_from_ary, m_core_hash_from_ary, 1); + rb_define_method_id(klass, id_core_hash_merge_ary, m_core_hash_merge_ary, 2); + rb_define_method_id(klass, id_core_hash_merge_ptr, m_core_hash_merge_ptr, -1); rb_obj_freeze(fcore); rb_gc_register_mark_object(fcore); rb_mRubyVMFrozenCore = fcore; |