summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class.c36
-rw-r--r--src/error.c17
-rw-r--r--src/kernel.c2
-rw-r--r--src/re.c2
-rw-r--r--src/variable.c4
-rw-r--r--src/vm.c10
6 files changed, 44 insertions, 27 deletions
diff --git a/src/class.c b/src/class.c
index 6efc9f5e7..50d0b6317 100644
--- a/src/class.c
+++ b/src/class.c
@@ -723,8 +723,8 @@ mrb_mod_include(mrb_state *mrb, mrb_value klass)
mrb_check_type(mrb, argv[i], MRB_TT_MODULE);
}
while (argc--) {
- mrb_funcall_argv(mrb, argv[argc], "append_features", 1, &klass);
- mrb_funcall_argv(mrb, argv[argc], "included", 1, &klass);
+ mrb_funcall(mrb, argv[argc], "append_features", 1, klass);
+ mrb_funcall(mrb, argv[argc], "included", 1, klass);
}
return klass;
@@ -877,29 +877,41 @@ mrb_method_search(mrb_state *mrb, struct RClass* c, mrb_sym mid)
mrb_value
mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, int argc, ...)
{
- mrb_value args[MRB_FUNCALL_ARGC_MAX];
+ mrb_sym mid = mrb_intern(mrb, name);
va_list ap;
int i;
- if (argc != 0) {
+ if (argc == 0) {
+ return mrb_funcall_argv(mrb, self, mid, 0, 0);
+ }
+ else if (argc == 1) {
+ mrb_value v;
+
+ va_start(ap, argc);
+ v = va_arg(ap, mrb_value);
+ va_end(ap);
+ return mrb_funcall_argv(mrb, self, mid, 1, &v);
+ }
+ else {
+ mrb_value argv[MRB_FUNCALL_ARGC_MAX];
+
if (argc > MRB_FUNCALL_ARGC_MAX) {
- mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)\n", MRB_FUNCALL_ARGC_MAX);
- }
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=%d)", MRB_FUNCALL_ARGC_MAX);
+ }
va_start(ap, argc);
for (i = 0; i < argc; i++) {
- args[i] = va_arg(ap, mrb_value);
+ argv[i] = va_arg(ap, mrb_value);
}
va_end(ap);
+ return mrb_funcall_argv(mrb, self, mid, argc, argv);
}
- return mrb_funcall_argv(mrb, self, name, argc, args);
}
-
void
mrb_obj_call_init(mrb_state *mrb, mrb_value obj, int argc, mrb_value *argv)
{
- mrb_funcall_argv(mrb, obj, "initialize", argc, argv);
+ mrb_funcall_argv(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv);
}
/*
@@ -938,7 +950,7 @@ mrb_class_new_instance_m(mrb_state *mrb, mrb_value klass)
c = (struct RClass*)mrb_obj_alloc(mrb, k->tt, k);
c->super = k;
obj = mrb_obj_value(c);
- mrb_funcall_with_block(mrb, obj, "initialize", argc, argv, blk);
+ mrb_funcall_with_block(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv, blk);
return obj;
}
@@ -957,7 +969,7 @@ mrb_instance_new(mrb_state *mrb, mrb_value cv)
o = (struct RObject*)mrb_obj_alloc(mrb, ttype, c);
obj = mrb_obj_value(o);
mrb_get_args(mrb, "*&", &argv, &argc, &blk);
- mrb_funcall_with_block(mrb, obj, "initialize", argc, argv, blk);
+ mrb_funcall_with_block(mrb, obj, mrb_intern(mrb, "initialize"), argc, argv, blk);
return obj;
}
diff --git a/src/error.c b/src/error.c
index e71245509..6fe839cb2 100644
--- a/src/error.c
+++ b/src/error.c
@@ -144,7 +144,7 @@ exc_equal(mrb_state *mrb, mrb_value exc)
if (mrb_obj_equal(mrb, exc, obj)) return mrb_true_value();
if (mrb_obj_class(mrb, exc) != mrb_obj_class(mrb, obj)) {
- if ( mrb_respond_to(mrb, obj, mrb_intern(mrb, "message")) ) {
+ if (mrb_respond_to(mrb, obj, mrb_intern(mrb, "message"))) {
mesg = mrb_funcall(mrb, obj, "message", 0);
}
else
@@ -306,12 +306,15 @@ make_exception(mrb_state *mrb, int argc, mrb_value *argv, int isstr)
case 3:
n = 1;
exception_call:
- if (mrb_respond_to(mrb, argv[0], mrb_intern(mrb, "exception"))) {
- mesg = mrb_funcall_argv(mrb, argv[0], "exception", n, argv+1);
- }
- else {
- /* undef */
- mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
+ {
+ mrb_sym exc = mrb_intern(mrb, "exception");
+ if (mrb_respond_to(mrb, argv[0], exc)) {
+ mesg = mrb_funcall_argv(mrb, argv[0], exc, n, argv+1);
+ }
+ else {
+ /* undef */
+ mrb_raise(mrb, E_TYPE_ERROR, "exception class/object expected");
+ }
}
break;
diff --git a/src/kernel.c b/src/kernel.c
index 36dfbe769..740960f80 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -245,7 +245,7 @@ mrb_f_send(mrb_state *mrb, mrb_value self)
int argc;
mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
- return mrb_funcall_with_block(mrb,self, mrb_sym2name(mrb, name), argc, argv, block);
+ return mrb_funcall_with_block(mrb,self, name, argc, argv, block);
}
/* 15.3.1.2.2 */
diff --git a/src/re.c b/src/re.c
index f3cfea484..0022f9a9c 100644
--- a/src/re.c
+++ b/src/re.c
@@ -76,7 +76,7 @@ mrb_reg_s_new_instance(mrb_state *mrb, /*int argc, mrb_value *argv, */mrb_value
re->ptr = 0;
re->src = 0;
re->usecnt = 0;
- return mrb_funcall_argv(mrb, mrb_obj_value(re), "initialize", argc, argv);
+ return mrb_funcall_argv(mrb, mrb_obj_value(re), mrb_intern(mrb, "initialize"), argc, argv);
}
mrb_value
diff --git a/src/variable.c b/src/variable.c
index b81b292d9..a62e7e126 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -320,8 +320,8 @@ const_get(mrb_state *mrb, struct RClass *base, mrb_sym sym)
return kh_value(h, k);
}
if (mrb_respond_to(mrb, mrb_obj_value(c), cm)) {
- mrb_value argv = mrb_symbol_value(sym);
- return mrb_funcall_argv(mrb, mrb_obj_value(c), "const_missing", 1, &argv);
+ mrb_value name = mrb_symbol_value(sym);
+ return mrb_funcall(mrb, mrb_obj_value(c), "const_missing", 1, name);
}
}
c = c->super;
diff --git a/src/vm.c b/src/vm.c
index 2a13f0ea4..130e56071 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -179,16 +179,18 @@ ecall(mrb_state *mrb, int i)
}
mrb_value
-mrb_funcall_with_block(mrb_state *mrb, mrb_value self, const char *name, int argc, mrb_value *argv, mrb_value blk)
+mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv, mrb_value blk)
{
struct RProc *p;
struct RClass *c;
- mrb_sym mid = mrb_intern(mrb, name);
mrb_sym undef = 0;
mrb_callinfo *ci;
int n = mrb->ci->nregs;
mrb_value val;
+ if (argc < 0) {
+ mrb_raise(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%d)", argc);
+ }
c = mrb_class(mrb, self);
p = mrb_method_search_vm(mrb, &c, mid);
if (!p) {
@@ -232,9 +234,9 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, const char *name, int arg
}
mrb_value
-mrb_funcall_argv(mrb_state *mrb, mrb_value self, const char *name, int argc, mrb_value *argv)
+mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, int argc, mrb_value *argv)
{
- return mrb_funcall_with_block(mrb, self, name, argc, argv, mrb_nil_value());
+ return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value());
}
mrb_value