summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--array.c17
2 files changed, 19 insertions, 2 deletions
diff --git a/ChangeLog b/ChangeLog
index 83de327daf..4dacc2a872 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+Fri May 8 10:07:02 2009 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * array.c (rb_ary_flatten_bang): clears temporary array.
+
Fri May 8 02:30:14 2009 Akinori MUSHA <knu@iDaemons.org>
* lib/set.rb (SortedSet#add): Do not require each newly added
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;
}