diff options
| -rw-r--r-- | mrbgems/mruby-enumerator/mrblib/enumerator.rb | 14 | ||||
| -rw-r--r-- | mrbgems/mruby-enumerator/test/enumerator.rb | 3 | ||||
| -rw-r--r-- | src/array.c | 11 | ||||
| -rw-r--r-- | src/proc.c | 2 | ||||
| -rw-r--r-- | test/t/proc.rb | 16 |
5 files changed, 38 insertions, 8 deletions
diff --git a/mrbgems/mruby-enumerator/mrblib/enumerator.rb b/mrbgems/mruby-enumerator/mrblib/enumerator.rb index 1515a7a89..89b66cd45 100644 --- a/mrbgems/mruby-enumerator/mrblib/enumerator.rb +++ b/mrbgems/mruby-enumerator/mrblib/enumerator.rb @@ -153,12 +153,18 @@ class Enumerator # def with_index(offset=0) return to_enum :with_index, offset unless block_given? - raise TypeError, "no implicit conversion of #{offset.class} into Integer" unless offset.respond_to?(:to_int) + offset = if offset.nil? + 0 + elsif offset.respond_to?(:to_int) + offset.to_int + else + raise TypeError, "no implicit conversion of #{offset.class} into Integer" + end - n = offset.to_int - 1 - enumerator_block_call do |i| + n = offset - 1 + enumerator_block_call do |*i| n += 1 - yield [i,n] + yield i.__svalue, n end end diff --git a/mrbgems/mruby-enumerator/test/enumerator.rb b/mrbgems/mruby-enumerator/test/enumerator.rb index 2e45dae4b..e86e874f0 100644 --- a/mrbgems/mruby-enumerator/test/enumerator.rb +++ b/mrbgems/mruby-enumerator/test/enumerator.rb @@ -50,6 +50,9 @@ end assert 'Enumerator#with_index' do assert_equal([[1,0],[2,1],[3,2]], @obj.to_enum(:foo, 1, 2, 3).with_index.to_a) assert_equal([[1,5],[2,6],[3,7]], @obj.to_enum(:foo, 1, 2, 3).with_index(5).to_a) + a = [] + @obj.to_enum(:foo, 1, 2, 3).with_index(10).with_index(20) { |*i| a << i } + assert_equal [[[1, 10], 20], [[2, 11], 21], [[3, 12], 22]], a end assert 'Enumerator#with_index nonnum offset' do diff --git a/src/array.c b/src/array.c index 9013492fb..f6599bd5b 100644 --- a/src/array.c +++ b/src/array.c @@ -173,11 +173,13 @@ ary_expand_capa(mrb_state *mrb, struct RArray *a, mrb_int len) capa = ARY_DEFAULT_LEN; } while (capa < len) { - capa *= 2; + if (capa <= ARY_MAX_SIZE / 2) { + capa *= 2; + } else { + capa = ARY_MAX_SIZE; + } } - if (capa > ARY_MAX_SIZE) capa = ARY_MAX_SIZE; /* len <= capa <= ARY_MAX_SIZE */ - if (capa > a->aux.capa) { mrb_value *expanded_ptr = (mrb_value *)mrb_realloc(mrb, a->ptr, sizeof(mrb_value)*capa); @@ -503,6 +505,9 @@ mrb_ary_unshift_m(mrb_state *mrb, mrb_value self) mrb_int len; mrb_get_args(mrb, "*", &vals, &len); + if (len > ARY_MAX_SIZE - a->len) { + mrb_raise(mrb, E_ARGUMENT_ERROR, "array size too big"); + } if (ARY_SHARED_P(a) && a->aux.shared->refcnt == 1 /* shared only referenced from this array */ && a->ptr - a->aux.shared->ptr >= len) /* there's room for unshifted item */ { diff --git a/src/proc.c b/src/proc.c index 4f770932b..470547094 100644 --- a/src/proc.c +++ b/src/proc.c @@ -140,7 +140,7 @@ mrb_proc_copy(struct RProc *a, struct RProc *b) { a->flags = b->flags; a->body = b->body; - if (!MRB_PROC_CFUNC_P(a)) { + if (!MRB_PROC_CFUNC_P(a) && a->body.irep) { a->body.irep->refcnt++; } a->target_class = b->target_class; diff --git a/test/t/proc.rb b/test/t/proc.rb index bc9821f7c..29530e8dd 100644 --- a/test/t/proc.rb +++ b/test/t/proc.rb @@ -163,3 +163,19 @@ assert('&obj call to_proc if defined') do assert_raise(TypeError){ mock(&(Object.new)) } end + +assert('initialize_copy works when initialize is removed') do + begin + Proc.alias_method(:old_initialize, :initialize) + Proc.remove_method(:initialize) + + a = Proc.new {} + b = Proc.new {} + assert_nothing_raised do + a.initialize_copy(b) + end + ensure + Proc.alias_method(:initialize, :old_initialize) + Proc.remove_method(:old_initialize) + end +end |
