зеркало из https://github.com/github/ruby.git
* 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`. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@50743 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
938eb46e80
Коммит
18bbd05709
36
ChangeLog
36
ChangeLog
|
@ -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.
|
||||
|
|
45
class.c
45
class.c
|
@ -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);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
25
eval_error.c
25
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",
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
2
load.c
2
load.c
|
@ -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));
|
||||
}
|
||||
|
||||
|
|
47
method.h
47
method.h
|
@ -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 {
|
||||
|
@ -52,6 +31,13 @@ typedef struct rb_method_entry_struct {
|
|||
const VALUE klass; /* should be marked */
|
||||
} 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,
|
||||
|
@ -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);
|
||||
|
|
2
parse.y
2
parse.y
|
@ -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);
|
||||
|
|
29
proc.c
29
proc.c
|
@ -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 {
|
||||
|
|
4
struct.c
4
struct.c
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
17
vm.c
17
vm.c
|
@ -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
|
||||
|
|
10
vm_core.h
10
vm_core.h
|
@ -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;
|
||||
|
||||
|
|
83
vm_eval.c
83
vm_eval.c
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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); \
|
||||
|
|
186
vm_method.c
186
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);
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче