diff options
Diffstat (limited to 'mrbgems')
| -rw-r--r-- | mrbgems/mruby-bin-config/mruby-config | 4 | ||||
| -rw-r--r-- | mrbgems/mruby-bin-config/mruby-config.bat | 12 | ||||
| -rw-r--r-- | mrbgems/mruby-catch/src/catch.c | 16 | ||||
| -rw-r--r-- | mrbgems/mruby-eval/src/eval.c | 9 | ||||
| -rw-r--r-- | mrbgems/mruby-method/src/method.c | 173 |
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 |
