mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
Modify Kernel#clone and Kernel#dup.
Kernel#clone, Kernel#dup: - 'iv' should not be shared with the original object, but it should be copied. Kernel#clone: - 'mt' of singleton_class should be copied.
This commit is contained in:
@@ -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); \
|
||||
void kh_resize_##name(kh_##name##_t *h, khint_t new_n_buckets); \
|
||||
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
|
||||
|
||||
@@ -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->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};
|
||||
#define kh_put(name, h, k) kh_put_##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_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_key(h, x) ((h)->keys[x])
|
||||
|
||||
+9
-4
@@ -338,7 +338,12 @@ mrb_singleton_class_clone(mrb_state *mrb, mrb_value obj)
|
||||
if (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;
|
||||
return clone;
|
||||
}
|
||||
@@ -361,10 +366,11 @@ init_copy(mrb_state *mrb, mrb_value dest, mrb_value obj)
|
||||
case MRB_TT_CLASS:
|
||||
case MRB_TT_MODULE:
|
||||
if (ROBJECT(dest)->iv) {
|
||||
kh_destroy(iv, ROBJECT(dest)->iv);
|
||||
ROBJECT(dest)->iv = 0;
|
||||
}
|
||||
if (ROBJECT(obj)->iv) {
|
||||
ROBJECT(dest)->iv = ROBJECT(obj)->iv;
|
||||
ROBJECT(dest)->iv = kh_copy(iv, mrb, ROBJECT(obj)->iv);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
p = mrb_obj_alloc(mrb, mrb_type(obj), mrb_obj_class(mrb, obj));
|
||||
//init_copy(dup, obj);
|
||||
dup = mrb_obj_value(p);
|
||||
mrb_funcall(mrb, dup, "initialize_copy", 1, obj);
|
||||
init_copy(mrb, dup, obj);
|
||||
|
||||
return dup;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user