diff options
-rw-r--r-- | ChangeLog | 26 | ||||
-rw-r--r-- | array.c | 8 | ||||
-rw-r--r-- | class.c | 52 | ||||
-rw-r--r-- | eval.c | 8 | ||||
-rw-r--r-- | node.h | 1 | ||||
-rw-r--r-- | parse.y | 3 | ||||
-rw-r--r-- | test/ruby/test_array.rb | 14 | ||||
-rw-r--r-- | version.h | 6 |
8 files changed, 73 insertions, 45 deletions
@@ -1,3 +1,29 @@ +Fri May 23 01:03:23 2008 Akinori MUSHA <knu@iDaemons.org> + + * class.c (rb_singleton_class_clone): Pass Qnil, not 0. + +Fri May 23 00:51:48 2008 Akinori MUSHA <knu@iDaemons.org> + + * class.c (clone_method): Totally revamp the previous fix which + was incorrect. + (rb_mod_init_copy): Ditto. + (singleton_class_clone_int): Ditto. + +Fri May 23 00:48:10 2008 Akinori MUSHA <knu@iDaemons.org> + + * eval.c (rb_copy_node_scope), node.h: Rename from copy_node_scope + and export. + +Thu May 22 21:24:15 2008 Yukihiro Matsumoto <matz@ruby-lang.org> + + * parse.y (top_local_setup): fixed memory leak bug based on a + patch from Roger Pack <rogerpack2005 at gmail.com> in + [ruby-core:16610]. + +Thu May 22 14:20:54 2008 Nobuyoshi Nakada <nobu@ruby-lang.org> + + * array.c (flatten): check if reentered. [ruby-dev:34798] + Thu May 22 08:28:49 2008 Yukihiro Matsumoto <matz@ruby-lang.org> * array.c (flatten): free memo hash table before raising exception. @@ -3107,8 +3107,8 @@ flatten(ary, level, modified) st_table *memo; st_data_t id; - stack = rb_ary_new(); - result = ary_new(rb_class_of(ary), RARRAY_LEN(ary)); + stack = ary_new(0, ARY_DEFAULT_SIZE); + result = ary_new(0, RARRAY_LEN(ary)); memo = st_init_numtable(); st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue); *modified = 0; @@ -3117,6 +3117,9 @@ flatten(ary, level, modified) while (i < RARRAY(ary)->len) { elt = RARRAY(ary)->ptr[i++]; tmp = rb_check_array_type(elt); + if (RBASIC(result)->klass) { + rb_raise(rb_eRuntimeError, "flatten reentered"); + } if (NIL_P(tmp) || (level >= 0 && RARRAY(stack)->len / 2 >= level)) { rb_ary_push(result, elt); } @@ -3146,6 +3149,7 @@ flatten(ary, level, modified) st_free_table(memo); + RBASIC(result)->klass = rb_class_of(ary); return result; } @@ -48,42 +48,33 @@ rb_class_new(super) return rb_class_boot(super); } -struct clone_method_data { - st_table *tbl; - VALUE klass; - VALUE cref; -}; - static int -clone_method(mid, body, data) +clone_method(mid, body, nklass) ID mid; NODE *body; - struct clone_method_data *data; + VALUE nklass; { NODE *fbody = body->nd_body; - if (fbody && data->cref) { - VALUE body; + if (fbody) { + NODE *cref = NEW_NODE(NODE_CREF, nklass, 0, 0); + VALUE nbody; switch (nd_type(fbody)) { case NODE_SCOPE: - if (fbody->nd_rval) { - NODE *tmp = NEW_NODE(nd_type(fbody->u2.node), data->cref, - fbody->u2.node->u2.node, fbody->u2.node->u3.node); - fbody = NEW_NODE(nd_type(fbody), fbody->u1.node, tmp, fbody->u3.node); - } - break; + fbody = rb_copy_node_scope(fbody, cref); + break; case NODE_BMETHOD: - body = rb_block_dup(fbody->nd_cval, data->klass, data->cref); - fbody = NEW_BMETHOD(body); + nbody = rb_block_dup(fbody->nd_cval, nklass, (VALUE)cref); + fbody = NEW_BMETHOD(nbody); break; case NODE_DMETHOD: - body = rb_method_dup(fbody->nd_cval, data->klass, data->cref); - fbody = NEW_DMETHOD(body); + nbody = rb_method_dup(fbody->nd_cval, nklass, (VALUE)cref); + fbody = NEW_DMETHOD(nbody); break; } } - st_insert(data->tbl, mid, (st_data_t)NEW_METHOD(fbody, body->nd_noex)); + st_insert(RCLASS(nklass)->m_tbl, mid, (st_data_t)NEW_METHOD(fbody, body->nd_noex)); return ST_CONTINUE; } @@ -109,13 +100,8 @@ rb_mod_init_copy(clone, orig) st_delete(RCLASS(clone)->iv_tbl, (st_data_t*)&id, 0); } if (RCLASS(orig)->m_tbl) { - struct clone_method_data data; - RCLASS(clone)->m_tbl = st_init_numtable(); - data.tbl = RCLASS(clone)->m_tbl; - data.klass = clone; - data.cref = clone; - st_foreach(RCLASS(orig)->m_tbl, clone_method, (st_data_t)&data); + st_foreach(RCLASS(orig)->m_tbl, clone_method, clone); } return clone; @@ -136,15 +122,14 @@ rb_class_init_copy(clone, orig) } static VALUE -singleton_class_clone_int(obj, cref) - VALUE obj, cref; +singleton_class_clone_int(obj, nklass) + VALUE obj, nklass; { VALUE klass = RBASIC(obj)->klass; if (!FL_TEST(klass, FL_SINGLETON)) return klass; else { - struct clone_method_data data; /* copy singleton(unnamed) class */ NEWOBJ(clone, struct RClass); OBJSETUP(clone, 0, RBASIC(klass)->flags); @@ -163,10 +148,7 @@ singleton_class_clone_int(obj, cref) clone->iv_tbl = st_copy(RCLASS(klass)->iv_tbl); } clone->m_tbl = st_init_numtable(); - data.tbl = clone->m_tbl; - data.klass = (VALUE)clone; - data.cref = cref; - st_foreach(RCLASS(klass)->m_tbl, clone_method, (st_data_t)&data); + st_foreach(RCLASS(klass)->m_tbl, clone_method, NIL_P(nklass) ? (VALUE)clone : nklass); rb_singleton_class_attached(RBASIC(clone)->klass, (VALUE)clone); FL_SET(clone, FL_SINGLETON); return (VALUE)clone; @@ -177,7 +159,7 @@ VALUE rb_singleton_class_clone(obj) VALUE obj; { - return singleton_class_clone_int(obj, 0); + return singleton_class_clone_int(obj, Qnil); } void @@ -2242,8 +2242,8 @@ rb_mod_alias_method(mod, newname, oldname) return mod; } -static NODE* -copy_node_scope(node, rval) +NODE * +rb_copy_node_scope(node, rval) NODE *node; NODE *rval; { @@ -3955,7 +3955,7 @@ rb_eval(self, n) noex |= NOEX_NOSUPER; } - defn = copy_node_scope(node->nd_defn, ruby_cref); + defn = rb_copy_node_scope(node->nd_defn, ruby_cref); rb_add_method(ruby_class, node->nd_mid, defn, noex); if (scope_vmode == SCOPE_MODFUNC) { rb_add_method(rb_singleton_class(ruby_class), @@ -3992,7 +3992,7 @@ rb_eval(self, n) rb_warning("redefine %s", rb_id2name(node->nd_mid)); } } - defn = copy_node_scope(node->nd_defn, ruby_cref); + defn = rb_copy_node_scope(node->nd_defn, ruby_cref); rb_add_method(klass, node->nd_mid, defn, NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0)); result = Qnil; @@ -371,6 +371,7 @@ typedef unsigned int rb_event_t; #define RUBY_EVENT_ALL 0xff typedef void (*rb_event_hook_func_t) _((rb_event_t,NODE*,VALUE,ID,VALUE)); +NODE *rb_copy_node_scope _((NODE *, NODE *)); void rb_add_event_hook _((rb_event_hook_func_t,rb_event_t)); int rb_remove_event_hook _((rb_event_hook_func_t)); @@ -5736,7 +5736,7 @@ top_local_setup() rb_mem_clear(vars+i, len-i); } else { - *vars++ = (VALUE)ruby_scope; + *vars++ = 0; rb_mem_clear(vars, len); } ruby_scope->local_vars = vars; @@ -5752,6 +5752,7 @@ top_local_setup() if (!(ruby_scope->flags & SCOPE_CLONE)) xfree(ruby_scope->local_tbl); } + ruby_scope->local_vars[-1] = 0; /* no reference needed */ ruby_scope->local_tbl = local_tbl(); } } diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 6a816a2c85..58ffe52675 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -717,6 +717,20 @@ class TestArray < Test::Unit::TestCase @cls[@cls[@cls[@cls[],@cls[]],@cls[@cls[]],@cls[]],@cls[@cls[@cls[]]]].flatten) end + def test_flatten_with_callcc + respond_to?(:callcc, true) or require 'continuation' + o = Object.new + def o.to_ary() callcc {|k| @cont = k; [1,2,3]} end + begin + assert_equal([10, 20, 1, 2, 3, 30, 1, 2, 3, 40], [10, 20, o, 30, o, 40].flatten) + rescue => e + else + o.instance_eval {@cont}.call + end + assert_instance_of(RuntimeError, e, '[ruby-dev:34798]') + assert_match(/reentered/, e.message, '[ruby-dev:34798]') + end + def test_hash a1 = @cls[ 'cat', 'dog' ] a2 = @cls[ 'cat', 'dog' ] @@ -1,7 +1,7 @@ #define RUBY_VERSION "1.8.7" -#define RUBY_RELEASE_DATE "2008-05-22" +#define RUBY_RELEASE_DATE "2008-05-23" #define RUBY_VERSION_CODE 187 -#define RUBY_RELEASE_CODE 20080522 +#define RUBY_RELEASE_CODE 20080523 #define RUBY_PATCHLEVEL 0 #define RUBY_VERSION_MAJOR 1 @@ -9,7 +9,7 @@ #define RUBY_VERSION_TEENY 7 #define RUBY_RELEASE_YEAR 2008 #define RUBY_RELEASE_MONTH 5 -#define RUBY_RELEASE_DAY 22 +#define RUBY_RELEASE_DAY 23 #ifdef RUBY_EXTERN RUBY_EXTERN const char ruby_version[]; |