summaryrefslogtreecommitdiffhomepage
path: root/mrbgems
diff options
context:
space:
mode:
Diffstat (limited to 'mrbgems')
-rw-r--r--mrbgems/mruby-bin-config/mruby-config4
-rw-r--r--mrbgems/mruby-bin-config/mruby-config.bat12
-rw-r--r--mrbgems/mruby-catch/src/catch.c16
-rw-r--r--mrbgems/mruby-eval/src/eval.c9
-rw-r--r--mrbgems/mruby-method/src/method.c173
5 files changed, 155 insertions, 59 deletions
diff --git a/mrbgems/mruby-bin-config/mruby-config b/mrbgems/mruby-bin-config/mruby-config
index 8bbb4ecc6..3adda9e1a 100644
--- a/mrbgems/mruby-bin-config/mruby-config
+++ b/mrbgems/mruby-bin-config/mruby-config
@@ -4,7 +4,9 @@ print_help()
{
echo "Usage: mruby-config [switches]"
echo " switches:"
+ echo " --cc print compiler name"
echo " --cflags print flags passed to compiler"
+ echo " --ld print linker name"
echo " --ldflags print flags passed to linker"
echo " --ldflags-before-libs print flags passed to linker before linked libraries"
echo " --libs print linked libraries"
@@ -19,7 +21,9 @@ fi
while [ $# -gt 0 ]; do
case $1 in
+ --cc) echo MRUBY_CC;;
--cflags) echo MRUBY_CFLAGS;;
+ --ld) echo MRUBY_LD;;
--ldflags) echo MRUBY_LDFLAGS;;
--ldflags-before-libs) echo MRUBY_LDFLAGS_BEFORE_LIBS;;
--libs) echo MRUBY_LIBS;;
diff --git a/mrbgems/mruby-bin-config/mruby-config.bat b/mrbgems/mruby-bin-config/mruby-config.bat
index a1f7bfdd1..949fea06f 100644
--- a/mrbgems/mruby-bin-config/mruby-config.bat
+++ b/mrbgems/mruby-bin-config/mruby-config.bat
@@ -3,7 +3,9 @@
:top
shift
if "%0" equ "" goto :eof
+if "%0" equ "--cc" goto cc
if "%0" equ "--cflags" goto cflags
+if "%0" equ "--ld" goto ld
if "%0" equ "--ldflags" goto ldflags
if "%0" equ "--ldflags-before-libs" goto ldflagsbeforelibs
if "%0" equ "--libs" goto libs
@@ -12,10 +14,18 @@ if "%0" equ "--help" goto showhelp
echo Invalid Option
goto :eof
+:cc
+echo MRUBY_CC
+goto top
+
:cflags
echo MRUBY_CFLAGS
goto top
+:ld
+echo MRUBY_LD
+goto top
+
:libs
echo MRUBY_LIBS
goto top
@@ -35,7 +45,9 @@ goto top
:showhelp
echo Usage: mruby-config [switches]
echo switches:
+echo --cc print compiler name
echo --cflags print flags passed to compiler
+echo --ld print linker name
echo --ldflags print flags passed to linker
echo --ldflags-before-libs print flags passed to linker before linked libraries
echo --libs print linked libraries
diff --git a/mrbgems/mruby-catch/src/catch.c b/mrbgems/mruby-catch/src/catch.c
index d910cac7f..148639530 100644
--- a/mrbgems/mruby-catch/src/catch.c
+++ b/mrbgems/mruby-catch/src/catch.c
@@ -61,21 +61,20 @@ static const mrb_irep catch_irep = {
29,0,3,1,0
};
-#define ID_PRESERVED_CATCH MRB_SYM(__preserved_catch_proc)
+static const struct RProc catch_proc = {
+ NULL, NULL, MRB_TT_PROC, 7 /* GC_RED */, MRB_FL_OBJ_IS_FROZEN | MRB_PROC_SCOPE | MRB_PROC_STRICT,
+ { &catch_irep }, NULL, { NULL }
+};
static const mrb_callinfo *
find_catcher(mrb_state *mrb, mrb_value tag)
{
- mrb_value pval = mrb_obj_iv_get(mrb, (struct RObject *)mrb->kernel_module, ID_PRESERVED_CATCH);
- mrb_assert(mrb_proc_p(pval));
- const struct RProc *proc = mrb_proc_ptr(pval);
-
const mrb_callinfo *ci = mrb->c->ci;
size_t n = ci - mrb->c->cibase;
ci--;
for (; n > 0; n--, ci--) {
const mrb_value *arg1 = ci->stack + 1;
- if (ci->proc == proc && mrb_obj_eq(mrb, *arg1, tag)) {
+ if (ci->proc == &catch_proc && mrb_obj_eq(mrb, *arg1, tag)) {
return ci;
}
}
@@ -109,15 +108,12 @@ mrb_f_throw(mrb_state *mrb, mrb_value self)
void
mrb_mruby_catch_gem_init(mrb_state *mrb)
{
- struct RProc *p;
mrb_method_t m;
MRB_PRESYM_INIT_SYMBOLS(mrb, catch_syms_3);
MRB_PRESYM_INIT_SYMBOLS(mrb, catch_syms_1);
- p = mrb_proc_new(mrb, &catch_irep);
- MRB_METHOD_FROM_PROC(m, p);
+ MRB_METHOD_FROM_PROC(m, &catch_proc);
mrb_define_method_raw(mrb, mrb->kernel_module, MRB_SYM(catch), m);
- mrb_obj_iv_set(mrb, (struct RObject *)mrb->kernel_module, ID_PRESERVED_CATCH, mrb_obj_value(p));
mrb_define_method(mrb, mrb->kernel_module, "throw", mrb_f_throw, MRB_ARGS_ARG(1,1));
}
diff --git a/mrbgems/mruby-eval/src/eval.c b/mrbgems/mruby-eval/src/eval.c
index 978d4fc30..508f5ffcb 100644
--- a/mrbgems/mruby-eval/src/eval.c
+++ b/mrbgems/mruby-eval/src/eval.c
@@ -131,15 +131,6 @@ exec_irep(mrb_state *mrb, mrb_value self, struct RProc *proc, mrb_func_t posthoo
{
/* no argument passed from eval() */
mrb->c->ci->argc = 0;
- if (mrb->c->ci->acc < 0) {
- ptrdiff_t cioff = mrb->c->ci - mrb->c->cibase;
- mrb_value ret = mrb_top_run(mrb, proc, self, 0);
- if (mrb->exc) {
- mrb_exc_raise(mrb, mrb_obj_value(mrb->exc));
- }
- mrb->c->ci = mrb->c->cibase + cioff;
- return ret;
- }
/* clear block */
mrb->c->ci->stack[1] = mrb_nil_value();
return mrb_exec_irep(mrb, self, proc, posthook);
diff --git a/mrbgems/mruby-method/src/method.c b/mrbgems/mruby-method/src/method.c
index 8c8ebcd4f..02eddda9c 100644
--- a/mrbgems/mruby-method/src/method.c
+++ b/mrbgems/mruby-method/src/method.c
@@ -6,12 +6,126 @@
#include "mruby/string.h"
#include "mruby/presym.h"
+mrb_noreturn void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
+mrb_value mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p, mrb_func_t posthook);
+
+static mrb_value
+args_shift(mrb_state *mrb)
+{
+ mrb_value *argv = mrb->c->ci->stack + 1;
+
+ if (mrb->c->ci->argc > 0) {
+ mrb_value obj = argv[0];
+ memmove(argv, argv + 1, (mrb->c->ci->argc + 1 /* block */ - 1 /* first value */) * sizeof(mrb_value));
+ mrb->c->ci->argc--;
+ return obj;
+ }
+ else if (mrb->c->ci->argc < 0 && RARRAY_LEN(*argv) > 0) {
+ return mrb_ary_shift(mrb, *argv);
+ }
+ else {
+ mrb_argnum_error(mrb, 0, 1, -1);
+ return mrb_undef_value(); /* not reached */
+ }
+}
+
+static void
+args_unshift(mrb_state *mrb, mrb_value obj)
+{
+ mrb_value *argv = mrb->c->ci->stack + 1;
+
+ if (mrb->c->ci->argc >= 0) {
+ mrb_value block = argv[mrb->c->ci->argc];
+ argv[0] = mrb_ary_new_from_values(mrb, mrb->c->ci->argc, argv);
+ argv[1] = block;
+ mrb->c->ci->argc = -1;
+ }
+
+ mrb_ary_unshift(mrb, *argv, obj);
+}
+
+static struct RProc*
+method_missing_prepare(mrb_state *mrb, mrb_sym *mid, mrb_value recv, struct RClass **tc)
+{
+ const mrb_sym id_method_missing = MRB_SYM(method_missing);
+
+ if (*mid == id_method_missing) {
+ method_missing: ;
+ int argc = mrb->c->ci->argc;
+ mrb_value *argv = mrb->c->ci->stack + 1;
+ mrb_value args = (argc < 0) ? argv[0] : mrb_ary_new_from_values(mrb, argc, argv);
+ mrb_method_missing(mrb, *mid, recv, args);
+ }
+
+ *tc = mrb_class(mrb, recv);
+ mrb_method_t m = mrb_method_search_vm(mrb, tc, id_method_missing);
+ if (MRB_METHOD_UNDEF_P(m)) {
+ goto method_missing;
+ }
+
+ struct RProc *proc;
+ if (MRB_METHOD_FUNC_P(m)) {
+ proc = mrb_proc_new_cfunc(mrb, MRB_METHOD_FUNC(m));
+ MRB_PROC_SET_TARGET_CLASS(proc, *tc);
+ }
+ else {
+ proc = MRB_METHOD_PROC(m);
+ }
+
+ args_unshift(mrb, mrb_symbol_value(*mid));
+ *mid = id_method_missing;
+
+ return proc;
+}
+
static struct RObject *
method_object_alloc(mrb_state *mrb, struct RClass *mclass)
{
return (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mclass);
}
+static struct RProc*
+method_extract_proc(mrb_state *mrb, mrb_value self)
+{
+ mrb_value obj = mrb_iv_get(mrb, self, MRB_SYM(_proc));
+ if (mrb_nil_p(obj)) {
+ return NULL;
+ }
+ else {
+ mrb_check_type(mrb, obj, MRB_TT_PROC);
+ return mrb_proc_ptr(obj);
+ }
+}
+
+static mrb_value
+method_extract_receiver(mrb_state *mrb, mrb_value self)
+{
+ return mrb_iv_get(mrb, self, MRB_SYM(_recv));
+}
+
+static mrb_sym
+method_extract_mid(mrb_state *mrb, mrb_value self)
+{
+ mrb_value obj = mrb_iv_get(mrb, self, MRB_SYM(_name));
+ mrb_check_type(mrb, obj, MRB_TT_SYMBOL);
+ return mrb_symbol(obj);
+}
+
+static struct RClass*
+method_extract_owner(mrb_state *mrb, mrb_value self)
+{
+ mrb_value obj = mrb_iv_get(mrb, self, MRB_SYM(_owner));
+ switch (mrb_type(obj)) {
+ case MRB_TT_CLASS:
+ case MRB_TT_MODULE:
+ case MRB_TT_SCLASS:
+ break;
+ default:
+ mrb_raise(mrb, E_TYPE_ERROR, "not class/module as owner of method object");
+ }
+ return mrb_class_ptr(obj);
+}
+
static void
bind_check(mrb_state *mrb, mrb_value recv, mrb_value owner)
{
@@ -109,61 +223,40 @@ method_eql(mrb_state *mrb, mrb_value self)
#undef IV_GET
static mrb_value
-mcall(mrb_state *mrb, mrb_value recv, mrb_value proc, mrb_value name, struct RClass *owner,
- mrb_int argc, const mrb_value *argv, mrb_value block)
+mcall(mrb_state *mrb, mrb_value self, mrb_value recv)
{
- mrb_value ret;
- mrb_sym orig_mid = mrb->c->ci->mid;
+ struct RProc *proc = method_extract_proc(mrb, self);
+ mrb_sym mid = method_extract_mid(mrb, self);
+ struct RClass *tc = method_extract_owner(mrb, self);
- mrb->c->ci->mid = mrb_symbol(name);
- if (mrb_nil_p(proc)) {
- mrb_value missing_argv = mrb_ary_new_from_values(mrb, argc, argv);
- mrb_ary_unshift(mrb, missing_argv, name);
- ret = mrb_funcall_argv(mrb, recv, MRB_SYM(method_missing), argc + 1, RARRAY_PTR(missing_argv));
- }
- else if (!mrb_nil_p(block)) {
- /*
- workaround since `mrb_yield_with_class` does not support passing block as parameter
- need new API that initializes `mrb->c->stack[argc+1]` with block passed by argument
- */
- ret = mrb_funcall_with_block(mrb, recv, mrb_symbol(name), argc, argv, block);
+ if (mrb_undef_p(recv)) {
+ recv = method_extract_receiver(mrb, self);
}
else {
- ret = mrb_yield_with_class(mrb, proc, argc, argv, recv, owner);
+ bind_check(mrb, recv, mrb_obj_value(tc));
}
- mrb->c->ci->mid = orig_mid;
- return ret;
+
+ if (!proc) {
+ proc = method_missing_prepare(mrb, &mid, recv, &tc);
+ }
+ mrb->c->ci->mid = mid;
+ mrb->c->ci->u.target_class = tc;
+
+ return mrb_exec_irep(mrb, recv, proc, NULL);
}
static mrb_value
method_call(mrb_state *mrb, mrb_value self)
{
- mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
- mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
- mrb_value recv = mrb_iv_get(mrb, self, MRB_SYM(_recv));
- struct RClass *owner = mrb_class_ptr(mrb_iv_get(mrb, self, MRB_SYM(_owner)));
- mrb_int argc;
- const mrb_value *argv;
- mrb_value block;
-
- mrb_get_args(mrb, "*&", &argv, &argc, &block);
- return mcall(mrb, recv, proc, name, owner, argc, argv, block);
+ return mcall(mrb, self, mrb_undef_value());
}
static mrb_value
method_bcall(mrb_state *mrb, mrb_value self)
{
- mrb_value proc = mrb_iv_get(mrb, self, MRB_SYM(_proc));
- mrb_value name = mrb_iv_get(mrb, self, MRB_SYM(_name));
- mrb_value recv = mrb_iv_get(mrb, self, MRB_SYM(_recv));
- mrb_value owner = mrb_iv_get(mrb, self, MRB_SYM(_owner));
- mrb_int argc;
- const mrb_value *argv;
- mrb_value block;
-
- mrb_get_args(mrb, "o*&", &recv, &argv, &argc, &block);
- bind_check(mrb, recv, owner);
- return mcall(mrb, recv, proc, name, mrb_class_ptr(owner), argc, argv, block);
+ mrb_value recv = args_shift(mrb);
+ mrb_gc_protect(mrb, recv);
+ return mcall(mrb, self, recv);
}
static mrb_value