summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--internal.h1
-rw-r--r--object.c44
3 files changed, 31 insertions, 19 deletions
diff --git a/ChangeLog b/ChangeLog
index 070269a..356a074 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+Mon Jun 23 11:32:59 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
+
+ * object.c (rb_obj_copy_ivar): extract function to copy instance
+ variables only for T_OBJECT from init_copy.
+
Mon Jun 23 11:11:16 2014 Nobuyoshi Nakada <nobu@ruby-lang.org>
* signal.c (check_stack_overflow): drop the last tag too close to
diff --git a/internal.h b/internal.h
index fc0f0d5..04aa693 100644
--- a/internal.h
+++ b/internal.h
@@ -733,6 +733,7 @@ rb_float_new_inline(double d)
#define rb_float_new(d) rb_float_new_inline(d)
/* object.c */
+void rb_obj_copy_ivar(VALUE dest, VALUE obj);
VALUE rb_obj_equal(VALUE obj1, VALUE obj2);
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
diff --git a/object.c b/object.c
index 57cbe68..a154d02 100644
--- a/object.c
+++ b/object.c
@@ -255,6 +255,30 @@ rb_obj_singleton_class(VALUE obj)
return rb_singleton_class(obj);
}
+void
+rb_obj_copy_ivar(VALUE dest, VALUE obj)
+{
+ if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
+ xfree(ROBJECT_IVPTR(dest));
+ ROBJECT(dest)->as.heap.ivptr = 0;
+ ROBJECT(dest)->as.heap.numiv = 0;
+ ROBJECT(dest)->as.heap.iv_index_tbl = 0;
+ }
+ if (RBASIC(obj)->flags & ROBJECT_EMBED) {
+ MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
+ RBASIC(dest)->flags |= ROBJECT_EMBED;
+ }
+ else {
+ long len = ROBJECT(obj)->as.heap.numiv;
+ VALUE *ptr = ALLOC_N(VALUE, len);
+ MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
+ ROBJECT(dest)->as.heap.ivptr = ptr;
+ ROBJECT(dest)->as.heap.numiv = len;
+ ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
+ RBASIC(dest)->flags &= ~ROBJECT_EMBED;
+ }
+}
+
static void
init_copy(VALUE dest, VALUE obj)
{
@@ -266,25 +290,7 @@ init_copy(VALUE dest, VALUE obj)
rb_copy_generic_ivar(dest, obj);
rb_gc_copy_finalizer(dest, obj);
if (RB_TYPE_P(obj, T_OBJECT)) {
- if (!(RBASIC(dest)->flags & ROBJECT_EMBED) && ROBJECT_IVPTR(dest)) {
- xfree(ROBJECT_IVPTR(dest));
- ROBJECT(dest)->as.heap.ivptr = 0;
- ROBJECT(dest)->as.heap.numiv = 0;
- ROBJECT(dest)->as.heap.iv_index_tbl = 0;
- }
- if (RBASIC(obj)->flags & ROBJECT_EMBED) {
- MEMCPY(ROBJECT(dest)->as.ary, ROBJECT(obj)->as.ary, VALUE, ROBJECT_EMBED_LEN_MAX);
- RBASIC(dest)->flags |= ROBJECT_EMBED;
- }
- else {
- long len = ROBJECT(obj)->as.heap.numiv;
- VALUE *ptr = ALLOC_N(VALUE, len);
- MEMCPY(ptr, ROBJECT(obj)->as.heap.ivptr, VALUE, len);
- ROBJECT(dest)->as.heap.ivptr = ptr;
- ROBJECT(dest)->as.heap.numiv = len;
- ROBJECT(dest)->as.heap.iv_index_tbl = ROBJECT(obj)->as.heap.iv_index_tbl;
- RBASIC(dest)->flags &= ~ROBJECT_EMBED;
- }
+ rb_obj_copy_ivar(dest, obj);
}
}