diff options
-rw-r--r-- | ChangeLog | 36 | ||||
-rw-r--r-- | class.c | 45 | ||||
-rw-r--r-- | eval_error.c | 25 | ||||
-rw-r--r-- | eval_intern.h | 23 | ||||
-rw-r--r-- | insns.def | 2 | ||||
-rw-r--r-- | internal.h | 2 | ||||
-rw-r--r-- | load.c | 2 | ||||
-rw-r--r-- | method.h | 47 | ||||
-rw-r--r-- | parse.y | 2 | ||||
-rw-r--r-- | proc.c | 29 | ||||
-rw-r--r-- | struct.c | 4 | ||||
-rw-r--r-- | vm.c | 17 | ||||
-rw-r--r-- | vm_core.h | 10 | ||||
-rw-r--r-- | vm_eval.c | 83 | ||||
-rw-r--r-- | vm_insnhelper.c | 55 | ||||
-rw-r--r-- | vm_insnhelper.h | 2 | ||||
-rw-r--r-- | vm_method.c | 186 |
17 files changed, 317 insertions, 253 deletions
@@ -1,3 +1,39 @@ +Wed Jun 03 10:35:45 2015 Koichi Sasada <ko1@atdot.net> + + * method.h: split rb_method_definition_t::flag to several flags. + + `flag' contains several categories of attributes and it makes us + confusion (at least, I had confused). + + * rb_method_visibility_t (flags::visi) + * NOEX_UNDEF -> METHOD_VISI_UNDEF = 0 + * NOEX_PUBLIC -> METHOD_VISI_PUBLIC = 1 + * NOEX_PRIVATE -> METHOD_VISI_PRIVATE = 2 + * NOEX_PROTECTED -> METHOD_VISI_PROTECTED = 3 + * NOEX_SAFE(flag)) -> safe (flags::safe, 2 bits) + * NOEX_BASIC -> basic (flags::basic, 1 bit) + * NOEX_MODFUNC -> rb_scope_visibility_t in CREF + * NOEX_SUPER -> MISSING_SUPER (enum missing_reason) + * NOEX_VCALL -> MISSING_VCALL (enum missing_reason) + * NOEX_RESPONDS -> BOUND_RESPONDS (macro) + + Now, NOEX_NOREDEF is not supported (I'm not sure it is needed). + + Background: + I did not know what "NOEX" stands for. + I asked Matz (who made this name) and his answer was "Nothing". + "At first, it meant NO EXport (private), but the original + meaning was gone." + This is why I remove the mysterious word "NOEX" from MRI. + + * vm_core.h: introduce `enum missing_reason' to represent + method_missing (NoMethodError) reason. + + * eval_intern.h: introduce rb_scope_visibility_t to represent + scope visibility. + It has 3 method visibilities (public/private/protected) + and `module_function`. + Wed Jun 3 08:06:30 2015 NAKAMURA Usaku <usa@ruby-lang.org> * gem/bundled_gems: updated to test-unit 3.1.1 and minitest 5.7.0. @@ -249,11 +249,11 @@ clone_method(VALUE klass, ID mid, const rb_method_entry_t *me) rb_cref_t *new_cref; newiseqval = rb_iseq_clone(me->def->body.iseq.iseqptr->self, klass); rb_vm_rewrite_cref_stack(me->def->body.iseq.cref, me->klass, klass, &new_cref); - rb_add_method_iseq(klass, mid, newiseqval, new_cref, me->def->flag); + rb_add_method_iseq(klass, mid, newiseqval, new_cref, me->def->flags.visi); RB_GC_GUARD(newiseqval); } else { - rb_method_entry_set(klass, mid, me, me->def->flag); + rb_method_entry_set(klass, mid, me, me->def->flags.visi); } } else { @@ -1055,22 +1055,21 @@ rb_mod_ancestors(VALUE mod) return ary; } -#define VISI(x) ((x)&NOEX_MASK) -#define VISI_CHECK(x,f) (VISI(x) == (f)) - static int ins_methods_push(ID name, long type, VALUE ary, long visi) { - if (type == -1) return ST_CONTINUE; + if (type == METHOD_VISI_UNDEF) return ST_CONTINUE; - switch (visi) { - case NOEX_PRIVATE: - case NOEX_PROTECTED: - case NOEX_PUBLIC: + switch ((rb_method_visibility_t)visi) { + case METHOD_VISI_UNDEF: + return ST_CONTINUE; + case METHOD_VISI_PRIVATE: + case METHOD_VISI_PROTECTED: + case METHOD_VISI_PUBLIC: visi = (type == visi); break; default: - visi = (type != NOEX_PRIVATE); + visi = (type != METHOD_VISI_PRIVATE); break; } if (visi) { @@ -1088,19 +1087,19 @@ ins_methods_i(st_data_t name, st_data_t type, st_data_t ary) static int ins_methods_prot_i(st_data_t name, st_data_t type, st_data_t ary) { - return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PROTECTED); + return ins_methods_push((ID)name, (long)type, (VALUE)ary, METHOD_VISI_PROTECTED); } static int ins_methods_priv_i(st_data_t name, st_data_t type, st_data_t ary) { - return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PRIVATE); + return ins_methods_push((ID)name, (long)type, (VALUE)ary, METHOD_VISI_PRIVATE); } static int ins_methods_pub_i(st_data_t name, st_data_t type, st_data_t ary) { - return ins_methods_push((ID)name, (long)type, (VALUE)ary, NOEX_PUBLIC); + return ins_methods_push((ID)name, (long)type, (VALUE)ary, METHOD_VISI_PUBLIC); } struct method_entry_arg { @@ -1113,7 +1112,7 @@ method_entry_i(st_data_t key, st_data_t value, st_data_t data) { const rb_method_entry_t *me = (const rb_method_entry_t *)value; struct method_entry_arg *arg = (struct method_entry_arg *)data; - long type; + rb_method_visibility_t type; if (me && me->def->type == VM_METHOD_TYPE_REFINED) { VALUE klass = me->klass; @@ -1123,12 +1122,12 @@ method_entry_i(st_data_t key, st_data_t value, st_data_t data) } if (!st_lookup(arg->list, key, 0)) { if (UNDEFINED_METHOD_ENTRY_P(me)) { - type = -1; /* none */ + type = METHOD_VISI_UNDEF; /* none */ } else { - type = VISI(me->def->flag); + type = me->def->flags.visi; } - st_add_direct(arg->list, key, type); + st_add_direct(arg->list, key, (long)type); } return ST_CONTINUE; } @@ -1469,31 +1468,31 @@ rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj) void rb_define_method_id(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc) { - rb_add_method_cfunc(klass, mid, func, argc, NOEX_PUBLIC); + rb_add_method_cfunc(klass, mid, func, argc, METHOD_VISI_PUBLIC); } void rb_define_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) { - rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PUBLIC); + rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PUBLIC); } void rb_define_protected_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) { - rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PROTECTED); + rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PROTECTED); } void rb_define_private_method(VALUE klass, const char *name, VALUE (*func)(ANYARGS), int argc) { - rb_add_method_cfunc(klass, rb_intern(name), func, argc, NOEX_PRIVATE); + rb_add_method_cfunc(klass, rb_intern(name), func, argc, METHOD_VISI_PRIVATE); } void rb_undef_method(VALUE klass, const char *name) { - rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, NOEX_UNDEF); + rb_add_method(klass, rb_intern(name), VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_UNDEF); } /*! diff --git a/eval_error.c b/eval_error.c index c32eff13f2..0f2f165cc8 100644 --- a/eval_error.c +++ b/eval_error.c @@ -209,23 +209,22 @@ ruby_error_print(void) } static const char * -method_scope_name(int scope) +method_visibility_name(rb_method_visibility_t visi) { - const char *v; - - switch (scope) { - default: - case NOEX_PUBLIC: v = ""; break; - case NOEX_PRIVATE: v = " private"; break; - case NOEX_PROTECTED: v = " protected"; break; + switch (visi) { + case METHOD_VISI_UNDEF: + case METHOD_VISI_PUBLIC: return ""; + case METHOD_VISI_PRIVATE: return " private"; + case METHOD_VISI_PROTECTED: return " protected"; } - return v; + rb_bug("method_visibility_name: unreachable (%d)", (int)visi); } void -rb_print_undef(VALUE klass, ID id, int scope) +rb_print_undef(VALUE klass, ID id, int visi) { - const char *v = method_scope_name(scope); + const char *v = method_visibility_name(visi); + rb_name_error(id, "undefined%s method `%"PRIsVALUE"' for %s `% "PRIsVALUE"'", v, QUOTE_ID(id), (RB_TYPE_P(klass, T_MODULE)) ? "module" : "class", @@ -242,9 +241,9 @@ rb_print_undef_str(VALUE klass, VALUE name) } void -rb_print_inaccessible(VALUE klass, ID id, int scope) +rb_print_inaccessible(VALUE klass, ID id, rb_method_visibility_t visi) { - const char *v = method_scope_name(scope); + const char *v = method_visibility_name(visi); rb_name_error(id, "method `%"PRIsVALUE"' for %s `% "PRIsVALUE"' is %s", QUOTE_ID(id), (RB_TYPE_P(klass, T_MODULE)) ? "module" : "class", diff --git a/eval_intern.h b/eval_intern.h index 0c04a1c6c3..e503d15d9d 100644 --- a/eval_intern.h +++ b/eval_intern.h @@ -228,16 +228,25 @@ CREF_NEXT_SET(rb_cref_t *cref, const rb_cref_t *next_cref) RB_OBJ_WRITE(cref, &cref->next, next_cref); } -static inline long -CREF_VISI(const rb_cref_t *cref) +typedef struct rb_scope_visi_struct { + rb_method_visibility_t method_visi : 3; + unsigned int module_func : 1; +} rb_scope_visibility_t; + +static inline const rb_scope_visibility_t * +CREF_SCOPE_VISI(const rb_cref_t *cref) { - return (long)cref->visi; + return (const rb_scope_visibility_t *)&cref->scope_visi; } static inline void -CREF_VISI_SET(rb_cref_t *cref, long v) +CREF_SCOPE_VISI_COPY(const rb_cref_t *dst_cref, rb_cref_t *src_cref) { - cref->visi = v; + rb_scope_visibility_t *src = (rb_scope_visibility_t *)&src_cref->scope_visi; + rb_scope_visibility_t *dst = (rb_scope_visibility_t *)&dst_cref->scope_visi; + + dst->method_visi = src->method_visi; + dst->module_func = src->module_func; } static inline VALUE @@ -282,7 +291,7 @@ CREF_OMOD_SHARED_UNSET(rb_cref_t *cref) cref->flags &= ~NODE_FL_CREF_OMOD_SHARED_; } -void rb_frame_visibility_set(rb_method_flag_t); +void rb_frame_visibility_set(rb_method_visibility_t); void rb_thread_cleanup(void); void rb_thread_wait_other_threads(void); @@ -308,7 +317,7 @@ NORETURN(void rb_fiber_start(void)); NORETURN(void rb_print_undef(VALUE, ID, int)); NORETURN(void rb_print_undef_str(VALUE, VALUE)); -NORETURN(void rb_print_inaccessible(VALUE, ID, int)); +NORETURN(void rb_print_inaccessible(VALUE, ID, rb_method_visibility_t)); NORETURN(void rb_vm_localjump_error(const char *,VALUE, int)); NORETURN(void rb_vm_jump_tag_but_local_jump(int)); NORETURN(void rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, @@ -917,7 +917,7 @@ defineclass vm_push_frame(th, class_iseq, VM_FRAME_MAGIC_CLASS, klass, 0, VM_ENVVAL_BLOCK_PTR(GET_BLOCK_PTR()), - (VALUE)vm_cref_push(th, klass, NOEX_PUBLIC, NULL), + (VALUE)vm_cref_push(th, klass, NULL), class_iseq->iseq_encoded, GET_SP(), class_iseq->local_size, class_iseq->stack_max); diff --git a/internal.h b/internal.h index d9cc93f9e6..06305f3b77 100644 --- a/internal.h +++ b/internal.h @@ -551,7 +551,7 @@ typedef struct rb_cref_struct { VALUE flags; const VALUE refinements; const VALUE klass; - VALUE visi; + VALUE scope_visi; struct rb_cref_struct * const next; } rb_cref_t; @@ -935,7 +935,7 @@ load_failed(VALUE fname) static VALUE load_ext(VALUE path) { - rb_frame_visibility_set(NOEX_PUBLIC); + rb_frame_visibility_set(METHOD_VISI_PUBLIC); return (VALUE)dln_load(RSTRING_PTR(path)); } @@ -21,27 +21,6 @@ # endif #endif -typedef enum { - NOEX_PUBLIC = 0x00, - NOEX_NOSUPER = 0x01, - NOEX_PRIVATE = 0x02, - NOEX_PROTECTED = 0x04, - NOEX_MASK = 0x06, - NOEX_BASIC = 0x08, - NOEX_UNDEF = NOEX_NOSUPER, - NOEX_MODFUNC = 0x12, - NOEX_SUPER = 0x20, - NOEX_VCALL = 0x40, - NOEX_RESPONDS = 0x80, - - NOEX_BIT_WIDTH = 8, - NOEX_SAFE_SHIFT_OFFSET = ((NOEX_BIT_WIDTH+3)/4)*4 /* round up to nibble */ -} rb_method_flag_t; - -#define NOEX_SAFE(n) ((int)((n) >> NOEX_SAFE_SHIFT_OFFSET) & 0x0F) -#define NOEX_WITH(n, s) (((s) << NOEX_SAFE_SHIFT_OFFSET) | (n) | (ruby_running ? 0 : NOEX_BASIC)) -#define NOEX_WITH_SAFE(n) NOEX_WITH((n), rb_safe_level()) - /* method data type */ typedef struct rb_method_entry_struct { @@ -53,6 +32,13 @@ typedef struct rb_method_entry_struct { } rb_method_entry_t; typedef enum { + METHOD_VISI_UNDEF = 0x00, + METHOD_VISI_PUBLIC = 0x01, + METHOD_VISI_PRIVATE = 0x02, + METHOD_VISI_PROTECTED = 0x03 +} rb_method_visibility_t; + +typedef enum { VM_METHOD_TYPE_ISEQ, VM_METHOD_TYPE_CFUNC, VM_METHOD_TYPE_ATTRSET, @@ -92,10 +78,12 @@ typedef struct rb_method_alias_struct { } rb_method_alias_t; typedef struct rb_method_definition_struct { - rb_method_flag_t flag; + struct { + rb_method_visibility_t visi: 3; + unsigned int basic: 1; + unsigned int safe: 3; + } flags; rb_method_type_t type; /* method type */ - int *alias_count_ptr; - ID original_id; union { rb_method_iseq_t iseq; @@ -111,6 +99,9 @@ typedef struct rb_method_definition_struct { } optimize_type; struct rb_method_entry_struct *orig_me; } body; + + int *alias_count_ptr; + ID original_id; } rb_method_definition_t; #define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF) @@ -118,9 +109,9 @@ typedef struct rb_method_definition_struct { ((def)->type == VM_METHOD_TYPE_REFINED && \ UNDEFINED_METHOD_ENTRY_P((def)->body.orig_me)) -void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex); -void rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_flag_t noex); -rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex); +void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi); +void rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi); +rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi); rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr); rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id); void rb_add_refined_method_entry(VALUE refined_class, ID mid); @@ -133,7 +124,7 @@ rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, VALUE *defined_class_ptr); rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr); -rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex); +rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex); int rb_method_entry_arity(const rb_method_entry_t *me); int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2); @@ -3012,7 +3012,7 @@ primary : literal /*%%%*/ NODE *body = remove_begin($5); reduce_nodes(&body); - $$ = NEW_DEFN($2, $4, body, NOEX_PRIVATE); + $$ = NEW_DEFN($2, $4, body, METHOD_VISI_PRIVATE); nd_set_line($$, $<num>1); /*% $$ = dispatch3(def, $2, $4, $5); @@ -1161,7 +1161,7 @@ mnew_missing(VALUE rclass, VALUE klass, VALUE obj, ID id, ID rid, VALUE mclass) data->id = rid; def = ZALLOC(rb_method_definition_t); - def->flag = 0; + def->flags.visi = METHOD_VISI_UNDEF; def->type = VM_METHOD_TYPE_MISSING; def->original_id = id; @@ -1182,7 +1182,7 @@ mnew_internal(const rb_method_entry_t *me, VALUE defined_class, VALUE klass, VALUE method; ID rid = id; rb_method_definition_t *def = 0; - rb_method_flag_t flag = NOEX_UNDEF; + rb_method_visibility_t visi = METHOD_VISI_UNDEF; again: if (UNDEFINED_METHOD_ENTRY_P(me)) { @@ -1193,11 +1193,11 @@ mnew_internal(const rb_method_entry_t *me, VALUE defined_class, VALUE klass, rb_print_undef(klass, id, 0); } def = me->def; - if (flag == NOEX_UNDEF) { - flag = def->flag; - if (scope && (flag & NOEX_MASK) != NOEX_PUBLIC) { + if (visi == METHOD_VISI_UNDEF) { + visi = def->flags.visi; + if (scope && (visi != METHOD_VISI_PUBLIC)) { if (!error) return Qnil; - rb_print_inaccessible(klass, id, flag & NOEX_MASK); + rb_print_inaccessible(klass, id, visi); } } if (def->type == VM_METHOD_TYPE_ZSUPER) { @@ -1658,11 +1658,12 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) { ID id; VALUE body; - rb_method_flag_t noex = NOEX_PUBLIC; const rb_cref_t *cref = rb_vm_cref_in_context(mod, mod); + const rb_scope_visibility_t default_scope_visi = {METHOD_VISI_PUBLIC, FALSE}; + const rb_scope_visibility_t *scope_visi = &default_scope_visi; if (cref) { - noex = (rb_method_flag_t)CREF_VISI(cref); + scope_visi = CREF_SCOPE_VISI(cref); } if (argc == 1) { @@ -1695,9 +1696,9 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) rb_class_name(rclass)); } } - rb_method_entry_set(mod, id, method->me, noex); - if (noex == NOEX_MODFUNC) { - rb_method_entry_set(rb_singleton_class(mod), id, method->me, NOEX_PUBLIC); + rb_method_entry_set(mod, id, method->me, scope_visi->method_visi); + if (scope_visi->module_func) { + rb_method_entry_set(rb_singleton_class(mod), id, method->me, METHOD_VISI_PUBLIC); } RB_GC_GUARD(body); } @@ -1712,9 +1713,9 @@ rb_mod_define_method(int argc, VALUE *argv, VALUE mod) proc->is_from_method = TRUE; proc->block.klass = mod; } - rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, noex); - if (noex == NOEX_MODFUNC) { - rb_add_method(rb_singleton_class(mod), id, VM_METHOD_TYPE_BMETHOD, (void *)body, NOEX_PUBLIC); + rb_add_method(mod, id, VM_METHOD_TYPE_BMETHOD, (void *)body, scope_visi->method_visi); + if (scope_visi->module_func) { + rb_add_method(rb_singleton_class(mod), id, VM_METHOD_TYPE_BMETHOD, (void *)body, METHOD_VISI_PUBLIC); } } else { @@ -177,7 +177,7 @@ define_aref_method(VALUE nstr, VALUE name, VALUE off) rb_control_frame_t *FUNC_FASTCALL(rb_vm_opt_struct_aref)(rb_thread_t *, rb_control_frame_t *); VALUE iseqval = rb_method_for_self_aref(name, off, rb_vm_opt_struct_aref); - rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, NOEX_PUBLIC); + rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, METHOD_VISI_PUBLIC); RB_GC_GUARD(iseqval); } @@ -187,7 +187,7 @@ define_aset_method(VALUE nstr, VALUE name, VALUE off) rb_control_frame_t *FUNC_FASTCALL(rb_vm_opt_struct_aset)(rb_thread_t *, rb_control_frame_t *); VALUE iseqval = rb_method_for_self_aset(name, off, rb_vm_opt_struct_aset); - rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, NOEX_PUBLIC); + rb_add_method_iseq(nstr, SYM2ID(name), iseqval, NULL, METHOD_VISI_PUBLIC); RB_GC_GUARD(iseqval); } @@ -89,10 +89,10 @@ vm_cref_new(VALUE klass, long visi, const rb_cref_t *prev_cref) static rb_cref_t * vm_cref_new_toplevel(rb_thread_t *th) { - rb_cref_t *cref = vm_cref_new(rb_cObject, NOEX_PRIVATE /* toplevel visibility is private */, NULL); + rb_cref_t *cref = vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE /* toplevel visibility is private */, NULL); if (th->top_wrapper) { - cref = vm_cref_new(th->top_wrapper, NOEX_PRIVATE, cref); + cref = vm_cref_new(th->top_wrapper, METHOD_VISI_PRIVATE, cref); } return cref; @@ -2285,7 +2285,8 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, rb_num_t is_singleton, rb_cref_t *cref) { VALUE klass = CREF_CLASS(cref); - rb_method_flag_t noex = (rb_method_flag_t)CREF_VISI(cref); + const rb_scope_visibility_t *scope_visi = CREF_SCOPE_VISI(cref); + rb_method_visibility_t visi = scope_visi->method_visi; rb_iseq_t *miseq; GetISeqPtr(iseqval, miseq); @@ -2300,17 +2301,17 @@ vm_define_method(rb_thread_t *th, VALUE obj, ID id, VALUE iseqval, if (is_singleton) { klass = rb_singleton_class(obj); /* class and frozen checked in this API */ - noex = NOEX_PUBLIC; + visi = METHOD_VISI_PUBLIC; } /* dup */ RB_OBJ_WRITE(miseq->self, &miseq->klass, klass); miseq->defined_method_id = id; - rb_add_method_iseq(klass, id, iseqval, cref, noex); + rb_add_method_iseq(klass, id, iseqval, cref, visi); - if (!is_singleton && noex == NOEX_MODFUNC) { + if (!is_singleton && scope_visi->module_func) { klass = rb_singleton_class(klass); - rb_add_method_iseq(klass, id, iseqval, cref, NOEX_PUBLIC); + rb_add_method_iseq(klass, id, iseqval, cref, METHOD_VISI_PUBLIC); } } @@ -2797,7 +2798,7 @@ Init_VM(void) th->cfp->self = th->top_self; th->cfp->klass = Qnil; - th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, NOEX_PRIVATE, NULL); + th->cfp->ep[-1] = (VALUE)vm_cref_new(rb_cObject, METHOD_VISI_PRIVATE, NULL); /* * The Binding of the top level scope @@ -167,7 +167,15 @@ typedef struct rb_call_info_struct { union { int opt_pc; /* used by iseq */ int index; /* used by ivar */ - int missing_reason; /* used by method_missing */ + enum missing_reason { + MISSING_NOENTRY = 0x00, + MISSING_PRIVATE = 0x01, + MISSING_PROTECTED = 0x02, + MISSING_VCALL = 0x04, + MISSING_SUPER = 0x08, + MISSING_MISSING = 0x10, + MISSING_NONE = 0x20 + } missing_reason; /* used by method_missing */ int inc_sp; /* used by cfunc */ } aux; @@ -15,7 +15,7 @@ struct local_var_list { VALUE tbl; }; -static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status); +static inline VALUE method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum missing_reason call_status); static inline VALUE vm_yield_with_cref(rb_thread_t *th, int argc, const VALUE *argv, const rb_cref_t *cref); static inline VALUE vm_yield(rb_thread_t *th, int argc, const VALUE *argv); static inline VALUE vm_yield_with_block(rb_thread_t *th, int argc, const VALUE *argv, const rb_block_t *blockargptr); @@ -208,7 +208,7 @@ vm_call0_body(rb_thread_t* th, rb_call_info_t *ci, const VALUE *argv) ci->defined_class = RCLASS_SUPER(ci->defined_class); if (!ci->defined_class || !(ci->me = rb_method_entry(ci->defined_class, ci->mid, &ci->defined_class))) { - int ex = type == VM_METHOD_TYPE_ZSUPER ? NOEX_SUPER : 0; + enum missing_reason ex = (type == VM_METHOD_TYPE_ZSUPER) ? MISSING_SUPER : 0; ret = method_missing(ci->recv, ci->mid, ci->argc, argv, ex); goto success; } @@ -285,7 +285,7 @@ vm_call_super(rb_thread_t *th, int argc, const VALUE *argv) id = rb_vm_frame_method_entry(cfp)->def->original_id; me = rb_method_entry(klass, id, &klass); if (!me) { - return method_missing(recv, id, argc, argv, NOEX_SUPER); + return method_missing(recv, id, argc, argv, MISSING_SUPER); } return vm_call0(th, recv, id, argc, argv, me, klass); @@ -321,8 +321,7 @@ stack_check(void) static inline rb_method_entry_t * rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr); -static inline int rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self); -#define NOEX_OK NOEX_NOSUPER +static inline enum missing_reason rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self); /*! * \internal @@ -347,9 +346,9 @@ rb_call0(VALUE recv, ID mid, int argc, const VALUE *argv, rb_method_entry_t *me = rb_search_method_entry(recv, mid, &defined_class); rb_thread_t *th = GET_THREAD(); - int call_status = rb_method_call_status(th, me, scope, self); + enum missing_reason call_status = rb_method_call_status(th, me, scope, self); - if (call_status != NOEX_OK) { + if (call_status != MISSING_NONE) { return method_missing(recv, mid, argc, argv, call_status); } stack_check(); @@ -391,7 +390,7 @@ check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid) VALUE defined_class; const rb_method_entry_t *me = rb_method_entry(klass, idRespond_to, &defined_class); - if (me && !(me->def->flag & NOEX_BASIC)) { + if (me && !me->def->flags.basic) { const rb_block_t *passed_block = th->passed_block; VALUE args[2], result; int arity = rb_method_entry_arity(me); @@ -415,7 +414,7 @@ check_funcall_respond_to(rb_thread_t *th, VALUE klass, VALUE recv, ID mid) static int check_funcall_callable(rb_thread_t *th, const rb_method_entry_t *me) { - return rb_method_call_status(th, me, CALL_FCALL, th->cfp->self) == NOEX_OK; + return rb_method_call_status(th, me, CALL_FCALL, th->cfp->self) == MISSING_NONE; } static VALUE @@ -450,7 +449,7 @@ rb_check_funcall(VALUE recv, ID mid, int argc, const VALUE *argv) return Qundef; me = rb_search_method_entry(recv, mid, &defined_class); - if (check_funcall_callable(th, me) != NOEX_OK) { + if (!check_funcall_callable(th, me)) { return check_funcall_missing(th, klass, recv, mid, argc, argv); } stack_check(); @@ -470,7 +469,7 @@ rb_check_funcall_with_hook(VALUE recv, ID mid, int argc, const VALUE *argv, return Qundef; me = rb_search_method_entry(recv, mid, &defined_class); - if (check_funcall_callable(th, me) != NOEX_OK) { + if (!check_funcall_callable(th, me)) { (*hook)(FALSE, recv, mid, argc, argv, arg); return check_funcall_missing(th, klass, recv, mid, argc, argv); } @@ -557,16 +556,16 @@ rb_search_method_entry(VALUE recv, ID mid, VALUE *defined_class_ptr) return rb_method_entry(klass, mid, defined_class_ptr); } -static inline int +static inline enum missing_reason rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type scope, VALUE self) { VALUE klass; ID oid; - int noex; + rb_method_visibility_t visi; if (UNDEFINED_METHOD_ENTRY_P(me)) { undefined: - return scope == CALL_VCALL ? NOEX_VCALL : 0; + return scope == CALL_VCALL ? MISSING_VCALL : MISSING_NOENTRY; } if (me->def->type == VM_METHOD_TYPE_REFINED) { me = rb_resolve_refined_method(Qnil, me, NULL); @@ -574,17 +573,17 @@ rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type sc } klass = me->klass; oid = me->def->original_id; - noex = me->def->flag; + visi = me->def->flags.visi; if (oid != idMethodMissing) { /* receiver specified form for private method */ - if (UNLIKELY(noex)) { - if (((noex & NOEX_MASK) & NOEX_PRIVATE) && scope == CALL_PUBLIC) { - return NOEX_PRIVATE; + if (UNLIKELY(visi != METHOD_VISI_PUBLIC)) { + if (visi == METHOD_VISI_PRIVATE && scope == CALL_PUBLIC) { + return MISSING_PRIVATE; } /* self must be kind of a specified form for protected method */ - if (((noex & NOEX_MASK) & NOEX_PROTECTED) && scope == CALL_PUBLIC) { + if (visi == METHOD_VISI_PROTECTED && scope == CALL_PUBLIC) { VALUE defined_class = klass; if (RB_TYPE_P(defined_class, T_ICLASS)) { @@ -592,17 +591,17 @@ rb_method_call_status(rb_thread_t *th, const rb_method_entry_t *me, call_type sc } if (self == Qundef || !rb_obj_is_kind_of(self, defined_class)) { - return NOEX_PROTECTED; + return MISSING_PROTECTED; } } - if (NOEX_SAFE(noex) > th->safe_level) { - rb_raise(rb_eSecurityError, "calling insecure method: %"PRIsVALUE, - rb_id2str(me->called_id)); + if (me->def->flags.safe > th->safe_level) { + rb_raise(rb_eSecurityError, "calling insecure method: %"PRIsVALUE, rb_id2str(me->called_id)); } } } - return NOEX_OK; + + return MISSING_NONE; } @@ -625,7 +624,7 @@ rb_call(VALUE recv, ID mid, int argc, const VALUE *argv, call_type scope) } NORETURN(static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, - VALUE obj, int call_status)); + VALUE obj, enum missing_reason call_status)); /* * call-seq: @@ -668,8 +667,6 @@ rb_method_missing(int argc, const VALUE *argv, VALUE obj) UNREACHABLE; } -#define NOEX_MISSING 0x80 - static VALUE make_no_method_exception(VALUE exc, const char *format, VALUE obj, int argc, const VALUE *argv) { @@ -696,7 +693,7 @@ make_no_method_exception(VALUE exc, const char *format, VALUE obj, int argc, con static void raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, - int last_call_status) + enum missing_reason last_call_status) { VALUE exc = rb_eNoMethodError; const char *format = 0; @@ -707,23 +704,23 @@ raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, stack_check(); - if (last_call_status & NOEX_PRIVATE) { + if (last_call_status & MISSING_PRIVATE) { format = "private method `%s' called for %s"; } - else if (last_call_status & NOEX_PROTECTED) { + else if (last_call_status & MISSING_PROTECTED) { format = "protected method `%s' called for %s"; } - else if (last_call_status & NOEX_VCALL) { + else if (last_call_status & MISSING_VCALL) { format = "undefined local variable or method `%s' for %s"; exc = rb_eNameError; } - else if (last_call_status & NOEX_SUPER) { + else if (last_call_status & MISSING_SUPER) { format = "super: no superclass method `%s' for %s"; } { exc = make_no_method_exception(exc, format, obj, argc, argv); - if (!(last_call_status & NOEX_MISSING)) { + if (!(last_call_status & MISSING_MISSING)) { rb_vm_pop_cfunc_frame(); } rb_exc_raise(exc); @@ -731,7 +728,7 @@ raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, } static inline VALUE -method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status) +method_missing(VALUE obj, ID id, int argc, const VALUE *argv, enum missing_reason call_status) { VALUE *nargv, result, work; rb_thread_t *th = GET_THREAD(); @@ -741,7 +738,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status) th->passed_block = 0; if (id == idMethodMissing) { - raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING); + raise_method_missing(th, argc, argv, obj, call_status | MISSING_MISSING); } nargv = ALLOCV_N(VALUE, work, argc + 1); @@ -749,7 +746,7 @@ method_missing(VALUE obj, ID id, int argc, const VALUE *argv, int call_status) MEMCPY(nargv + 1, argv, VALUE, argc); if (rb_method_basic_definition_p(CLASS_OF(obj) , idMethodMissing)) { - raise_method_missing(th, argc+1, nargv, obj, call_status | NOEX_MISSING); + raise_method_missing(th, argc+1, nargv, obj, call_status | MISSING_MISSING); } th->passed_block = blockptr; result = rb_funcall2(obj, idMethodMissing, argc + 1, nargv); @@ -762,7 +759,7 @@ rb_raise_method_missing(rb_thread_t *th, int argc, const VALUE *argv, VALUE obj, int call_status) { th->passed_block = 0; - raise_method_missing(th, argc, argv, obj, call_status | NOEX_MISSING); + raise_method_missing(th, argc, argv, obj, call_status | MISSING_MISSING); } /*! @@ -1310,7 +1307,7 @@ eval_string_with_cref(VALUE self, VALUE src, VALUE scope, rb_cref_t *const cref_ if (!cref && base_block->iseq) { if (NIL_P(scope)) { orig_cref = rb_vm_get_cref(base_block->ep); - cref = vm_cref_new(Qnil, 0, NULL); + cref = vm_cref_new(Qnil, METHOD_VISI_PUBLIC, NULL); crefval = (VALUE) cref; COPY_CREF(cref, orig_cref); } @@ -1568,7 +1565,7 @@ yield_under(VALUE under, VALUE self, VALUE values) block.self = self; VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block); } - cref = vm_cref_push(th, under, NOEX_PUBLIC, blockptr); + cref = vm_cref_push(th, under, blockptr); CREF_PUSHED_BY_EVAL_SET(cref); if (values == Qundef) { @@ -1591,7 +1588,7 @@ rb_yield_refine_block(VALUE refinement, VALUE refinements) block.self = refinement; VM_CF_LEP(th->cfp)[0] = VM_ENVVAL_BLOCK_PTR(&block); } - cref = vm_cref_push(th, refinement, NOEX_PUBLIC, blockptr); + cref = vm_cref_push(th, refinement, blockptr); CREF_PUSHED_BY_EVAL_SET(cref); CREF_REFINEMENTS_SET(cref, refinements); @@ -1602,7 +1599,7 @@ rb_yield_refine_block(VALUE refinement, VALUE refinements) static VALUE eval_under(VALUE under, VALUE self, VALUE src, VALUE file, int line) { - rb_cref_t *cref = vm_cref_push(GET_THREAD(), under, NOEX_PUBLIC, NULL); + rb_cref_t *cref = vm_cref_push(GET_THREAD(), under, NULL); if (SPECIAL_CONST_P(self) && !NIL_P(under)) { CREF_PUSHED_BY_EVAL_SET(cref); @@ -2162,9 +2159,9 @@ Init_vm_eval(void) #if 1 rb_add_method(rb_cBasicObject, rb_intern("__send__"), - VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0); + VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC); rb_add_method(rb_mKernel, rb_intern("send"), - VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, 0); + VM_METHOD_TYPE_OPTIMIZED, (void *)OPTIMIZED_METHOD_TYPE_SEND, METHOD_VISI_PUBLIC); #else rb_define_method(rb_cBasicObject, "__send__", rb_f_send, -1); rb_define_method(rb_mKernel, "send", rb_f_send, -1); diff --git a/vm_insnhelper.c b/vm_insnhelper.c index 64a23b7d80..87c9e5f739 100644 --- a/vm_insnhelper.c +++ b/vm_insnhelper.c @@ -487,7 +487,7 @@ rb_vm_rewrite_cref_stack(rb_cref_t *node, VALUE old_klass, VALUE new_klass, rb_c } static rb_cref_t * -vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr) +vm_cref_push(rb_thread_t *th, VALUE klass, rb_block_t *blockptr) { const rb_cref_t *prev_cref = NULL; rb_cref_t *cref = NULL; @@ -502,7 +502,7 @@ vm_cref_push(rb_thread_t *th, VALUE klass, int noex, rb_block_t *blockptr) prev_cref = vm_env_cref(cfp->ep); } } - cref = vm_cref_new(klass, noex, prev_cref); + cref = vm_cref_new(klass, METHOD_VISI_PUBLIC, prev_cref); /* TODO: why CREF_NEXT(cref) is 1? */ if (CREF_NEXT(cref) && CREF_NEXT(cref) != (void *) 1 && @@ -1315,7 +1315,7 @@ vm_callee_setup_arg(rb_thread_t *th, rb_call_info_t *ci, const rb_iseq_t *iseq, CI_SET_FASTPATH(ci, (UNLIKELY(ci->flag & VM_CALL_TAILCALL) ? vm_call_iseq_setup_tailcall : vm_call_iseq_setup_normal), - (!IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) && !(ci->me->def->flag & NOEX_PROTECTED))); + (!IS_ARGS_SPLAT(ci) && !IS_ARGS_KEYWORD(ci) && !(ci->me->def->flags.visi == METHOD_VISI_PROTECTED))); } else { ci->aux.opt_pc = setup_parameters_complex(th, iseq, ci, argv, arg_setup_method); @@ -1659,7 +1659,7 @@ vm_call_cfunc(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_info_t *ci) RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, me->klass, me->called_id); EXEC_EVENT_HOOK(th, RUBY_EVENT_C_CALL, recv, me->called_id, me->klass, Qnil); - if (!(ci->me->def->flag & NOEX_PROTECTED) && + if (!(ci->me->def->flag & METHOD_VISI_PROTECTED) && !(ci->flag & VM_CALL_ARGS_SPLAT) && !(ci->kw_arg != NULL)) { CI_SET_FASTPATH(ci, vm_call_cfunc_latter, 1); @@ -1740,16 +1740,12 @@ vm_call_bmethod(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci) return vm_call_bmethod_body(th, ci, argv); } -static int +static enum missing_reason ci_missing_reason(const rb_call_info_t *ci) { - int stat = 0; - if (ci->flag & VM_CALL_VCALL) { - stat |= NOEX_VCALL; - } - if (ci->flag & VM_CALL_SUPER) { - stat |= NOEX_SUPER; - } + enum missing_reason stat = MISSING_NOENTRY; + if (ci->flag & VM_CALL_VCALL) stat |= MISSING_VCALL; + if (ci->flag & VM_CALL_SUPER) stat |= MISSING_SUPER; return stat; } @@ -1915,7 +1911,7 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci) start_method_dispatch: if (ci->me != 0) { - if ((ci->me->def->flag == 0)) { + if (ci->me->def->flags.visi == METHOD_VISI_PUBLIC && ci->me->def->flags.safe == 0) { VALUE klass; normal_method_dispatch: @@ -2042,28 +2038,27 @@ vm_call_method(rb_thread_t *th, rb_control_frame_t *cfp, rb_call_info_t *ci) rb_bug("vm_call_method: unsupported method type (%d)", ci->me->def->type); } else { - int noex_safe; - if (!(ci->flag & VM_CALL_FCALL) && (ci->me->def->flag & NOEX_MASK) & NOEX_PRIVATE) { - int stat = NOEX_PRIVATE; + int safe; + if (!(ci->flag & VM_CALL_FCALL) && (ci->me->def->flags.visi == METHOD_VISI_PRIVATE)) { + enum missing_reason stat = MISSING_PRIVATE; + bp(); + if (ci->flag & VM_CALL_VCALL) stat |= MISSING_VCALL; - if (ci->flag & VM_CALL_VCALL) { - stat |= NOEX_VCALL; - } ci->aux.missing_reason = stat; CI_SET_FASTPATH(ci, vm_call_method_missing, 1); return vm_call_method_missing(th, cfp, ci); } - else if (!(ci->flag & VM_CALL_OPT_SEND) && (ci->me->def->flag & NOEX_MASK) & NOEX_PROTECTED) { + else if (!(ci->flag & VM_CALL_OPT_SEND) && (ci->me->def->flags.visi == METHOD_VISI_PROTECTED)) { enable_fastpath = 0; if (!rb_obj_is_kind_of(cfp->self, ci->defined_class)) { - ci->aux.missing_reason = NOEX_PROTECTED; + ci->aux.missing_reason = MISSING_PROTECTED; return vm_call_method_missing(th, cfp, ci); } else { goto normal_method_dispatch; } } - else if ((noex_safe = NOEX_SAFE(ci->me->def->flag)) > th->safe_level && (noex_safe > 2)) { + else if ((safe = ci->me->def->flags.safe) > th->safe_level && safe > 2) { rb_raise(rb_eSecurityError, "calling insecure method: %"PRIsVALUE, rb_id2str(ci->mid)); } else { @@ -2216,7 +2211,7 @@ vm_search_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_call_inf } if (!ci->klass) { /* bound instance method of module */ - ci->aux.missing_reason = NOEX_SUPER; + ci->aux.missing_reason = MISSING_SUPER; CI_SET_FASTPATH(ci, vm_call_method_missing, 1); return; } @@ -2475,9 +2470,19 @@ vm_defined(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE if (me) { const rb_method_definition_t *def = me->def; - if (!(def->flag & NOEX_PRIVATE) && - !((def->flag & NOEX_PROTECTED) && !rb_obj_is_kind_of(GET_SELF(), rb_class_real(klass)))) { + + switch ((unsigned int)def->flags.visi) { + case METHOD_VISI_PRIVATE: + break; + case METHOD_VISI_PROTECTED: + if (!rb_obj_is_kind_of(GET_SELF(), rb_class_real(klass))) { + break; + } + case METHOD_VISI_PUBLIC: expr_type = DEFINED_METHOD; + break; + default: + rb_bug("unreachable"); } } else { diff --git a/vm_insnhelper.h b/vm_insnhelper.h index e8d9b8a88d..b5266dc619 100644 --- a/vm_insnhelper.h +++ b/vm_insnhelper.h @@ -157,7 +157,7 @@ enum vm_regan_acttype { rb_cref_t *__tmp_c2 = (c2); \ COPY_CREF_OMOD((c1), __tmp_c2); \ CREF_CLASS_SET((c1), CREF_CLASS(__tmp_c2));\ - CREF_VISI_SET((c1), CREF_VISI(__tmp_c2));\ + CREF_SCOPE_VISI_COPY((c1), __tmp_c2);\ CREF_NEXT_SET((c1), CREF_NEXT(__tmp_c2));\ if (CREF_PUSHED_BY_EVAL(__tmp_c2)) { \ CREF_PUSHED_BY_EVAL_SET(c1); \ diff --git a/vm_method.c b/vm_method.c index 8afc39901e..fcc033bc3f 100644 --- a/vm_method.c +++ b/vm_method.c @@ -110,23 +110,23 @@ rb_f_notimplement(int argc, const VALUE *argv, VALUE obj) } static void -rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_flag_t noex) +rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_visibility_t visi) { - rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, (void *)1, noex); + rb_add_method(mod, id, VM_METHOD_TYPE_NOTIMPLEMENTED, (void *)1, visi); } void -rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex) +rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi) { if (argc < -2 || 15 < argc) rb_raise(rb_eArgError, "arity out of range: %d for -2..15", argc); if (func != rb_f_notimplement) { rb_method_cfunc_t opt; opt.func = func; opt.argc = argc; - rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, noex); + rb_add_method(klass, mid, VM_METHOD_TYPE_CFUNC, &opt, visi); } else { - rb_define_notimplement_method_id(klass, mid, noex); + rb_define_notimplement_method_id(klass, mid, visi); } } @@ -293,11 +293,13 @@ rb_method_definition_set(rb_method_definition_t *def, void *opts) } static rb_method_definition_t * -rb_method_definition_create(rb_method_flag_t flag, rb_method_type_t type, ID mid, void *opts) +rb_method_definition_create(rb_method_visibility_t visi, rb_method_type_t type, ID mid, void *opts) { rb_method_definition_t *def = ZALLOC(rb_method_definition_t); /* def->alias_count_ptr = NULL; already cleared */ - def->flag = flag; + def->flags.visi = visi; + def->flags.basic = ruby_running ? FALSE : TRUE; + def->flags.safe = rb_safe_level(); def->type = type; def->original_id = mid; if (opts != NULL) rb_method_definition_set(def, opts); @@ -335,7 +337,10 @@ static rb_method_definition_t * rb_method_definition_clone(rb_method_definition_t *src_def) { int *iptr = src_def->alias_count_ptr; - rb_method_definition_t *def = rb_method_definition_create(src_def->flag, src_def->type, src_def->original_id, NULL); + rb_method_definition_t *def = rb_method_definition_create(src_def->flags.visi, src_def->type, src_def->original_id, NULL); + + def->flags.basic = src_def->flags.basic; + def->flags.safe = src_def->flags.safe; memcpy(&def->body, &src_def->body, sizeof(def->body)); def->alias_count_ptr = src_def->alias_count_ptr; @@ -383,7 +388,7 @@ make_method_entry_refined(rb_method_entry_t *me) rb_vm_check_redefinition_opt_method(me, me->klass); - new_def = rb_method_definition_create(NOEX_WITH_SAFE(NOEX_PUBLIC), VM_METHOD_TYPE_REFINED, me->called_id, rb_method_entry_clone(me)); + new_def = rb_method_definition_create(METHOD_VISI_PUBLIC, VM_METHOD_TYPE_REFINED, me->called_id, rb_method_entry_clone(me)); rb_method_definition_reset(me, new_def); } @@ -397,12 +402,12 @@ rb_add_refined_method_entry(VALUE refined_class, ID mid) rb_clear_method_cache_by_class(refined_class); } else { - rb_add_method(refined_class, mid, VM_METHOD_TYPE_REFINED, 0, NOEX_PUBLIC); + rb_add_method(refined_class, mid, VM_METHOD_TYPE_REFINED, 0, METHOD_VISI_PUBLIC); } } static rb_method_entry_t * -rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_definition_t *def, rb_method_flag_t noex, VALUE defined_class) +rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_definition_t *def, rb_method_visibility_t visi, VALUE defined_class) { rb_method_entry_t *me; #if NOEX_NOREDEF @@ -424,7 +429,7 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_defin case idInitialize_clone: case idInitialize_dup: case idRespond_to_missing: - noex |= NOEX_PRIVATE; + visi = METHOD_VISI_PRIVATE; } } @@ -492,7 +497,8 @@ rb_method_entry_make(VALUE klass, ID mid, rb_method_type_t type, rb_method_defin } me = rb_method_entry_create(mid, defined_class, def); - def->flag = NOEX_WITH_SAFE(noex);; + def->flags.visi = visi; + def->flags.safe = rb_safe_level(); /* TODO: maybe we need to remove it. */ rb_clear_method_cache_by_class(klass); @@ -537,10 +543,10 @@ method_added(VALUE klass, ID mid) } rb_method_entry_t * -rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_flag_t noex) +rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi) { - rb_method_definition_t *def = rb_method_definition_create(noex, type, mid, opts); - rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, def, noex, klass); + rb_method_definition_t *def = rb_method_definition_create(visi, type, mid, opts); + rb_method_entry_t *me = rb_method_entry_make(klass, mid, type, def, visi, klass); if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.orig_me) { /* TODO: really needed? */ rb_method_definition_reset(me->def->body.orig_me, def); @@ -553,29 +559,31 @@ rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_ } void -rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_flag_t noex) +rb_add_method_iseq(VALUE klass, ID mid, VALUE iseqval, rb_cref_t *cref, rb_method_visibility_t visi) { rb_iseq_t *iseq; GetISeqPtr(iseqval, iseq); { rb_method_iseq_t iseq_body = {iseq, cref}; - rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, noex); + rb_add_method(klass, mid, VM_METHOD_TYPE_ISEQ, &iseq_body, visi); } } static rb_method_entry_t * method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, - rb_method_flag_t noex, VALUE defined_class) + rb_method_visibility_t visi, VALUE defined_class) { - rb_method_entry_t *newme = rb_method_entry_make(klass, mid, me->def->type, rb_method_definition_clone(me->def), noex, defined_class); + rb_method_definition_t *def = rb_method_definition_clone(me->def); + rb_method_entry_t *newme = rb_method_entry_make(klass, mid, me->def->type, def, visi, defined_class); + def->flags.safe = me->def->flags.safe; method_added(klass, mid); return newme; } rb_method_entry_t * -rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_flag_t noex) +rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_visibility_t visi) { - return method_entry_set(klass, mid, me, noex, klass); + return method_entry_set(klass, mid, me, visi, klass); } #define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1) @@ -864,7 +872,7 @@ rb_mod_remove_method(int argc, VALUE *argv, VALUE mod) } static void -rb_export_method(VALUE klass, ID name, rb_method_flag_t noex) +rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi) { rb_method_entry_t *me; VALUE defined_class; @@ -879,23 +887,26 @@ rb_export_method(VALUE klass, ID name, rb_method_flag_t noex) rb_print_undef(klass, name, 0); } - if (me->def->flag != noex) { + if (me->def->flags.visi != visi) { rb_vm_check_redefinition_opt_method(me, klass); if (klass == defined_class || RCLASS_ORIGIN(klass) == defined_class) { - me->def->flag = noex; + me->def->flags.visi = visi; if (me->def->type == VM_METHOD_TYPE_REFINED && me->def->body.orig_me) { - me->def->body.orig_me->def->flag = noex; + me->def->body.orig_me->def->flags.visi = visi; } rb_clear_method_cache_by_class(klass); } else { - rb_add_method(klass, name, VM_METHOD_TYPE_ZSUPER, 0, noex); + rb_add_method(klass, name, VM_METHOD_TYPE_ZSUPER, 0, visi); } } } +#define BOUND_PRIVATE 0x01 +#define BOUND_RESPONDS 0x02 + int rb_method_boundp(VALUE klass, ID id, int ex) { @@ -905,14 +916,14 @@ rb_method_boundp(VALUE klass, ID id, int ex) if (me != 0) { rb_method_definition_t *def = me->def; - if ((ex & ~NOEX_RESPONDS) && - ((def->flag & NOEX_PRIVATE) || - ((ex & NOEX_RESPONDS) && (def->flag & NOEX_PROTECTED)))) { + if ((ex & ~BOUND_RESPONDS) && + ((def->flags.visi == METHOD_VISI_PRIVATE) || + ((ex & BOUND_RESPONDS) && (def->flags.visi == METHOD_VISI_PROTECTED)))) { return 0; } if (def->type == VM_METHOD_TYPE_NOTIMPLEMENTED) { - if (ex & NOEX_RESPONDS) return 2; + if (ex & BOUND_RESPONDS) return 2; return 0; } return 1; @@ -923,29 +934,39 @@ rb_method_boundp(VALUE klass, ID id, int ex) extern ID rb_check_attr_id(ID id); static int -rb_frame_visibility_test(rb_method_flag_t flag) +rb_frame_visibility_test(rb_method_visibility_t visi) { rb_thread_t *th = GET_THREAD(); rb_control_frame_t *cfp = rb_vm_get_ruby_level_next_cfp(th, th->cfp); if (!vm_env_cref_by_cref(cfp->ep)) { - return NOEX_PUBLIC & flag; + return METHOD_VISI_PUBLIC == visi; } else { - return CREF_VISI(rb_vm_cref()) & flag; + return CREF_SCOPE_VISI(rb_vm_cref())->method_visi == visi; } } static int -rb_frame_visibility_check(rb_method_flag_t flag) +rb_frame_module_func_check(void) { - return CREF_VISI(rb_vm_cref()) == (long)flag; + return CREF_SCOPE_VISI(rb_vm_cref())->module_func; } void -rb_frame_visibility_set(rb_method_flag_t flag) +rb_frame_visibility_set(rb_method_visibility_t visi) { - CREF_VISI_SET(rb_vm_cref(), flag); + rb_scope_visibility_t *scope_visi = (rb_scope_visibility_t *)&rb_vm_cref()->scope_visi; + scope_visi->method_visi = visi; + scope_visi->module_func = FALSE; +} + +void +rb_frame_module_func_set(void) +{ + rb_scope_visibility_t *scope_visi = (rb_scope_visibility_t *)&rb_vm_cref()->scope_visi; + scope_visi->method_visi = METHOD_VISI_PRIVATE; + scope_visi->module_func = TRUE; } void @@ -953,23 +974,23 @@ rb_attr(VALUE klass, ID id, int read, int write, int ex) { VALUE attriv; VALUE aname; - rb_method_flag_t noex; + rb_method_visibility_t visi; if (!ex) { - noex = NOEX_PUBLIC; + visi = METHOD_VISI_PUBLIC; } else { - if (rb_frame_visibility_test(NOEX_PRIVATE)) { - noex = NOEX_PRIVATE; - if (rb_frame_visibility_check(NOEX_MODFUNC)) { + if (rb_frame_visibility_test(METHOD_VISI_PRIVATE)) { + visi = METHOD_VISI_PRIVATE; + if (rb_frame_module_func_check()) { rb_warning("attribute accessor as module_function"); } } - else if (rb_frame_visibility_test(NOEX_PROTECTED)) { - noex = NOEX_PROTECTED; + else if (rb_frame_visibility_test(METHOD_VISI_PROTECTED)) { + visi = METHOD_VISI_PROTECTED; } else { - noex = NOEX_PUBLIC; + visi = METHOD_VISI_PUBLIC; } } @@ -979,10 +1000,10 @@ rb_attr(VALUE klass, ID id, int read, int write, int ex) } attriv = (VALUE)rb_intern_str(rb_sprintf("@%"PRIsVALUE, aname)); if (read) { - rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, noex); + rb_add_method(klass, id, VM_METHOD_TYPE_IVAR, (void *)attriv, visi); } if (write) { - rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, noex); + rb_add_method(klass, rb_id_attrset(id), VM_METHOD_TYPE_ATTRSET, (void *)attriv, visi); } } @@ -1021,7 +1042,7 @@ rb_undef(VALUE klass, ID id) QUOTE_ID(id), s0, rb_class_name(c)); } - rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, NOEX_PUBLIC); + rb_add_method(klass, id, VM_METHOD_TYPE_UNDEF, 0, METHOD_VISI_PUBLIC); CALL_METHOD_HOOK(klass, undefined, id); } @@ -1125,17 +1146,15 @@ rb_mod_method_defined(VALUE mod, VALUE mid) } -#define VISI_CHECK(x,f) (((x)&NOEX_MASK) == (f)) - static VALUE -check_definition(VALUE mod, VALUE mid, rb_method_flag_t noex) +check_definition(VALUE mod, VALUE mid, rb_method_visibility_t visi) { const rb_method_entry_t *me; ID id = rb_check_id(&mid); if (!id) return Qfalse; me = rb_method_entry_without_refinements(mod, id, 0); if (me) { - if (VISI_CHECK(me->def->flag, noex)) return Qtrue; + if (me->def->flags.visi == visi) return Qtrue; } return Qfalse; } @@ -1171,7 +1190,7 @@ check_definition(VALUE mod, VALUE mid, rb_method_flag_t noex) static VALUE rb_mod_public_method_defined(VALUE mod, VALUE mid) { - return check_definition(mod, mid, NOEX_PUBLIC); + return check_definition(mod, mid, METHOD_VISI_PUBLIC); } /* @@ -1205,7 +1224,7 @@ rb_mod_public_method_defined(VALUE mod, VALUE mid) static VALUE rb_mod_private_method_defined(VALUE mod, VALUE mid) { - return check_definition(mod, mid, NOEX_PRIVATE); + return check_definition(mod, mid, METHOD_VISI_PRIVATE); } /* @@ -1239,7 +1258,7 @@ rb_mod_private_method_defined(VALUE mod, VALUE mid) static VALUE rb_mod_protected_method_defined(VALUE mod, VALUE mid) { - return check_definition(mod, mid, NOEX_PROTECTED); + return check_definition(mod, mid, METHOD_VISI_PROTECTED); } int @@ -1353,7 +1372,7 @@ rb_alias(VALUE klass, ID alias_name, ID original_name) const VALUE target_klass = klass; VALUE defined_class; rb_method_entry_t *orig_me; - rb_method_flag_t flag = NOEX_UNDEF; + rb_method_visibility_t visi = METHOD_VISI_UNDEF; if (NIL_P(klass)) { rb_raise(rb_eTypeError, "no class to make alias"); @@ -1379,11 +1398,11 @@ rb_alias(VALUE klass, ID alias_name, ID original_name) if (orig_me->def->type == VM_METHOD_TYPE_ZSUPER) { klass = RCLASS_SUPER(klass); original_name = orig_me->def->original_id; - flag = orig_me->def->flag; + visi = orig_me->def->flags.visi; goto again; } - if (flag == NOEX_UNDEF) flag = orig_me->def->flag; + if (visi == METHOD_VISI_UNDEF) visi = orig_me->def->flags.visi; if (defined_class != target_klass) { /* inter class/module alias */ VALUE real_owner; @@ -1397,13 +1416,14 @@ rb_alias(VALUE klass, ID alias_name, ID original_name) } /* make mthod entry */ - alias_me = rb_add_method(target_klass, alias_name, VM_METHOD_TYPE_ALIAS, rb_method_entry_clone(orig_me), flag); + alias_me = rb_add_method(target_klass, alias_name, VM_METHOD_TYPE_ALIAS, rb_method_entry_clone(orig_me), visi); RB_OBJ_WRITE(alias_me, &alias_me->klass, defined_class); alias_me->def->original_id = orig_me->called_id; *(ID *)&alias_me->def->body.alias.original_me->called_id = alias_name; + alias_me->def->flags.safe = orig_me->def->flags.safe; } else { - method_entry_set(target_klass, alias_name, orig_me, flag, defined_class); + method_entry_set(target_klass, alias_name, orig_me, visi, defined_class); } } @@ -1441,7 +1461,7 @@ rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname) } static void -set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_flag_t ex) +set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi) { int i; @@ -1457,18 +1477,18 @@ set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_flag_t if (!id) { rb_print_undef_str(self, v); } - rb_export_method(self, id, ex); + rb_export_method(self, id, visi); } } static VALUE -set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_flag_t ex) +set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi) { if (argc == 0) { - rb_frame_visibility_set(ex); + rb_frame_visibility_set(visi); } else { - set_method_visibility(module, argc, argv, ex); + set_method_visibility(module, argc, argv, visi); } return module; } @@ -1488,7 +1508,7 @@ set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_flag_t ex) static VALUE rb_mod_public(int argc, VALUE *argv, VALUE module) { - return set_visibility(argc, argv, module, NOEX_PUBLIC); + return set_visibility(argc, argv, module, METHOD_VISI_PUBLIC); } /* @@ -1506,7 +1526,7 @@ rb_mod_public(int argc, VALUE *argv, VALUE module) static VALUE rb_mod_protected(int argc, VALUE *argv, VALUE module) { - return set_visibility(argc, argv, module, NOEX_PROTECTED); + return set_visibility(argc, argv, module, METHOD_VISI_PROTECTED); } /* @@ -1533,7 +1553,7 @@ rb_mod_protected(int argc, VALUE *argv, VALUE module) static VALUE rb_mod_private(int argc, VALUE *argv, VALUE module) { - return set_visibility(argc, argv, module, NOEX_PRIVATE); + return set_visibility(argc, argv, module, METHOD_VISI_PRIVATE); } /* @@ -1549,7 +1569,7 @@ rb_mod_private(int argc, VALUE *argv, VALUE module) static VALUE rb_mod_public_method(int argc, VALUE *argv, VALUE obj) { - set_method_visibility(rb_singleton_class(obj), argc, argv, NOEX_PUBLIC); + set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PUBLIC); return obj; } @@ -1575,7 +1595,7 @@ rb_mod_public_method(int argc, VALUE *argv, VALUE obj) static VALUE rb_mod_private_method(int argc, VALUE *argv, VALUE obj) { - set_method_visibility(rb_singleton_class(obj), argc, argv, NOEX_PRIVATE); + set_method_visibility(rb_singleton_class(obj), argc, argv, METHOD_VISI_PRIVATE); return obj; } @@ -1666,11 +1686,11 @@ rb_mod_modfunc(int argc, VALUE *argv, VALUE module) } if (argc == 0) { - rb_frame_visibility_set(NOEX_MODFUNC); + rb_frame_module_func_set(); return module; } - set_method_visibility(module, argc, argv, NOEX_PRIVATE); + set_method_visibility(module, argc, argv, METHOD_VISI_PRIVATE); for (i = 0; i < argc; i++) { VALUE m = module; @@ -1691,7 +1711,7 @@ rb_mod_modfunc(int argc, VALUE *argv, VALUE module) if (!m) break; } - rb_method_entry_set(rb_singleton_class(module), id, me, NOEX_PUBLIC); + rb_method_entry_set(rb_singleton_class(module), id, me, METHOD_VISI_PUBLIC); } return module; } @@ -1700,8 +1720,7 @@ int rb_method_basic_definition_p(VALUE klass, ID id) { const rb_method_entry_t *me = rb_method_entry(klass, id, 0); - if (me && (me->def->flag & NOEX_BASIC)) return 1; - return 0; + return (me && me->def->flags.basic) ? TRUE : FALSE; } static inline int @@ -1710,7 +1729,7 @@ basic_obj_respond_to(VALUE obj, ID id, int pub) VALUE klass = CLASS_OF(obj); VALUE args[2]; - switch (rb_method_boundp(klass, id, pub|NOEX_RESPONDS)) { + switch (rb_method_boundp(klass, id, pub|BOUND_RESPONDS)) { case 2: return FALSE; case 0: @@ -1885,12 +1904,11 @@ Init_eval_method(void) "private", top_private, -1); { -#define REPLICATE_METHOD(klass, id, noex) \ - rb_method_entry_set((klass), (id), \ - rb_method_entry((klass), (id), 0), \ - (rb_method_flag_t)(noex | NOEX_BASIC | NOEX_NOREDEF)) - REPLICATE_METHOD(rb_eException, idMethodMissing, NOEX_PRIVATE); - REPLICATE_METHOD(rb_eException, idRespond_to, NOEX_PUBLIC); - REPLICATE_METHOD(rb_eException, idRespond_to_missing, NOEX_PUBLIC); +#define REPLICATE_METHOD(klass, id, visi) \ + rb_method_entry_set((klass), (id), rb_method_entry((klass), (id), 0), (visi)); + + REPLICATE_METHOD(rb_eException, idMethodMissing, METHOD_VISI_PRIVATE); + REPLICATE_METHOD(rb_eException, idRespond_to, METHOD_VISI_PUBLIC); + REPLICATE_METHOD(rb_eException, idRespond_to_missing, METHOD_VISI_PUBLIC); } } |