summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--include/mruby/khash.h15
-rw-r--r--mrbgems/mruby-math/src/math.c2
-rw-r--r--src/class.c40
-rw-r--r--src/codegen.c4
-rw-r--r--src/kernel.c40
-rw-r--r--src/object.c8
-rw-r--r--src/vm.c2
-rw-r--r--test/t/class.rb5
-rw-r--r--test/t/nameerror.rb2
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");
}
diff --git a/src/vm.c b/src/vm.c
index a08565d55..155c31391 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -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