summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-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
5 files changed, 66 insertions, 28 deletions
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;