llrb 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.gitmodules +4 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +56 -0
- data/README.md +311 -0
- data/Rakefile +30 -0
- data/bin/bm_app_fib +41 -0
- data/bin/bm_empty_method +33 -0
- data/bin/bm_loop_while +27 -0
- data/bin/bm_plus +33 -0
- data/bin/console +14 -0
- data/bin/loop_while.rb +5 -0
- data/bin/setup +8 -0
- data/ext/llrb/cfg.h +124 -0
- data/ext/llrb/compiler.c +987 -0
- data/ext/llrb/compiler/funcs.h +164 -0
- data/ext/llrb/compiler/stack.h +43 -0
- data/ext/llrb/cruby.h +42 -0
- data/ext/llrb/cruby/ccan/build_assert/build_assert.h +40 -0
- data/ext/llrb/cruby/ccan/check_type/check_type.h +63 -0
- data/ext/llrb/cruby/ccan/container_of/container_of.h +142 -0
- data/ext/llrb/cruby/ccan/list/list.h +773 -0
- data/ext/llrb/cruby/ccan/str/str.h +16 -0
- data/ext/llrb/cruby/internal.h +1774 -0
- data/ext/llrb/cruby/iseq.h +252 -0
- data/ext/llrb/cruby/method.h +213 -0
- data/ext/llrb/cruby/node.h +520 -0
- data/ext/llrb/cruby/probes_helper.h +43 -0
- data/ext/llrb/cruby/ruby_assert.h +54 -0
- data/ext/llrb/cruby/ruby_atomic.h +233 -0
- data/ext/llrb/cruby/thread_pthread.h +54 -0
- data/ext/llrb/cruby/vm_core.h +1646 -0
- data/ext/llrb/cruby/vm_debug.h +37 -0
- data/ext/llrb/cruby/vm_exec.h +182 -0
- data/ext/llrb/cruby/vm_opts.h +57 -0
- data/ext/llrb/cruby_extra/id.h +220 -0
- data/ext/llrb/cruby_extra/insns.inc +113 -0
- data/ext/llrb/cruby_extra/insns_info.inc +796 -0
- data/ext/llrb/cruby_extra/probes.h +80 -0
- data/ext/llrb/extconf.rb +102 -0
- data/ext/llrb/llrb.c +148 -0
- data/ext/llrb/optimizer.cc +118 -0
- data/ext/llrb/parser.c +191 -0
- data/ext/llrb/profiler.c +336 -0
- data/ext/llrb_insn_checkkeyword.c +20 -0
- data/ext/llrb_insn_checkmatch.c +28 -0
- data/ext/llrb_insn_concatarray.c +23 -0
- data/ext/llrb_insn_concatstrings.c +21 -0
- data/ext/llrb_insn_defined.c +9 -0
- data/ext/llrb_insn_getclassvariable.c +10 -0
- data/ext/llrb_insn_getinstancevariable.c +44 -0
- data/ext/llrb_insn_getlocal.c +14 -0
- data/ext/llrb_insn_getlocal_level0.c +8 -0
- data/ext/llrb_insn_getlocal_level1.c +8 -0
- data/ext/llrb_insn_getspecial.c +14 -0
- data/ext/llrb_insn_invokeblock.c +39 -0
- data/ext/llrb_insn_invokesuper.c +47 -0
- data/ext/llrb_insn_opt_aref.c +25 -0
- data/ext/llrb_insn_opt_aset.c +28 -0
- data/ext/llrb_insn_opt_div.c +32 -0
- data/ext/llrb_insn_opt_eq.c +57 -0
- data/ext/llrb_insn_opt_ge.c +28 -0
- data/ext/llrb_insn_opt_gt.c +38 -0
- data/ext/llrb_insn_opt_le.c +29 -0
- data/ext/llrb_insn_opt_lt.c +38 -0
- data/ext/llrb_insn_opt_ltlt.c +27 -0
- data/ext/llrb_insn_opt_minus.c +36 -0
- data/ext/llrb_insn_opt_mod.c +32 -0
- data/ext/llrb_insn_opt_mult.c +30 -0
- data/ext/llrb_insn_opt_neq.c +103 -0
- data/ext/llrb_insn_opt_plus.c +48 -0
- data/ext/llrb_insn_opt_send_without_block.c +45 -0
- data/ext/llrb_insn_opt_str_freeze.c +12 -0
- data/ext/llrb_insn_putspecialobject.c +23 -0
- data/ext/llrb_insn_send.c +49 -0
- data/ext/llrb_insn_setclassvariable.c +19 -0
- data/ext/llrb_insn_setconstant.c +23 -0
- data/ext/llrb_insn_setinstancevariable.c +48 -0
- data/ext/llrb_insn_setlocal.c +16 -0
- data/ext/llrb_insn_setlocal_level0.c +9 -0
- data/ext/llrb_insn_setlocal_level1.c +10 -0
- data/ext/llrb_insn_setspecial.c +15 -0
- data/ext/llrb_insn_splatarray.c +13 -0
- data/ext/llrb_insn_throw.c +11 -0
- data/ext/llrb_insn_trace.c +37 -0
- data/ext/llrb_push_result.c +14 -0
- data/ext/llrb_self_from_cfp.c +12 -0
- data/ext/llrb_set_pc.c +8 -0
- data/lib/llrb.rb +2 -0
- data/lib/llrb/jit.rb +76 -0
- data/lib/llrb/start.rb +2 -0
- data/lib/llrb/version.rb +3 -0
- data/llrb.gemspec +48 -0
- data/wercker.yml +31 -0
- metadata +227 -0
@@ -0,0 +1,252 @@
|
|
1
|
+
/**********************************************************************
|
2
|
+
|
3
|
+
iseq.h -
|
4
|
+
|
5
|
+
$Author$
|
6
|
+
created at: 04/01/01 23:36:57 JST
|
7
|
+
|
8
|
+
Copyright (C) 2004-2008 Koichi Sasada
|
9
|
+
|
10
|
+
**********************************************************************/
|
11
|
+
|
12
|
+
#ifndef RUBY_ISEQ_H
|
13
|
+
#define RUBY_ISEQ_H 1
|
14
|
+
|
15
|
+
#define ISEQ_MAJOR_VERSION 2
|
16
|
+
#define ISEQ_MINOR_VERSION 3
|
17
|
+
|
18
|
+
#ifndef rb_iseq_t
|
19
|
+
typedef struct rb_iseq_struct rb_iseq_t;
|
20
|
+
#define rb_iseq_t rb_iseq_t
|
21
|
+
#endif
|
22
|
+
|
23
|
+
static inline size_t
|
24
|
+
rb_call_info_kw_arg_bytes(int keyword_len)
|
25
|
+
{
|
26
|
+
return sizeof(struct rb_call_info_kw_arg) + sizeof(VALUE) * (keyword_len - 1);
|
27
|
+
}
|
28
|
+
|
29
|
+
enum iseq_mark_ary_index {
|
30
|
+
ISEQ_MARK_ARY_COVERAGE,
|
31
|
+
ISEQ_MARK_ARY_FLIP_CNT,
|
32
|
+
ISEQ_MARK_ARY_ORIGINAL_ISEQ,
|
33
|
+
ISEQ_MARK_ARY_INITIAL_SIZE
|
34
|
+
};
|
35
|
+
|
36
|
+
static inline VALUE
|
37
|
+
iseq_mark_ary_create(int flip_cnt)
|
38
|
+
{
|
39
|
+
VALUE ary = rb_ary_tmp_new(ISEQ_MARK_ARY_INITIAL_SIZE);
|
40
|
+
rb_ary_push(ary, Qnil); /* ISEQ_MARK_ARY_COVERAGE */
|
41
|
+
rb_ary_push(ary, INT2FIX(flip_cnt)); /* ISEQ_MARK_ARY_FLIP_CNT */
|
42
|
+
rb_ary_push(ary, Qnil); /* ISEQ_MARK_ARY_ORIGINAL_ISEQ */
|
43
|
+
return ary;
|
44
|
+
}
|
45
|
+
|
46
|
+
#define ISEQ_MARK_ARY(iseq) (iseq)->body->mark_ary
|
47
|
+
|
48
|
+
#define ISEQ_COVERAGE(iseq) RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_COVERAGE)
|
49
|
+
#define ISEQ_COVERAGE_SET(iseq, cov) RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_COVERAGE, cov)
|
50
|
+
|
51
|
+
#define ISEQ_FLIP_CNT(iseq) FIX2INT(RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_FLIP_CNT))
|
52
|
+
|
53
|
+
static inline int
|
54
|
+
ISEQ_FLIP_CNT_INCREMENT(const rb_iseq_t *iseq)
|
55
|
+
{
|
56
|
+
int cnt = ISEQ_FLIP_CNT(iseq);
|
57
|
+
RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_FLIP_CNT, INT2FIX(cnt+1));
|
58
|
+
return cnt;
|
59
|
+
}
|
60
|
+
|
61
|
+
static inline VALUE *
|
62
|
+
ISEQ_ORIGINAL_ISEQ(const rb_iseq_t *iseq)
|
63
|
+
{
|
64
|
+
VALUE str = RARRAY_AREF(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_ORIGINAL_ISEQ);
|
65
|
+
if (RTEST(str)) return (VALUE *)RSTRING_PTR(str);
|
66
|
+
return NULL;
|
67
|
+
}
|
68
|
+
|
69
|
+
static inline VALUE *
|
70
|
+
ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
|
71
|
+
{
|
72
|
+
VALUE str = rb_str_tmp_new(size * sizeof(VALUE));
|
73
|
+
RARRAY_ASET(ISEQ_MARK_ARY(iseq), ISEQ_MARK_ARY_ORIGINAL_ISEQ, str);
|
74
|
+
return (VALUE *)RSTRING_PTR(str);
|
75
|
+
}
|
76
|
+
|
77
|
+
#define ISEQ_COMPILE_DATA(iseq) (iseq)->aux.compile_data
|
78
|
+
|
79
|
+
static inline rb_iseq_t *
|
80
|
+
iseq_imemo_alloc(void)
|
81
|
+
{
|
82
|
+
return (rb_iseq_t *)rb_imemo_new(imemo_iseq, 0, 0, 0, 0);
|
83
|
+
}
|
84
|
+
|
85
|
+
#define ISEQ_NOT_LOADED_YET IMEMO_FL_USER1
|
86
|
+
|
87
|
+
VALUE iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt);
|
88
|
+
void ibf_load_iseq_complete(rb_iseq_t *iseq);
|
89
|
+
const rb_iseq_t *iseq_ibf_load(VALUE str);
|
90
|
+
VALUE iseq_ibf_load_extra_data(VALUE str);
|
91
|
+
|
92
|
+
RUBY_SYMBOL_EXPORT_BEGIN
|
93
|
+
|
94
|
+
/* compile.c */
|
95
|
+
VALUE rb_iseq_compile_node(rb_iseq_t *iseq, NODE *node);
|
96
|
+
int rb_iseq_translate_threaded_code(rb_iseq_t *iseq);
|
97
|
+
VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
|
98
|
+
void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
|
99
|
+
VALUE locals, VALUE args,
|
100
|
+
VALUE exception, VALUE body);
|
101
|
+
|
102
|
+
/* iseq.c */
|
103
|
+
void rb_iseq_add_mark_object(const rb_iseq_t *iseq, VALUE obj);
|
104
|
+
VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
|
105
|
+
VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
|
106
|
+
struct st_table *ruby_insn_make_insn_table(void);
|
107
|
+
unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos);
|
108
|
+
|
109
|
+
int rb_iseqw_line_trace_each(VALUE iseqval, int (*func)(int line, rb_event_flag_t *events_ptr, void *d), void *data);
|
110
|
+
VALUE rb_iseqw_line_trace_all(VALUE iseqval);
|
111
|
+
VALUE rb_iseqw_line_trace_specify(VALUE iseqval, VALUE pos, VALUE set);
|
112
|
+
VALUE rb_iseqw_new(const rb_iseq_t *iseq);
|
113
|
+
const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw);
|
114
|
+
|
115
|
+
VALUE rb_iseq_path(const rb_iseq_t *iseq);
|
116
|
+
VALUE rb_iseq_absolute_path(const rb_iseq_t *iseq);
|
117
|
+
VALUE rb_iseq_label(const rb_iseq_t *iseq);
|
118
|
+
VALUE rb_iseq_base_label(const rb_iseq_t *iseq);
|
119
|
+
VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq);
|
120
|
+
VALUE rb_iseq_method_name(const rb_iseq_t *iseq);
|
121
|
+
|
122
|
+
/* proc.c */
|
123
|
+
const rb_iseq_t *rb_method_iseq(VALUE body);
|
124
|
+
const rb_iseq_t *rb_proc_get_iseq(VALUE proc, int *is_proc);
|
125
|
+
|
126
|
+
struct rb_compile_option_struct {
|
127
|
+
unsigned int inline_const_cache: 1;
|
128
|
+
unsigned int peephole_optimization: 1;
|
129
|
+
unsigned int tailcall_optimization: 1;
|
130
|
+
unsigned int specialized_instruction: 1;
|
131
|
+
unsigned int operands_unification: 1;
|
132
|
+
unsigned int instructions_unification: 1;
|
133
|
+
unsigned int stack_caching: 1;
|
134
|
+
unsigned int trace_instruction: 1;
|
135
|
+
unsigned int frozen_string_literal: 1;
|
136
|
+
unsigned int debug_frozen_string_literal: 1;
|
137
|
+
unsigned int coverage_enabled: 1;
|
138
|
+
int debug_level;
|
139
|
+
};
|
140
|
+
|
141
|
+
struct iseq_line_info_entry {
|
142
|
+
unsigned int position;
|
143
|
+
unsigned int line_no;
|
144
|
+
};
|
145
|
+
|
146
|
+
struct iseq_catch_table_entry {
|
147
|
+
enum catch_type {
|
148
|
+
CATCH_TYPE_RESCUE = INT2FIX(1),
|
149
|
+
CATCH_TYPE_ENSURE = INT2FIX(2),
|
150
|
+
CATCH_TYPE_RETRY = INT2FIX(3),
|
151
|
+
CATCH_TYPE_BREAK = INT2FIX(4),
|
152
|
+
CATCH_TYPE_REDO = INT2FIX(5),
|
153
|
+
CATCH_TYPE_NEXT = INT2FIX(6)
|
154
|
+
} type;
|
155
|
+
const rb_iseq_t *iseq;
|
156
|
+
unsigned int start;
|
157
|
+
unsigned int end;
|
158
|
+
unsigned int cont;
|
159
|
+
unsigned int sp;
|
160
|
+
};
|
161
|
+
|
162
|
+
PACKED_STRUCT_UNALIGNED(struct iseq_catch_table {
|
163
|
+
unsigned int size;
|
164
|
+
struct iseq_catch_table_entry entries[1]; /* flexible array */
|
165
|
+
});
|
166
|
+
|
167
|
+
static inline int
|
168
|
+
iseq_catch_table_bytes(int n)
|
169
|
+
{
|
170
|
+
enum {
|
171
|
+
catch_table_entries_max = (INT_MAX - sizeof(struct iseq_catch_table)) / sizeof(struct iseq_catch_table_entry)
|
172
|
+
};
|
173
|
+
if (n > catch_table_entries_max) rb_fatal("too large iseq_catch_table - %d", n);
|
174
|
+
return (int)(sizeof(struct iseq_catch_table) +
|
175
|
+
(n - 1) * sizeof(struct iseq_catch_table_entry));
|
176
|
+
}
|
177
|
+
|
178
|
+
#define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512)
|
179
|
+
|
180
|
+
struct iseq_compile_data_storage {
|
181
|
+
struct iseq_compile_data_storage *next;
|
182
|
+
unsigned int pos;
|
183
|
+
unsigned int size;
|
184
|
+
char buff[1]; /* flexible array */
|
185
|
+
};
|
186
|
+
|
187
|
+
/* account for flexible array */
|
188
|
+
#define SIZEOF_ISEQ_COMPILE_DATA_STORAGE \
|
189
|
+
(sizeof(struct iseq_compile_data_storage) - 1)
|
190
|
+
|
191
|
+
struct iseq_compile_data {
|
192
|
+
/* GC is needed */
|
193
|
+
const VALUE err_info;
|
194
|
+
VALUE mark_ary;
|
195
|
+
const VALUE catch_table_ary; /* Array */
|
196
|
+
|
197
|
+
/* GC is not needed */
|
198
|
+
struct iseq_label_data *start_label;
|
199
|
+
struct iseq_label_data *end_label;
|
200
|
+
struct iseq_label_data *redo_label;
|
201
|
+
const rb_iseq_t *current_block;
|
202
|
+
VALUE ensure_node;
|
203
|
+
VALUE for_iseq;
|
204
|
+
struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
|
205
|
+
int loopval_popped; /* used by NODE_BREAK */
|
206
|
+
int cached_const;
|
207
|
+
struct iseq_compile_data_storage *storage_head;
|
208
|
+
struct iseq_compile_data_storage *storage_current;
|
209
|
+
int last_line;
|
210
|
+
int last_coverable_line;
|
211
|
+
int label_no;
|
212
|
+
int node_level;
|
213
|
+
unsigned int ci_index;
|
214
|
+
unsigned int ci_kw_index;
|
215
|
+
const rb_compile_option_t *option;
|
216
|
+
struct rb_id_table *ivar_cache_table;
|
217
|
+
#if SUPPORT_JOKE
|
218
|
+
st_table *labels_table;
|
219
|
+
#endif
|
220
|
+
};
|
221
|
+
|
222
|
+
/* defined? */
|
223
|
+
|
224
|
+
enum defined_type {
|
225
|
+
DEFINED_NIL = 1,
|
226
|
+
DEFINED_IVAR,
|
227
|
+
DEFINED_LVAR,
|
228
|
+
DEFINED_GVAR,
|
229
|
+
DEFINED_CVAR,
|
230
|
+
DEFINED_CONST,
|
231
|
+
DEFINED_METHOD,
|
232
|
+
DEFINED_YIELD,
|
233
|
+
DEFINED_ZSUPER,
|
234
|
+
DEFINED_SELF,
|
235
|
+
DEFINED_TRUE,
|
236
|
+
DEFINED_FALSE,
|
237
|
+
DEFINED_ASGN,
|
238
|
+
DEFINED_EXPR,
|
239
|
+
DEFINED_IVAR2,
|
240
|
+
DEFINED_REF,
|
241
|
+
DEFINED_FUNC
|
242
|
+
};
|
243
|
+
|
244
|
+
VALUE rb_iseq_defined_string(enum defined_type type);
|
245
|
+
void rb_iseq_make_compile_option(struct rb_compile_option_struct *option, VALUE opt);
|
246
|
+
|
247
|
+
/* vm.c */
|
248
|
+
VALUE rb_iseq_local_variables(const rb_iseq_t *iseq);
|
249
|
+
|
250
|
+
RUBY_SYMBOL_EXPORT_END
|
251
|
+
|
252
|
+
#endif /* RUBY_ISEQ_H */
|
@@ -0,0 +1,213 @@
|
|
1
|
+
/**********************************************************************
|
2
|
+
|
3
|
+
method.h -
|
4
|
+
|
5
|
+
$Author$
|
6
|
+
created at: Wed Jul 15 20:02:33 2009
|
7
|
+
|
8
|
+
Copyright (C) 2009 Koichi Sasada
|
9
|
+
|
10
|
+
**********************************************************************/
|
11
|
+
#ifndef RUBY_METHOD_H
|
12
|
+
#define RUBY_METHOD_H 1
|
13
|
+
|
14
|
+
#include "internal.h"
|
15
|
+
|
16
|
+
#ifndef END_OF_ENUMERATION
|
17
|
+
# if defined(__GNUC__) &&! defined(__STRICT_ANSI__)
|
18
|
+
# define END_OF_ENUMERATION(key)
|
19
|
+
# else
|
20
|
+
# define END_OF_ENUMERATION(key) END_OF_##key##_PLACEHOLDER = 0
|
21
|
+
# endif
|
22
|
+
#endif
|
23
|
+
|
24
|
+
/* cref */
|
25
|
+
|
26
|
+
typedef enum {
|
27
|
+
METHOD_VISI_UNDEF = 0x00,
|
28
|
+
METHOD_VISI_PUBLIC = 0x01,
|
29
|
+
METHOD_VISI_PRIVATE = 0x02,
|
30
|
+
METHOD_VISI_PROTECTED = 0x03,
|
31
|
+
|
32
|
+
METHOD_VISI_MASK = 0x03
|
33
|
+
} rb_method_visibility_t;
|
34
|
+
|
35
|
+
typedef struct rb_scope_visi_struct {
|
36
|
+
rb_method_visibility_t method_visi : 3;
|
37
|
+
unsigned int module_func : 1;
|
38
|
+
} rb_scope_visibility_t;
|
39
|
+
|
40
|
+
typedef struct rb_cref_struct {
|
41
|
+
VALUE flags;
|
42
|
+
const VALUE refinements;
|
43
|
+
const VALUE klass;
|
44
|
+
struct rb_cref_struct * const next;
|
45
|
+
const rb_scope_visibility_t scope_visi;
|
46
|
+
} rb_cref_t;
|
47
|
+
|
48
|
+
/* method data type */
|
49
|
+
|
50
|
+
typedef struct rb_method_entry_struct {
|
51
|
+
VALUE flags;
|
52
|
+
const VALUE defined_class;
|
53
|
+
struct rb_method_definition_struct * const def;
|
54
|
+
ID called_id;
|
55
|
+
const VALUE owner;
|
56
|
+
} rb_method_entry_t;
|
57
|
+
|
58
|
+
typedef struct rb_callable_method_entry_struct { /* same fields with rb_method_entry_t */
|
59
|
+
VALUE flags;
|
60
|
+
const VALUE defined_class;
|
61
|
+
struct rb_method_definition_struct * const def;
|
62
|
+
ID called_id;
|
63
|
+
const VALUE owner;
|
64
|
+
} rb_callable_method_entry_t;
|
65
|
+
|
66
|
+
#define METHOD_ENTRY_VISI(me) (rb_method_visibility_t)(((me)->flags & (IMEMO_FL_USER0 | IMEMO_FL_USER1)) >> (IMEMO_FL_USHIFT+0))
|
67
|
+
#define METHOD_ENTRY_BASIC(me) (int) (((me)->flags & (IMEMO_FL_USER2 )) >> (IMEMO_FL_USHIFT+2))
|
68
|
+
#define METHOD_ENTRY_COMPLEMENTED(me) ((me)->flags & IMEMO_FL_USER3)
|
69
|
+
#define METHOD_ENTRY_COMPLEMENTED_SET(me) ((me)->flags = (me)->flags | IMEMO_FL_USER3)
|
70
|
+
|
71
|
+
static inline void
|
72
|
+
METHOD_ENTRY_VISI_SET(rb_method_entry_t *me, rb_method_visibility_t visi)
|
73
|
+
{
|
74
|
+
VM_ASSERT((int)visi >= 0 && visi <= 3);
|
75
|
+
me->flags = (me->flags & ~(IMEMO_FL_USER0 | IMEMO_FL_USER1)) | (visi << (IMEMO_FL_USHIFT+0));
|
76
|
+
}
|
77
|
+
static inline void
|
78
|
+
METHOD_ENTRY_BASIC_SET(rb_method_entry_t *me, unsigned int basic)
|
79
|
+
{
|
80
|
+
VM_ASSERT(basic <= 1);
|
81
|
+
me->flags = (me->flags & ~(IMEMO_FL_USER2 )) | (basic << (IMEMO_FL_USHIFT+2));
|
82
|
+
}
|
83
|
+
static inline void
|
84
|
+
METHOD_ENTRY_FLAGS_SET(rb_method_entry_t *me, rb_method_visibility_t visi, unsigned int basic)
|
85
|
+
{
|
86
|
+
VM_ASSERT((int)visi >= 0 && visi <= 3);
|
87
|
+
VM_ASSERT(basic <= 1);
|
88
|
+
me->flags =
|
89
|
+
(me->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)) |
|
90
|
+
((visi << (IMEMO_FL_USHIFT+0)) | (basic << (IMEMO_FL_USHIFT+2)));
|
91
|
+
}
|
92
|
+
static inline void
|
93
|
+
METHOD_ENTRY_FLAGS_COPY(rb_method_entry_t *dst, const rb_method_entry_t *src)
|
94
|
+
{
|
95
|
+
dst->flags =
|
96
|
+
(dst->flags & ~(IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2)) |
|
97
|
+
(src->flags & (IMEMO_FL_USER0|IMEMO_FL_USER1|IMEMO_FL_USER2));
|
98
|
+
}
|
99
|
+
|
100
|
+
typedef enum {
|
101
|
+
VM_METHOD_TYPE_ISEQ,
|
102
|
+
VM_METHOD_TYPE_CFUNC,
|
103
|
+
VM_METHOD_TYPE_ATTRSET,
|
104
|
+
VM_METHOD_TYPE_IVAR,
|
105
|
+
VM_METHOD_TYPE_BMETHOD,
|
106
|
+
VM_METHOD_TYPE_ZSUPER,
|
107
|
+
VM_METHOD_TYPE_ALIAS,
|
108
|
+
VM_METHOD_TYPE_UNDEF,
|
109
|
+
VM_METHOD_TYPE_NOTIMPLEMENTED,
|
110
|
+
VM_METHOD_TYPE_OPTIMIZED, /* Kernel#send, Proc#call, etc */
|
111
|
+
VM_METHOD_TYPE_MISSING, /* wrapper for method_missing(id) */
|
112
|
+
VM_METHOD_TYPE_REFINED,
|
113
|
+
|
114
|
+
END_OF_ENUMERATION(VM_METHOD_TYPE)
|
115
|
+
} rb_method_type_t;
|
116
|
+
|
117
|
+
#ifndef rb_iseq_t
|
118
|
+
typedef struct rb_iseq_struct rb_iseq_t;
|
119
|
+
#define rb_iseq_t rb_iseq_t
|
120
|
+
#endif
|
121
|
+
|
122
|
+
typedef struct rb_method_iseq_struct {
|
123
|
+
const rb_iseq_t * const iseqptr; /* should be separated from iseqval */
|
124
|
+
rb_cref_t * const cref; /* should be marked */
|
125
|
+
} rb_method_iseq_t; /* check rb_add_method_iseq() when modify the fields */
|
126
|
+
|
127
|
+
typedef struct rb_method_cfunc_struct {
|
128
|
+
VALUE (*func)(ANYARGS);
|
129
|
+
VALUE (*invoker)(VALUE (*func)(ANYARGS), VALUE recv, int argc, const VALUE *argv);
|
130
|
+
int argc;
|
131
|
+
} rb_method_cfunc_t;
|
132
|
+
|
133
|
+
typedef struct rb_method_attr_struct {
|
134
|
+
ID id;
|
135
|
+
const VALUE location; /* should be marked */
|
136
|
+
} rb_method_attr_t;
|
137
|
+
|
138
|
+
typedef struct rb_method_alias_struct {
|
139
|
+
const struct rb_method_entry_struct * const original_me; /* original_me->klass is original owner */
|
140
|
+
} rb_method_alias_t;
|
141
|
+
|
142
|
+
typedef struct rb_method_refined_struct {
|
143
|
+
const struct rb_method_entry_struct * const orig_me;
|
144
|
+
const VALUE owner;
|
145
|
+
} rb_method_refined_t;
|
146
|
+
|
147
|
+
typedef struct rb_method_definition_struct {
|
148
|
+
rb_method_type_t type : 8; /* method type */
|
149
|
+
int alias_count : 28;
|
150
|
+
int complemented_count: 28;
|
151
|
+
|
152
|
+
union {
|
153
|
+
rb_method_iseq_t iseq;
|
154
|
+
rb_method_cfunc_t cfunc;
|
155
|
+
rb_method_attr_t attr;
|
156
|
+
rb_method_alias_t alias;
|
157
|
+
rb_method_refined_t refined;
|
158
|
+
|
159
|
+
const VALUE proc; /* should be marked */
|
160
|
+
enum method_optimized_type {
|
161
|
+
OPTIMIZED_METHOD_TYPE_SEND,
|
162
|
+
OPTIMIZED_METHOD_TYPE_CALL,
|
163
|
+
|
164
|
+
OPTIMIZED_METHOD_TYPE__MAX
|
165
|
+
} optimize_type;
|
166
|
+
} body;
|
167
|
+
|
168
|
+
ID original_id;
|
169
|
+
} rb_method_definition_t;
|
170
|
+
|
171
|
+
#define UNDEFINED_METHOD_ENTRY_P(me) (!(me) || !(me)->def || (me)->def->type == VM_METHOD_TYPE_UNDEF)
|
172
|
+
#define UNDEFINED_REFINED_METHOD_P(def) \
|
173
|
+
((def)->type == VM_METHOD_TYPE_REFINED && \
|
174
|
+
UNDEFINED_METHOD_ENTRY_P((def)->body.refined.orig_me))
|
175
|
+
|
176
|
+
void rb_add_method_cfunc(VALUE klass, ID mid, VALUE (*func)(ANYARGS), int argc, rb_method_visibility_t visi);
|
177
|
+
void rb_add_method_iseq(VALUE klass, ID mid, const rb_iseq_t *iseq, rb_cref_t *cref, rb_method_visibility_t visi);
|
178
|
+
void rb_add_refined_method_entry(VALUE refined_class, ID mid);
|
179
|
+
|
180
|
+
rb_method_entry_t *rb_add_method(VALUE klass, ID mid, rb_method_type_t type, void *option, rb_method_visibility_t visi);
|
181
|
+
rb_method_entry_t *rb_method_entry_set(VALUE klass, ID mid, const rb_method_entry_t *, rb_method_visibility_t noex);
|
182
|
+
rb_method_entry_t *rb_method_entry_create(ID called_id, VALUE klass, rb_method_visibility_t visi, const rb_method_definition_t *def);
|
183
|
+
|
184
|
+
const rb_method_entry_t *rb_method_entry_at(VALUE obj, ID id);
|
185
|
+
|
186
|
+
const rb_method_entry_t *rb_method_entry(VALUE klass, ID id);
|
187
|
+
const rb_method_entry_t *rb_method_entry_with_refinements(VALUE klass, ID id);
|
188
|
+
const rb_method_entry_t *rb_method_entry_without_refinements(VALUE klass, ID id);
|
189
|
+
const rb_method_entry_t *rb_resolve_refined_method(VALUE refinements, const rb_method_entry_t *me);
|
190
|
+
|
191
|
+
const rb_callable_method_entry_t *rb_callable_method_entry(VALUE klass, ID id);
|
192
|
+
const rb_callable_method_entry_t *rb_callable_method_entry_with_refinements(VALUE klass, ID id);
|
193
|
+
const rb_callable_method_entry_t *rb_callable_method_entry_without_refinements(VALUE klass, ID id);
|
194
|
+
const rb_callable_method_entry_t *rb_resolve_refined_method_callable(VALUE refinements, const rb_callable_method_entry_t *me);
|
195
|
+
|
196
|
+
int rb_method_entry_arity(const rb_method_entry_t *me);
|
197
|
+
int rb_method_entry_eq(const rb_method_entry_t *m1, const rb_method_entry_t *m2);
|
198
|
+
st_index_t rb_hash_method_entry(st_index_t hash, const rb_method_entry_t *me);
|
199
|
+
|
200
|
+
VALUE rb_method_entry_location(const rb_method_entry_t *me);
|
201
|
+
VALUE rb_mod_method_location(VALUE mod, ID id);
|
202
|
+
VALUE rb_obj_method_location(VALUE obj, ID id);
|
203
|
+
|
204
|
+
void rb_free_method_entry(const rb_method_entry_t *me);
|
205
|
+
void rb_sweep_method_entry(void *vm);
|
206
|
+
|
207
|
+
const rb_method_entry_t *rb_method_entry_clone(const rb_method_entry_t *me);
|
208
|
+
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);
|
209
|
+
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
|
210
|
+
|
211
|
+
void rb_scope_visibility_set(rb_method_visibility_t);
|
212
|
+
|
213
|
+
#endif /* RUBY_METHOD_H */
|