diff options
| -rw-r--r-- | include/mruby/khash.h | 16 | ||||
| -rw-r--r-- | src/class.c | 2 | ||||
| -rw-r--r-- | src/gc.c | 14 | ||||
| -rw-r--r-- | src/kernel.c | 13 | ||||
| -rw-r--r-- | src/struct.c | 4 | ||||
| -rw-r--r-- | test/t/kernel.rb | 83 | ||||
| -rw-r--r-- | test/t/struct.rb | 7 |
7 files changed, 117 insertions, 22 deletions
diff --git a/include/mruby/khash.h b/include/mruby/khash.h index e236f0bea..0803521b7 100644 --- a/include/mruby/khash.h +++ b/include/mruby/khash.h @@ -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]) diff --git a/src/class.c b/src/class.c index 881a0072e..16fb36617 100644 --- a/src/class.c +++ b/src/class.c @@ -37,7 +37,7 @@ mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) if (kh_exist(h, k)){ struct RProc *m = kh_value(h, k); if (m) { - paint_black(m); + mrb_gc_mark(mrb, (struct RBasic*)m); } } } @@ -345,8 +345,8 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) break; case MRB_TT_CLASS: - case MRB_TT_SCLASS: case MRB_TT_MODULE: + case MRB_TT_SCLASS: { struct RClass *c = (struct RClass*)obj; @@ -430,6 +430,18 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) break; #endif +#ifdef ENABLE_STRUCT + case MRB_TT_STRUCT: + { + struct RStruct *s = (struct RStruct*)obj; + long i; + for (i=0; i<s->len; i++){ + mrb_gc_mark_value(mrb, s->ptr[i]); + } + } + break; +#endif + default: break; } diff --git a/src/kernel.c b/src/kernel.c index 8da112ee5..5e17d4b5a 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -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; } diff --git a/src/struct.c b/src/struct.c index 855974182..25cd02d3d 100644 --- a/src/struct.c +++ b/src/struct.c @@ -286,8 +286,8 @@ make_struct(mrb_state *mrb, mrb_value name, mrb_value members, struct RClass * k nstr = mrb_obj_value(c); mrb_iv_set(mrb, nstr, mrb_intern(mrb, "__members__"), members); - mrb_define_class_method(mrb, c, "new", mrb_class_new_instance_m, ARGS_ANY()); - mrb_define_class_method(mrb, c, "[]", mrb_class_new_instance_m, ARGS_ANY()); + mrb_define_class_method(mrb, c, "new", mrb_instance_new, ARGS_ANY()); + mrb_define_class_method(mrb, c, "[]", mrb_instance_new, ARGS_ANY()); mrb_define_class_method(mrb, c, "members", mrb_struct_s_members_m, ARGS_NONE()); //RSTRUCT(nstr)->basic.c->super = c->c; ptr_members = RARRAY_PTR(members); diff --git a/test/t/kernel.rb b/test/t/kernel.rb index ba708dbb7..c1f42e420 100644 --- a/test/t/kernel.rb +++ b/test/t/kernel.rb @@ -71,11 +71,67 @@ assert('Kernel.raise', '15.3.1.2.12') do e_list[0].class == RuntimeError end -assert('Kernel#hash', '15.3.1.2.15') do +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.3.15') do hash == hash end -assert('Kernel#loop', '15.3.1.2.29') do +assert('Kernel#loop', '15.3.1.3.29') do i = 0 loop do @@ -86,32 +142,31 @@ assert('Kernel#loop', '15.3.1.2.29') do i == 100 end -assert('Kernel#methods', '15.3.1.2.31') do +assert('Kernel#methods', '15.3.1.3.31') do methods.class == Array end -assert('Kernel#nil?', '15.3.1.2.32') do - # TODO why is Kernel nil ???? - nil? == true +assert('Kernel#nil?', '15.3.1.3.32') do + nil.nil? == true end -assert('Kernel#private_methods', '15.3.1.2.36') do - private_methods.class == Array +assert('Kernel#private_methods', '15.3.1.3.36') do + private_methods.class == Array end -assert('Kernel#protected_methods', '15.3.1.2.37') do +assert('Kernel#protected_methods', '15.3.1.3.37') do protected_methods.class == Array end -assert('Kernel#public_methods', '15.3.1.2.38') do +assert('Kernel#public_methods', '15.3.1.3.38') do public_methods.class == Array end -assert('Kernel#respond_to?', '15.3.1.2.43') do +assert('Kernel#respond_to?', '15.3.1.3.43') do respond_to? :nil? end -assert('Kernel#send', '15.3.1.2.44') do +assert('Kernel#send', '15.3.1.3.44') do # test with block l = send(:lambda) do true @@ -123,11 +178,11 @@ assert('Kernel#send', '15.3.1.2.44') do send(:public_methods).class == Array end -assert('Kernel#singleton_methods', '15.3.1.2.45') do +assert('Kernel#singleton_methods', '15.3.1.3.45') do singleton_methods.class == Array end -assert('Kernel#to_s', '15.3.1.2.46') do +assert('Kernel#to_s', '15.3.1.3.46') do # TODO looks strange.. to_s == '' end diff --git a/test/t/struct.rb b/test/t/struct.rb index fff02ee56..5cf6929b8 100644 --- a/test/t/struct.rb +++ b/test/t/struct.rb @@ -16,6 +16,13 @@ if Object.const_defined?(:Struct) c.members == [:m1,:m2] end + assert('Struct#==', '15.2.18.4.1') do + c = Struct.new(:m1, :m2) + cc1 = c.new(1,2) + cc2 = c.new(1,2) + cc1 == cc2 + end + assert('Struct#[]', '15.2.18.4.2') do c = Struct.new(:m1, :m2) cc = c.new(1,2) |
