Commit 431d1c8e authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #316 from masamitsu-murase/modify_obj_clone

Modify Kernel#clone and Kernel#dup
parents 97c9c859 062e9696
...@@ -61,6 +61,7 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; ...@@ -61,6 +61,7 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
khint_t kh_put_##name(kh_##name##_t *h, khkey_t key); \ khint_t kh_put_##name(kh_##name##_t *h, khkey_t key); \
void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \ void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
void kh_del_##name(kh_##name##_t *h, khint_t x); \ void kh_del_##name(kh_##name##_t *h, khint_t x); \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h);
/* define kh_xxx_funcs /* define kh_xxx_funcs
...@@ -179,6 +180,20 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; ...@@ -179,6 +180,20 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
{ \ { \
h->d_flags[x/8] |= __m[x%8]; \ h->d_flags[x/8] |= __m[x%8]; \
h->size--; \ h->size--; \
} \
kh_##name##_t *kh_copy_##name(mrb_state *mrb, kh_##name##_t *h) \
{ \
kh_##name##_t *h2; \
khiter_t k, k2; \
\
h2 = kh_init_##name(mrb); \
for (k = kh_begin(h); k != kh_end(h); k++) { \
if (kh_exist(h, k)) { \
k2 = kh_put_##name(h2, kh_key(h, k)); \
kh_value(h2, k2) = kh_value(h, k); \
} \
} \
return h2; \
} }
...@@ -191,6 +206,7 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; ...@@ -191,6 +206,7 @@ static const uint8_t __m[8] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
#define kh_put(name, h, k) kh_put_##name(h, k) #define kh_put(name, h, k) kh_put_##name(h, k)
#define kh_get(name, h, k) kh_get_##name(h, k) #define kh_get(name, h, k) kh_get_##name(h, k)
#define kh_del(name, h, k) kh_del_##name(h, k) #define kh_del(name, h, k) kh_del_##name(h, k)
#define kh_copy(name, mrb, h) kh_copy_##name(mrb, h)
#define kh_exist(h, x) (!__ac_iseither((h)->e_flags, (h)->d_flags, (x))) #define kh_exist(h, x) (!__ac_iseither((h)->e_flags, (h)->d_flags, (x)))
#define kh_key(h, x) ((h)->keys[x]) #define kh_key(h, x) ((h)->keys[x])
......
...@@ -338,7 +338,12 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj) ...@@ -338,7 +338,12 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
if (klass->iv) { if (klass->iv) {
clone->iv = klass->iv; clone->iv = klass->iv;
} }
clone->mt = kh_init(mt, mrb); if (klass->mt) {
clone->mt = kh_copy(mt, mrb, klass->mt);
}
else {
clone->mt = kh_init(mt, mrb);
}
clone->tt = MRB_TT_SCLASS; clone->tt = MRB_TT_SCLASS;
return clone; return clone;
} }
...@@ -361,10 +366,11 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj) ...@@ -361,10 +366,11 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
case MRB_TT_CLASS: case MRB_TT_CLASS:
case MRB_TT_MODULE: case MRB_TT_MODULE:
if (ROBJECT(dest)->iv) { if (ROBJECT(dest)->iv) {
kh_destroy(iv, ROBJECT(dest)->iv);
ROBJECT(dest)->iv = 0; ROBJECT(dest)->iv = 0;
} }
if (ROBJECT(obj)->iv) { if (ROBJECT(obj)->iv) {
ROBJECT(dest)->iv = ROBJECT(obj)->iv; ROBJECT(dest)->iv = kh_copy(iv, mrb, ROBJECT(obj)->iv);
} }
break; break;
...@@ -446,9 +452,8 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj) ...@@ -446,9 +452,8 @@ mrb_obj_dup(mrb_state *mrb, mrb_value obj)
mrb_raise(mrb, E_TYPE_ERROR, "can't dup %s", mrb_obj_classname(mrb, obj)); mrb_raise(mrb, E_TYPE_ERROR, "can't dup %s", mrb_obj_classname(mrb, obj));
} }
p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj)); p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
//init_copy(dup, obj);
dup = mrb_obj_value(p); dup = mrb_obj_value(p);
mrb_funcall(mrb, dup, "initialize_copy", 1, obj); init_copy(mrb, dup, obj);
return dup; return dup;
} }
......
...@@ -71,6 +71,62 @@ assert('Kernel.raise', '15.3.1.2.12') do ...@@ -71,6 +71,62 @@ assert('Kernel.raise', '15.3.1.2.12') do
e_list[0].class == RuntimeError e_list[0].class == RuntimeError
end end
assert('Kernel#clone', '15.3.1.3.8') do
class KernelCloneTest
def initialize
@v = 0
end
def get
@v
end
def set(v)
@v = v
end
end
a = KernelCloneTest.new
a.set(1)
b = a.clone
def a.test
end
a.set(2)
c = a.clone
a.get == 2 && b.get == 1 && c.get == 2 &&
a.respond_to?(:test) == true && b.respond_to?(:test) == false && c.respond_to?(:test) == true
end
assert('Kernel#dup', '15.3.1.3.9') do
class KernelDupTest
def initialize
@v = 0
end
def get
@v
end
def set(v)
@v = v
end
end
a = KernelDupTest.new
a.set(1)
b = a.dup
def a.test
end
a.set(2)
c = a.dup
a.get == 2 && b.get == 1 && c.get == 2 &&
a.respond_to?(:test) == true && b.respond_to?(:test) == false && c.respond_to?(:test) == false
end
assert('Kernel#hash', '15.3.1.2.15') do assert('Kernel#hash', '15.3.1.2.15') do
hash == hash hash == hash
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment