summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-05-08 01:07:03 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2009-05-08 01:07:03 +0000
commit0d9c4400fce3f52c305b299d405f09e6bfaa6069 (patch)
tree04154b33f2f53cd4addb54c100b8582326ffe44e /array.c
parentf6ac12f7beb853417ce991ba72116b9908d68e42 (diff)
* array.c (rb_ary_flatten_bang): clears temporary array.
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@23367 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'array.c')
-rw-r--r--array.c17
1 files changed, 15 insertions, 2 deletions
diff --git a/array.c b/array.c
index 034aa7fcf0..ece53ee68c 100644
--- a/array.c
+++ b/array.c
@@ -382,10 +382,18 @@ void
rb_ary_free(VALUE ary)
{
if (ARY_OWNS_HEAP_P(ary)) {
- xfree(RARRAY_PTR(ary));
+ xfree(ARY_HEAP_PTR(ary));
}
}
+static inline void
+ary_discard(VALUE ary)
+{
+ rb_ary_free(ary);
+ RBASIC(ary)->flags |= RARRAY_EMBED_FLAG;
+ RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK;
+}
+
static VALUE
ary_make_shared(VALUE ary)
{
@@ -3341,8 +3349,13 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary)
if (level == 0) return Qnil;
result = flatten(ary, level, &mod);
- if (mod == 0) return Qnil;
+ if (mod == 0) {
+ ary_discard(result);
+ return Qnil;
+ }
+ if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result);
rb_ary_replace(ary, result);
+ if (mod) ARY_SET_EMBED_LEN(result, 0);
return ary;
}