diff options
| -rw-r--r-- | .github/workflows/build.yml | 2 | ||||
| -rw-r--r-- | include/mruby.h | 13 | ||||
| -rw-r--r-- | include/mruby/numeric.h | 1 | ||||
| -rw-r--r-- | mrbgems/mruby-array-ext/src/array.c | 12 | ||||
| -rw-r--r-- | mrbgems/mruby-kernel-ext/src/kernel.c | 3 | ||||
| -rw-r--r-- | src/class.c | 27 | ||||
| -rw-r--r-- | src/kernel.c | 2 | ||||
| -rw-r--r-- | src/numeric.c | 21 | ||||
| -rw-r--r-- | src/object.c | 19 | ||||
| -rw-r--r-- | src/proc.c | 6 | ||||
| -rw-r--r-- | src/string.c | 27 | ||||
| -rw-r--r-- | src/variable.c | 27 | ||||
| -rw-r--r-- | src/vm.c | 113 |
13 files changed, 123 insertions, 150 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index dbdd35fba..bf963ff0b 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -95,7 +95,7 @@ jobs: Windows-Cygwin: runs-on: windows-latest - timeout-minutes: 10 + timeout-minutes: 15 env: ACTIONS_ALLOW_UNSECURE_COMMANDS: true MRUBY_CONFIG: ci/gcc-clang diff --git a/include/mruby.h b/include/mruby.h index 21b96817a..806ceaff6 100644 --- a/include/mruby.h +++ b/include/mruby.h @@ -1269,7 +1269,10 @@ MRB_API mrb_bool mrb_obj_eq(mrb_state *mrb, mrb_value a, mrb_value b); MRB_API mrb_bool mrb_obj_equal(mrb_state *mrb, mrb_value a, mrb_value b); MRB_API mrb_bool mrb_equal(mrb_state *mrb, mrb_value obj1, mrb_value obj2); #ifndef MRB_NO_FLOAT -MRB_API mrb_value mrb_to_float(mrb_state *mrb, mrb_value val); +MRB_API mrb_value mrb_ensure_float_type(mrb_state *mrb, mrb_value val); +#define mrb_as_float(mrb, x) mrb_float(mrb_ensure_float_type(mrb, x)) +/* obsolete: use mrb_ensure_float_type() instead */ +#define mrb_to_float(mrb, val) mrb_ensure_float_type(mrb, val) #endif MRB_API mrb_value mrb_inspect(mrb_state *mrb, mrb_value obj); MRB_API mrb_bool mrb_eql(mrb_state *mrb, mrb_value obj1, mrb_value obj2); @@ -1398,9 +1401,11 @@ MRB_API mrb_value mrb_check_string_type(mrb_state *mrb, mrb_value str); #define mrb_to_str(mrb, str) mrb_ensure_string_type(mrb,str) /* obsolete: use mrb_obj_as_string() instead */ #define mrb_str_to_str(mrb, str) mrb_obj_as_string(mrb, str) -MRB_API mrb_value mrb_to_integer(mrb_state *mrb, mrb_value val); -#define mrb_to_int(mrb, val) mrb_to_integer(mrb, val) -#define mrb_as_int(mrb, val) mrb_integer(mrb_to_integer(mrb, val)) +MRB_API mrb_value mrb_ensure_int_type(mrb_state *mrb, mrb_value val); +#define mrb_as_int(mrb, val) mrb_integer(mrb_ensure_int_type(mrb, val)) +/* obsolete: use mrb_ensure_int_type() instead */ +#define mrb_to_integer(mrb, val) mrb_ensure_int_type(mrb, val) +#define mrb_to_int(mrb, val) mrb_ensure_int_type(mrb, val) /* string type checking (contrary to the name, it doesn't convert) */ MRB_API void mrb_check_type(mrb_state *mrb, mrb_value x, enum mrb_vtype t); diff --git a/include/mruby/numeric.h b/include/mruby/numeric.h index 4b14588ac..aec46413c 100644 --- a/include/mruby/numeric.h +++ b/include/mruby/numeric.h @@ -160,7 +160,6 @@ mrb_int_mul_overflow(mrb_int a, mrb_int b, mrb_int *c) # endif /* MRB_USE_FLOAT32 */ MRB_API mrb_value mrb_float_to_integer(mrb_state *mrb, mrb_value val); -MRB_API mrb_float mrb_as_float(mrb_state *mrb, mrb_value x); /* internal functions */ mrb_float mrb_div_float(mrb_float x, mrb_float y); diff --git a/mrbgems/mruby-array-ext/src/array.c b/mrbgems/mruby-array-ext/src/array.c index d97778642..ae8a55d4d 100644 --- a/mrbgems/mruby-array-ext/src/array.c +++ b/mrbgems/mruby-array-ext/src/array.c @@ -264,12 +264,14 @@ mrb_ary_compact_bang(mrb_state *mrb, mrb_value self) static mrb_value mrb_ary_rotate(mrb_state *mrb, mrb_value self) { + mrb_int count=1; + mrb_get_args(mrb, "|i", &count); + mrb_value ary = mrb_ary_new(mrb); mrb_int len = RARRAY_LEN(self); mrb_value *p = RARRAY_PTR(self); - mrb_int count=1, idx; + mrb_int idx; - mrb_get_args(mrb, "|i", &count); if (len <= 0) return ary; if (count < 0) { idx = len - (~count % len) - 1; @@ -313,12 +315,14 @@ rev(mrb_value *p, mrb_int beg, mrb_int end) static mrb_value mrb_ary_rotate_bang(mrb_state *mrb, mrb_value self) { + mrb_int count=1; + mrb_get_args(mrb, "|i", &count); + struct RArray *a = mrb_ary_ptr(self); mrb_int len = ARY_LEN(a); mrb_value *p = ARY_PTR(a); - mrb_int count=1, idx; + mrb_int idx; - mrb_get_args(mrb, "|i", &count); mrb_ary_modify(mrb, a); if (len == 0 || count == 0) return self; if (count == 1) { diff --git a/mrbgems/mruby-kernel-ext/src/kernel.c b/mrbgems/mruby-kernel-ext/src/kernel.c index 5b3dd6b35..976615f6e 100644 --- a/mrbgems/mruby-kernel-ext/src/kernel.c +++ b/mrbgems/mruby-kernel-ext/src/kernel.c @@ -187,6 +187,9 @@ mrb_f_float(mrb_state *mrb, mrb_value self) { mrb_value arg = mrb_get_arg1(mrb); + if (mrb_string_p(arg)) { + return mrb_float_value(mrb, mrb_str_to_dbl(mrb, arg, TRUE)); + } return mrb_to_float(mrb, arg); } #endif diff --git a/src/class.c b/src/class.c index 6249aa640..f97cc4c40 100644 --- a/src/class.c +++ b/src/class.c @@ -36,8 +36,8 @@ union mt_ptr { /* method table structure */ typedef struct mt_tbl { - size_t size; - size_t alloc; + int size; + int alloc; union mt_ptr *ptr; } mt_tbl; @@ -65,8 +65,8 @@ static void mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union static void mt_rehash(mrb_state *mrb, mt_tbl *t) { - size_t old_alloc = t->alloc; - size_t new_alloc = old_alloc+8; + int old_alloc = t->alloc; + int new_alloc = old_alloc+8; union mt_ptr *old_ptr = t->ptr; khash_power2(new_alloc); @@ -79,7 +79,7 @@ mt_rehash(mrb_state *mrb, mt_tbl *t) mrb_sym *keys = (mrb_sym*)&old_ptr[old_alloc]; union mt_ptr *vals = old_ptr; - for (size_t i = 0; i < old_alloc; i++) { + for (int i = 0; i < old_alloc; i++) { mrb_sym key = keys[i]; if (MT_KEY_P(key)) { mt_put(mrb, t, MT_KEY_SYM(key), MT_KEY_FLG(key), vals[i]); @@ -94,8 +94,7 @@ mt_rehash(mrb_state *mrb, mt_tbl *t) static void mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union mt_ptr ptr) { - size_t hash, pos, start; - ssize_t dpos = -1; + int hash, pos, start, dpos = -1; if (t->alloc == 0) { mt_rehash(mrb, t); @@ -140,7 +139,7 @@ mt_put(mrb_state *mrb, mt_tbl *t, mrb_sym sym, mrb_sym flags, union mt_ptr ptr) static mrb_sym mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) { - size_t hash, pos, start; + int hash, pos, start; if (t == NULL) return 0; if (t->alloc == 0) return 0; @@ -150,7 +149,7 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) union mt_ptr *vals = t->ptr; hash = kh_int_hash_func(mrb, sym); #ifdef MRB_USE_INLINE_METHOD_CACHE - size_t cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE; + int cpos = (hash^(uintptr_t)t) % MT_CACHE_SIZE; pos = mt_cache[cpos]; if (cpos < t->alloc && t->table[cpos].key == sym) { return &t->table[cpos]; @@ -182,7 +181,7 @@ mt_get(mrb_state *mrb, mt_tbl *t, mrb_sym sym, union mt_ptr *pp) static mrb_bool mt_del(mrb_state *mrb, mt_tbl *t, mrb_sym sym) { - size_t hash, pos, start; + int hash, pos, start; if (t == NULL) return FALSE; if (t->alloc == 0) return FALSE; @@ -213,7 +212,7 @@ static struct mt_tbl* mt_copy(mrb_state *mrb, mt_tbl *t) { mt_tbl *t2; - size_t i; + int i; if (t == NULL) return NULL; if (t->alloc == 0) return NULL; @@ -242,7 +241,7 @@ MRB_API void mrb_mt_foreach(mrb_state *mrb, struct RClass *c, mrb_mt_foreach_func *fn, void *p) { mt_tbl *t = c->mt; - size_t i; + int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -276,7 +275,7 @@ void mrb_gc_mark_mt(mrb_state *mrb, struct RClass *c) { mt_tbl *t = c->mt; - size_t i; + int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -299,7 +298,7 @@ mrb_gc_mark_mt_size(mrb_state *mrb, struct RClass *c) struct mt_tbl *h = c->mt; if (!h) return 0; - return h->size; + return (size_t)h->size; } void diff --git a/src/kernel.c b/src/kernel.c index 5ecebabeb..7a261560f 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -659,7 +659,7 @@ mrb_init_kernel(mrb_state *mrb) mrb_define_method(mrb, krn, "respond_to?", obj_respond_to, MRB_ARGS_ARG(1,1)); /* 15.3.1.3.43 */ mrb_define_method(mrb, krn, "to_s", mrb_any_to_s, MRB_ARGS_NONE()); /* 15.3.1.3.46 */ mrb_define_method(mrb, krn, "__case_eqq", mrb_obj_ceqq, MRB_ARGS_REQ(1)); /* internal */ - mrb_define_method(mrb, krn, "__to_int", mrb_to_integer, MRB_ARGS_NONE()); /* internal */ + mrb_define_method(mrb, krn, "__to_int", mrb_ensure_int_type, MRB_ARGS_NONE()); /* internal */ mrb_define_method(mrb, krn, "__ENCODING__", mrb_encoding, MRB_ARGS_NONE()); mrb_include_module(mrb, mrb->object_class, mrb->kernel_module); diff --git a/src/numeric.c b/src/numeric.c index fd9f5ce2c..fb3c0e48f 100644 --- a/src/numeric.c +++ b/src/numeric.c @@ -20,27 +20,6 @@ #endif #endif -#ifndef MRB_NO_FLOAT -MRB_API mrb_float -mrb_as_float(mrb_state *mrb, mrb_value val) -{ - switch (mrb_type(val)) { - case MRB_TT_INTEGER: - return (mrb_float)mrb_integer(val); - case MRB_TT_FLOAT: - break; - case MRB_TT_STRING: - case MRB_TT_FALSE: - case MRB_TT_TRUE: - mrb_raise(mrb, E_TYPE_ERROR, "non float value"); - default: - val = mrb_type_convert(mrb, val, MRB_TT_FLOAT, MRB_SYM(to_f)); - break; - } - return mrb_float(val); -} -#endif - static void int_overflow(mrb_state *mrb, const char *reason) { diff --git a/src/object.c b/src/object.c index de0298fab..8a2addc20 100644 --- a/src/object.c +++ b/src/object.c @@ -485,26 +485,22 @@ mrb_obj_is_kind_of(mrb_state *mrb, mrb_value obj, struct RClass *c) } MRB_API mrb_value -mrb_to_integer(mrb_state *mrb, mrb_value val) +mrb_ensure_int_type(mrb_state *mrb, mrb_value val) { - if (!mrb_integer_p(val)) { #ifndef MRB_NO_FLOAT if (mrb_float_p(val)) { return mrb_float_to_integer(mrb, val); } #endif - if (mrb_string_p(val)) { - mrb_raise(mrb, E_TYPE_ERROR, "can't convert String to Integer"); - } - return mrb_type_convert(mrb, val, MRB_TT_INTEGER, MRB_SYM(to_i)); + mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Integer", val); } return val; } #ifndef MRB_NO_FLOAT MRB_API mrb_value -mrb_to_float(mrb_state *mrb, mrb_value val) +mrb_ensure_float_type(mrb_state *mrb, mrb_value val) { if (mrb_nil_p(val)) { mrb_raise(mrb, E_TYPE_ERROR, "can't convert nil into Float"); @@ -516,11 +512,14 @@ mrb_to_float(mrb_state *mrb, mrb_value val) case MRB_TT_FLOAT: return val; - case MRB_TT_STRING: - return mrb_float_value(mrb, mrb_str_to_dbl(mrb, val, TRUE)); + case MRB_TT_RATIONAL: + case MRB_TT_COMPLEX: + return mrb_type_convert(mrb, val, MRB_TT_FLOAT, MRB_SYM(to_f)); default: - return mrb_type_convert(mrb, val, MRB_TT_FLOAT, MRB_SYM(to_f)); + mrb_raisef(mrb, E_TYPE_ERROR, "%Y cannot be converted to Float", val); + /* not reached */ + return val; } } #endif diff --git a/src/proc.c b/src/proc.c index e11cb7fec..01a69fbf1 100644 --- a/src/proc.c +++ b/src/proc.c @@ -207,12 +207,12 @@ mrb_proc_copy(mrb_state *mrb, struct RProc *a, struct RProc *b) /* already initialized proc */ return; } + if (!MRB_PROC_CFUNC_P(b) && b->body.irep) { + mrb_irep_incref(mrb, (mrb_irep*)b->body.irep); + } a->flags = b->flags; a->body = b->body; a->upper = b->upper; - if (!MRB_PROC_CFUNC_P(a) && a->body.irep) { - mrb_irep_incref(mrb, (mrb_irep*)a->body.irep); - } a->e.env = b->e.env; /* a->e.target_class = a->e.target_class; */ } diff --git a/src/string.c b/src/string.c index 6c9dd2996..332c4e777 100644 --- a/src/string.c +++ b/src/string.c @@ -1108,6 +1108,9 @@ str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, } else { switch (mrb_type(indx)) { + default: + indx = mrb_ensure_int_type(mrb, indx); + /* fall through */ case MRB_TT_INTEGER: *beg = mrb_integer(indx); *len = 1; @@ -1120,16 +1123,6 @@ str_convert_range(mrb_state *mrb, mrb_value str, mrb_value indx, mrb_value alen, return STR_BYTE_RANGE_CORRECTED; case MRB_TT_RANGE: - goto range_arg; - - default: - indx = mrb_to_integer(mrb, indx); - if (mrb_integer_p(indx)) { - *beg = mrb_integer(indx); - *len = 1; - return STR_CHAR_RANGE; - } -range_arg: *len = RSTRING_CHAR_LEN(str); switch (mrb_range_beg_len(mrb, indx, beg, len, *len, TRUE)) { case MRB_RANGE_OK: @@ -1139,8 +1132,6 @@ range_arg: default: break; } - - mrb_raise(mrb, E_TYPE_ERROR, "can't convert to Integer"); } } return STR_OUT_OF_RANGE; @@ -2047,9 +2038,11 @@ static mrb_value mrb_str_rindex(mrb_state *mrb, mrb_value str) { mrb_value sub; - mrb_int pos, len = RSTRING_CHAR_LEN(str); + mrb_int pos; + int argc = mrb_get_args(mrb, "S|i", &sub, &pos); + mrb_int len = RSTRING_CHAR_LEN(str); - if (mrb_get_args(mrb, "S|i", &sub, &pos) == 1) { + if (argc == 1) { pos = len; } else { @@ -2828,23 +2821,25 @@ static mrb_value mrb_str_byteslice(mrb_state *mrb, mrb_value str) { mrb_value a1; - mrb_int str_len = RSTRING_LEN(str), beg, len; + mrb_int str_len, beg, len; mrb_bool empty = TRUE; len = mrb_get_argc(mrb); switch (len) { case 2: mrb_get_args(mrb, "ii", &beg, &len); + str_len = RSTRING_LEN(str); break; case 1: a1 = mrb_get_arg1(mrb); + str_len = RSTRING_LEN(str); if (mrb_range_p(a1)) { if (mrb_range_beg_len(mrb, a1, &beg, &len, str_len, TRUE) != MRB_RANGE_OK) { return mrb_nil_value(); } } else { - beg = mrb_integer(mrb_to_integer(mrb, a1)); + beg = mrb_as_int(mrb, a1); len = 1; empty = FALSE; } diff --git a/src/variable.c b/src/variable.c index daee93655..53b760d0f 100644 --- a/src/variable.c +++ b/src/variable.c @@ -14,7 +14,7 @@ /* Instance variable table structure */ typedef struct iv_tbl { - size_t size, alloc; + int size, alloc; mrb_value *ptr; } iv_tbl; @@ -41,8 +41,8 @@ static void iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val); static void iv_rehash(mrb_state *mrb, iv_tbl *t) { - size_t old_alloc = t->alloc; - size_t new_alloc = old_alloc+4; + int old_alloc = t->alloc; + int new_alloc = old_alloc+4; mrb_value *old_ptr = t->ptr; khash_power2(new_alloc); @@ -55,7 +55,7 @@ iv_rehash(mrb_state *mrb, iv_tbl *t) mrb_sym *keys = (mrb_sym*)&old_ptr[old_alloc]; mrb_value *vals = old_ptr; - for (size_t i = 0; i < old_alloc; i++) { + for (int i = 0; i < old_alloc; i++) { if (IV_KEY_P(keys[i])) { iv_put(mrb, t, keys[i], vals[i]); } @@ -67,8 +67,7 @@ iv_rehash(mrb_state *mrb, iv_tbl *t) static void iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) { - size_t hash, pos, start; - int dpos = -1; + int hash, pos, start, dpos = -1; if (t == NULL) return; if (t->alloc == 0) { @@ -112,10 +111,10 @@ iv_put(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value val) } /* Get a value for a symbol from the instance variable table. */ -static size_t +static int iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) { - size_t hash, pos, start; + int hash, pos, start; if (t == NULL) return FALSE; if (t->alloc == 0) return FALSE; @@ -145,7 +144,7 @@ iv_get(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) static mrb_bool iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) { - size_t hash, pos, start; + int hash, pos, start; if (t == NULL) return FALSE; if (t->alloc == 0) return FALSE; @@ -177,7 +176,7 @@ iv_del(mrb_state *mrb, iv_tbl *t, mrb_sym sym, mrb_value *vp) static void iv_foreach(mrb_state *mrb, iv_tbl *t, mrb_iv_foreach_func *func, void *p) { - size_t i; + int i; if (t == NULL) return; if (t->alloc == 0) return; @@ -201,7 +200,7 @@ static size_t iv_size(mrb_state *mrb, iv_tbl *t) { if (t == NULL) return 0; - return t->size; + return (size_t)t->size; } /* Copy the instance variable table. */ @@ -209,7 +208,7 @@ static iv_tbl* iv_copy(mrb_state *mrb, iv_tbl *t) { iv_tbl *t2; - size_t i; + int i; if (t == NULL) return NULL; if (t->alloc == 0) return NULL; @@ -486,7 +485,7 @@ mrb_value mrb_obj_iv_inspect(mrb_state *mrb, struct RObject *obj) { iv_tbl *t = obj->iv; - size_t len = iv_size(mrb, t); + int len = iv_size(mrb, t); if (len > 0) { const char *cn = mrb_obj_classname(mrb, mrb_obj_value(obj)); @@ -660,7 +659,7 @@ mrb_mod_cv_set(mrb_state *mrb, struct RClass *c, mrb_sym sym, mrb_value v) while (c) { iv_tbl *t = c->iv; - size_t pos = iv_get(mrb, t, sym, NULL); + int pos = iv_get(mrb, t, sym, NULL); if (pos) { mrb_check_frozen(mrb, c); @@ -430,6 +430,52 @@ mrb_ci_nregs(mrb_callinfo *ci) return nregs; } +mrb_value mrb_obj_missing(mrb_state *mrb, mrb_value mod); + +static mrb_method_t +prepare_missing(mrb_state *mrb, mrb_value recv, mrb_sym mid, struct RClass **clsp, uint32_t a, uint16_t *c, mrb_value blk, int super) +{ + mrb_sym missing = MRB_SYM(method_missing); + mrb_callinfo *ci = mrb->c->ci; + uint16_t b = *c; + mrb_int n = b & 0xf; + mrb_int nk = (b>>4) & 0xf; + mrb_value *argv = &ci->stack[a+1]; + mrb_value args; + mrb_method_t m; + + /* pack positional arguments */ + if (n == 15) args = argv[0]; + else args = mrb_ary_new_from_values(mrb, n, argv); + + if (mrb_func_basic_p(mrb, recv, missing, mrb_obj_missing)) { + method_missing: + if (super) mrb_no_method_error(mrb, mid, args, "no superclass method '%n'", mid); + else mrb_method_missing(mrb, mid, recv, args); + /* not reached */ + } + if (mid != missing) { + *clsp = mrb_class(mrb, recv); + } + m = mrb_method_search_vm(mrb, clsp, missing); + if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */ + mrb_stack_extend(mrb, a+4); + + argv = &ci->stack[a+1]; /* maybe reallocated */ + argv[0] = args; + if (nk == 0) { + argv[1] = blk; + } + else { + mrb_assert(nk == 15); + argv[1] = argv[n]; + argv[2] = blk; + } + *c = 15 | (nk<<4); + mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); + return m; +} + MRB_API mrb_value mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) { @@ -478,24 +524,15 @@ mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc c = mrb_class(mrb, self); m = mrb_method_search_vm(mrb, &c, mid); mrb_stack_extend(mrb, n + argc + 3); - if (MRB_METHOD_UNDEF_P(m) || argc >= 15) { - mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); - - ci->stack[n+1] = args; + if (argc >= 15) { + ci->stack[n+1] = mrb_ary_new_from_values(mrb, argc, argv); argc = 15; } if (MRB_METHOD_UNDEF_P(m)) { - mrb_sym missing = MRB_SYM(method_missing); - mrb_value args = ci->stack[n+1]; - - m = mrb_method_search_vm(mrb, &c, missing); - if (MRB_METHOD_UNDEF_P(m)) { - mrb_method_missing(mrb, mid, self, args); - } - mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); - mrb_stack_extend(mrb, n+2); - ci->stack[n+1] = args; - argc = 15; + uint16_t ac = (uint16_t)argc; + m = prepare_missing(mrb, self, mid, &c, n, &ac, mrb_nil_value(), 0); + argc = (mrb_int)ac; + mid = MRB_SYM(method_missing); } ci = cipush(mrb, n, 0, c, NULL, mid, argc); if (MRB_METHOD_PROC_P(m)) { @@ -1123,52 +1160,6 @@ hash_new_from_values(mrb_state *mrb, mrb_int argc, mrb_value *regs) return hash; } -mrb_value mrb_obj_missing(mrb_state *mrb, mrb_value mod); - -static mrb_method_t -prepare_missing(mrb_state *mrb, mrb_value recv, mrb_sym mid, struct RClass **clsp, uint32_t a, uint16_t *c, mrb_value blk, int super) -{ - mrb_sym missing = MRB_SYM(method_missing); - mrb_callinfo *ci = mrb->c->ci; - uint16_t b = *c; - mrb_int n = b & 0xf; - mrb_int nk = (b>>4) & 0xf; - mrb_value *argv = &ci->stack[a+1]; - mrb_value args; - mrb_method_t m; - - /* pack positional arguments */ - if (n == 15) args = argv[0]; - else args = mrb_ary_new_from_values(mrb, n, argv); - - if (mrb_func_basic_p(mrb, recv, missing, mrb_obj_missing)) { - method_missing: - if (super) mrb_no_method_error(mrb, mid, args, "no superclass method '%n'", mid); - else mrb_method_missing(mrb, mid, recv, args); - /* not reached */ - } - if (mid != missing) { - *clsp = mrb_class(mrb, recv); - } - m = mrb_method_search_vm(mrb, clsp, missing); - if (MRB_METHOD_UNDEF_P(m)) goto method_missing; /* just in case */ - mrb_stack_extend(mrb, a+4); - - argv = &ci->stack[a+1]; /* maybe reallocated */ - argv[0] = args; - if (nk == 0) { - argv[1] = blk; - } - else { - mrb_assert(nk == 15); - argv[1] = argv[n]; - argv[2] = blk; - } - *c = 15 | (nk<<4); - mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); - return m; -} - void mrb_method_added(mrb_state *mrb, struct RClass *c, mrb_sym mid); mrb_value mrb_str_aref(mrb_state *mrb, mrb_value str, mrb_value idx, mrb_value len); |
