9 #if OPT_GLOBAL_METHOD_CACHE 10 #ifndef GLOBAL_METHOD_CACHE_SIZE 11 #define GLOBAL_METHOD_CACHE_SIZE 0x800 13 #define LSB_ONLY(x) ((x) & ~((x) - 1)) 14 #define POWER_OF_2_P(x) ((x) == LSB_ONLY(x)) 15 #if !POWER_OF_2_P(GLOBAL_METHOD_CACHE_SIZE) 16 # error GLOBAL_METHOD_CACHE_SIZE must be power of 2 18 #ifndef GLOBAL_METHOD_CACHE_MASK 19 #define GLOBAL_METHOD_CACHE_MASK (GLOBAL_METHOD_CACHE_SIZE-1) 22 #define GLOBAL_METHOD_CACHE_KEY(c,m) ((((c)>>3)^(m))&(global_method_cache.mask)) 23 #define GLOBAL_METHOD_CACHE(c,m) (global_method_cache.entries + GLOBAL_METHOD_CACHE_KEY(c,m)) 25 #define GLOBAL_METHOD_CACHE(c,m) (rb_bug("global method cache disabled improperly"), NULL) 31 #define object_id idObject_id 32 #define added idMethod_added 33 #define singleton_added idSingleton_method_added 34 #define removed idMethod_removed 35 #define singleton_removed idSingleton_method_removed 36 #define undefined idMethod_undefined 37 #define singleton_undefined idSingleton_method_undefined 38 #define attached id__attached__ 48 #if OPT_GLOBAL_METHOD_CACHE 53 } global_method_cache = {
54 GLOBAL_METHOD_CACHE_SIZE,
55 GLOBAL_METHOD_CACHE_MASK,
59 #define ruby_running (GET_VM()->running) 76 rb_bug(
"RCLASS_CALLABLE_M_TBL(klass) != 0");
98 if (klass && klass !=
Qundef) {
114 for (; entry !=
NULL; entry = entry->
next) {
159 if (alias_count + complemented_count == 0) {
219 rb_bug(
"call_cfunc_func: unsupported length: %d", argc);
246 if (0)
vm_cref_dump(
"rb_method_definition_create", cref);
454 refined.owner =
owner;
502 struct rb_id_table *mtbl;
504 int make_refined = 0;
514 case idInitialize_copy:
515 case idInitialize_clone:
516 case idInitialize_dup:
557 switch (old_def->
type) {
570 "previous definition of %"PRIsVALUE" was here",
584 if (klass ==
rb_cObject && mid == idInitialize) {
585 rb_warn(
"redefining Object#initialize may cause infinite loop");
588 if (mid ==
object_id || mid == id__send__) {
611 #define CALL_METHOD_HOOK(klass, hook, mid) do { \ 612 const VALUE arg = ID2SYM(mid); \ 613 VALUE recv_class = (klass); \ 614 ID hook_id = (hook); \ 615 if (FL_TEST((klass), FL_SINGLETON)) { \ 616 recv_class = rb_ivar_get((klass), attached); \ 617 hook_id = singleton_##hook; \ 619 rb_funcallv(recv_class, hook_id, 1, &arg); \ 650 iseq_body.iseqptr = iseq;
651 iseq_body.cref = cref;
671 #define UNDEF_ALLOC_FUNC ((rb_alloc_func_t)-1) 694 if (allocator)
return allocator;
708 if (defined_class_ptr)
709 *defined_class_ptr = klass;
727 VALUE *defined_class_ptr)
756 if (defined_class_ptr)
761 #if VM_DEBUG_VERIFY_METHOD_CACHE 765 VALUE actual_defined_class;
769 if (me != actual_me || defined_class != actual_defined_class) {
770 rb_bug(
"method cache verification failed");
778 #if OPT_GLOBAL_METHOD_CACHE 784 #if VM_DEBUG_VERIFY_METHOD_CACHE 787 if (defined_class_ptr) *defined_class_ptr = ent->
defined_class;
804 struct rb_id_table *mtbl;
850 if (with_refinement) {
921 if (
NIL_P(refinement)) {
969 if (mid ==
object_id || mid == id__send__ || mid == idInitialize) {
1020 for (i = 0; i <
argc; i++) {
1051 if (klass == defined_class ||
RCLASS_ORIGIN(klass) == defined_class) {
1065 #define BOUND_PRIVATE 0x01 1066 #define BOUND_RESPONDS 0x02 1081 if (ex & BOUND_RESPONDS)
return 2;
1150 rb_warning(
"attribute accessor as module_function");
1181 if (
id ==
object_id ||
id == id__send__ ||
id == idInitialize) {
1249 for (i = 0; i <
argc; i++) {
1431 switch (def->
type) {
1454 if (d1 == d2)
return 1;
1455 if (!d1 || !d2)
return 0;
1456 if (d1->
type != d2->
type)
return 0;
1482 rb_bug(
"rb_method_definition_eq: unsupported type: %d\n", d1->
type);
1491 if (!def)
return hash;
1493 switch (def->
type) {
1516 rb_bug(
"rb_hash_method_definition: unsupported method type (%d)\n", def->
type);
1528 const VALUE target_klass = klass;
1540 orig_me =
search_method(klass, original_name, &defined_class);
1623 for (i = 0; i <
argc; i++) {
1855 for (i = 0; i <
argc; i++) {
1883 if (!klass)
return TRUE;
1956 "respond_to? must accept 1 or 2 arguments (requires %d)",
1965 " the deprecated method signature, which takes one parameter",
1969 if (!
NIL_P(location)) {
1974 "respond_to? is defined here");
1980 return RTEST(result);
2064 #if OPT_GLOBAL_METHOD_CACHE 2065 char *ptr =
getenv(
"RUBY_GLOBAL_METHOD_CACHE_SIZE");
2068 if (ptr !=
NULL && (val = atoi(ptr)) > 0) {
2069 if ((val & (val - 1)) == 0) {
2070 global_method_cache.size =
val;
2071 global_method_cache.mask = val - 1;
2074 fprintf(stderr,
"RUBY_GLOBAL_METHOD_CACHE_SIZE was set to %d but ignored because the value is not a power of 2.\n", val);
2079 if (global_method_cache.entries ==
NULL) {
2080 fprintf(stderr,
"[FATAL] failed to allocate memory\n");
2090 #define rb_intern(str) rb_intern_const(str) 2116 #define REPLICATE_METHOD(klass, id) do { \ 2117 const rb_method_entry_t *me = rb_method_entry((klass), (id)); \ 2118 rb_method_entry_set((klass), (id), me, METHOD_ENTRY_VISI(me)); \ static rb_method_definition_t * method_definition_addref(rb_method_definition_t *def)
#define UNDEFINED_REFINED_METHOD_P(def)
static rb_method_definition_t * method_definition_create(rb_method_type_t type, ID mid)
int rb_method_boundp(VALUE klass, ID id, int ex)
static VALUE basic_obj_respond_to_missing(rb_thread_t *th, VALUE klass, VALUE obj, VALUE mid, VALUE priv)
static int rb_method_definition_eq(const rb_method_definition_t *d1, const rb_method_definition_t *d2)
rb_control_frame_t * rb_vm_get_ruby_level_next_cfp(const rb_thread_t *th, const rb_control_frame_t *cfp)
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE(*func)(ANYARGS), int argc, rb_method_visibility_t visi)
#define UNDEFINED_METHOD_ENTRY_P(me)
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
static VALUE rb_mod_public_method(int argc, VALUE *argv, VALUE obj)
static VALUE call_cfunc_0(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static void vm_passed_block_handler_set(rb_thread_t *th, VALUE block_handler)
void rb_bug(const char *fmt,...)
static VALUE rb_mod_method_defined(VALUE mod, VALUE mid)
void rb_print_undef(VALUE klass, ID id, rb_method_visibility_t visi)
VALUE rb_ary_freeze(VALUE ary)
static VALUE rb_mod_alias_method(VALUE mod, VALUE newname, VALUE oldname)
int rb_vm_get_sourceline(const rb_control_frame_t *cfp)
static int vm_env_cref_by_cref(const VALUE *ep)
#define RB_OBJ_WRITTEN(a, oldv, b)
void rb_remove_method(VALUE klass, const char *name)
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me)
static unsigned int hash(str, len) register const char *str
static VALUE rb_mod_remove_method(int argc, VALUE *argv, VALUE mod)
static rb_method_entry_t * method_entry_get_without_cache(VALUE klass, ID id, VALUE *defined_class_ptr)
rb_subclass_entry_t * next
static VALUE find_refinement(VALUE refinements, VALUE klass)
static const rb_iseq_t * def_iseq_ptr(rb_method_definition_t *def)
static rb_method_entry_t * rb_method_entry_alloc(ID called_id, VALUE owner, VALUE defined_class, const rb_method_definition_t *def)
const rb_iseq_t * rb_proc_get_iseq(VALUE proc, int *is_proc)
void rb_add_refined_method_entry(VALUE refined_class, ID mid)
static void rb_class_clear_method_cache(VALUE klass, VALUE arg)
static const rb_method_definition_t * original_method_definition(const rb_method_definition_t *def)
VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0)
static VALUE call_cfunc_10(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
rb_alloc_func_t rb_get_alloc_func(VALUE klass)
VALUE rb_refinement_module_get_refined_class(VALUE module)
void rb_define_private_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
static void setup_method_cfunc_struct(rb_method_cfunc_t *cfunc, VALUE(*func)(), int argc)
static void make_method_entry_refined(VALUE owner, rb_method_entry_t *me)
rb_method_entry_t * rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *opts, rb_method_visibility_t visi)
SSL_METHOD *(* func)(void)
const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me)
int rb_id_table_lookup(struct rb_id_table *tbl, ID id, VALUE *valp)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
static const rb_method_entry_t * method_entry_resolve_refinement(VALUE klass, ID id, int with_refinement, VALUE *defined_class_ptr)
const rb_callable_method_entry_t * rb_callable_method_entry(VALUE klass, ID id)
struct rb_iseq_constant_body * body
static const rb_method_entry_t * refined_method_original_method_entry(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
static void METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi)
void rb_print_undef_str(VALUE klass, VALUE name)
void rb_raise(VALUE exc, const char *fmt,...)
#define METHOD_ENTRY_COMPLEMENTED(me)
void rb_compile_warn(const char *file, int line, const char *fmt,...)
static VALUE set_visibility(int argc, const VALUE *argv, VALUE module, rb_method_visibility_t visi)
static VALUE CREF_REFINEMENTS(const rb_cref_t *cref)
void rb_method_name_error(VALUE klass, VALUE str)
#define GET_GLOBAL_METHOD_STATE()
static void rb_export_method(VALUE klass, ID name, rb_method_visibility_t visi)
static const rb_cref_t * method_cref(VALUE method)
#define RUBY_DTRACE_HOOK(name, arg)
void rb_obj_info_dump(VALUE obj)
static void rb_define_notimplement_method_id(VALUE mod, ID id, rb_method_visibility_t visi)
int rb_method_basic_definition_p(VALUE klass, ID id)
static rb_method_entry_t * lookup_method_table(VALUE klass, ID id)
static void rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
VALUE rb_f_notimplement(int argc, const VALUE *argv, VALUE obj)
#define rb_name_err_raise(mesg, recv, name)
static VALUE call_cfunc_11(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static void METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
static rb_method_entry_t * search_method(VALUE klass, ID id, VALUE *defined_class_ptr)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
static void remove_method(VALUE klass, ID mid)
static st_index_t rb_hash_method_definition(st_index_t hash, const rb_method_definition_t *def)
static void method_definition_set(const rb_method_entry_t *me, rb_method_definition_t *def, void *opts)
VALUE rb_singleton_class(VALUE obj)
Returns the singleton class of obj.
void rb_attr(VALUE klass, ID id, int read, int write, int ex)
int rb_obj_respond_to(VALUE obj, ID id, int priv)
#define RB_TYPE_P(obj, type)
const rb_scope_visibility_t scope_visi
static VALUE call_cfunc_15(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const rb_method_entry_t * rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me)
#define rb_intern_str(string)
#define METHOD_ENTRY_COMPLEMENTED_SET(me)
static void METHOD_ENTRY_FLAGS_SET(rb_method_entry_t *me, rb_method_visibility_t visi, unsigned int basic)
RUBY_EXTERN VALUE rb_cObject
static VALUE vm_call0(rb_thread_t *th, VALUE recv, ID id, int argc, const VALUE *argv, const rb_callable_method_entry_t *me)
int rb_respond_to(VALUE obj, ID id)
void rb_clear_cache(void)
void rb_id_table_clear(struct rb_id_table *tbl)
RUBY_EXTERN VALUE rb_cBasicObject
static VALUE top_public(int argc, VALUE *argv)
const rb_callable_method_entry_t * rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me)
static VALUE obj_respond_to(int argc, VALUE *argv, VALUE obj)
rb_method_entry_t * rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def)
RUBY_EXTERN VALUE rb_mKernel
void rb_remove_method_id(VALUE klass, ID mid)
int rb_id_table_delete(struct rb_id_table *tbl, ID id)
struct rb_id_table * rb_id_table_create(size_t size)
void rb_undef_alloc_func(VALUE klass)
struct rb_method_definition_struct *const def
static VALUE top_private(int argc, VALUE *argv)
static rb_method_visibility_t rb_scope_visibility_get(void)
static VALUE call_cfunc_2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
int rb_method_entry_arity(const rb_method_entry_t *me)
const rb_method_entry_t * rb_method_entry(VALUE klass, ID id)
const VALUE defined_class
const rb_callable_method_entry_t * rb_method_entry_complement_defined_class(const rb_method_entry_t *src_me, ID called_id, VALUE defined_class)
RUBY_EXTERN VALUE rb_cModule
static void vm_cref_set_visibility(rb_method_visibility_t method_visi, int module_func)
void rb_clear_constant_cache(void)
static VALUE call_cfunc_1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define OPT_GLOBAL_METHOD_CACHE
VALUE rb_method_entry_location(const rb_method_entry_t *me)
static VALUE call_cfunc_9(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_3(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE filter_defined_class(VALUE klass)
void rb_alias(VALUE klass, ID alias_name, ID original_name)
static void method_definition_reset(const rb_method_entry_t *me)
static VALUE rb_mod_private_method_defined(VALUE mod, VALUE mid)
const rb_callable_method_entry_t * rb_callable_method_entry_without_refinements(VALUE klass, ID id)
static int rb_scope_module_func_check(void)
VALUE(* invoker)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
union rb_method_definition_struct::@144 body
static VALUE(*)(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *) call_cfunc_invoker_func(int argc)
void rb_class_foreach_subclass(VALUE klass, void(*f)(VALUE, VALUE), VALUE arg)
static VALUE call_cfunc_13(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
VALUE rb_sprintf(const char *format,...)
unsigned long rb_serial_t
static VALUE rb_mod_public(int argc, VALUE *argv, VALUE module)
static int vm_redefinition_check_flag(VALUE klass)
VALUE rb_to_symbol(VALUE name)
static int basic_obj_respond_to(rb_thread_t *th, VALUE obj, ID id, int pub)
static VALUE rb_mod_protected_method_defined(VALUE mod, VALUE mid)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
#define INC_GLOBAL_METHOD_STATE()
#define INC_GLOBAL_CONSTANT_STATE()
#define METHOD_ENTRY_VISI(me)
VALUE rb_vm_top_self(void)
static VALUE rb_mod_modfunc(int argc, VALUE *argv, VALUE module)
static rb_method_entry_t * rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibility_t visi, rb_method_type_t type, rb_method_definition_t *def, ID original_id, void *opts)
const VALUE defined_class
const char * rb_class2name(VALUE)
static VALUE obj_respond_to_missing(VALUE obj, VALUE mid, VALUE priv)
rb_method_visibility_t method_visi
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi)
const struct rb_method_entry_struct *const original_me
static void check_override_opt_method(VALUE klass, VALUE arg)
static rb_method_entry_t * method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_visibility_t visi, VALUE defined_class)
static VALUE call_cfunc_m2(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const char * rb_id2name(ID)
static VALUE call_cfunc_12(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE call_cfunc_5(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE rb_mod_undef_method(int argc, VALUE *argv, VALUE mod)
#define CALL_METHOD_HOOK(klass, hook, mid)
static void method_added(VALUE klass, ID mid)
static rb_method_entry_t * method_entry_get(VALUE klass, ID id, VALUE *defined_class_ptr)
static VALUE call_cfunc_7(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
static VALUE rb_mod_private_method(int argc, VALUE *argv, VALUE obj)
static VALUE call_method_entry(rb_thread_t *th, VALUE defined_class, VALUE obj, ID id, const rb_method_entry_t *me, int argc, const VALUE *argv)
VALUE rb_equal(VALUE, VALUE)
static void set_method_visibility(VALUE self, int argc, const VALUE *argv, rb_method_visibility_t visi)
#define RARRAY_AREF(a, i)
static VALUE call_cfunc_m1(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define METHOD_ENTRY_BASIC(me)
const rb_method_entry_t * rb_method_entry_at(VALUE klass, ID id)
const rb_method_entry_t * rb_method_entry_with_refinements(VALUE klass, ID id)
static VALUE call_cfunc_14(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2)
static void rb_scope_module_func_set(void)
void rb_compile_warning(const char *file, int line, const char *fmt,...)
#define RCLASS_CALLABLE_M_TBL(c)
st_index_t rb_hash_uint(st_index_t, st_index_t)
void rb_define_alloc_func(VALUE klass, VALUE(*func)(VALUE))
#define GLOBAL_METHOD_CACHE(c, m)
#define ONLY_FOR_INTERNAL_USE(func)
static VALUE rb_mod_protected(int argc, VALUE *argv, VALUE module)
static VALUE call_cfunc_6(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
const char * rb_obj_info(VALUE obj)
void rb_notimplement(void)
static VALUE call_cfunc_4(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
void Init_eval_method(void)
static VALUE rb_mod_public_method_defined(VALUE mod, VALUE mid)
static void vm_cref_dump(const char *mesg, const rb_cref_t *cref)
static int vm_respond_to(rb_thread_t *th, VALUE klass, VALUE obj, ID id, int priv)
static VALUE rb_mod_private(int argc, VALUE *argv, VALUE module)
const rb_method_entry_t * rb_method_entry_without_refinements(VALUE klass, ID id)
void rb_frozen_class_p(VALUE klass)
static VALUE vm_passed_block_handler(rb_thread_t *th)
#define REPLICATE_METHOD(klass, id)
void rb_undef(VALUE klass, ID id)
static const rb_callable_method_entry_t * prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_t *me)
rb_serial_t rb_next_class_serial(void)
void rb_warning(const char *fmt,...)
rb_method_entry_t * rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *me, rb_method_visibility_t visi)
static const rb_scope_visibility_t * CREF_SCOPE_VISI(const rb_cref_t *cref)
#define rb_check_frozen(obj)
enum rb_method_definition_struct::@144::method_optimized_type optimize_type
const rb_callable_method_entry_t * rb_callable_method_entry_with_refinements(VALUE klass, ID id)
const rb_iseq_t *const iseqptr
st_index_t rb_hash_proc(st_index_t hash, VALUE proc)
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src)
const struct rb_method_entry_struct *const orig_me
static rb_cref_t * vm_cref_new_toplevel(rb_thread_t *th)
VALUE(* rb_alloc_func_t)(VALUE)
static rb_method_definition_t * method_definition_addref_complement(rb_method_definition_t *def)
rb_method_refined_t refined
static void rb_method_definition_release(rb_method_definition_t *def, int complemented)
void rb_free_method_entry(const rb_method_entry_t *me)
void rb_scope_visibility_set(rb_method_visibility_t visi)
static const rb_method_entry_t * resolve_refined_method(VALUE refinements, const rb_method_entry_t *me, VALUE *defined_class_ptr)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
rb_cref_t * rb_vm_cref(void)
void rb_warn(const char *fmt,...)
void rb_clear_method_cache_by_class(VALUE klass)
int rb_id_table_insert(struct rb_id_table *tbl, ID id, VALUE val)
static VALUE call_cfunc_8(VALUE(*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv)
#define RB_OBJ_WRITE(a, slot, b)
rb_iseq_location_t location
static VALUE check_definition(VALUE mod, VALUE mid, rb_method_visibility_t visi)