Ruby  3.1.4p223 (2023-03-30 revision HEAD)
iseq.h
1 #ifndef RUBY_ISEQ_H
2 #define RUBY_ISEQ_H 1
3 /**********************************************************************
4 
5  iseq.h -
6 
7  $Author$
8  created at: 04/01/01 23:36:57 JST
9 
10  Copyright (C) 2004-2008 Koichi Sasada
11 
12 **********************************************************************/
13 #include "internal/gc.h"
14 #include "vm_core.h"
15 
16 RUBY_EXTERN const int ruby_api_version[];
17 #define ISEQ_MAJOR_VERSION ((unsigned int)ruby_api_version[0])
18 #define ISEQ_MINOR_VERSION ((unsigned int)ruby_api_version[1])
19 
20 #ifndef USE_ISEQ_NODE_ID
21 #define USE_ISEQ_NODE_ID 1
22 #endif
23 
24 #ifndef rb_iseq_t
25 typedef struct rb_iseq_struct rb_iseq_t;
26 #define rb_iseq_t rb_iseq_t
27 #endif
28 
29 extern const ID rb_iseq_shared_exc_local_tbl[];
30 
31 #define ISEQ_COVERAGE(iseq) iseq->body->variable.coverage
32 #define ISEQ_COVERAGE_SET(iseq, cov) RB_OBJ_WRITE(iseq, &iseq->body->variable.coverage, cov)
33 #define ISEQ_LINE_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_LINES)
34 #define ISEQ_BRANCH_COVERAGE(iseq) RARRAY_AREF(ISEQ_COVERAGE(iseq), COVERAGE_INDEX_BRANCHES)
35 
36 #define ISEQ_PC2BRANCHINDEX(iseq) iseq->body->variable.pc2branchindex
37 #define ISEQ_PC2BRANCHINDEX_SET(iseq, h) RB_OBJ_WRITE(iseq, &iseq->body->variable.pc2branchindex, h)
38 
39 #define ISEQ_FLIP_CNT(iseq) (iseq)->body->variable.flip_count
40 
41 static inline rb_snum_t
42 ISEQ_FLIP_CNT_INCREMENT(const rb_iseq_t *iseq)
43 {
44  rb_snum_t cnt = iseq->body->variable.flip_count;
45  iseq->body->variable.flip_count += 1;
46  return cnt;
47 }
48 
49 static inline VALUE *
50 ISEQ_ORIGINAL_ISEQ(const rb_iseq_t *iseq)
51 {
52  return iseq->body->variable.original_iseq;
53 }
54 
55 static inline void
56 ISEQ_ORIGINAL_ISEQ_CLEAR(const rb_iseq_t *iseq)
57 {
58  void *ptr = iseq->body->variable.original_iseq;
59  iseq->body->variable.original_iseq = NULL;
60  if (ptr) {
61  ruby_xfree(ptr);
62  }
63 }
64 
65 static inline VALUE *
66 ISEQ_ORIGINAL_ISEQ_ALLOC(const rb_iseq_t *iseq, long size)
67 {
68  return iseq->body->variable.original_iseq =
69  ALLOC_N(VALUE, size);
70 }
71 
72 #define ISEQ_TRACE_EVENTS (RUBY_EVENT_LINE | \
73  RUBY_EVENT_CLASS | \
74  RUBY_EVENT_END | \
75  RUBY_EVENT_CALL | \
76  RUBY_EVENT_RETURN| \
77  RUBY_EVENT_C_CALL| \
78  RUBY_EVENT_C_RETURN| \
79  RUBY_EVENT_B_CALL| \
80  RUBY_EVENT_B_RETURN| \
81  RUBY_EVENT_COVERAGE_LINE| \
82  RUBY_EVENT_COVERAGE_BRANCH)
83 
84 #define ISEQ_NOT_LOADED_YET IMEMO_FL_USER1
85 #define ISEQ_USE_COMPILE_DATA IMEMO_FL_USER2
86 #define ISEQ_TRANSLATED IMEMO_FL_USER3
87 #define ISEQ_MARKABLE_ISEQ IMEMO_FL_USER4
88 
89 #define ISEQ_EXECUTABLE_P(iseq) (FL_TEST_RAW(((VALUE)iseq), ISEQ_NOT_LOADED_YET | ISEQ_USE_COMPILE_DATA) == 0)
90 
92  /* GC is needed */
93  const VALUE err_info;
94  const VALUE catch_table_ary; /* Array */
95 
96  /* GC is not needed */
97  struct iseq_label_data *start_label;
98  struct iseq_label_data *end_label;
99  struct iseq_label_data *redo_label;
100  const rb_iseq_t *current_block;
101  struct iseq_compile_data_ensure_node_stack *ensure_node_stack;
102  struct {
103  struct iseq_compile_data_storage *storage_head;
104  struct iseq_compile_data_storage *storage_current;
105  } node;
106  struct {
107  struct iseq_compile_data_storage *storage_head;
108  struct iseq_compile_data_storage *storage_current;
109  } insn;
110  bool in_rescue;
111  int loopval_popped; /* used by NODE_BREAK */
112  int last_line;
113  int label_no;
114  int node_level;
115  int isolated_depth;
116  unsigned int ci_index;
117  const rb_compile_option_t *option;
118  struct rb_id_table *ivar_cache_table;
119  const struct rb_builtin_function *builtin_function_table;
120  const NODE *root_node;
121 #if OPT_SUPPORT_JOKE
122  st_table *labels_table;
123 #endif
124 };
125 
126 static inline struct iseq_compile_data *
127 ISEQ_COMPILE_DATA(const rb_iseq_t *iseq)
128 {
129  if (iseq->flags & ISEQ_USE_COMPILE_DATA) {
130  return iseq->aux.compile_data;
131  }
132  else {
133  return NULL;
134  }
135 }
136 
137 static inline void
138 ISEQ_COMPILE_DATA_ALLOC(rb_iseq_t *iseq)
139 {
140  iseq->aux.compile_data = ZALLOC(struct iseq_compile_data);
141  iseq->flags |= ISEQ_USE_COMPILE_DATA;
142 }
143 
144 static inline void
145 ISEQ_COMPILE_DATA_CLEAR(rb_iseq_t *iseq)
146 {
147  iseq->flags &= ~ISEQ_USE_COMPILE_DATA;
148  iseq->aux.compile_data = NULL;
149 }
150 
151 static inline rb_iseq_t *
152 iseq_imemo_alloc(void)
153 {
154  return (rb_iseq_t *)rb_imemo_new(imemo_iseq, 0, 0, 0, 0);
155 }
156 
157 VALUE rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt);
158 void rb_ibf_load_iseq_complete(rb_iseq_t *iseq);
159 const rb_iseq_t *rb_iseq_ibf_load(VALUE str);
160 const rb_iseq_t *rb_iseq_ibf_load_bytes(const char *cstr, size_t);
161 VALUE rb_iseq_ibf_load_extra_data(VALUE str);
162 void rb_iseq_init_trace(rb_iseq_t *iseq);
163 int rb_iseq_add_local_tracepoint_recursively(const rb_iseq_t *iseq, rb_event_flag_t turnon_events, VALUE tpval, unsigned int target_line, bool target_bmethod);
164 int rb_iseq_remove_local_tracepoint_recursively(const rb_iseq_t *iseq, VALUE tpval);
165 const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
166 
167 #if VM_INSN_INFO_TABLE_IMPL == 2
168 unsigned int *rb_iseq_insns_info_decode_positions(const struct rb_iseq_constant_body *body);
169 #endif
170 
171 int rb_vm_insn_addr2opcode(const void *addr);
172 
173 RUBY_SYMBOL_EXPORT_BEGIN
174 
175 /* compile.c */
176 VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node);
177 VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc);
178 VALUE *rb_iseq_original_iseq(const rb_iseq_t *iseq);
179 void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc,
180  VALUE locals, VALUE args,
181  VALUE exception, VALUE body);
182 void rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *arena);
183 
184 /* iseq.c */
185 VALUE rb_iseq_load(VALUE data, VALUE parent, VALUE opt);
186 VALUE rb_iseq_parameters(const rb_iseq_t *iseq, int is_proc);
187 unsigned int rb_iseq_line_no(const rb_iseq_t *iseq, size_t pos);
188 #ifdef USE_ISEQ_NODE_ID
189 int rb_iseq_node_id(const rb_iseq_t *iseq, size_t pos);
190 #endif
191 void rb_iseq_trace_set(const rb_iseq_t *iseq, rb_event_flag_t turnon_events);
192 void rb_iseq_trace_set_all(rb_event_flag_t turnon_events);
193 void rb_iseq_insns_info_encode_positions(const rb_iseq_t *iseq);
194 
195 struct rb_iseq_constant_body *rb_iseq_constant_body_alloc(void);
196 VALUE rb_iseqw_new(const rb_iseq_t *iseq);
197 const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw);
198 
199 VALUE rb_iseq_absolute_path(const rb_iseq_t *iseq); /* obsolete */
200 int rb_iseq_from_eval_p(const rb_iseq_t *iseq);
201 VALUE rb_iseq_type(const rb_iseq_t *iseq);
202 VALUE rb_iseq_label(const rb_iseq_t *iseq);
203 VALUE rb_iseq_base_label(const rb_iseq_t *iseq);
204 VALUE rb_iseq_first_lineno(const rb_iseq_t *iseq);
205 VALUE rb_iseq_method_name(const rb_iseq_t *iseq);
206 void rb_iseq_code_location(const rb_iseq_t *iseq, int *first_lineno, int *first_column, int *last_lineno, int *last_column);
207 
208 void rb_iseq_remove_coverage_all(void);
209 
210 /* proc.c */
211 const rb_iseq_t *rb_method_iseq(VALUE body);
212 const rb_iseq_t *rb_proc_get_iseq(VALUE proc, int *is_proc);
213 
215  unsigned int inline_const_cache: 1;
216  unsigned int peephole_optimization: 1;
217  unsigned int tailcall_optimization: 1;
218  unsigned int specialized_instruction: 1;
219  unsigned int operands_unification: 1;
220  unsigned int instructions_unification: 1;
221  unsigned int stack_caching: 1;
222  unsigned int frozen_string_literal: 1;
223  unsigned int debug_frozen_string_literal: 1;
224  unsigned int coverage_enabled: 1;
225  int debug_level;
226 };
227 
229  int line_no;
230 #ifdef USE_ISEQ_NODE_ID
231  int node_id;
232 #endif
233  rb_event_flag_t events;
234 };
235 
237  enum catch_type {
238  CATCH_TYPE_RESCUE = INT2FIX(1),
239  CATCH_TYPE_ENSURE = INT2FIX(2),
240  CATCH_TYPE_RETRY = INT2FIX(3),
241  CATCH_TYPE_BREAK = INT2FIX(4),
242  CATCH_TYPE_REDO = INT2FIX(5),
243  CATCH_TYPE_NEXT = INT2FIX(6)
244  } type;
245 
246  /*
247  * iseq type:
248  * CATCH_TYPE_RESCUE, CATCH_TYPE_ENSURE:
249  * use iseq as continuation.
250  *
251  * CATCH_TYPE_BREAK (iter):
252  * use iseq as key.
253  *
254  * CATCH_TYPE_BREAK (while), CATCH_TYPE_RETRY,
255  * CATCH_TYPE_REDO, CATCH_TYPE_NEXT:
256  * NULL.
257  */
258  rb_iseq_t *iseq;
259 
260  unsigned int start;
261  unsigned int end;
262  unsigned int cont;
263  unsigned int sp;
264 };
265 
266 PACKED_STRUCT_UNALIGNED(struct iseq_catch_table {
267  unsigned int size;
268  struct iseq_catch_table_entry entries[FLEX_ARY_LEN];
269 });
270 
271 static inline int
272 iseq_catch_table_bytes(int n)
273 {
274  enum {
275  catch_table_entry_size = sizeof(struct iseq_catch_table_entry),
276  catch_table_entries_max = (INT_MAX - offsetof(struct iseq_catch_table, entries)) / catch_table_entry_size
277  };
278  if (n > catch_table_entries_max) rb_fatal("too large iseq_catch_table - %d", n);
279  return (int)(offsetof(struct iseq_catch_table, entries) +
280  n * catch_table_entry_size);
281 }
282 
283 #define INITIAL_ISEQ_COMPILE_DATA_STORAGE_BUFF_SIZE (512)
284 
286  struct iseq_compile_data_storage *next;
287  unsigned int pos;
288  unsigned int size;
289  char buff[FLEX_ARY_LEN];
290 };
291 
292 /* defined? */
293 
294 enum defined_type {
295  DEFINED_NOT_DEFINED,
296  DEFINED_NIL = 1,
297  DEFINED_IVAR,
298  DEFINED_LVAR,
299  DEFINED_GVAR,
300  DEFINED_CVAR,
301  DEFINED_CONST,
302  DEFINED_METHOD,
303  DEFINED_YIELD,
304  DEFINED_ZSUPER,
305  DEFINED_SELF,
306  DEFINED_TRUE,
307  DEFINED_FALSE,
308  DEFINED_ASGN,
309  DEFINED_EXPR,
310  DEFINED_REF,
311  DEFINED_FUNC,
312  DEFINED_CONST_FROM
313 };
314 
315 VALUE rb_iseq_defined_string(enum defined_type type);
316 
317 /* vm.c */
318 VALUE rb_iseq_local_variables(const rb_iseq_t *iseq);
319 
320 RUBY_SYMBOL_EXPORT_END
321 
322 #endif /* RUBY_ISEQ_H */
#define RUBY_EXTERN
Declaration of externally visible global variables.
Definition: dllexport.h:47
uint32_t rb_event_flag_t
Represents event(s).
Definition: event.h:103
#define INT2FIX
Old name of RB_INT2FIX.
Definition: long.h:48
#define ZALLOC
Old name of RB_ZALLOC.
Definition: memory.h:396
#define ALLOC_N
Old name of RB_ALLOC_N.
Definition: memory.h:393
void rb_fatal(const char *fmt,...)
Raises the unsung "fatal" exception.
Definition: error.c:3076
const int ruby_api_version[3]
API versions, in { major, minor, teeny } order.
Definition: version.c:27
VALUE type(ANYARGS)
ANYARGS-ed function type.
Definition: cxxanyargs.hpp:56
Definition: node.h:155
Definition: iseq.h:236
Definition: iseq.h:228
Definition: st.h:79
uintptr_t ID
Type that represents a Ruby identifier such as a variable name.
Definition: value.h:52
uintptr_t VALUE
Type that represents a Ruby object.
Definition: value.h:40
void ruby_xfree(void *ptr)
Deallocates a storage instance.
Definition: gc.c:11775