1/********************************************************************** 2 3 method.h - 4 5 $Author: nagachika $ 6 created at: Wed Jul 15 20:02:33 2009 7 8 Copyright (C) 2009 Koichi Sasada 9 10**********************************************************************/ 11#ifndef METHOD_H 12#define METHOD_H 13 14#ifndef END_OF_ENUMERATION 15# ifdef __GNUC__ 16# define END_OF_ENUMERATION(key) 17# else 18# define END_OF_ENUMERATION(key) END_OF_##key##_PLACEHOLDER = 0 19# endif 20#endif 21 22typedef enum { 23 NOEX_PUBLIC = 0x00, 24 NOEX_NOSUPER = 0x01, 25 NOEX_PRIVATE = 0x02, 26 NOEX_PROTECTED = 0x04, 27 NOEX_MASK = 0x06, 28 NOEX_BASIC = 0x08, 29 NOEX_UNDEF = NOEX_NOSUPER, 30 NOEX_MODFUNC = 0x12, 31 NOEX_SUPER = 0x20, 32 NOEX_VCALL = 0x40, 33 NOEX_RESPONDS = 0x80, 34 35 NOEX_BIT_WIDTH = 8, 36 NOEX_SAFE_SHIFT_OFFSET = ((NOEX_BIT_WIDTH+3)/4)*4 /* round up to nibble */ 37} rb_method_flag_t; 38 39#define NOEX_SAFE(n) ((int)((n) >> NOEX_SAFE_SHIFT_OFFSET) & 0x0F) 40#define NOEX_WITH(n, s) (((s) << NOEX_SAFE_SHIFT_OFFSET) | (n) | (ruby_running ? 0 : NOEX_BASIC)) 41#define NOEX_WITH_SAFE(n) NOEX_WITH((n), rb_safe_level()) 42 43/* method data type */ 44 45typedef enum { 46 VM_METHOD_TYPE_ISEQ, 47 VM_METHOD_TYPE_CFUNC, 48 VM_METHOD_TYPE_ATTRSET, 49 VM_METHOD_TYPE_IVAR, 50 VM_METHOD_TYPE_BMETHOD, 51 VM_METHOD_TYPE_ZSUPER, 52 VM_METHOD_TYPE_UNDEF, 53 VM_METHOD_TYPE_NOTIMPLEMENTED, 54 VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */ 55 VM_METHOD_TYPE_MISSING, /* wrapper for method_missing(id) */ 56 VM_METHOD_TYPE_REFINED, 57 58 END_OF_ENUMERATION(VM_METHOD_TYPE) 59} rb_method_type_t; 60 61struct rb_call_info_struct; 62 63typedef struct rb_method_cfunc_struct { 64 VALUE (*func)(ANYARGS); 65 VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv); 66 int argc; 67} rb_method_cfunc_t; 68 69typedef struct rb_method_attr_struct { 70 ID id; 71 VALUE location; 72} rb_method_attr_t; 73 74typedef struct rb_iseq_struct rb_iseq_t; 75 76typedef struct rb_method_definition_struct { 77 rb_method_type_t type; /* method type */ 78 ID original_id; 79 union { 80 rb_iseq_t *iseq; /* should be mark */ 81 rb_method_cfunc_t cfunc; 82 rb_method_attr_t attr; 83 VALUE proc; /* should be mark */ 84 enum method_optimized_type { 85 OPTIMIZED_METHOD_TYPE_SEND, 86 OPTIMIZED_METHOD_TYPE_CALL, 87 88 OPTIMIZED_METHOD_TYPE__MAX 89 } optimize_type; 90 struct rb_method_entry_struct *orig_me; 91 } body; 92 int alias_count; 93} rb_method_definition_t; 94 95typedef struct rb_method_entry_struct { 96 rb_method_flag_t flag; 97 char mark; 98 rb_method_definition_t *def; 99 ID called_id; 100 VALUE klass; /* should be mark */ 101} rb_method_entry_t; 102 103struct unlinked_method_entry_list_entry { 104 struct unlinked_method_entry_list_entry *next; 105 rb_method_entry_t *me; 106}; 107 108#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF) 109 110void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_flag_t noex); 111rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_flag_t noex); 112rb_method_entry_t *rb_method_entry(VALUE klass, ID id, VALUE *define_class_ptr); 113void rb_add_refined_method_entry(VALUE refined_class, ID mid); 114rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, 115 const rb_method_entry_t *me, 116 VALUE *defined_class_ptr); 117rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id, 118 VALUE *defined_class_ptr); 119rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id, 120 VALUE *defined_class_ptr); 121 122rb_method_entry_t *rb_method_entry_get_without_cache(VALUE klass, ID id, VALUE *define_class_ptr); 123rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_flag_t noex); 124 125int rb_method_entry_arity(const rb_method_entry_t *me); 126int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2); 127st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me); 128 129VALUE rb_method_entry_location(rb_method_entry_t *me); 130VALUE rb_mod_method_location(VALUE mod, ID id); 131VALUE rb_obj_method_location(VALUE obj, ID id); 132 133void rb_mark_method_entry(const rb_method_entry_t *me); 134void rb_free_method_entry(rb_method_entry_t *me); 135void rb_sweep_method_entry(void *vm); 136void rb_free_m_table(st_table *tbl); 137 138#endif /* METHOD_H */ 139