diff options
| -rw-r--r-- | include/mruby/khash.h | 15 | ||||
| -rw-r--r-- | mrbgems/mruby-math/src/math.c | 2 | ||||
| -rw-r--r-- | src/class.c | 40 | ||||
| -rw-r--r-- | src/codegen.c | 4 | ||||
| -rw-r--r-- | src/kernel.c | 40 | ||||
| -rw-r--r-- | src/object.c | 8 | ||||
| -rw-r--r-- | src/vm.c | 2 | ||||
| -rw-r--r-- | test/t/class.rb | 5 | ||||
| -rw-r--r-- | test/t/nameerror.rb | 2 |
9 files changed, 81 insertions, 37 deletions
diff --git a/include/mruby/khash.h b/include/mruby/khash.h index fb11586d2..cadb3d074 100644 --- a/include/mruby/khash.h +++ b/include/mruby/khash.h @@ -50,7 +50,7 @@ static const uint8_t __m_either[8] = {0x03, 0x0c, 0x30, 0xc0}; name: hash name khkey_t: key data type khval_t: value data type - kh_is_map: (not implemented / not used in RiteVM) + kh_is_map: (0: hash set / 1: hash map) */ #define KHASH_DECLARE(name, khkey_t, khval_t, kh_is_map) \ typedef struct kh_##name { \ @@ -89,7 +89,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) name: hash name khkey_t: key data type khval_t: value data type - kh_is_map: (not implemented / not used in RiteVM) + kh_is_map: (0: hash set / 1: hash map) __hash_func: hash function __hash_equal: hash comparation function */ @@ -97,12 +97,13 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) void kh_alloc_##name(kh_##name##_t *h) \ { \ khint_t sz = h->n_buckets; \ - uint8_t *p = mrb_malloc(h->mrb, sizeof(uint8_t)*sz/4+(sizeof(khkey_t)+sizeof(khval_t))*sz); \ + int len = sizeof(khkey_t) + (kh_is_map ? sizeof(khval_t) : 0); \ + uint8_t *p = mrb_malloc(h->mrb, sizeof(uint8_t)*sz/4+len*sz); \ h->size = h->n_occupied = 0; \ h->upper_bound = UPPER_BOUND(sz); \ h->keys = (khkey_t *)p; \ - h->vals = (khval_t *)(p+sizeof(khkey_t)*sz); \ - h->ed_flags = (p+sizeof(khkey_t)*sz+sizeof(khval_t)*sz); \ + h->vals = kh_is_map ? (khval_t *)(p+sizeof(khkey_t)*sz) : NULL; \ + h->ed_flags = p+len*sz; \ kh_fill_flags(h->ed_flags, 0xaa, sz/4); \ h->mask = sz-1; \ h->inc = sz/2-1; \ @@ -162,7 +163,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) for (i=0 ; i<old_n_buckets ; i++) { \ if (!__ac_iseither(old_ed_flags, i)) { \ khint_t k = kh_put_##name(h, old_keys[i]); \ - kh_value(h,k) = old_vals[i]; \ + if (kh_is_map) kh_value(h,k) = old_vals[i]; \ } \ } \ mrb_free(h->mrb, old_keys); \ @@ -207,7 +208,7 @@ kh_fill_flags(uint8_t *p, uint8_t c, size_t len) 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); \ + if(kh_is_map) kh_value(h2, k2) = kh_value(h, k); \ } \ } \ return h2; \ diff --git a/mrbgems/mruby-math/src/math.c b/mrbgems/mruby-math/src/math.c index 4960de6dd..3daece9bc 100644 --- a/mrbgems/mruby-math/src/math.c +++ b/mrbgems/mruby-math/src/math.c @@ -89,7 +89,7 @@ erfc(double x) #endif -#if (defined _MSC_VER && _MSC_VER < 1800) || defined __ANDROID__ +#if (defined _MSC_VER && _MSC_VER < 1800) || defined __ANDROID__ || (defined __FreeBSD__ && __FreeBSD_version < 803000) double log2(double x) diff --git a/src/class.c b/src/class.c index a7d77924f..60c9ced19 100644 --- a/src/class.c +++ b/src/class.c @@ -380,6 +380,7 @@ to_hash(mrb_state *mrb, mrb_value val) string mruby type C type note ---------------------------------------------------------------------------------------------- o: Object [mrb_value] + C: class/module [mrb_value] S: String [mrb_value] A: Array [mrb_value] H: Hash [mrb_value] @@ -434,6 +435,29 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) } } break; + case 'C': + { + mrb_value *p; + + p = va_arg(ap, mrb_value*); + if (i < argc) { + mrb_value ss; + + ss = *sp++; + switch (mrb_type(ss)) { + case MRB_TT_CLASS: + case MRB_TT_MODULE: + case MRB_TT_SCLASS: + break; + default: + mrb_raisef(mrb, E_TYPE_ERROR, "%S is not class/module", ss); + break; + } + *p = ss; + i++; + } + } + break; case 'S': { mrb_value *p; @@ -576,16 +600,8 @@ mrb_get_args(mrb_state *mrb, const char *format, ...) *p = (mrb_int)f; } break; - case MRB_TT_FALSE: - *p = 0; - break; default: - { - mrb_value tmp; - - tmp = mrb_convert_type(mrb, *sp, MRB_TT_FIXNUM, "Integer", "to_int"); - *p = mrb_fixnum(tmp); - } + *p = mrb_fixnum(mrb_Integer(mrb, *sp)); break; } sp++; @@ -740,7 +756,7 @@ mrb_mod_append_features(mrb_state *mrb, mrb_value mod) mrb_value klass; mrb_check_type(mrb, mod, MRB_TT_MODULE); - mrb_get_args(mrb, "o", &klass); + mrb_get_args(mrb, "C", &klass); mrb_include_module(mrb, mrb_class_ptr(klass), mrb_class_ptr(mod)); return mod; } @@ -788,7 +804,7 @@ mrb_mod_include_p(mrb_state *mrb, mrb_value mod) mrb_value mod2; struct RClass *c = mrb_class_ptr(mod); - mrb_get_args(mrb, "o", &mod2); + mrb_get_args(mrb, "C", &mod2); mrb_check_type(mrb, mod2, MRB_TT_MODULE); while (c) { @@ -1067,7 +1083,7 @@ mrb_class_new_class(mrb_state *mrb, mrb_value cv) mrb_value super; struct RClass *new_class; - if (mrb_get_args(mrb, "|o", &super) == 0) { + if (mrb_get_args(mrb, "|C", &super) == 0) { super = mrb_obj_value(mrb->object_class); } new_class = mrb_class_new(mrb, mrb_class_ptr(super)); diff --git a/src/codegen.c b/src/codegen.c index bb479842c..578fb96ac 100644 --- a/src/codegen.c +++ b/src/codegen.c @@ -646,7 +646,9 @@ scope_body(codegen_scope *s, node *tree) genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); } else { - genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL), NOVAL); + pop(); + genop_peep(scope, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); + push(); } } scope_finish(scope); diff --git a/src/kernel.c b/src/kernel.c index bd58078fe..f07fbbab1 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -542,7 +542,7 @@ obj_is_instance_of(mrb_state *mrb, mrb_value self) mrb_value arg; mrb_bool instance_of_p; - mrb_get_args(mrb, "o", &arg); + mrb_get_args(mrb, "C", &arg); instance_of_p = mrb_obj_is_instance_of(mrb, self, mrb_class_ptr(arg)); return mrb_bool_value(instance_of_p); @@ -715,14 +715,17 @@ mrb_obj_is_kind_of_m(mrb_state *mrb, mrb_value self) mrb_value arg; mrb_bool kind_of_p; - mrb_get_args(mrb, "o", &arg); + mrb_get_args(mrb, "C", &arg); kind_of_p = mrb_obj_is_kind_of(mrb, self, mrb_class_ptr(arg)); return mrb_bool_value(kind_of_p); } +KHASH_DECLARE(st, mrb_sym, char, 0) +KHASH_DEFINE(st, mrb_sym, char, 0, kh_int_hash_func, kh_int_hash_equal) + static void -method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary) +method_entry_loop(mrb_state *mrb, struct RClass* klass, khash_t(st)* set) { khint_t i; @@ -730,7 +733,7 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary) if (!h) return; for (i=0;i<kh_end(h);i++) { if (kh_exist(h, i)) { - mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(h,i))); + kh_put(st, set, kh_key(h,i)); } } } @@ -738,13 +741,14 @@ method_entry_loop(mrb_state *mrb, struct RClass* klass, mrb_value ary) mrb_value class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, int obj) { + khint_t i; mrb_value ary; struct RClass* oldklass; + khash_t(st)* set = kh_init(st, mrb); - ary = mrb_ary_new(mrb); oldklass = 0; while (klass && (klass != oldklass)) { - method_entry_loop(mrb, klass, ary); + method_entry_loop(mrb, klass, set); if ((klass->tt == MRB_TT_ICLASS) || (klass->tt == MRB_TT_SCLASS)) { } @@ -755,28 +759,46 @@ class_instance_method_list(mrb_state *mrb, mrb_bool recur, struct RClass* klass, klass = klass->super; } + ary = mrb_ary_new(mrb); + for (i=0;i<kh_end(set);i++) { + if (kh_exist(set, i)) { + mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set,i))); + } + } + kh_destroy(st, set); + return ary; } mrb_value mrb_obj_singleton_methods(mrb_state *mrb, mrb_bool recur, mrb_value obj) { + khint_t i; mrb_value ary; struct RClass* klass; + khash_t(st)* set = kh_init(st, mrb); klass = mrb_class(mrb, obj); - ary = mrb_ary_new(mrb); + if (klass && (klass->tt == MRB_TT_SCLASS)) { - method_entry_loop(mrb, klass, ary); + method_entry_loop(mrb, klass, set); klass = klass->super; } if (recur) { while (klass && ((klass->tt == MRB_TT_SCLASS) || (klass->tt == MRB_TT_ICLASS))) { - method_entry_loop(mrb, klass, ary); + method_entry_loop(mrb, klass, set); klass = klass->super; } } + ary = mrb_ary_new(mrb); + for (i=0;i<kh_end(set);i++) { + if (kh_exist(set, i)) { + mrb_ary_push(mrb, ary, mrb_symbol_value(kh_key(set,i))); + } + } + kh_destroy(st, set); + return ary; } diff --git a/src/object.c b/src/object.c index 1040a08ed..56d5e65cd 100644 --- a/src/object.c +++ b/src/object.c @@ -532,16 +532,14 @@ mrb_convert_to_integer(mrb_state *mrb, mrb_value val, int base) if (base != 0) goto arg_error; return val; - case MRB_TT_STRING: -string_conv: - return mrb_str_to_inum(mrb, val, base, TRUE); - default: break; } if (base != 0) { tmp = mrb_check_string_type(mrb, val); - if (!mrb_nil_p(tmp)) goto string_conv; + if (!mrb_nil_p(tmp)) { + return mrb_str_to_inum(mrb, val, base, TRUE); + } arg_error: mrb_raise(mrb, E_ARGUMENT_ERROR, "base specified for non string value"); } @@ -595,7 +595,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self) if (!mrb->c->stack) { stack_init(mrb); } - stack_extend(mrb, irep->nregs, irep->nregs); + stack_extend(mrb, irep->nregs, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */ mrb->c->ci->err = pc; mrb->c->ci->proc = proc; mrb->c->ci->nregs = irep->nregs + 1; diff --git a/test/t/class.rb b/test/t/class.rb index 3dea2152f..403a95f10 100644 --- a/test/t/class.rb +++ b/test/t/class.rb @@ -222,6 +222,11 @@ assert('Class new') do assert_equal(Class, Class.new.class) end +assert('class to return the last value') do + m = class C; :m end + assert_equal(m, :m) +end + assert('Class#inherited') do class Foo @@subclass_name = nil diff --git a/test/t/nameerror.rb b/test/t/nameerror.rb index 644c6a3cb..3e3c59264 100644 --- a/test/t/nameerror.rb +++ b/test/t/nameerror.rb @@ -20,7 +20,7 @@ assert('NameError#name', '15.2.31.2.1') do $test_dummy_result = e.name end - assert_equal $test_dummy_result, :bar + assert_equal :bar, $test_dummy_result end assert('NameError#initialize', '15.2.31.2.2') do |
