Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /********************************************************************** 00002 00003 method.h - 00004 00005 $Author: nobu $ 00006 created at: Wed Jul 15 20:02:33 2009 00007 00008 Copyright (C) 2009 Koichi Sasada 00009 00010 **********************************************************************/ 00011 #ifndef METHOD_H 00012 #define METHOD_H 00013 00014 #ifndef END_OF_ENUMERATION 00015 # ifdef __GNUC__ 00016 # define END_OF_ENUMERATION(key) 00017 # else 00018 # define END_OF_ENUMERATION(key) END_OF_##key##_PLACEHOLDER = 0 00019 # endif 00020 #endif 00021 00022 typedef enum { 00023 NOEX_PUBLIC = 0x00, 00024 NOEX_NOSUPER = 0x01, 00025 NOEX_PRIVATE = 0x02, 00026 NOEX_PROTECTED = 0x04, 00027 NOEX_MASK = 0x06, 00028 NOEX_BASIC = 0x08, 00029 NOEX_UNDEF = NOEX_NOSUPER, 00030 NOEX_MODFUNC = 0x12, 00031 NOEX_SUPER = 0x20, 00032 NOEX_VCALL = 0x40, 00033 NOEX_RESPONDS = 0x80, 00034 00035 NOEX_BIT_WIDTH = 8, 00036 NOEX_SAFE_SHIFT_OFFSET = ((NOEX_BIT_WIDTH+3)/4)*4 /* round up to nibble */ 00037 } rb_method_flag_t; 00038 00039 #define NOEX_SAFE(n) ((int)((n) >> NOEX_SAFE_SHIFT_OFFSET) & 0x0F) 00040 #define NOEX_WITH(n, s) (((s) << NOEX_SAFE_SHIFT_OFFSET) | (n) | (ruby_running ? 0 : NOEX_BASIC)) 00041 #define NOEX_WITH_SAFE(n) NOEX_WITH((n), rb_safe_level()) 00042 00043 /* method data type */ 00044 00045 typedef enum { 00046 VM_METHOD_TYPE_ISEQ, 00047 VM_METHOD_TYPE_CFUNC, 00048 VM_METHOD_TYPE_ATTRSET, 00049 VM_METHOD_TYPE_IVAR, 00050 VM_METHOD_TYPE_BMETHOD, 00051 VM_METHOD_TYPE_ZSUPER, 00052 VM_METHOD_TYPE_UNDEF, 00053 VM_METHOD_TYPE_NOTIMPLEMENTED, 00054 VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */ 00055 VM_METHOD_TYPE_MISSING, /* wrapper for method_missing(id) */ 00056 VM_METHOD_TYPE_REFINED, 00057 00058 END_OF_ENUMERATION(VM_METHOD_TYPE) 00059 } rb_method_type_t; 00060 00061 struct rb_call_info_struct; 00062 00063 typedef struct rb_method_cfunc_struct { 00064 VALUE (*func)(ANYARGS); 00065 VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv); 00066 int argc; 00067 } rb_method_cfunc_t; 00068 00069 typedef struct rb_method_attr_struct { 00070 ID id; 00071 VALUE location; 00072 } rb_method_attr_t; 00073 00074 typedef struct rb_iseq_struct rb_iseq_t; 00075 00076 typedef struct rb_method_definition_struct { 00077 rb_method_type_t type; /* method type */ 00078 ID original_id; 00079 union { 00080 rb_iseq_t *iseq; /* should be mark */ 00081 rb_method_cfunc_t cfunc; 00082 rb_method_attr_t attr; 00083 VALUE proc; /* should be mark */ 00084 enum method_optimized_type { 00085 OPTIMIZED_METHOD_TYPE_SEND, 00086 OPTIMIZED_METHOD_TYPE_CALL, 00087 00088 OPTIMIZED_METHOD_TYPE__MAX 00089 } optimize_type; 00090 struct rb_method_entry_struct *orig_me; 00091 } body; 00092 int alias_count; 00093 } rb_method_definition_t; 00094 00095 typedef struct rb_method_entry_struct { 00096 rb_method_flag_t flag; 00097 char mark; 00098 rb_method_definition_t *def; 00099 ID called_id; 00100 VALUE klass; /* should be mark */ 00101 } rb_method_entry_t; 00102 00103 struct unlinked_method_entry_list_entry { 00104 struct unlinked_method_entry_list_entry *next; 00105 rb_method_entry_t *me; 00106 }; 00107 00108 #define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF) 00109 00110 void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex); 00111 rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex); 00112 rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr); 00113 void rb_add_refined_method_entry(VALUE refined_class, ID mid); 00114 rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, 00115 rb_method_entry_t *me, 00116 VALUE *defined_class_ptr); 00117 rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id, 00118 VALUE *defined_class_ptr); 00119 rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, 00120 VALUE *defined_class_ptr); 00121 00122 rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr); 00123 rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex); 00124 00125 int rb_method_entry_arity(const rb_method_entry_t *me); 00126 int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2); 00127 st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me); 00128 00129 VALUE rb_method_entry_location(rb_method_entry_t *me); 00130 VALUE rb_mod_method_location(VALUE mod, ID id); 00131 VALUE rb_obj_method_location(VALUE obj, ID id); 00132 00133 void rb_mark_method_entry(const rb_method_entry_t *me); 00134 void rb_free_method_entry(rb_method_entry_t *me); 00135 void rb_sweep_method_entry(void *vm); 00136 void rb_free_m_table(st_table *tbl); 00137 00138 #endif /* METHOD_H */ 00139